integrations/beads-mcp/README.md
MCP server for beads issue tracker and agentic memory system. Enables AI agents to manage tasks using bd CLI through Model Context Protocol.
Note: For environments with shell access (Claude Code, Cursor, Windsurf), the CLI + hooks approach is recommended over MCP. It uses ~1-2k tokens vs 10-50k for MCP schemas, resulting in lower compute cost and latency. See the main README for CLI setup.
Use this MCP server for MCP-only environments like Claude Desktop where CLI access is unavailable.
Install from PyPI:
# Using uv (recommended)
uv tool install beads-mcp
# Or using pip
pip install beads-mcp
Add to your Claude Desktop config:
{
"mcpServers": {
"beads": {
"command": "beads-mcp"
}
}
}
For development, clone the repository:
git clone https://github.com/gastownhall/beads
cd beads/integrations/beads-mcp
uv sync
Then use in Claude Desktop config:
{
"mcpServers": {
"beads": {
"command": "uv",
"args": [
"--directory",
"/path/to/beads-mcp",
"run",
"beads-mcp"
]
}
}
}
Environment Variables (all optional):
BEADS_PATH - Path to bd executable (default: ~/.local/bin/bd)BEADS_DB - Path to beads database file (default: auto-discover from cwd)BEADS_WORKING_DIR - Working directory for bd commands (default: $PWD or current directory). Used for multi-repo setups - see belowBEADS_ACTOR - Actor name for audit trail (default: $USER)BEADS_NO_AUTO_FLUSH - Disable automatic sync (default: false)BEADS_NO_AUTO_IMPORT - Disable automatic import (default: false)Recommended: Use a single MCP server instance for all beads projects - it automatically routes to per-project Dolt servers.
Simple config - works for all projects:
{
"mcpServers": {
"beads": {
"command": "beads-mcp"
}
}
}
How it works (LSP model):
Architecture:
MCP Server (one instance)
↓
Per-Project Dolt Servers (one per workspace)
↓
Dolt Databases (complete isolation)
Why per-project Dolt servers?
Configure separate MCP servers for specific projects using BEADS_WORKING_DIR:
{
"mcpServers": {
"beads-webapp": {
"command": "beads-mcp",
"env": {
"BEADS_WORKING_DIR": "/Users/yourname/projects/webapp"
}
},
"beads-api": {
"command": "beads-mcp",
"env": {
"BEADS_WORKING_DIR": "/Users/yourname/projects/api"
}
}
}
}
⚠️ Problem: AI may select the wrong MCP server for your workspace, causing commands to operate on the wrong database. Use single MCP server instead.
The MCP server supports managing multiple beads projects in a single session using per-request workspace routing.
workspace_root ParameterEvery tool accepts an optional workspace_root parameter for explicit project targeting:
# Query issues from different projects concurrently
results = await asyncio.gather(
beads_ready_work(workspace_root="/Users/you/project-a"),
beads_ready_work(workspace_root="/Users/you/project-b"),
)
# Create issue in specific project
await beads_create_issue(
title="Fix auth bug",
priority=1,
workspace_root="/Users/you/project-a"
)
Connection Pool: The MCP server maintains a connection pool keyed by canonical workspace path:
asyncio.Lock to prevent race conditionsContextVar Routing: Per-request workspace context is managed via Python's ContextVar:
BEADS_WORKING_DIR if workspace_root not providedPath Canonicalization:
.beads directories use local contextThe set_context() tool still works and sets a default workspace:
# Old way (still supported)
await set_context(workspace_root="/Users/you/project-a")
await beads_ready_work() # Uses project-a
# New way (more flexible)
await beads_ready_work(workspace_root="/Users/you/project-a")
⚠️ IMPORTANT: Tool implementations must NOT spawn background tasks using asyncio.create_task().
Why? ContextVar doesn't propagate to spawned tasks, which can cause cross-project data leakage.
Solution: Keep all tool logic synchronous or use sequential await calls.
Symlink aliasing: Different paths to same project are deduplicated automatically via realpath.
Submodule handling: Submodules with their own .beads directory are treated as separate projects.
Stale connections: Currently no health checks. Phase 2 will add retry-on-failure if monitoring shows need.
Version mismatches: Dolt server version is auto-checked. Mismatched servers are automatically restarted.
Resource:
beads://quickstart - Quickstart guide for using beadsTools (all support workspace_root parameter):
init - Initialize bd in current directorycreate - Create new issue (bug, feature, task, epic, chore, decision)list - List issues with filters (status, priority, type, assignee)ready - Find tasks with no blockers ready to work onshow - Show detailed issue info including dependenciesupdate - Update issue (status, priority, design, notes, etc). Note: status="closed" or status="open" automatically route to close or reopen tools to respect approval workflowsclose - Close completed issuedep - Add dependency (blocks, related, parent-child, discovered-from)blocked - Get blocked issuesstats - Get project statisticsreopen - Reopen a closed issue with optional reasonset_context - Set default workspace for subsequent calls (backward compatibility)Status: ✅ Fixed in v0.24.0+
This issue affected versions prior to v0.24.0. The problem was caused by self-referential Pydantic models (Issue with dependencies: list["Issue"]) generating invalid MCP schemas with $ref at root level.
Solution: The issue was fixed in commit f3a678f by refactoring the data models:
IssueBase with common fieldsLinkedIssue(IssueBase) for dependency referencesIssue to use list[LinkedIssue] instead of list["Issue"]This breaks the circular reference and ensures all tool outputSchemas have type: object at root level.
Upgrade: If you're running beads-mcp < 0.24.0:
pip install --upgrade beads-mcp
All MCP tools now load correctly in Claude Code with v0.24.0+.
Run MCP inspector:
# inside beads-mcp dir
uv run fastmcp dev src/beads_mcp/server.py
Type checking:
uv run mypy src/beads_mcp
Linting and formatting:
uv run ruff check src/beads_mcp
uv run ruff format src/beads_mcp
Run all tests:
uv run pytest
With coverage:
uv run pytest --cov=beads_mcp tests/
Test suite includes both mocked unit tests and integration tests with real bd CLI.
Test Dolt server with multiple repositories:
# Start the Dolt server first
cd /path/to/beads
bd dolt start
# Run multi-repo test
cd integrations/beads-mcp
uv run python test_multi_repo.py
This test verifies that the Dolt server can handle operations across multiple repositories simultaneously using per-request context routing.