paperclip-mcp
Enables AI clients to manage Paperclip issues, comments, and approvals via read, write, and composite action tools.
README
paperclip-mcp
An MCP server for Paperclip, deployed as a Cloudflare Worker. Exposes full contractor-scale capabilities — read, write, and composite action tools — for use in AI clients (TypingMind, Brain, Claude, etc.).
Server version: 1.1.0 · Protocol: MCP 2025-03-26 · Tools: 18
Tools
Read tools
| Tool | Description | Key parameters |
|---|---|---|
list_issues |
List company issues with filters | status (comma-separated), q, assignee_user_id, assignee_agent_id, project_id, company_id, limit? (default 500, max 1000), offset? |
get_issue |
Full details for one issue | issue_id (UUID or CON-1234) |
get_dashboard |
Overview of agents and open issues | — |
list_agents |
Agent roster | company_id? |
list_humans |
Human user directory (falls back to /members) |
company_id? |
list_comments |
Comments / activity feed on an issue | issue_id |
get_actionable_issues |
Issues needing human decision (in_review,blocked), sorted by priority then age |
company_id? |
get_activity |
Company activity log, most recent first | agentId?, entityType?, entityId?, limit? |
get_costs |
Cost/spend data | breakdown (summary/by-agent/by-project), from?, to? |
get_approvals |
Pending or historical approval requests | status? (pending / approved / rejected / revision_requested) |
list_issues status filter patterns:
status=in_review,blocked # Action Queue default
status=todo,in_progress,in_review,blocked,done # "My items"
status=todo,in_progress,in_review,blocked # Active issues only
Write tools
Critical rule: Never send
commentandstatusin the same PATCH. Alwaysadd_commentfirst, thenupdate_issue_status. Mixing them causes "Agent cannot mutate another agent's issue" errors in Paperclip.
| Tool | Description | Key parameters |
|---|---|---|
add_comment |
Post a comment without changing status | issue_id, body, dashboard_user_id?, dashboard_user_email? |
update_issue_status |
Status-only PATCH — rejects any comment field |
issue_id, status, dashboard_user_id?, dashboard_user_email? |
update_issue |
Multi-field PATCH — rejects comment field |
issue_id, title?, description?, status?, priority?, assignee_agent_id?, assignee_user_id?, project_id?, goal_id?, dashboard_user_id?, dashboard_user_email? |
Valid statuses: backlog · todo · in_progress · in_review · done · blocked · cancelled
Valid priorities: critical · high · medium · low
Action / composite tools
| Tool | Description | Key parameters | Steps performed |
|---|---|---|---|
approve_issue |
Approve from Action Queue | issue_id, comment? (default: "Approved from Command Center."), dashboard_user_id?, dashboard_user_email? |
1. POST comment → 2. PATCH status done |
reject_issue |
Request changes | issue_id, reason (required), dashboard_user_id?, dashboard_user_email? |
1. POST comment "Changes requested: {reason}" → 2. PATCH status todo |
cancel_issue |
Mark as not actionable | issue_id, dashboard_user_id?, dashboard_user_email? |
PATCH status cancelled (no comment) |
Convenience / diagnostics tools
| Tool | Description | Key parameters |
|---|---|---|
list_issues_for_human |
"My items" — merges user ID, alias IDs, and agent IDs; deduplicates; sorts by priority then age | human_id, alias_ids?, agent_ids?, status?, company_id? |
probe_connection |
Test reachability of Paperclip upstream (Cloudflare Tunnel / Access) | company_id? |
Human attribution on writes
All write tools accept optional dashboard_user_id / dashboard_user_email parameters. When provided, they are sent as X-Dashboard-User-Id / X-Dashboard-User-Email headers and the comment body is prefixed with [displayName] so the Paperclip activity log shows who acted (workaround for paperclipai/paperclip#1177).
You can also set defaults via env vars:
wrangler secret put PAPERCLIP_DASHBOARD_USER_ID
wrangler secret put PAPERCLIP_DASHBOARD_USER_EMAIL
Endpoints
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/ |
GET | No | Health check — returns server info |
/mcp |
POST | Yes | Streamable HTTP MCP (recommended) |
/mcp |
DELETE | Yes | Terminate MCP session |
/sse |
GET | Yes | SSE transport — establishes streaming session |
/sse/message?sessionId=… |
POST | Yes | Send messages on an SSE session |
Authentication
The server requires an API key on all endpoints except the health check.
Option A — Header (preferred):
X-API-Key: your-api-key
Option B — Query parameter (for clients that can't set custom headers, e.g. Claude):
https://paperclip-mcp.isagani.workers.dev/mcp?api_key=your-api-key
Secrets
All sensitive values are stored as Cloudflare secrets — never in wrangler.jsonc. Set them with:
wrangler secret put API_KEY # Key clients use to call this worker
wrangler secret put PAPERCLIP_API_KEY # Paperclip board/service key (pcp_board_...)
wrangler secret put PAPERCLIP_API_URL # e.g. https://paperclip-hetzner.ctrsc.co
wrangler secret put PAPERCLIP_COMPANY_ID # Company UUID
wrangler secret put CF_ACCESS_CLIENT_ID # Cloudflare Access service token ID (optional)
wrangler secret put CF_ACCESS_CLIENT_SECRET # Cloudflare Access service token secret (optional)
wrangler secret put PAPERCLIP_DASHBOARD_USER_ID # Optional: default user UUID for write attribution
wrangler secret put PAPERCLIP_DASHBOARD_USER_EMAIL # Optional: default user email for write attribution
Secrets are scoped per worker — setting API_KEY on this worker does not affect other workers with the same variable name.
To verify what's set:
wrangler secret list --name paperclip-mcp
Local Development
Create a .dev.vars file (gitignored) with your secrets:
API_KEY=your-key
PAPERCLIP_API_KEY=pcp_board_...
PAPERCLIP_API_URL=https://paperclip-hetzner.ctrsc.co
PAPERCLIP_COMPANY_ID=your-company-uuid
CF_ACCESS_CLIENT_ID=your-cf-access-id
CF_ACCESS_CLIENT_SECRET=your-cf-access-secret
# Optional write attribution defaults:
PAPERCLIP_DASHBOARD_USER_ID=your-user-uuid
PAPERCLIP_DASHBOARD_USER_EMAIL=you@example.com
Wrangler loads this automatically when running wrangler dev.
npm run dev # Start local dev server at http://localhost:8787
npm run deploy # Deploy to Cloudflare Workers
Deployment
# 1. Login to Cloudflare
wrangler login
# 2. Set all secrets (see Secrets section above)
# 3. Deploy
npm run deploy
Debugging
Tail live logs after deployment:
wrangler tail --name paperclip-mcp
# Filter to errors only
wrangler tail --name paperclip-mcp --status error
The worker logs every request, outbound Paperclip API URL, whether secrets are set, and full error responses from the Paperclip API on failures.
Testing with curl
# Step 1: initialize — note the Mcp-Session-Id in response headers
curl -si -X POST https://paperclip-mcp.isagani.workers.dev/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
# Step 2: call a tool using the session ID from above
curl -s -X POST https://paperclip-mcp.isagani.workers.dev/mcp \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-H "Mcp-Session-Id: <session-id-from-step-1>" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_issues","arguments":{"limit":5}}}'
MCP Client Setup
Brain / Claude / TypingMind (query parameter — recommended, works everywhere):
- URL:
https://paperclip-mcp.isagani.workers.dev/mcp?api_key=your-api-key - Transport: Streamable HTTP
TypingMind (header-based alternative):
- URL:
https://paperclip-mcp.isagani.workers.dev/mcp - Transport: Streamable HTTP
- Header:
X-API-Key: your-api-key
Brain note: When using Brain's tool picker, all 18 tools are present in a scrollable list — Brain displays them in a fixed-height box so you may need to scroll to see them all.
Architecture
- Runtime: Cloudflare Workers (serverless, global edge)
- Transport: Streamable HTTP (
/mcp) and SSE (/sse) - Protocol: MCP
2025-03-26 - Auth model: Single shared
API_KEYfor inbound requests; separatePAPERCLIP_API_KEY(never exposed) for outbound Paperclip API calls - Paperclip access: All requests to Paperclip include
Authorization: Bearer,CF-Access-Client-Id, andCF-Access-Client-Secretheaders — required because the Paperclip backend is behind a Cloudflare Access tunnel
Notes
- Comment-then-patch rule: Never mix
commentandstatusin one PATCH. Post the comment first (add_comment), then update the status (update_issue_status). The composite tools (approve_issue,reject_issue) do this correctly. - No
assigneeUserId=me: Service tokens resolvemeto the API key owner. Always pass explicit UUIDs for human assignee filters. - Cloudflare Tunnel:
paperclip-hetzner.ctrsc.cois only reachable via Cloudflare Tunnel. Direct curl from your machine will timeout (524). Test via the worker orwrangler tail. wrangler.jsoncis gitignored: Use.dev.varsfor local secrets andwrangler secret putfor production. Never put secrets invarsinwrangler.jsonc— they appear as plain text in the Cloudflare dashboard.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。