Skip to main content

MCP server for beads issue tracker.

Project description

mcp-beads

MCP server for beads issue tracker and agentic memory system. Enables AI agents to manage tasks using beads CLI through Model Context Protocol.

Installing

Option 1: Using uvx (Recommended)

No installation required - UV runs it on-demand:

{
  "mcpServers": {
    "beads": {
      "command": "uvx",
      "args": ["mcp-beads"]
    }
  }
}

Benefits:

  • No global installation needed
  • Always uses latest version (or pin with uvx mcp-beads@0.30.0)
  • UV handles caching automatically

Option 2: Using uv tool install

Install permanently to PATH:

uv tool install mcp-beads

Then configure Claude Desktop:

{
  "mcpServers": {
    "beads": {
      "command": "mcp-beads"
    }
  }
}

Option 3: Development Installation

For development, clone the repository:

git clone https://github.com/shaneholloman/beads
cd beads/adapters/mcp
uv sync

Then use in Claude Desktop config:

{
  "mcpServers": {
    "beads": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp-beads",
        "run",
        "mcp-beads"
      ]
    }
  }
}

Environment Variables (all optional):

  • BEADS_USE_DAEMON - Use daemon RPC instead of CLI (default: 1, set to 0 to disable)
  • BEADS_PATH - Path to beads executable (default: ~/.local/bin/beads)
  • BEADS_DB - Path to beads database file (default: auto-discover from cwd)
  • BEADS_WORKING_DIR - Working directory for beads commands (default: $PWD or current directory). Used for multi-repo setups - see below
  • BEADS_ACTOR - Actor name for audit trail (default: $USER)
  • BEADS_NO_AUTO_FLUSH - Disable automatic JSONL sync (default: false)
  • BEADS_NO_AUTO_IMPORT - Disable automatic JSONL import (default: false)

Multi-Repository Setup

Recommended: Use a single MCP server instance for all beads projects - it automatically routes to per-project local daemons.

Single MCP Server (Recommended)

Simple config - works for all projects:

{
  "mcpServers": {
    "beads": {
      "command": "mcp-beads"
    }
  }
}

How it works (LSP model):

  1. MCP server checks for local daemon socket (.beads/beads.sock) in your current workspace
  2. Routes requests to the per-project daemon based on working directory
  3. Auto-starts the local daemon if not running
  4. Each project gets its own isolated daemon serving only its database

Architecture:

MCP Server (one instance)
    ↓
Per-Project Daemons (one per workspace)
    ↓
SQLite Databases (complete isolation)

Why per-project daemons?

  • ✔ Complete database isolation between projects
  • ✔ No cross-project pollution or git worktree conflicts
  • ✔ Simpler mental model: one project = one database = one daemon
  • ✔ Follows LSP (Language Server Protocol) architecture
  • ✔ One MCP config works for unlimited projects

Note: Global daemon support was removed in v0.16.0 to prevent cross-project database pollution.

Alternative: Per-Project MCP Instances (Not Recommended)

Configure separate MCP servers for specific projects using BEADS_WORKING_DIR:

{
  "mcpServers": {
    "beads-webapp": {
      "command": "mcp-beads",
      "env": {
        "BEADS_WORKING_DIR": "/Users/yourname/projects/webapp"
      }
    },
    "beads-api": {
      "command": "mcp-beads",
      "env": {
        "BEADS_WORKING_DIR": "/Users/yourname/projects/api"
      }
    }
  }
}

WARNING: Problem: AI may select the wrong MCP server for your workspace, causing commands to operate on the wrong database. Use single MCP server instead.

Multi-Project Support

The MCP server supports managing multiple beads projects in a single session using per-request workspace routing.

Using workspace_root Parameter

Every 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"
)

Architecture

Connection Pool: The MCP server maintains a connection pool keyed by canonical workspace path:

  • Each workspace gets its own daemon socket connection
  • Paths are canonicalized (symlinks resolved, git toplevel detected)
  • Concurrent requests use asyncio.Lock to prevent race conditions
  • No LRU eviction (keeps all connections open for session)

ContextVar Routing: Per-request workspace context is managed via Python's ContextVar:

  • Each tool call sets the workspace for its duration
  • Properly isolated for concurrent calls (no cross-contamination)
  • Falls back to BEADS_WORKING_DIR if workspace_root not provided

Path Canonicalization:

  • Symlinks are resolved to physical paths (prevents duplicate connections)
  • Git submodules with .beads directories use local context
  • Git toplevel is used for non-initialized directories
  • Results are cached for performance

Backward Compatibility

The 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")

Concurrency Gotchas

WARNING: 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.

Troubleshooting

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 sockets: Currently no health checks. Phase 2 will add retry-on-failure if monitoring shows need.

Version mismatches: Daemon version is auto-checked since v0.16.0. Mismatched daemons are automatically restarted.

Features

Resource:

  • beads://quickstart - Quickstart guide for using beads

Tools (all support workspace_root parameter):

  • init - Initialize beads in current directory
  • create - Create new issue (bug, feature, task, epic, chore)
  • list - List issues with filters (status, priority, type, assignee)
  • ready - Find tasks with no blockers ready to work on
  • show - Show detailed issue info including dependencies
  • update - Update issue (status, priority, design, notes, etc). Note: status="closed" or status="open" automatically route to close or reopen tools to respect approval workflows
  • close - Close completed issue
  • dep - Add dependency (blocks, related, parent-child, discovered-from)
  • blocked - Get blocked issues
  • stats - Get project statistics
  • reopen - Reopen a closed issue with optional reason
  • set_context - Set default workspace for subsequent calls (backward compatibility)
  • where_am_i - Show current workspace context and database path
  • debug_env - Debug tool to show environment and working directory information

Development

Run MCP inspector:

# inside mcp-beads dir
uv run fastmcp dev src/beads_mcp/server.py

Type checking:

uv run ty check src/

Linting and formatting:

uv run ruff check src/beads_mcp
uv run ruff format src/beads_mcp

Testing

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 beads CLI.

Multi-Repo Integration Test

Test daemon RPC with multiple repositories:

# Start the daemon first
cd /path/to/beads
./beads daemon start

# Run multi-repo test
cd adapters/mcp
uv run test_multi_repo.py

This test verifies that the daemon can handle operations across multiple repositories simultaneously using per-request context routing.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcp_beads-0.30.3.tar.gz (25.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcp_beads-0.30.3-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

Details for the file mcp_beads-0.30.3.tar.gz.

File metadata

  • Download URL: mcp_beads-0.30.3.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.23

File hashes

Hashes for mcp_beads-0.30.3.tar.gz
Algorithm Hash digest
SHA256 6361e7fbc25e622bf4e67c637e87201b8c37591ab4cd26c83d715c414f4a15a3
MD5 78d72c1adc87e4131506afe8302316eb
BLAKE2b-256 46153b7ed596fc700b71b9a49638bb65cc19a5c1ba7a4efbbdc7d842529e8f17

See more details on using hashes here.

File details

Details for the file mcp_beads-0.30.3-py3-none-any.whl.

File metadata

  • Download URL: mcp_beads-0.30.3-py3-none-any.whl
  • Upload date:
  • Size: 27.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.23

File hashes

Hashes for mcp_beads-0.30.3-py3-none-any.whl
Algorithm Hash digest
SHA256 108a87795f9665cef668fd409f469f25057aba7f38901c1b39638c8e9f184afd
MD5 705bc673f22f03911c00d243351e3384
BLAKE2b-256 a73ba689ba9f0a900a30dd74a1c69f14e2066f4c71ede73679015f7b72d6f016

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page