paperclip-mcp 1.2.5 → 2.1.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 +152 -634
  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 +145 -23
  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 +14 -6
package/README.md CHANGED
@@ -1,22 +1,18 @@
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
+ MCP server that exposes the [Paperclip](https://paperclip.ing) control plane API as tools for Claude Code agents manage issues, coordinate agents, post comments, and orchestrate work without direct API calls.
4
4
 
5
- ## Installation
6
-
7
- ```bash
8
- npx paperclip-mcp
9
- ```
5
+ [![npm](https://img.shields.io/npm/v/paperclip-mcp)](https://www.npmjs.com/package/paperclip-mcp)
6
+ [![MCP protocol](https://img.shields.io/badge/MCP-1.29.0-blue)](https://modelcontextprotocol.io)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
10
8
 
11
- Or install globally:
9
+ ## Quickstart
12
10
 
13
11
  ```bash
14
- npm install -g paperclip-mcp
12
+ npx paperclip-mcp
15
13
  ```
16
14
 
17
- ## Claude Code setup
18
-
19
- Add to your MCP config (`.claude/settings.json` or `~/.config/claude/settings.json`):
15
+ Add to `.claude/settings.json`:
20
16
 
21
17
  ```json
22
18
  {
@@ -37,636 +33,113 @@ Add to your MCP config (`.claude/settings.json` or `~/.config/claude/settings.js
37
33
 
38
34
  For heartbeat runs, Paperclip injects all required env vars automatically.
39
35
 
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` |
72
-
73
- ---
74
-
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.
334
-
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 |
342
-
343
- ---
344
-
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) |
36
+ ## Installation
355
37
 
356
- **Output:** Created comment object.
38
+ Three first-class variants:
357
39
 
358
- **Example:**
40
+ ### npm
359
41
 
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
- ```
42
+ ```bash
43
+ # one-shot (no install)
44
+ npx paperclip-mcp
369
45
 
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
- }
46
+ # global install
47
+ npm install -g paperclip-mcp
377
48
  ```
378
49
 
379
- ---
380
-
381
- ### `paperclip_list_documents`
382
-
383
- List all documents attached to an issue (e.g. `plan`, `notes`).
384
-
385
- **Input:**
386
-
387
- | Parameter | Type | Required | Description |
388
- | --------- | ------ | -------- | ------------------------ |
389
- | `issueId` | string | Yes | Issue UUID or identifier |
390
-
391
- **Output:** Array of document metadata objects (key, title, format, latestRevisionId, updatedAt).
392
-
393
- ---
394
-
395
- ### `paperclip_get_document`
396
-
397
- Get the full content of a specific issue document by key.
398
-
399
- **Input:**
400
-
401
- | Parameter | Type | Required | Description |
402
- | --------- | ------ | -------- | -------------------------- |
403
- | `issueId` | string | Yes | Issue UUID or identifier |
404
- | `key` | string | Yes | Document key (e.g. `plan`) |
50
+ ### Docker / Podman
405
51
 
406
- **Output:** Document object including `body` (markdown) and `latestRevisionId`. Use `latestRevisionId` as `baseRevisionId` when updating.
407
-
408
- ---
409
-
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`.
426
-
427
- **Example:**
52
+ ```bash
53
+ # Docker
54
+ docker run --rm -i \
55
+ -e PAPERCLIP_API_URL=http://host.docker.internal:3100 \
56
+ -e PAPERCLIP_API_KEY=<your-api-key> \
57
+ -e PAPERCLIP_AGENT_ID=<your-agent-id> \
58
+ -e PAPERCLIP_COMPANY_ID=<your-company-id> \
59
+ ghcr.io/bruhsb/paperclip-mcp:2.1.0
428
60
 
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
- }
61
+ # Podman (same flags, replace docker → podman)
62
+ podman run --rm -i \
63
+ -e PAPERCLIP_API_URL=http://host.containers.internal:3100 \
64
+ -e PAPERCLIP_API_KEY=<your-api-key> \
65
+ -e PAPERCLIP_AGENT_ID=<your-agent-id> \
66
+ -e PAPERCLIP_COMPANY_ID=<your-company-id> \
67
+ ghcr.io/bruhsb/paperclip-mcp:2.1.0
439
68
  ```
440
69
 
441
- ---
442
-
443
- ### `paperclip_list_agents`
444
-
445
- Return all agents registered in the company.
446
-
447
- **Input:** none
448
-
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`) |
70
+ ### Compose stack (v2.1.0+)
458
71
 
459
- ---
72
+ Run the full Paperclip server + MCP server together via `podman-compose` (or `docker-compose`):
460
73
 
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:**
477
-
478
- ```json
479
- {
480
- "name": "paperclip_get_dashboard",
481
- "arguments": {}
482
- }
483
- ```
484
-
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
- }
74
+ ```bash
75
+ podman-compose up -d
492
76
  ```
493
77
 
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:**
529
-
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.
78
+ See [`docs/guides/local-stack.md`](docs/guides/local-stack.md) for the full compose setup, volume config, and health-check instructions.
543
79
 
544
- **Input:**
80
+ ## Host integration
545
81
 
546
- | Parameter | Type | Required | Description |
547
- | ------------ | ------ | -------- | ------------- |
548
- | `approvalId` | string | Yes | Approval UUID |
82
+ paperclip-mcp works with any MCP-compatible host. Platform-specific config files are in [`docs/installation/`](docs/installation/):
549
83
 
550
- **Output:** Updated approval with `status: "approved"`.
84
+ | Host | Guide |
85
+ | -------------- | ---------------------------------------------------------------------------- |
86
+ | Claude Code | [`docs/installation/claude-code.md`](docs/installation/claude-code.md) |
87
+ | Claude Desktop | [`docs/installation/claude-desktop.md`](docs/installation/claude-desktop.md) |
88
+ | Cursor | [`docs/installation/cursor.md`](docs/installation/cursor.md) |
89
+ | VS Code | [`docs/installation/vscode.md`](docs/installation/vscode.md) |
90
+ | Windsurf | [`docs/installation/windsurf.md`](docs/installation/windsurf.md) |
551
91
 
552
- ---
92
+ Each guide includes the exact config block, where to place it, and verification steps. Do not copy configs from this README — use the host-specific guides so you get the right file paths and format.
553
93
 
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.
572
-
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"`.
581
-
582
- ---
583
-
584
- ### `paperclip_resubmit_approval`
585
-
586
- Resubmit an approval after addressing revision feedback. Run ID is injected automatically.
587
-
588
- **Input:**
589
-
590
- | Parameter | Type | Required | Description |
591
- | ------------ | ------ | -------- | ----------------------- |
592
- | `approvalId` | string | Yes | Approval UUID |
593
- | `comment` | string | No | Summary of changes made |
594
-
595
- **Output:** Updated approval with `status: "pending"`.
596
-
597
- ---
598
-
599
- ### `paperclip_list_approval_comments`
600
-
601
- List comments on an approval request.
602
-
603
- **Input:**
604
-
605
- | Parameter | Type | Required | Description |
606
- | ------------ | ------ | -------- | ------------- |
607
- | `approvalId` | string | Yes | Approval UUID |
608
-
609
- **Output:** Array of comment objects.
610
-
611
- ---
612
-
613
- ### `paperclip_add_approval_comment`
614
-
615
- Post a markdown comment on an approval request. Run ID is injected automatically.
616
-
617
- **Input:**
618
-
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.
625
-
626
- ---
627
-
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 |
642
-
643
- **Output:** Created hire request object including the linked approval UUID.
644
-
645
- **Example:**
94
+ ## Environment variables
646
95
 
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
- ```
96
+ | Variable | Required | Description |
97
+ | ---------------------- | -------- | ------------------------------------------------------------ |
98
+ | `PAPERCLIP_API_KEY` | Yes | Bearer token for API authentication |
99
+ | `PAPERCLIP_API_URL` | Yes | Base URL of the Paperclip API (e.g. `http://127.0.0.1:3100`) |
100
+ | `PAPERCLIP_AGENT_ID` | Yes | UUID of the agent running this MCP server |
101
+ | `PAPERCLIP_COMPANY_ID` | Yes | UUID of the company (used for company-scoped endpoints) |
102
+ | `PAPERCLIP_RUN_ID` | No | Heartbeat run ID — injected by Paperclip during agent runs |
103
+ | `PAPERCLIP_TASK_ID` | No | Task ID injected by Paperclip on @-mention wakes |
104
+
105
+ ## Tool catalog
106
+
107
+ <!-- TOOLS-START -->
108
+
109
+ | Domain | Tools |
110
+ | ----------------------- | ------- |
111
+ | Identity | 4 |
112
+ | Issues | 7 |
113
+ | Comments | 3 |
114
+ | Documents | 5 |
115
+ | Agents & Organization | 17 |
116
+ | Dashboard | 1 |
117
+ | Approvals | 11 |
118
+ | Goals | 4 |
119
+ | Projects & Workspaces | 8 |
120
+ | Activity & Costs | 5 |
121
+ | Routines | 9 |
122
+ | Attachments | 4 |
123
+ | Labels | 2 |
124
+ | Companies | 5 |
125
+ | Plugins | 6 |
126
+ | Secrets | 4 |
127
+ | Run Observability | 3 |
128
+ | Feedback Traces | 3 |
129
+ | Company Import / Export | 3 |
130
+ | **Total** | **104** |
131
+
132
+ <!-- TOOLS-END -->
133
+
134
+ Full per-tool reference: [`docs/tools/`](docs/tools/README.md). Generated from Zod schemas — run `npm run docs:generate` to refresh.
135
+
136
+ ## Authentication
137
+
138
+ paperclip-mcp authenticates every request with a Bearer token derived from `PAPERCLIP_API_KEY`. The agent identity (`PAPERCLIP_AGENT_ID`) and company scope (`PAPERCLIP_COMPANY_ID`) are resolved at startup — the server will exit immediately if any required variable is missing. For details on generating API keys and scoping them to a specific agent, see [`docs/auth-keys.md`](docs/auth-keys.md).
658
139
 
659
- ```json
660
- {
661
- "id": "hire-uuid-...",
662
- "agentName": "QA",
663
- "role": "engineer",
664
- "approvalId": "ca6ba09d-...",
665
- "status": "pending_approval"
666
- }
667
- ```
140
+ ## Run ID injection
668
141
 
669
- ---
142
+ 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.
670
143
 
671
144
  ## Error handling
672
145
 
@@ -680,35 +153,80 @@ All tool handlers catch API errors and return `isError: true` results. The `cont
680
153
  | 409 | `isError: true` with conflict message (no retry) |
681
154
  | 5xx | `isError: true` with server error message |
682
155
 
683
- ## Upcoming
156
+ ## Architecture
684
157
 
685
- All originally planned v2 capabilities have shipped. Future work is tracked in the project backlog.
158
+ **Entry flow:** `src/index.ts` creates an MCP `Server`, calls `registerAllTools(server)`, then connects a `StdioServerTransport` for JSON-RPC over stdio.
686
159
 
687
- ## Development
160
+ **Key modules:**
688
161
 
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
- ```
162
+ - `src/client.ts` — `PaperclipClient`: typed HTTP wrapper (`get`, `post`, `patch`, `put`, `delete`). Injects `Authorization` header and `X-Paperclip-Run-Id` on mutations.
163
+ - `src/auth.ts` — Reads env vars at startup (fail-fast on missing required vars).
164
+ - `src/errors.ts` `PaperclipApiError` for non-2xx HTTP responses.
165
+ - `src/types.ts` Shared domain types.
166
+ - `src/tools/index.ts` Tool registry. Collects `ToolDefinition[]` arrays from each tool module into `ALL_TOOLS`, builds a dispatch map, and registers MCP `ListTools` / `CallTool` handlers.
167
+ - `src/tools/validation.ts` `validate(zodSchema, args)` helper and shared Zod schemas.
698
168
 
699
- Branch strategy: `feature/*` → `develop` → `main`
169
+ ## Documentation
170
+
171
+ - **End-user** — [`docs/README.md`](docs/README.md): quickstart, auth keys, troubleshooting, cookbook, host install guides, tool reference.
172
+ - **Contributor** — [`CONTRIBUTING.md`](CONTRIBUTING.md): branch strategy, PR flow, dev environment, and conventions for adding new tools.
173
+ - **Agent-orchestration** — [`AGENTS.md`](AGENTS.md): Paperclip-orchestrated agent protocol, BMAD integration, and heartbeat model.
174
+
175
+ ## Skills
176
+
177
+ paperclip-mcp ships public Claude Code skills under `skills/` — `paperclip-triage-inbox`, `paperclip-close-epic`, `paperclip-audit-approvals`, `paperclip-release-flow`. Copy the relevant skill directory to `~/.claude/skills/` to use it in your Claude Code session. See [`skills/README.md`](skills/README.md) for the full list and usage notes.
178
+
179
+ ## Development
180
+
181
+ | Task | Command |
182
+ | -------------------- | ----------------------- |
183
+ | Build | `npm run build` |
184
+ | Dev (live TS) | `npm run dev` |
185
+ | Start (compiled) | `npm run start` |
186
+ | Type-check only | `npm run typecheck` |
187
+ | Lint | `npm run lint` |
188
+ | Format | `npm run format` |
189
+ | Format check | `npm run format:check` |
190
+ | Run all tests | `npm run test` |
191
+ | Regenerate tool docs | `npm run docs:generate` |
192
+ | Check doc links | `npm run docs:check` |
193
+
194
+ Branch strategy: `feature/*` → `main` (squash-merge via PR)
195
+
196
+ ## Status & compatibility
197
+
198
+ | Component | Version |
199
+ | ------------------------------------------ | ------- |
200
+ | MCP protocol (`@modelcontextprotocol/sdk`) | 1.29.0 |
201
+ | Node.js (minimum) | 22 |
202
+ | Paperclip API | v2 |
700
203
 
701
204
  ## Releases
702
205
 
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.
206
+ Releases are automated. Squash-merge a PR to `main`; semantic-release handles version bumping, changelog generation, npm publish, and GitHub release creation. No manual publish step is needed.
704
207
 
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:
208
+ To trigger a release, open a PR from your feature branch 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
209
 
707
210
  - `fix:` commits → patch release
708
211
  - `feat:` commits → minor release
709
212
  - `BREAKING CHANGE:` commits → major release
710
213
  - `chore:`, `docs:`, `test:` commits → no release
711
214
 
215
+ ## Contributing
216
+
217
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the full contributor guide, including how to add new tools, branch naming, commit format, and PR process.
218
+
219
+ ## Security
220
+
221
+ Please report security vulnerabilities via the process described in [`SECURITY.md`](SECURITY.md). Do not open public issues for security bugs.
222
+
223
+ ## Links
224
+
225
+ - [Paperclip](https://paperclip.ing) — the control plane this MCP server wraps
226
+ - [Model Context Protocol](https://modelcontextprotocol.io) — the open protocol standard
227
+ - [npm package](https://www.npmjs.com/package/paperclip-mcp)
228
+ - [GitHub](https://github.com/bruhsb/paperclip-mcp)
229
+
712
230
  ## License
713
231
 
714
232
  MIT