Skip to content

A Model Context Protocol (MCP) server for managing project documentation and saving conversation logs within a user-specified target project directory.

Notifications You must be signed in to change notification settings

dwarvesf/mcp-playbook

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Playbook Server

A Model Context Protocol (MCP) server for managing project documentation and saving conversation logs within a user-specified target project directory.

Usage with Claude Desktop or MCP clients

To use this MCP server with Claude Desktop, you would add a configuration entry to your Claude Desktop settings. The exact command and args will depend on how you choose to run the server (e.g., directly via node or using Docker).

First, ensure that you add this prompt to your cursor rules, cline rules, or windsurf rules:

ALWAYS run the `init_playbook` tool before starting to get instructions on how things should be done and documented.

Then, add the following configuration to your MCP client:

{
  "mcpServers": {
    "mcp-playbook": {
      "command": "npx",
      "args": ["-y", "@dwarvesf/mcp-playbook@latest"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "your_github_token_here"
      }
    }
  }
}

Consult the Claude Desktop documentation for detailed instructions on configuring MCP servers.

How the MCP works behind the scenes

The MCP Playbook server operates by receiving tool call requests from an MCP client (like Claude Desktop). These requests are processed in the src/index.ts file, which acts as the server's entry point.

graph LR
    A[MCP Client] --> B["CallToolRequestSchema"];
    A --> E["ListToolsRequestSchema"];
    A --> F["ListPromptsRequestSchema"];
    A --> G["GetPromptRequestSchema"];

    subgraph src/index.ts
        B
        E
        F
        G
    end

    B --> C["Switch Case (toolName)"];

    subgraph src/tools/
        C --> C1("init_playbook");
        C --> C2("create_adr");
        C --> C3("search_runbook");
        C --> C4("... ... ...");
    end

    C1 --> D1("handleInitPlaybook");
    C2 --> D2("handleCreateAdr");
    C3 --> D3("handleSearchRunbook");
    C4 --> D4("... ... ...");

    E --> D12("toolDefinitions");
    F --> D13("handleListPrompts");
    G --> D14("handleGetPrompt");

    subgraph src/handlers/
        D1
        D2
        D3
        D4
        D12
        D13
        D14
    end
Loading
  1. Tool Call Request: An MCP client sends a CallToolRequest to the server, specifying the toolName and any necessary arguments.
  2. Request Handling: The src/index.ts file has a request handler set up for CallToolRequest using server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => { ... }).
  3. Tool Routing (Switch Case): Inside the request handler, a switch statement on the toolName routes the request to the appropriate handler function.
  4. Handler Execution: Each case in the switch statement calls a dedicated handler function (e.g., handleCreateSpec, handleSearchRunbook, handleSyncPrompt) located in the src/handlers.ts file. These handlers contain the specific logic for each tool.
  5. Result: The handler function performs the requested action and returns a result. This result is then sent back to the MCP client.

This flow ensures that each tool call is directed to the correct logic for execution, allowing the server to perform various documentation and utility tasks.

Available Tools

Tool Name Description
init_playbook Provides an instruction to the LLM about the purpose of the mcp-playbook server, which is to facilitate local project documentation and enable partial replication of documentation and chat logs for an AI-powered playbook.
create_spec Creates or overwrites a new specification file (e.g., PRD, RFC, architectural planning) in the docs/specs/ directory of the target project. Specification files will be named following a spec-name.md convention with sequence numbering.
create_adr Creates or overwrites a new Architectural Decision Record (ADR) file in the docs/adr/ directory of the target project. ADR files will be named following an adr-name.md convention with sequence numbering.
create_changelog Creates a new, detailed, and user-facing changelog entry file in the docs/changelog/ directory of the target project. Each changelog entry will be a separate file named following a changelog-entry.md convention with sequence numbering.
save_and_upload_chat_log Captures the current conversation history, saves it as a markdown file in the .chat/ directory of the target project, and uploads it to the dwarvesf/prompt-log GitHub repository. Requires a user ID for organization.
search_runbook Fuzzy search for keywords in the dwarvesf/runbook GitHub repository. If keyword has spaces, searches exact phrase OR individual words. Returns top 5 matches with full content & total count.
search_prompts Fuzzy search for keywords in the dwarvesf/prompt-db GitHub repository (excluding the .synced_prompts/ folder).
suggest_runbook Creates or updates a Pull Request in the dwarvesf/runbook repository with a new runbook entry.
sync_prompt Syncs an LLM prompt to the dwarvesf/prompt-db GitHub repository.
think Use the tool to think about something. It will not obtain new information or make any changes to the repository, but just log the thought. Use it when complex reasoning or brainstorming is needed.

Overview

This mcp-playbook server is a self-contained Node.js/TypeScript application that provides a set of tools accessible via the Model Context Protocol (MCP). Its primary functions are to help LLMs structure documentation within a designated project directory and to save/upload conversation histories. Unlike tools that might rely on external commander or github environments, this server implements file system operations and GitHub API interactions directly using Node.js's built-in modules (fs, path, https) and libraries like node-fetch.

The server operates on a target_project_dir specified by the LLM, managing files and directories within that location. It does not store documentation or chat logs within its own repository structure.

Data Flow and Interaction

The interaction between the AI conversation, file exploration, the LLM, the mcp-playbook server, and the GitHub repositories can be visualized as follows:

graph TD
    A[LLM] --> B("AI Conversation")
    B --> C{Explore Files}
    C -->|Files with Prompts| D("Prompts in Files")
    C -->|Files without Prompts| B
    B -->|Provides Context| F("MCP Playbook Server")
    D -->|Provides Context| F
    F -->|suggest_runbook| G["dwarvesf/runbook (Practices/Specs)"]
    F -->|save_and_upload_chat_log| H["dwarvesf/prompt-log (Conversation Logs)"]
    F -->|sync_prompt| I["dwarvesf/prompt-db (Synced Prompts)"]
Loading

This diagram illustrates how the AI conversation and the prompts found during file exploration provide context to the MCP Playbook server. The server then executes the suggest_runbook, save_and_upload_chat_log, and sync_prompt tools to interact with the respective GitHub repositories.

Tool Details

init_playbook

Provides an instruction to the LLM about the purpose of the mcp-playbook server, which is to facilitate local project documentation and enable partial replication of documentation and chat logs for an AI-powered playbook.

Parameters: None.

Returns: A JSON object containing the instruction.

{
  "instruction": "string" // Instruction for the LLM regarding the purpose of the mcp-playbook.
}

create_spec

Creates or overwrites a new specification file (e.g., PRD, RFC, architectural planning) in the docs/specs/ directory of the target project. Specification files will be named following a spec-name.md convention with sequence numbering (e.g., 0001-initial-design.md).

Parameters:

  • target_project_dir (string, required): The absolute or relative path to the root of the target project directory.
  • spec_name (string, required): The name of the specification file (without sequence numbers and the .md extension). Basic sanitization is applied.
  • content (string, required): The markdown content of the specification.

Returns: A JSON object indicating success or failure, including the path if successful.

{
  "status": "success" | "error",
  "path": "string" | undefined, // Path to the created file if successful
  "message": "string" // Description of the result or error
}

create_adr

Creates or overwrites a new Architectural Decision Record (ADR) file in the docs/adr/ directory of the target project. ADR files will be named following an adr-name.md convention with sequence numbering (e.g., 0001-use-react.md).

Parameters:

  • target_project_dir (string, required): The absolute path to the root of the target project directory. Using an absolute path is highly recommended for reliability.
  • adr_name (string, required): The name of the ADR file (without sequence numbers and the .md extension). Basic sanitization is applied.
  • content (string, required): The markdown content of the ADR.

Returns: A JSON object indicating success or failure, including the path if successful.

{
  "status": "success" | "error",
  "path": "string" | undefined, // Path to the created file if successful
  "message": "string" // Description of the result or error
}

create_changelog

Creates a new, detailed, and user-facing changelog entry file in the docs/changelog/ directory of the target project. Each changelog entry will be a separate file named following a changelog-entry.md convention with sequence numbering (e.g., 0001-added-new-feature.md). Entries should provide comprehensive information about changes, including how to use new features or any impact on existing functionality, rather than being brief summaries.

Parameters:

  • target_project_dir (string, required): The absolute path to the root of the target project directory. Using an absolute path is highly recommended for reliability.
  • entry_content (string, required): The markdown content of the new changelog entry.
  • changelog_name (string, required): The desired name for the changelog file (without sequence numbers and the .md extension).

Returns: A JSON object indicating success or failure, including the path if successful.

{
  "status": "success" | "error",
  "path": "string" | undefined, // Path to the updated file if successful
  "message": "string" // Description of the result or error
}

save_and_upload_chat_log

Captures the current conversation history. If the MCP client provides the history directly, it's used. Otherwise, the server attempts to parse chat logs from locally installed supported editors (Cursor, Zed, Cline) based on the optional editorType parameter or by trying each parser. The captured/parsed history is then saved as a uniquely named markdown file in the .chat/ directory of the target project and uploaded to the dwarvesf/prompt-log GitHub repository. Requires a userId for organizing logs.

Parameters:

  • target_project_dir (string, required): The absolute path to the root of the target project directory where the chat log should be saved locally before uploading. Using an absolute path is highly recommended for reliability.
  • userId (string, required): The unique ID of the user/LLM client (e.g., your GitHub username).
  • editorType (string, optional): Specifies the editor (e.g., 'cursor', 'zed', 'cline') from which to attempt parsing chat history if not directly provided by the client. If omitted, the server may try to detect logs from all supported editors.

Returns: A JSON object indicating success or failure, including the local path, GitHub path, and potentially the GitHub URL if successful.

{
  "status": "success" | "error",
  "local_path": "string" | undefined, // Path to the locally saved file
  "github_path": "string" | undefined, // Path within the GitHub repository
  "github_url": "string" | undefined, // URL of the file on GitHub
  "commit_sha": "string" | undefined, // SHA of the commit if successful
  "commit_url": "string" | undefined, // URL of the commit if successful
  "message": "string" // Description of the result or error
}

search_runbook

Fuzzy search for keywords in the dwarvesf/runbook GitHub repository. If the keyword contains spaces, it searches for the exact phrase OR the individual words. It returns the top 5 matching files with their full content and the total number of matches found by GitHub. Includes an in-memory cache to avoid repeated GitHub API calls for the same query while the server is active.

Parameters:

  • keyword (string, required): The keyword to search for in the dwarvesf/runbook repository.

Returns: A JSON object containing the search results.

{
  "results": [ // An array of search results (limited to top 5)
    {
      "path": "string", // The path to the file in the repository
      "snippet": "string", // A snippet of the content where the keyword was found
      "full_content": "string" | null, // The full decoded content of the file, or null if fetching failed
      "url": "string" // The URL to the file on GitHub
    }
  ],
  "total_count": "number", // The total number of results found by GitHub's search
  "message": "string" // A message describing the result of the search, e.g., "Found and processed 5 results out of 10 total."
}

search_prompts

Fuzzy search for keywords in the dwarvesf/prompt-db GitHub repository (excluding the .synced_prompts/ folder).

Parameters:

  • keyword (string, required): The keyword to search for in the dwarvesf/prompt-db repository (excluding the .synced_prompts/ folder).

Returns: A JSON object containing the search results.

{
  "results": [ // An array of search results (limited to top 5)
    {
      "path": "string", // The path to the file in the repository
      "snippet": "string", // A snippet of the content where the keyword was found
      "full_content": "string" | null, // The full decoded content of the file, or null if fetching failed
      "url": "string" // The URL to the file on GitHub
    }
  ],
  "total_count": "number", // The total number of results found by GitHub's search
  "message": "string" // A message describing the result of the search, e.g., "Found and processed 5 results out of 10 total."
}

suggest_runbook

Creates or updates a Pull Request in the dwarvesf/runbook repository with a new runbook entry.

Parameters:

  • content (string, required): The markdown content of the runbook entry. Include frontmatter (--- title: ..., description: ..., date: ..., authors: ..., tags: ... ---) at the beginning for better organization.
  • target_folder (string, required): The specific folder within the dwarvesf/runbook repository. Must be one of: technical-patterns, operational-state-reporting, human-escalation-protocols, diagnostic-and-information-gathering, automations, action-policies-and-constraints.
  • filename_slug (string, optional): A slug to be used for the filename.
  • pr_number (number, optional): The number of an existing Pull Request to update.
  • branch_name (string, optional): The name of the branch to use for the changes. Suggestion: follow a descriptive naming convention (e.g., 'feat/add-runbook-entry-slug').
  • commit_message (string, optional): The commit message for the file change.
  • pr_title (string, optional): The title for a new Pull Request. Follow commitlint standards (e.g., 'feat: add new runbook entry').
  • pr_body (string, optional): The body content for a new Pull Request. Provide a comprehensive and detailed description explaining the context and purpose of the runbook entry.

Returns: A JSON object indicating success or failure, including the PR number and URL if successful.

{
  "status": "success" | "error",
  "pr_number": "number" | undefined, // The number of the created or updated Pull Request.
  "pr_url": "string" | undefined, // The URL of the created or updated Pull Request.
  "message": "string" // Description of the result or error
}

sync_prompt

Syncs an LLM prompt to the dwarvesf/prompt-db GitHub repository.

Parameters:

  • projectName (string, required): The name of the project the prompt belongs to.
  • promptName (string, required): The variable or logical name of the prompt within the project.
  • promptContent (string, required): The actual content of the LLM prompt.

Returns: A JSON object indicating success or failure, including the GitHub path and URL if successful.

{
  "status": "success" | "error",
  "github_path": "string" | undefined, // Path within the GitHub repository
  "github_url": "string" | undefined, // URL of the file on GitHub
  "commit_sha": "string" | undefined, // SHA of the commit if successful
  "commit_url": "string" | undefined, // URL of the commit if successful
  "message": "string" // Description of the result or error
}

think

Use the tool to think about something. It will not obtain new information or make any changes to the repository, but just log the thought. Use it when complex reasoning or brainstorming is needed. For example, if you explore the repo and discover the source of a bug, call this tool to brainstorm several unique ways of fixing the bug, and assess which change(s) are likely to be simplest and most effective. Alternatively, if you receive some test results, call this tool to brainstorm ways to fix the failing tests.

Parameters:

  • thought (string, required): Your thoughts.

Returns: A JSON object containing the thought that was processed. The server wraps the raw string returned by the handler.

{
  "content": [
    {
      "type": "text",
      "text": "\"Your processed thought here\"" // Note: The thought string itself will be JSON stringified
    }
  ]
}

Or, if an error occurs:

{
  "isError": true,
  "content": [
    {
      "type": "text",
      "text": "Error: Invalid arguments: Your error message"
    }
  ]
}

Setup

Local Development

  1. Clone the repository:
    git clone [email protected]:dwarvesf/mcp-playbook.git
    cd mcp-playbook
  2. Install dependencies:
    npm install
  3. Build the project:
    npm run build # This compiles TypeScript to JavaScript in the 'dist' directory
  4. Configure GitHub Authentication (see Configuration section below).
  5. Run the compiled server:
    node dist/src/index.js

Running with Docker (Optional)

A Dockerfile is included in the plan but not fully implemented here. Once completed, you can build and run the Docker image:

  1. Build the Docker image:
    docker build -t mcp-playbook .
  2. Run the container, ensuring the GITHUB_PERSONAL_ACCESS_TOKEN environment variable is passed:
    docker run --pull=always -e GITHUB_PERSONAL_ACCESS_TOKEN="your_token" mcp-playbook

Configuration and testing

The save_and_upload_chat_log tool requires a GitHub Personal Access Token with repo scope to upload files to dwarvesf/prompt-log. This token must be provided via the GITHUB_PERSONAL_ACCESS_TOKEN environment variable.

For local development, you can use a .env file in the project root:

GITHUB_PERSONAL_ACCESS_TOKEN=your_github_token_here

Ensure .env is added to your .gitignore file.

Testing

Run npm run build and update your MCP config to direct it to the output index.js file.

{
  "mcpServers": {
    "mcp-playbook": {
      "command": "node",
      "args": ["/path/to/your/mcp-playbook/dist/src/index.js"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "your_github_token_here"
      }
    }
  }
}

Usage Example

mcp_mcp-playbook_create_spec(target_project_dir="/Users/monotykamary/VCS/working-remote/my-new-project", spec_name="Initial Design", content="# Initial Design Specification\n\nThis document outlines the initial design of the project...")

Troubleshooting

  • Environment Variable Not Set: Ensure the GITHUB_PERSONAL_ACCESS_TOKEN environment variable is correctly set in the environment where the mcp-playbook server process is running.
  • File/Directory Not Found: The server operates within the specified target_project_dir. Ensure the path provided exists and is accessible by the server process. File system errors (ENOENT) often indicate an incorrect path or missing directory.
  • GitHub API Errors: If save_and_upload_chat_log fails, check the server logs for details from the githubApi.ts error handling. Common issues include incorrect tokens, insufficient permissions, or rate limiting.

Handoff Guidance for Another Engineer

  • Self-Contained Implementation: This server uses direct Node.js fs and node-fetch for file system and GitHub API interactions, not external commander or github tools provided by the environment.
  • target_project_dir: All tools interacting with user files require and operate within the target_project_dir. Input validation for this path is crucial for security.
  • Dependencies: Ensure all npm dependencies are installed (npm install). The project uses TypeScript; compile with npm run build (or npx tsc).
  • Authentication: GitHub authentication relies solely on the GITHUB_PERSONAL_ACCESS_TOKEN environment variable read by process.env in src/githubApi.ts.
  • Conversation History Placeholder: The getConversationHistoryPlaceholder() function in src/handlers.ts is a dummy implementation. It must be replaced with logic to retrieve actual conversation history from the MCP framework hosting this server for the save_and_upload_chat_log tool to work correctly.
  • MCP Framework Integration: The handler functions in src/handlers.ts are designed to be called by an external MCP framework that receives and routes tool calls from the LLM. The src/index.ts file is the conceptual entry point for this integration.

About

A Model Context Protocol (MCP) server for managing project documentation and saving conversation logs within a user-specified target project directory.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published