paperclip-mcp 1.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 (78) hide show
  1. package/README.md +703 -0
  2. package/dist/auth.d.ts +9 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +17 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/client.d.ts +17 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +94 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/errors.d.ts +7 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +13 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +23 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/tools/activity.d.ts +3 -0
  19. package/dist/tools/activity.d.ts.map +1 -0
  20. package/dist/tools/activity.js +106 -0
  21. package/dist/tools/activity.js.map +1 -0
  22. package/dist/tools/agents.d.ts +3 -0
  23. package/dist/tools/agents.d.ts.map +1 -0
  24. package/dist/tools/agents.js +373 -0
  25. package/dist/tools/agents.js.map +1 -0
  26. package/dist/tools/approvals.d.ts +3 -0
  27. package/dist/tools/approvals.d.ts.map +1 -0
  28. package/dist/tools/approvals.js +306 -0
  29. package/dist/tools/approvals.js.map +1 -0
  30. package/dist/tools/attachments.d.ts +3 -0
  31. package/dist/tools/attachments.d.ts.map +1 -0
  32. package/dist/tools/attachments.js +125 -0
  33. package/dist/tools/attachments.js.map +1 -0
  34. package/dist/tools/comments.d.ts +3 -0
  35. package/dist/tools/comments.d.ts.map +1 -0
  36. package/dist/tools/comments.js +75 -0
  37. package/dist/tools/comments.js.map +1 -0
  38. package/dist/tools/dashboard.d.ts +3 -0
  39. package/dist/tools/dashboard.d.ts.map +1 -0
  40. package/dist/tools/dashboard.js +24 -0
  41. package/dist/tools/dashboard.js.map +1 -0
  42. package/dist/tools/documents.d.ts +3 -0
  43. package/dist/tools/documents.d.ts.map +1 -0
  44. package/dist/tools/documents.js +150 -0
  45. package/dist/tools/documents.js.map +1 -0
  46. package/dist/tools/goals.d.ts +3 -0
  47. package/dist/tools/goals.d.ts.map +1 -0
  48. package/dist/tools/goals.js +128 -0
  49. package/dist/tools/goals.js.map +1 -0
  50. package/dist/tools/identity.d.ts +3 -0
  51. package/dist/tools/identity.d.ts.map +1 -0
  52. package/dist/tools/identity.js +44 -0
  53. package/dist/tools/identity.js.map +1 -0
  54. package/dist/tools/index.d.ts +25 -0
  55. package/dist/tools/index.d.ts.map +1 -0
  56. package/dist/tools/index.js +49 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/issues.d.ts +3 -0
  59. package/dist/tools/issues.d.ts.map +1 -0
  60. package/dist/tools/issues.js +297 -0
  61. package/dist/tools/issues.js.map +1 -0
  62. package/dist/tools/projects.d.ts +3 -0
  63. package/dist/tools/projects.d.ts.map +1 -0
  64. package/dist/tools/projects.js +233 -0
  65. package/dist/tools/projects.js.map +1 -0
  66. package/dist/tools/routines.d.ts +3 -0
  67. package/dist/tools/routines.d.ts.map +1 -0
  68. package/dist/tools/routines.js +305 -0
  69. package/dist/tools/routines.js.map +1 -0
  70. package/dist/tools/validation.d.ts +24 -0
  71. package/dist/tools/validation.d.ts.map +1 -0
  72. package/dist/tools/validation.js +33 -0
  73. package/dist/tools/validation.js.map +1 -0
  74. package/dist/types.d.ts +36 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/types.js +3 -0
  77. package/dist/types.js.map +1 -0
  78. package/package.json +61 -0
package/README.md ADDED
@@ -0,0 +1,703 @@
1
+ # paperclip-mcp
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.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx paperclip-mcp
9
+ ```
10
+
11
+ Or install globally:
12
+
13
+ ```bash
14
+ npm install -g paperclip-mcp
15
+ ```
16
+
17
+ ## Claude Code setup
18
+
19
+ Add to your MCP config (`.claude/settings.json` or `~/.config/claude/settings.json`):
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "paperclip": {
25
+ "command": "npx",
26
+ "args": ["paperclip-mcp"],
27
+ "env": {
28
+ "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>"
32
+ }
33
+ }
34
+ }
35
+ }
36
+ ```
37
+
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` |
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": "959ce36e-...", "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": "467f800f-b971-4494-b25e-bc1d573ad70c",
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) |
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
+ ```
369
+
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
+ ```
378
+
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`) |
405
+
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:**
428
+
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
+ ```
440
+
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`) |
458
+
459
+ ---
460
+
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
+ }
492
+ ```
493
+
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.
543
+
544
+ **Input:**
545
+
546
+ | Parameter | Type | Required | Description |
547
+ | ------------ | ------ | -------- | ------------- |
548
+ | `approvalId` | string | Yes | Approval UUID |
549
+
550
+ **Output:** Updated approval with `status: "approved"`.
551
+
552
+ ---
553
+
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:**
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
+ ```
668
+
669
+ ---
670
+
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
+ ## License
702
+
703
+ MIT