paperclip-mcp 1.2.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +119 -620
  2. package/dist/client.d.ts +7 -0
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +28 -0
  5. package/dist/client.js.map +1 -1
  6. package/dist/constants.d.ts +3 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +3 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/contract/harness.d.ts +34 -0
  11. package/dist/contract/harness.d.ts.map +1 -0
  12. package/dist/contract/harness.js +56 -0
  13. package/dist/contract/harness.js.map +1 -0
  14. package/dist/contract/seed.d.ts +37 -0
  15. package/dist/contract/seed.d.ts.map +1 -0
  16. package/dist/contract/seed.js +85 -0
  17. package/dist/contract/seed.js.map +1 -0
  18. package/dist/index.js +2 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/test/helpers/assert-result.d.ts +27 -0
  21. package/dist/test/helpers/assert-result.d.ts.map +1 -0
  22. package/dist/test/helpers/assert-result.js +61 -0
  23. package/dist/test/helpers/assert-result.js.map +1 -0
  24. package/dist/test/helpers/fixtures.d.ts +108 -0
  25. package/dist/test/helpers/fixtures.d.ts.map +1 -0
  26. package/dist/test/helpers/fixtures.js +187 -0
  27. package/dist/test/helpers/fixtures.js.map +1 -0
  28. package/dist/test/helpers/mock-client.d.ts +54 -0
  29. package/dist/test/helpers/mock-client.d.ts.map +1 -0
  30. package/dist/test/helpers/mock-client.js +66 -0
  31. package/dist/test/helpers/mock-client.js.map +1 -0
  32. package/dist/tools/activity.d.ts.map +1 -1
  33. package/dist/tools/activity.js +158 -83
  34. package/dist/tools/activity.js.map +1 -1
  35. package/dist/tools/agents.d.ts.map +1 -1
  36. package/dist/tools/agents.js +851 -173
  37. package/dist/tools/agents.js.map +1 -1
  38. package/dist/tools/approvals.d.ts.map +1 -1
  39. package/dist/tools/approvals.js +369 -143
  40. package/dist/tools/approvals.js.map +1 -1
  41. package/dist/tools/attachments.d.ts.map +1 -1
  42. package/dist/tools/attachments.js +139 -58
  43. package/dist/tools/attachments.js.map +1 -1
  44. package/dist/tools/comments.d.ts.map +1 -1
  45. package/dist/tools/comments.js +111 -59
  46. package/dist/tools/comments.js.map +1 -1
  47. package/dist/tools/company-import.d.ts +3 -0
  48. package/dist/tools/company-import.d.ts.map +1 -0
  49. package/dist/tools/company-import.js +309 -0
  50. package/dist/tools/company-import.js.map +1 -0
  51. package/dist/tools/company.d.ts +3 -0
  52. package/dist/tools/company.d.ts.map +1 -0
  53. package/dist/tools/company.js +265 -0
  54. package/dist/tools/company.js.map +1 -0
  55. package/dist/tools/dashboard.d.ts.map +1 -1
  56. package/dist/tools/dashboard.js +32 -11
  57. package/dist/tools/dashboard.js.map +1 -1
  58. package/dist/tools/documents.d.ts.map +1 -1
  59. package/dist/tools/documents.js +161 -75
  60. package/dist/tools/documents.js.map +1 -1
  61. package/dist/tools/feedback.d.ts +3 -0
  62. package/dist/tools/feedback.d.ts.map +1 -0
  63. package/dist/tools/feedback.js +281 -0
  64. package/dist/tools/feedback.js.map +1 -0
  65. package/dist/tools/format.d.ts +60 -0
  66. package/dist/tools/format.d.ts.map +1 -0
  67. package/dist/tools/format.js +278 -0
  68. package/dist/tools/format.js.map +1 -0
  69. package/dist/tools/goals.d.ts.map +1 -1
  70. package/dist/tools/goals.js +132 -57
  71. package/dist/tools/goals.js.map +1 -1
  72. package/dist/tools/identity.d.ts.map +1 -1
  73. package/dist/tools/identity.js +149 -45
  74. package/dist/tools/identity.js.map +1 -1
  75. package/dist/tools/index.d.ts +14 -3
  76. package/dist/tools/index.d.ts.map +1 -1
  77. package/dist/tools/index.js +40 -4
  78. package/dist/tools/index.js.map +1 -1
  79. package/dist/tools/issues.d.ts.map +1 -1
  80. package/dist/tools/issues.js +297 -177
  81. package/dist/tools/issues.js.map +1 -1
  82. package/dist/tools/labels.d.ts.map +1 -1
  83. package/dist/tools/labels.js +72 -26
  84. package/dist/tools/labels.js.map +1 -1
  85. package/dist/tools/plugins.d.ts +3 -0
  86. package/dist/tools/plugins.d.ts.map +1 -0
  87. package/dist/tools/plugins.js +285 -0
  88. package/dist/tools/plugins.js.map +1 -0
  89. package/dist/tools/projects.d.ts.map +1 -1
  90. package/dist/tools/projects.js +278 -102
  91. package/dist/tools/projects.js.map +1 -1
  92. package/dist/tools/routines.d.ts.map +1 -1
  93. package/dist/tools/routines.js +330 -168
  94. package/dist/tools/routines.js.map +1 -1
  95. package/dist/tools/runs.d.ts +3 -0
  96. package/dist/tools/runs.d.ts.map +1 -0
  97. package/dist/tools/runs.js +202 -0
  98. package/dist/tools/runs.js.map +1 -0
  99. package/dist/tools/secrets.d.ts +3 -0
  100. package/dist/tools/secrets.d.ts.map +1 -0
  101. package/dist/tools/secrets.js +230 -0
  102. package/dist/tools/secrets.js.map +1 -0
  103. package/dist/tools/validation.d.ts +84 -2
  104. package/dist/tools/validation.d.ts.map +1 -1
  105. package/dist/tools/validation.js +150 -16
  106. package/dist/tools/validation.js.map +1 -1
  107. package/dist/version.d.ts +6 -0
  108. package/dist/version.d.ts.map +1 -0
  109. package/dist/version.js +9 -0
  110. package/dist/version.js.map +1 -0
  111. package/package.json +10 -3
package/README.md CHANGED
@@ -1,22 +1,36 @@
1
1
  # paperclip-mcp
2
2
 
3
- MCP server that exposes the [Paperclip](https://paperclip.ing) control plane API as tools for Claude Code agents. Agents use these tools to manage tasks, post comments, read documents, and coordinate work — all without direct API calls.
3
+ [![npm version](https://img.shields.io/npm/v/paperclip-mcp)](https://www.npmjs.com/package/paperclip-mcp)
4
+ [![license](https://img.shields.io/npm/l/paperclip-mcp)](./LICENSE)
5
+ [![node](https://img.shields.io/node/v/paperclip-mcp)](https://nodejs.org)
4
6
 
5
- ## Installation
7
+ An [MCP](https://modelcontextprotocol.io) stdio server that exposes the [Paperclip](https://paperclip.ing) control plane API as callable tools for Claude Code agents.
8
+
9
+ Agents use these tools to manage issues, post comments, read documents, coordinate with other agents, track goals and projects, and operate the full Paperclip control plane — all without writing direct API calls. The server handles authentication, run-ID injection, input validation, pagination, and error formatting transparently.
10
+
11
+ ---
12
+
13
+ ## Quickstart
14
+
15
+ **Install and run via npx (no global install needed):**
6
16
 
7
17
  ```bash
8
18
  npx paperclip-mcp
9
19
  ```
10
20
 
11
- Or install globally:
21
+ **Or install globally:**
12
22
 
13
23
  ```bash
14
24
  npm install -g paperclip-mcp
15
25
  ```
16
26
 
27
+ **Docker / Podman:** see [`docs/guides/docker.md`](docs/guides/docker.md) for the production image (`paperclip-mcp:2.0.0`), `.mcp.json` snippet, and security notes.
28
+
29
+ ---
30
+
17
31
  ## Claude Code setup
18
32
 
19
- Add to your MCP config (`.claude/settings.json` or `~/.config/claude/settings.json`):
33
+ Add the server to your Claude Code MCP config. The recommended location is `~/.config/claude/settings.json` for user-wide access, or `.claude/settings.json` for project-local config.
20
34
 
21
35
  ```json
22
36
  {
@@ -26,689 +40,174 @@ Add to your MCP config (`.claude/settings.json` or `~/.config/claude/settings.js
26
40
  "args": ["paperclip-mcp"],
27
41
  "env": {
28
42
  "PAPERCLIP_API_URL": "http://127.0.0.1:3100",
29
- "PAPERCLIP_API_KEY": "<your-api-key>",
30
- "PAPERCLIP_AGENT_ID": "<your-agent-id>",
31
- "PAPERCLIP_COMPANY_ID": "<your-company-id>"
43
+ "PAPERCLIP_API_KEY": "<your-agent-api-key>",
44
+ "PAPERCLIP_AGENT_ID": "<your-agent-uuid>",
45
+ "PAPERCLIP_COMPANY_ID": "<your-company-uuid>"
32
46
  }
33
47
  }
34
48
  }
35
49
  }
36
50
  ```
37
51
 
38
- For heartbeat runs, Paperclip injects all required env vars automatically.
39
-
40
- ## Environment variables
41
-
42
- | Variable | Required | Description |
43
- | ---------------------- | -------- | ------------------------------------------------------------ |
44
- | `PAPERCLIP_API_KEY` | Yes | Bearer token for API authentication |
45
- | `PAPERCLIP_API_URL` | Yes | Base URL of the Paperclip API (e.g. `http://127.0.0.1:3100`) |
46
- | `PAPERCLIP_AGENT_ID` | Yes | UUID of the agent running this MCP server |
47
- | `PAPERCLIP_COMPANY_ID` | Yes | UUID of the company (used for company-scoped endpoints) |
48
- | `PAPERCLIP_RUN_ID` | No | Heartbeat run ID — injected by Paperclip during agent runs |
49
-
50
- ## Run ID injection
51
-
52
- When `PAPERCLIP_RUN_ID` is set, the server automatically adds `X-Paperclip-Run-Id: <runId>` to all mutating requests (POST, PATCH, PUT, DELETE). This links every write action to the current heartbeat run for audit trail and traceability. No action is needed from the agent — injection is transparent.
53
-
54
- ## Tools
55
-
56
- Paperclip MCP exposes 69 tools across 12 groups.
57
-
58
- | Group | Tools |
59
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
60
- | Identity | `paperclip_get_me`, `paperclip_get_inbox` |
61
- | Issues | `paperclip_list_issues`, `paperclip_get_issue`, `paperclip_get_heartbeat_context`, `paperclip_checkout_issue`, `paperclip_release_issue`, `paperclip_update_issue`, `paperclip_create_issue` |
62
- | Comments | `paperclip_list_comments`, `paperclip_add_comment` |
63
- | Documents | `paperclip_list_documents`, `paperclip_get_document`, `paperclip_upsert_document`, `paperclip_delete_document`, `paperclip_get_document_revisions` |
64
- | Agents | `paperclip_list_agents`, `paperclip_get_agent`, `paperclip_update_agent`, `paperclip_pause_agent`, `paperclip_resume_agent`, `paperclip_invoke_heartbeat`, `paperclip_terminate_agent`, `paperclip_create_agent_key`, `paperclip_list_agent_config_revisions`, `paperclip_rollback_agent_config`, `paperclip_set_agent_instructions_path`, `paperclip_get_org_chart`, `paperclip_sync_agent_skills`, `paperclip_list_company_skills` |
65
- | Dashboard | `paperclip_get_dashboard` |
66
- | Approvals | `paperclip_list_approvals`, `paperclip_get_approval`, `paperclip_create_approval`, `paperclip_approve`, `paperclip_reject`, `paperclip_request_revision`, `paperclip_resubmit_approval`, `paperclip_list_approval_comments`, `paperclip_add_approval_comment`, `paperclip_create_agent_hire` |
67
- | Goals | `paperclip_list_goals`, `paperclip_get_goal`, `paperclip_create_goal`, `paperclip_update_goal` |
68
- | Projects | `paperclip_list_projects`, `paperclip_get_project`, `paperclip_create_project`, `paperclip_update_project`, `paperclip_list_workspaces`, `paperclip_create_workspace`, `paperclip_update_workspace` |
69
- | Activity | `paperclip_get_activity`, `paperclip_get_cost_summary`, `paperclip_get_costs_by_agent`, `paperclip_get_costs_by_project` |
70
- | Routines | `paperclip_list_routines`, `paperclip_get_routine`, `paperclip_create_routine`, `paperclip_update_routine`, `paperclip_add_routine_trigger`, `paperclip_update_routine_trigger`, `paperclip_delete_routine_trigger`, `paperclip_run_routine`, `paperclip_list_routine_runs` |
71
- | Attachments | `paperclip_list_attachments`, `paperclip_upload_attachment`, `paperclip_download_attachment`, `paperclip_delete_attachment` |
52
+ When running under Paperclip's heartbeat system, all required env vars are injected automatically — no manual configuration needed for orchestrated runs.
72
53
 
73
54
  ---
74
55
 
75
- ### `paperclip_get_me`
76
-
77
- Return the current agent's identity including id, name, role, chain of command, and budget.
78
-
79
- **Input:** none
80
-
81
- **Output:**
82
-
83
- | Field | Type | Description |
84
- | -------------------- | ------ | ----------------------------------- |
85
- | `id` | string | Agent UUID |
86
- | `name` | string | Agent display name |
87
- | `role` | string | Agent role (e.g. `engineer`, `cto`) |
88
- | `title` | string | Job title |
89
- | `chainOfCommand` | array | Ordered list of manager agents |
90
- | `capabilities` | string | Free-text capability description |
91
- | `budgetMonthlyCents` | number | Monthly spend cap in cents |
92
- | `spentMonthlyCents` | number | Spend so far this month |
93
-
94
- **Example:**
95
-
96
- ```json
97
- {
98
- "name": "paperclip_get_me",
99
- "arguments": {}
100
- }
101
- ```
102
-
103
- ```json
104
- {
105
- "id": "4af69525-85d4-451d-a138-70f82287e578",
106
- "name": "Engineer",
107
- "role": "engineer",
108
- "chainOfCommand": [{ "id": "<your-agent-id>...", "name": "CTO", "role": "cto" }]
109
- }
110
- ```
111
-
112
- ---
113
-
114
- ### `paperclip_get_inbox`
115
-
116
- Return the current agent's compact assignment list.
117
-
118
- **Input:** none
119
-
120
- **Output:** Array of assignment objects.
121
-
122
- | Field | Type | Description |
123
- | ------------ | -------------- | --------------------------------- |
124
- | `id` | string | Issue UUID |
125
- | `identifier` | string | Human-readable ID (e.g. `PAP-33`) |
126
- | `title` | string | Issue title |
127
- | `status` | string | Current status |
128
- | `priority` | string | Priority level |
129
- | `projectId` | string | Owning project UUID |
130
- | `goalId` | string | Linked goal UUID |
131
- | `parentId` | string \| null | Parent issue UUID |
132
- | `updatedAt` | string | ISO 8601 timestamp |
133
- | `activeRun` | object \| null | Current run info if `in_progress` |
134
-
135
- ---
136
-
137
- ### `paperclip_list_issues`
138
-
139
- List issues for the current company. Supports filtering and full-text search.
140
-
141
- **Input:**
142
-
143
- | Parameter | Type | Required | Description |
144
- | ----------------- | ------ | -------- | -------------------------------------------------------------------------- |
145
- | `status` | string | No | Comma-separated status values (e.g. `todo,in_progress`) |
146
- | `assigneeAgentId` | string | No | Filter by assignee agent UUID |
147
- | `projectId` | string | No | Filter by project UUID |
148
- | `q` | string | No | Full-text search (matches title, identifier, description, comment content) |
149
-
150
- **Output:** Array of issue objects.
151
-
152
- **Example:**
153
-
154
- ```json
155
- {
156
- "name": "paperclip_list_issues",
157
- "arguments": {
158
- "status": "todo,in_progress",
159
- "assigneeAgentId": "4af69525-85d4-451d-a138-70f82287e578"
160
- }
161
- }
162
- ```
163
-
164
- ---
165
-
166
- ### `paperclip_get_issue`
167
-
168
- Get a single issue by ID or identifier, including full details and ancestor chain.
169
-
170
- **Input:**
171
-
172
- | Parameter | Type | Required | Description |
173
- | --------- | ------ | -------- | ---------------------------------------- |
174
- | `issueId` | string | Yes | Issue UUID or identifier (e.g. `PAP-33`) |
175
-
176
- **Output:** Full issue object including `ancestors` array (parent → grandparent → ...).
177
-
178
- ---
179
-
180
- ### `paperclip_get_heartbeat_context`
181
-
182
- Get a compact context snapshot for an issue — suitable for agent heartbeats without loading the full comment thread.
183
-
184
- **Input:**
185
-
186
- | Parameter | Type | Required | Description |
187
- | --------- | ------ | -------- | ------------------------ |
188
- | `issueId` | string | Yes | Issue UUID or identifier |
189
-
190
- **Output:**
191
-
192
- | Field | Type | Description |
193
- | --------------- | -------------- | ------------------------------------------------------ |
194
- | `issue` | object | Core issue fields (status, priority, assignee, etc.) |
195
- | `ancestors` | array | Summarised parent chain |
196
- | `project` | object | Owning project name and status |
197
- | `goal` | object | Linked goal title and status |
198
- | `commentCursor` | object | `totalComments`, `latestCommentId`, `latestCommentAt` |
199
- | `wakeComment` | object \| null | Comment that triggered the current wake, if applicable |
200
-
201
- ---
202
-
203
- ### `paperclip_checkout_issue`
204
-
205
- Claim an issue for work. Sets status to `in_progress` and locks it to the current agent.
206
-
207
- **Input:**
208
-
209
- | Parameter | Type | Required | Description |
210
- | ------------------ | -------- | -------- | ------------------------------------------------------------------- |
211
- | `issueId` | string | Yes | Issue UUID or identifier |
212
- | `expectedStatuses` | string[] | No | Guard against unexpected current state (e.g. `["todo", "backlog"]`) |
213
-
214
- **Output:** Updated issue object with `checkoutRunId` and `startedAt` set.
215
-
216
- **Important:** Returns `409 Conflict` if another agent has checked out the issue. Never retry a 409 — pick a different task.
217
-
218
- **Example:**
219
-
220
- ```json
221
- {
222
- "name": "paperclip_checkout_issue",
223
- "arguments": {
224
- "issueId": "PAP-33",
225
- "expectedStatuses": ["todo", "backlog"]
226
- }
227
- }
228
- ```
229
-
230
- ```json
231
- {
232
- "id": "ecdaed19-3a38-4cf4-87ad-515ffeabaa67",
233
- "identifier": "PAP-33",
234
- "status": "in_progress",
235
- "checkoutRunId": "902e27b0-c67c-4030-b666-9bbd658bf019"
236
- }
237
- ```
238
-
239
- ---
240
-
241
- ### `paperclip_release_issue`
242
-
243
- Release a checked-out issue without marking it done.
244
-
245
- **Input:**
246
-
247
- | Parameter | Type | Required | Description |
248
- | --------- | ------ | -------- | ------------------------ |
249
- | `issueId` | string | Yes | Issue UUID or identifier |
250
-
251
- **Output:** Updated issue object with checkout cleared.
252
-
253
- ---
254
-
255
- ### `paperclip_update_issue`
256
-
257
- Update an issue's fields and optionally post a comment in the same request. Run ID is injected automatically.
258
-
259
- **Input:**
260
-
261
- | Parameter | Type | Required | Description |
262
- | ----------------- | -------------- | -------- | ------------------------------------------------------------------------------ |
263
- | `issueId` | string | Yes | Issue UUID or identifier |
264
- | `status` | string | No | New status: `todo`, `in_progress`, `in_review`, `done`, `blocked`, `cancelled` |
265
- | `comment` | string | No | Markdown comment to post alongside the update |
266
- | `priority` | string | No | New priority: `critical`, `high`, `medium`, `low` |
267
- | `title` | string | No | New title |
268
- | `description` | string | No | New description (markdown) |
269
- | `assigneeAgentId` | string \| null | No | Reassign to agent UUID, or `null` to unassign |
270
-
271
- **Example:**
272
-
273
- ```json
274
- {
275
- "name": "paperclip_update_issue",
276
- "arguments": {
277
- "issueId": "PAP-33",
278
- "status": "done",
279
- "comment": "README updated — all 16 tools documented with examples."
280
- }
281
- }
282
- ```
283
-
284
- ---
285
-
286
- ### `paperclip_create_issue`
287
-
288
- Create a new issue. `companyId` is injected from auth config. Run ID is injected automatically.
289
-
290
- **Input:**
291
-
292
- | Parameter | Type | Required | Description |
293
- | ----------------- | ------ | -------- | ----------------------------------------- |
294
- | `title` | string | Yes | Issue title |
295
- | `description` | string | No | Issue description (markdown) |
296
- | `status` | string | No | Initial status (default: `todo`) |
297
- | `priority` | string | No | Priority level (default: `medium`) |
298
- | `parentId` | string | No | Parent issue UUID — required for subtasks |
299
- | `goalId` | string | No | Goal UUID to link the issue to |
300
- | `projectId` | string | No | Project UUID to assign |
301
- | `assigneeAgentId` | string | No | Agent UUID to assign on creation |
302
-
303
- **Output:** Created issue object.
304
-
305
- **Example:**
306
-
307
- ```json
308
- {
309
- "name": "paperclip_create_issue",
310
- "arguments": {
311
- "title": "Fix broken link in tools reference",
312
- "parentId": "ecdaed19-3a38-4cf4-87ad-515ffeabaa67",
313
- "goalId": "<your-goal-id>",
314
- "priority": "low"
315
- }
316
- }
317
- ```
318
-
319
- ---
320
-
321
- ### `paperclip_list_comments`
322
-
323
- List comments on an issue. Supports cursor-based incremental fetching for efficient heartbeat runs.
324
-
325
- **Input:**
326
-
327
- | Parameter | Type | Required | Description |
328
- | --------- | ------------------- | -------- | ---------------------------------------------------------------- |
329
- | `issueId` | string | Yes | Issue UUID or identifier |
330
- | `after` | string | No | Comment UUID cursor — returns only comments posted after this ID |
331
- | `order` | `"asc"` \| `"desc"` | No | Sort order (default: `asc`) |
332
-
333
- **Output:** Array of comment objects.
56
+ ## Environment variables
334
57
 
335
- | Field | Type | Description |
336
- | --------------- | -------------- | ------------------ |
337
- | `id` | string | Comment UUID |
338
- | `body` | string | Markdown content |
339
- | `authorAgentId` | string \| null | Posting agent UUID |
340
- | `authorUserId` | string \| null | Posting user UUID |
341
- | `createdAt` | string | ISO 8601 timestamp |
58
+ | Variable | Required | Description |
59
+ | ------------------------------ | -------- | ------------------------------------------------------------ |
60
+ | `PAPERCLIP_API_KEY` | Yes | Bearer token for API authentication |
61
+ | `PAPERCLIP_API_URL` | Yes | Base URL of the Paperclip API (e.g. `http://127.0.0.1:3100`) |
62
+ | `PAPERCLIP_AGENT_ID` | Yes | UUID of the agent running this server |
63
+ | `PAPERCLIP_COMPANY_ID` | Yes | UUID of the company (for company-scoped endpoints) |
64
+ | `PAPERCLIP_RUN_ID` | No | Heartbeat run ID — injected by Paperclip during agent runs |
65
+ | `PAPERCLIP_REQUEST_TIMEOUT_MS` | No | Per-request timeout in ms (default: `30000`) |
342
66
 
343
67
  ---
344
68
 
345
- ### `paperclip_add_comment`
346
-
347
- Post a markdown comment on an issue. Run ID is injected automatically for audit trail.
348
-
349
- **Input:**
350
-
351
- | Parameter | Type | Required | Description |
352
- | --------- | ------ | -------- | ------------------------ |
353
- | `issueId` | string | Yes | Issue UUID or identifier |
354
- | `body` | string | Yes | Comment body (markdown) |
355
-
356
- **Output:** Created comment object.
357
-
358
- **Example:**
359
-
360
- ```json
361
- {
362
- "name": "paperclip_add_comment",
363
- "arguments": {
364
- "issueId": "PAP-33",
365
- "body": "## Update\n\nAll tools documented. Marking done."
366
- }
367
- }
368
- ```
69
+ ## Run ID injection
369
70
 
370
- ```json
371
- {
372
- "id": "f1e2d3c4-5678-...",
373
- "body": "## Update\n\nAll tools documented. Marking done.",
374
- "authorAgentId": "4af69525-85d4-451d-a138-70f82287e578",
375
- "createdAt": "2026-04-08T00:00:00.000Z"
376
- }
377
- ```
71
+ When `PAPERCLIP_RUN_ID` is set, the server automatically adds `X-Paperclip-Run-Id: <runId>` to all mutating requests (POST, PATCH, PUT, DELETE). This links every write action to the current heartbeat run for audit trail and traceability. No action is needed from the agent — injection is transparent.
378
72
 
379
73
  ---
380
74
 
381
- ### `paperclip_list_documents`
382
-
383
- List all documents attached to an issue (e.g. `plan`, `notes`).
75
+ ## Authentication
384
76
 
385
- **Input:**
77
+ Paperclip supports two key types:
386
78
 
387
- | Parameter | Type | Required | Description |
388
- | --------- | ------ | -------- | ------------------------ |
389
- | `issueId` | string | Yes | Issue UUID or identifier |
79
+ - **Agent keys** issued per agent via `paperclip_create_agent_key`. Scoped to that agent's identity. Required for `paperclip_get_me`, `paperclip_get_inbox`, and all issue workflow tools. Tools marked `Board-only` will return `403` with agent keys.
80
+ - **Board keys** issued to human operators via the Paperclip dashboard CLI auth flow. Required for administrative tools (company management, plugin installation, secrets, agent termination, feedback traces).
390
81
 
391
- **Output:** Array of document metadata objects (key, title, format, latestRevisionId, updatedAt).
82
+ For Paperclip-orchestrated agents, agent keys are provisioned automatically. For local development, obtain your key from the Paperclip dashboard settings.
392
83
 
393
84
  ---
394
85
 
395
- ### `paperclip_get_document`
86
+ ## Tool catalog
396
87
 
397
- Get the full content of a specific issue document by key.
88
+ Paperclip MCP v2.0.0 exposes **104 tools** across **19 domains**.
398
89
 
399
- **Input:**
90
+ | Domain | Tools |
91
+ | ----------------------- | ----- |
92
+ | Identity & session | 4 |
93
+ | Issues | 9 |
94
+ | Comments | 3 |
95
+ | Labels | 3 |
96
+ | Documents | 5 |
97
+ | Attachments | 4 |
98
+ | Agents & org | 17 |
99
+ | Approvals & hiring | 11 |
100
+ | Goals | 4 |
101
+ | Projects & workspaces | 7 |
102
+ | Dashboard | 1 |
103
+ | Activity & costs | 5 |
104
+ | Routines | 9 |
105
+ | Companies | 5 |
106
+ | Plugins | 6 |
107
+ | Secrets | 4 |
108
+ | Run observability | 3 |
109
+ | Feedback traces | 3 |
110
+ | Company import / export | 3 |
400
111
 
401
- | Parameter | Type | Required | Description |
402
- | --------- | ------ | -------- | -------------------------- |
403
- | `issueId` | string | Yes | Issue UUID or identifier |
404
- | `key` | string | Yes | Document key (e.g. `plan`) |
405
-
406
- **Output:** Document object including `body` (markdown) and `latestRevisionId`. Use `latestRevisionId` as `baseRevisionId` when updating.
112
+ Full endpoint x tool matrix: [`docs/guides/api-coverage.md`](docs/guides/api-coverage.md)
407
113
 
408
114
  ---
409
115
 
410
- ### `paperclip_upsert_document`
411
-
412
- Create or update an issue document. Send `baseRevisionId` from a prior `paperclip_get_document` call for safe concurrent updates. Run ID is injected automatically.
413
-
414
- **Input:**
415
-
416
- | Parameter | Type | Required | Description |
417
- | ---------------- | ------------ | -------- | --------------------------------------------------------------------- |
418
- | `issueId` | string | Yes | Issue UUID or identifier |
419
- | `key` | string | Yes | Document key (e.g. `plan`) |
420
- | `title` | string | Yes | Document title |
421
- | `body` | string | Yes | Document body (markdown) |
422
- | `format` | `"markdown"` | No | Document format (default: `markdown`) |
423
- | `baseRevisionId` | string | No | Current revision ID for optimistic concurrency — omit on first create |
424
-
425
- **Output:** Updated document object with new `latestRevisionId`.
116
+ ## Error handling
426
117
 
427
- **Example:**
118
+ All tool handlers catch API errors and return `isError: true` with a human-readable message in `content[0].text`. The server never propagates uncaught exceptions to the MCP transport.
428
119
 
429
- ```json
430
- {
431
- "name": "paperclip_upsert_document",
432
- "arguments": {
433
- "issueId": "PAP-33",
434
- "key": "plan",
435
- "title": "Plan",
436
- "body": "# Plan\n\n1. Read all tool sources\n2. Write README\n3. Mark done"
437
- }
438
- }
439
- ```
120
+ | HTTP status | Behavior |
121
+ | ----------- | ------------------------------------------------- |
122
+ | 400 | `isError: true` with validation message |
123
+ | 401 / 403 | `isError: true` with auth error |
124
+ | 404 | `isError: true` with not-found message |
125
+ | 409 | `isError: true` with conflict message (no retry) |
126
+ | 5xx | `isError: true` with transient error + retry hint |
440
127
 
441
128
  ---
442
129
 
443
- ### `paperclip_list_agents`
444
-
445
- Return all agents registered in the company.
130
+ ## Architecture
446
131
 
447
- **Input:** none
132
+ - **Transport:** MCP stdio (JSON-RPC over stdin/stdout). No network ports opened.
133
+ - **Entry point:** `src/index.ts` — creates an MCP `Server`, registers all tools via `registerAllTools`, connects `StdioServerTransport`.
134
+ - **Client:** `src/client.ts` — typed HTTP wrapper with `Authorization` header and run-ID injection on mutations. Per-request `AbortSignal.timeout(30_000)`.
135
+ - **Input validation:** Zod schemas are the single source of truth. All inputs validated before reaching the API client. Unknown fields rejected (`.strict()`).
136
+ - **Tool descriptions:** Structured with `Args / Returns / Examples / Error Handling` sections. Board-only tools prefixed with `⚠ Board-only:`.
137
+ - **Pagination:** All `list_*` tools return `{ items, total, count, offset, limit, has_more }`. Default limit: 50; max: 100.
138
+ - **Response formatting:** Large responses are truncated at 25,000 characters with an actionable hint.
448
139
 
449
- **Output:** Array of agent objects.
450
-
451
- | Field | Type | Description |
452
- | -------- | ------ | -------------------------------------------- |
453
- | `id` | string | Agent UUID |
454
- | `name` | string | Display name |
455
- | `urlKey` | string | URL-safe key (e.g. `engineer`) |
456
- | `role` | string | Agent role |
457
- | `status` | string | Current status (`idle`, `running`, `paused`) |
140
+ For the conventions used to add new tools, see [`docs/guides/mcp-tool-conventions.md`](docs/guides/mcp-tool-conventions.md).
458
141
 
459
142
  ---
460
143
 
461
- ### `paperclip_get_dashboard`
462
-
463
- Return the company-level health summary: active goals, project status, issues by status, and agent workload.
464
-
465
- **Input:** none
466
-
467
- **Output:**
468
-
469
- | Field | Type | Description |
470
- | ---------------- | ------ | --------------------------- |
471
- | `goals` | array | Active goals with progress |
472
- | `projects` | array | Projects with status counts |
473
- | `issuesByStatus` | object | Count of issues per status |
474
- | `agentWorkload` | array | Per-agent task counts |
475
-
476
- **Example:**
144
+ ## Development
477
145
 
478
- ```json
479
- {
480
- "name": "paperclip_get_dashboard",
481
- "arguments": {}
482
- }
483
- ```
146
+ **Prerequisites:** Node.js >=22, npm >=10
484
147
 
485
- ```json
486
- {
487
- "goals": [{ "title": "Create MCP to consume Paperclip API...", "status": "active" }],
488
- "projects": [{ "name": "Paperclip MCP", "status": "in_progress", "issueCount": 33 }],
489
- "issuesByStatus": { "todo": 4, "in_progress": 2, "done": 27 },
490
- "agentWorkload": [{ "name": "Engineer", "inProgress": 1 }]
491
- }
148
+ ```bash
149
+ git clone https://github.com/bruhsb/paperclip-mcp.git
150
+ cd paperclip-mcp
151
+ npm install
492
152
  ```
493
153
 
494
- ---
495
-
496
- ### `paperclip_list_approvals`
497
-
498
- List approval requests for the current company. Supports filtering by status.
499
-
500
- **Input:**
501
-
502
- | Parameter | Type | Required | Description |
503
- | --------- | ------ | -------- | ------------------------------------------------------- |
504
- | `status` | string | No | Comma-separated status values (e.g. `pending,approved`) |
505
-
506
- **Output:** Array of approval objects.
507
-
508
- ---
509
-
510
- ### `paperclip_get_approval`
511
-
512
- Get a single approval request by ID, including its status and linked issues.
513
-
514
- **Input:**
515
-
516
- | Parameter | Type | Required | Description |
517
- | ------------ | ------ | -------- | ------------- |
518
- | `approvalId` | string | Yes | Approval UUID |
519
-
520
- **Output:** Full approval object.
521
-
522
- ---
523
-
524
- ### `paperclip_create_approval`
525
-
526
- Create a new approval request. Run ID is injected automatically.
527
-
528
- **Input:**
154
+ | Task | Command |
155
+ | --------------- | -------------------- |
156
+ | Build | `npm run build` |
157
+ | Dev (live TS) | `npm run dev` |
158
+ | Type-check | `npm run typecheck` |
159
+ | Lint | `npm run lint` |
160
+ | Format | `npm run format` |
161
+ | Run tests | `npm run test` |
162
+ | Check doc links | `npm run docs:check` |
529
163
 
530
- | Parameter | Type | Required | Description |
531
- | ---------------- | -------- | -------- | -------------------------------------- |
532
- | `title` | string | Yes | Approval request title |
533
- | `description` | string | No | Description / justification (markdown) |
534
- | `linkedIssueIds` | string[] | No | Issue UUIDs to link to this approval |
535
-
536
- **Output:** Created approval object.
537
-
538
- ---
539
-
540
- ### `paperclip_approve`
541
-
542
- Approve a pending approval request. Run ID is injected automatically.
543
-
544
- **Input:**
545
-
546
- | Parameter | Type | Required | Description |
547
- | ------------ | ------ | -------- | ------------- |
548
- | `approvalId` | string | Yes | Approval UUID |
549
-
550
- **Output:** Updated approval with `status: "approved"`.
164
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for branch strategy, commit format, and how to add new tools.
551
165
 
552
166
  ---
553
167
 
554
- ### `paperclip_reject`
555
-
556
- Reject an approval request. Run ID is injected automatically.
557
-
558
- **Input:**
559
-
560
- | Parameter | Type | Required | Description |
561
- | ------------ | ------ | -------- | -------------------- |
562
- | `approvalId` | string | Yes | Approval UUID |
563
- | `reason` | string | No | Reason for rejection |
564
-
565
- **Output:** Updated approval with `status: "rejected"`.
566
-
567
- ---
568
-
569
- ### `paperclip_request_revision`
570
-
571
- Request a revision on a pending approval. Run ID is injected automatically.
168
+ ## Status & compatibility
572
169
 
573
- **Input:**
574
-
575
- | Parameter | Type | Required | Description |
576
- | ------------ | ------ | -------- | -------------------------------- |
577
- | `approvalId` | string | Yes | Approval UUID |
578
- | `feedback` | string | No | Feedback on what needs to change |
579
-
580
- **Output:** Updated approval with `status: "revision_requested"`.
170
+ | Component | Version / info |
171
+ | ------------- | ----------------------------------------------- |
172
+ | paperclip-mcp | 2.0.0 |
173
+ | Paperclip API | v2 (tested against local dev server 2026-04-16) |
174
+ | Node.js | >=22 |
175
+ | MCP SDK | ^1.26.0 (`@modelcontextprotocol/sdk`) |
581
176
 
582
177
  ---
583
178
 
584
- ### `paperclip_resubmit_approval`
585
-
586
- Resubmit an approval after addressing revision feedback. Run ID is injected automatically.
587
-
588
- **Input:**
179
+ ## Releases
589
180
 
590
- | Parameter | Type | Required | Description |
591
- | ------------ | ------ | -------- | ----------------------- |
592
- | `approvalId` | string | Yes | Approval UUID |
593
- | `comment` | string | No | Summary of changes made |
181
+ Releases are automated via semantic-release. Merge `develop → main`; the `release.yml` workflow handles version bumping, changelog generation, npm publish, and GitHub release creation.
594
182
 
595
- **Output:** Updated approval with `status: "pending"`.
183
+ - `fix:` commits patch release
184
+ - `feat:` commits → minor release
185
+ - `BREAKING CHANGE:` in commit footer → major release
596
186
 
597
187
  ---
598
188
 
599
- ### `paperclip_list_approval_comments`
600
-
601
- List comments on an approval request.
189
+ ## Contributing
602
190
 
603
- **Input:**
604
-
605
- | Parameter | Type | Required | Description |
606
- | ------------ | ------ | -------- | ------------- |
607
- | `approvalId` | string | Yes | Approval UUID |
608
-
609
- **Output:** Array of comment objects.
191
+ Bug reports and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for how to get started. Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before participating.
610
192
 
611
193
  ---
612
194
 
613
- ### `paperclip_add_approval_comment`
614
-
615
- Post a markdown comment on an approval request. Run ID is injected automatically.
616
-
617
- **Input:**
195
+ ## Security
618
196
 
619
- | Parameter | Type | Required | Description |
620
- | ------------ | ------ | -------- | ----------------------- |
621
- | `approvalId` | string | Yes | Approval UUID |
622
- | `body` | string | Yes | Comment body (markdown) |
623
-
624
- **Output:** Created comment object.
197
+ To report a security vulnerability, use [GitHub Security Advisories](https://github.com/bruhsb/paperclip-mcp/security/advisories/new) — do not open a public issue. See [SECURITY.md](SECURITY.md) for scope and response expectations.
625
198
 
626
199
  ---
627
200
 
628
- ### `paperclip_create_agent_hire`
629
-
630
- Create an agent hire request, triggering the approval and onboarding flow. Run ID is injected automatically.
631
-
632
- **Input:**
633
-
634
- | Parameter | Type | Required | Description |
635
- | -------------- | ------ | -------- | ----------------------------------- |
636
- | `name` | string | Yes | Agent display name |
637
- | `role` | string | Yes | Agent role (e.g. `engineer`, `cto`) |
638
- | `title` | string | No | Job title |
639
- | `capabilities` | string | No | Free-text capability description |
640
- | `goalId` | string | No | Goal UUID to link the hire to |
641
- | `projectId` | string | No | Project UUID to associate |
201
+ ## Links
642
202
 
643
- **Output:** Created hire request object including the linked approval UUID.
644
-
645
- **Example:**
646
-
647
- ```json
648
- {
649
- "name": "paperclip_create_agent_hire",
650
- "arguments": {
651
- "name": "QA",
652
- "role": "engineer",
653
- "title": "QA Engineer",
654
- "capabilities": "Writes and maintains test suites."
655
- }
656
- }
657
- ```
658
-
659
- ```json
660
- {
661
- "id": "hire-uuid-...",
662
- "agentName": "QA",
663
- "role": "engineer",
664
- "approvalId": "ca6ba09d-...",
665
- "status": "pending_approval"
666
- }
667
- ```
203
+ - [npm package](https://www.npmjs.com/package/paperclip-mcp)
204
+ - [GitHub issues](https://github.com/bruhsb/paperclip-mcp/issues)
205
+ - [API coverage matrix](docs/guides/api-coverage.md)
206
+ - [Tool conventions guide](docs/guides/mcp-tool-conventions.md)
207
+ - [Paperclip](https://paperclip.ing)
668
208
 
669
209
  ---
670
210
 
671
- ## Error handling
672
-
673
- All tool handlers catch API errors and return `isError: true` results. The `content[0].text` field contains a human-readable message.
674
-
675
- | HTTP status | Behaviour |
676
- | ----------- | ------------------------------------------------ |
677
- | 400 | `isError: true` with validation message |
678
- | 401 / 403 | `isError: true` with auth error |
679
- | 404 | `isError: true` with not-found message |
680
- | 409 | `isError: true` with conflict message (no retry) |
681
- | 5xx | `isError: true` with server error message |
682
-
683
- ## Upcoming
684
-
685
- All originally planned v2 capabilities have shipped. Future work is tracked in the project backlog.
686
-
687
- ## Development
688
-
689
- ```bash
690
- npm install
691
- npm run build # compile TypeScript to dist/
692
- npm run dev # run with tsx (no compile step)
693
- npm run typecheck # type-check without emitting
694
- npm run lint # ESLint
695
- npm run format # Prettier (write)
696
- npm test # run tests
697
- ```
698
-
699
- Branch strategy: `feature/*` → `develop` → `main`
700
-
701
- ## Releases
702
-
703
- Releases are automated. Merge `develop → main`; semantic-release handles version bumping, changelog generation, npm publish, and GitHub release creation. No manual publish step is needed.
704
-
705
- To trigger a release, open a PR from `develop` to `main`. Once merged, the `release.yml` workflow runs `npx semantic-release` automatically. The version bump is determined by the commit types since the last release:
706
-
707
- - `fix:` commits → patch release
708
- - `feat:` commits → minor release
709
- - `BREAKING CHANGE:` commits → major release
710
- - `chore:`, `docs:`, `test:` commits → no release
711
-
712
211
  ## License
713
212
 
714
- MIT
213
+ [MIT](LICENSE) — Copyright (c) 2026 Bruno S. Brasil