Skip to main content
Glama

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 comment and status in the same PATCH. Always add_comment first, then update_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

Related MCP server: JIRA MCP Server

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_KEY for inbound requests; separate PAPERCLIP_API_KEY (never exposed) for outbound Paperclip API calls

  • Paperclip access: All requests to Paperclip include Authorization: Bearer, CF-Access-Client-Id, and CF-Access-Client-Secret headers — required because the Paperclip backend is behind a Cloudflare Access tunnel

Notes

  • Comment-then-patch rule: Never mix comment and status in 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 resolve me to the API key owner. Always pass explicit UUIDs for human assignee filters.

  • Cloudflare Tunnel: paperclip-hetzner.ctrsc.co is only reachable via Cloudflare Tunnel. Direct curl from your machine will timeout (524). Test via the worker or wrangler tail.

  • wrangler.jsonc is gitignored: Use .dev.vars for local secrets and wrangler secret put for production. Never put secrets in vars in wrangler.jsonc — they appear as plain text in the Cloudflare dashboard.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Provides tools for AI assistants to interact with JIRA APIs, enabling them to read, create, update, and manage JIRA issues through standardized MCP tools.
    6
    6 npm
    3
    MIT