Skip to main content
Glama
README.md
# Paperclip MCP server

## About

An MCP server for [Paperclip](https://github.com/paperclipai/paperclip). It wraps
the Paperclip HTTP API in a small set of agent-oriented tools and communicates
over stdio.

## What does it do?

The server simplifies the Paperclip API for language models:

- turns API responses into compact Markdown;
- provides dedicated tools for common issue, comment, document, and agent work;
- returns short acknowledgements for mutations instead of entire API responses;
- keeps a guarded raw API tool for endpoints without a dedicated tool;
- rejects external URLs in the raw tool.

Read responses are returned inline until they exceed
`PAPERCLIP_MCP_INLINE_TOKEN_THRESHOLD`. Larger responses are written as immutable
Markdown snapshots and the tool returns the file path instead. Snapshots are
read-only caches and may become stale; call the tool again when current state
matters.

## Usage

Requires Node.js 22.19+ and pnpm 11.

```bash
pnpm install --frozen-lockfile
pnpm run build

PAPERCLIP_API_URL=http://localhost:3100 \
PAPERCLIP_API_KEY=your-key \
pnpm start
```

Example MCP configuration:

```json
{
  "mcpServers": {
    "paperclip": {
      "command": "node",
      "args": ["/absolute/path/to/paperclip-mcp/dist/index.js"]
    }
  }
}
```

## Tools

| Tool | Description |
| --- | --- |
| `paperclip_context` | Read the current run and wake context without an API call. |
| `paperclip_inbox` | Read the current agent inbox. |
| `paperclip_issue` | Read one issue. |
| `paperclip_heartbeat_context` | Read the compact heartbeat context for an issue. |
| `paperclip_issues` | List or search company issues, including user-touched, archived, and unread filters. |
| `paperclip_issue_create` | Create an issue or subtask. |
| `paperclip_issue_update` | Update issue fields, status, assignment, or comments. |
| `paperclip_issue_checkout` | Atomically claim an issue for the current agent. |
| `paperclip_issue_release` | Release a checked-out issue to `todo`. |
| `paperclip_comments` | Read issue comments. |
| `paperclip_comment` | Read one issue comment. |
| `paperclip_comment_add` | Add a comment to an issue, optionally reopening it or interrupting its active run. |
| `paperclip_issue_approval` | List, link, or unlink approvals on an issue. |
| `paperclip_approvals` | List, read, or create company approvals. |
| `paperclip_approval_action` | Approve, reject, request revision for, or resubmit an approval. |
| `paperclip_approval_comments` | Read or add approval review comments. |
| `paperclip_decision` | List, inspect, propose, decide, dismiss, or cancel Paperclip decisions. |
| `paperclip_decision_queue` | Manage decision queues and their attention items. |
| `paperclip_decision_triage` | Read or update decide-by and snooze state for attention items. |
| `paperclip_goals` | List, read, create, update, or delete Paperclip goals. |
| `paperclip_projects` | List, read, create, update, or delete Paperclip projects. |
| `paperclip_project_workspace` | Manage project workspaces and runtime services. |
| `paperclip_documents` | List documents attached to an issue. |
| `paperclip_document` | Read one issue document, optionally as raw base64 or a local path. |
| `paperclip_document_content` | Read an issue document body as raw base64 or a local path. Defaults to base64. |
| `paperclip_document_put` | Create or update an issue document. |
| `paperclip_attachment_upload` | Upload an image or other file attachment from a local path or base64 data. |
| `paperclip_attachments` | List binary files attached to an issue. |
| `paperclip_attachment_content` | Read an issue attachment as raw base64 or a local path. Defaults to base64. |
| `paperclip_workspace_file_content` | Read a project or execution workspace file as raw base64 or a local path. Defaults to base64. |
| `paperclip_agents` | List company agents or read one agent. |
| `paperclip_agent_create` | Submit a governance-aware agent hire, with optional issue linkage and managed instructions. |
| `paperclip_raw` | Call a relative Paperclip API path not covered above. |

## Environment variables

| Name | Required | Default | Description |
| --- | --- | --- | --- |
| `PAPERCLIP_API_URL` | Yes | — | Paperclip base URL. |
| `PAPERCLIP_API_KEY` | No | — | Bearer token for API requests. |
| `PAPERCLIP_COMPANY_ID` | No | — | Company context; required by company-scoped tools. |
| `PAPERCLIP_AGENT_ID` | No | — | Current agent; required for issue checkout. |
| `PAPERCLIP_RUN_ID` | No | — | Run identity sent on mutations and used in snapshot paths. |
| `PAPERCLIP_TASK_ID` | No | — | Current task context. |
| `PAPERCLIP_WAKE_REASON` | No | — | Wake reason exposed by `paperclip_context`. |
| `PAPERCLIP_WAKE_COMMENT_ID` | No | — | Comment that triggered the run. |
| `PAPERCLIP_APPROVAL_ID` | No | — | Current approval context. |
| `PAPERCLIP_APPROVAL_STATUS` | No | — | Current approval status. |
| `PAPERCLIP_LINKED_ISSUE_IDS` | No | — | Comma-separated linked issue IDs. |
| `PAPERCLIP_WAKE_PAYLOAD_JSON` | No | — | JSON wake payload rendered by `paperclip_context`. |
| `PAPERCLIP_MCP_ARTIFACT_DIR` | No | OS temp directory | Snapshot output directory. |
| `PAPERCLIP_MCP_TIMEOUT_MS` | No | `30000` | API request timeout. |
| `PAPERCLIP_MCP_INLINE_TOKEN_THRESHOLD` | No | `30000` | Maximum estimated tokens returned inline. |
| `PAPERCLIP_MCP_MAX_BASE64_BYTES` | No | `5242880` | Maximum binary size returned as base64. Use `download`/`path` for larger files. |
| `PAPERCLIP_MCP_HEADERS_JSON` | No | `{}` | Additional request headers as a JSON object. |
| `PAPERCLIP_MCP_TELEMETRY` | No | `true` | Enable operation telemetry. |
| `PAPERCLIP_MCP_TELEMETRY_FILE` | No | — | Optional telemetry JSONL output path. |

## Custom headers

Use `PAPERCLIP_MCP_HEADERS_JSON` for reverse-proxy or routing headers:

```bash
export PAPERCLIP_MCP_HEADERS_JSON='{"CF-Access-Client-Id":"...","CF-Access-Client-Secret":"..."}'
```

Header names and values are validated at startup. Values containing CR or LF
are rejected. `PAPERCLIP_API_KEY` overrides a custom `Authorization` header, and
`PAPERCLIP_RUN_ID` overrides `X-Paperclip-Run-Id` on mutations.

## Development

```bash
pnpm install --frozen-lockfile
pnpm run check
pnpm run build
```

`scripts/test.sh` is an end-to-end test against a disposable Paperclip company.
Copy `.env.example` to the ignored `.env.test`, fill in its values, and explicitly
set `PAPERCLIP_TEST_ALLOW_WRITES=1` before running it.

```bash
cp .env.example .env.test
scripts/test.sh
```

TDQS

A4/5.0

Scored across 16 tools

Disambiguation4/5

Most tools target a distinct resource and action, with clear singular/plural pairs such as issue/issues and document/documents. The main ambiguity is paperclip_context vs paperclip_heartbeat_context, but their descriptions differentiate current run/wake state from an issue-specific heartbeat.

Naming Consistency5/5

All tools share the paperclip_ prefix and follow a predictable pattern: read operations use resource nouns while mutations use resource_action naming like paperclip_issue_create and paperclip_comment_add. The paperclip_raw fallback is clearly labeled and does not disrupt the overall convention.

Tool Count4/5

At 16 tools the surface is slightly above the ideal 3-15 range, but the count is justified by the domain: issue lifecycle, comments, documents, agent lookup, context retrieval, and a raw fallback each have a distinct purpose. Nothing feels redundant or excessive.

Completeness4/5

The core issue workflow is well covered: list/get/create/update/checkout/release, plus comments, documents, agents, and context. Minor gaps such as no explicit delete or comment edit exist, but the update operations and paperclip_raw fallback give agents practical workarounds.

Maintenance

ActivityMaintained
ResponsivenessNo issues