A Model Context Protocol (MCP) server for managing project documentation and saving conversation logs within a user-specified target project directory.
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.
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
- Tool Call Request: An MCP client sends a
CallToolRequest
to the server, specifying thetoolName
and any necessaryarguments
. - Request Handling: The
src/index.ts
file has a request handler set up forCallToolRequest
usingserver.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => { ... })
. - Tool Routing (Switch Case): Inside the request handler, a
switch
statement on thetoolName
routes the request to the appropriate handler function. - Handler Execution: Each case in the
switch
statement calls a dedicated handler function (e.g.,handleCreateSpec
,handleSearchRunbook
,handleSyncPrompt
) located in thesrc/handlers.ts
file. These handlers contain the specific logic for each tool. - 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.
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. |
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.
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)"]
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.
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.
}
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
}
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
}
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
}
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
}
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 thedwarvesf/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."
}
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 thedwarvesf/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."
}
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 thedwarvesf/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
}
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
}
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"
}
]
}
- Clone the repository:
git clone [email protected]:dwarvesf/mcp-playbook.git cd mcp-playbook
- Install dependencies:
npm install
- Build the project:
npm run build # This compiles TypeScript to JavaScript in the 'dist' directory
- Configure GitHub Authentication (see Configuration section below).
- Run the compiled server:
node dist/src/index.js
A Dockerfile
is included in the plan but not fully implemented here. Once completed, you can build and run the Docker image:
- Build the Docker image:
docker build -t mcp-playbook .
- 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
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.
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"
}
}
}
}
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...")
- Environment Variable Not Set: Ensure the
GITHUB_PERSONAL_ACCESS_TOKEN
environment variable is correctly set in the environment where themcp-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 thegithubApi.ts
error handling. Common issues include incorrect tokens, insufficient permissions, or rate limiting.
- Self-Contained Implementation: This server uses direct Node.js
fs
andnode-fetch
for file system and GitHub API interactions, not externalcommander
orgithub
tools provided by the environment. target_project_dir
: All tools interacting with user files require and operate within thetarget_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 withnpm run build
(ornpx tsc
). - Authentication: GitHub authentication relies solely on the
GITHUB_PERSONAL_ACCESS_TOKEN
environment variable read byprocess.env
insrc/githubApi.ts
. - Conversation History Placeholder: The
getConversationHistoryPlaceholder()
function insrc/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 thesave_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. Thesrc/index.ts
file is the conceptual entry point for this integration.