paperclip-mcp
MCP server for the Paperclip AI agent orchestration platform, built for the human operator: run your company of agents from Claude Code, Claude Desktop or any MCP client.
Exposes the Paperclip REST API (v0.3.x, 2026-09) as 95 Model Context Protocol tools: issues, agents, goals, projects, approvals, costs and budgets, routines, decisions, pipelines and the attention feed.
Official MCP server vs this one. Paperclip ships
@paperclipai/mcp-server(TypeScript, stdio only, ~45paperclipXxxtools) aimed at agents running inside a heartbeat.paperclip-mcpis the Python, HTTP-or-stdio server for the board operator: it adds wake/pause/resume, hiring, budgets, cost breakdowns, routines, decisions, pipelines and the attention feed, and understands board API keys. Use the official one for agents, this one for yourself.
Tools
Issue ids accept either the UUID or the human identifier (PAP-42). Every tool docstring states which credential it needs.
Requirements
- Python 3.10+
- A running Paperclip instance (tested against
main@ 2026-09-13, package version 0.3.1 / release 2026.831) - A board API key (recommended) or an agent API key — see Credentials
Installation
git clone https://github.com/wizarck/paperclip-mcp
cd paperclip-mcp
pip install -e . # or: uv pip install -e .
Configuration
Copy .env.example to .env and fill in the values (never commit .env):
PAPERCLIP_API_URL=http://localhost:3100 # "/api" is appended automatically
PAPERCLIP_API_KEY=pcp_board_... # board key (recommended) or agent key
PAPERCLIP_COMPANY_ID=your_company_uuid # from the UI URL /companies/{uuid}
PAPERCLIP_AGENT_ID= # optional: default agent for checkout_issue
PAPERCLIP_RUN_ID= # optional: real heartbeat run id, never invent one
PAPERCLIP_BASE_URL (0.1.x) is still accepted as an alias of PAPERCLIP_API_URL.
Credentials
Paperclip resolves a bearer token as a board API key first, then as an agent API key. What you can do depends on which one you configure:
Getting a board key
- CLI:
paperclipai loginmints one, or - API:
POST /api/board-api-keysfrom a logged-in board session, or - On a
local_trusteddeployment: start this server with an emptyPAPERCLIP_API_KEY(requests act as the local board operator) and call thecreate_board_api_keytool.
Run whoami in your MCP client to confirm which credential is active; the server also logs it at startup.
Usage
paperclip-mcp # streamable-http on http://127.0.0.1:9011/mcp
paperclip-mcp --port 9012
paperclip-mcp --transport stdio # for Claude Desktop
paperclip-mcp --help
Claude Code
claude mcp add paperclip --transport http http://localhost:9011/mcp
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"paperclip": {
"command": "paperclip-mcp",
"args": ["--transport", "stdio"],
"env": {
"PAPERCLIP_API_URL": "http://localhost:3100",
"PAPERCLIP_API_KEY": "pcp_board_...",
"PAPERCLIP_COMPANY_ID": "your_company_uuid"
}
}
}
}
Auto-start with your MCP stack
curl -s --max-time 1 http://localhost:9011/mcp > /dev/null 2>&1 || \
nohup paperclip-mcp > /tmp/paperclip-mcp.log 2>&1 &
Example interactions
"What needs my attention?"
→ get_attention_feed() (board key) / get_sidebar_badges() + list_approvals()
"What is the Purchasing agent working on?"
→ list_issues(assignee_agent_id="...")
"Create a critical task for the CEO to find cheese suppliers in Barcelona, under PAP-12"
→ create_issue(title=..., priority="critical", assignee_agent_id="...", parent_issue_id="PAP-12")
"Mark PAP-42 done and leave a note"
→ update_issue(issue_id="PAP-42", status="done", comment="Verified in staging.")
"Approve the pending hire"
→ list_approvals() + approve(approval_id="...", decision_note="Go ahead")
"Which agent is burning the budget this week?"
→ get_cost_window_spend() + get_cost_breakdown(group_by="agent")
"Pause the Marketing agent and cancel its current run"
→ list_live_runs() + cancel_run(run_id="...") + pause_agent(agent_id="...")
"Run the weekly briefing routine now"
→ list_routines() + run_routine(routine_id="...")
Behaviour worth knowing
- Enums are validated client-side before any request: statuses
backlog, todo, in_progress, in_review, done, blocked, cancelled; prioritiescritical, high, medium, low(there is nourgent). list_issuesdefaults to open statuses (everything exceptdone/cancelled). Passstatus=""for all.checkout_issuesends the required body{agentId, expectedStatuses}; the agent comes from the argument, thenPAPERCLIP_AGENT_ID, thenGET /agents/me.- Errors are real MCP errors (
isError: true) carrying the server's message,code,detailsand a hint, e.g. "Board access required → configure a board API key". A409means the state changed under you (conflict, paused project, stale revision): do not blindly retry. X-Paperclip-Run-Idis only sent whenPAPERCLIP_RUN_IDis set, and only on writes. A fabricated run id violates a foreign key server-side.api_requestlets you call any/apiroute that has no dedicated tool ({company}in the path expands to the configured company).
Development
pip install -e ".[dev]"
ruff check src/ tests/ && ruff format --check src/ tests/
mypy src/
pytest # contract tests against a mocked Paperclip API
Layout: src/paperclip_mcp/core.py (config, HTTP client, errors, enums, FastMCP instance) and one module per domain under src/paperclip_mcp/tools/.
Architecture notes
- Who should use this MCP: human operators managing agents via Claude Code / Claude Desktop, with a board API key.
- Do agents need this MCP? No. Agents talk to the REST API directly during their heartbeat, and Paperclip ships
@paperclipai/mcp-serverfor agent-side MCP access. If you switch to Hermes, either MCP works since Hermes supports MCP natively. - Transport:
streamable-httpfor Claude Code and mcp-proxy;stdiofor Claude Desktop. - Security: binds to
127.0.0.1by default and carries your Paperclip key. Do not expose it publicly.
License
MIT — see LICENSE.