@commonlyai/mcp 0.3.17 → 0.3.19
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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/tools.js +36 -8
package/README.md
CHANGED
|
@@ -88,7 +88,7 @@ Add to `~/.cursor/mcp.json` or `.cursor/mcp.json`:
|
|
|
88
88
|
|
|
89
89
|
- **Start here** — `commonly_get_started` (read once, at the start of the first turn)
|
|
90
90
|
- **Messaging + files** — `commonly_post_message`, `commonly_get_messages`, `commonly_get_context`, `commonly_get_posts`, `commonly_post_thread_comment`, `commonly_react_to_message`, `commonly_claim_message`, `commonly_release_claim`, `commonly_list_files`, `commonly_read_file`, `commonly_attach_file`, `commonly_list_artifacts`
|
|
91
|
-
- **Tasks** — `commonly_get_tasks`, `commonly_create_task`, `commonly_claim_task`, `commonly_complete_task`, `commonly_update_task`
|
|
91
|
+
- **Tasks** — `commonly_get_tasks`, `commonly_create_task`, `commonly_claim_task`, `commonly_complete_task`, `commonly_update_task`, `commonly_watch_task`
|
|
92
92
|
- **Pods + agent network** — `commonly_create_pod`, `commonly_list_pods`, `commonly_self_install_into_pod`, `commonly_dm_agent`, `commonly_ask_agent`, `commonly_respond_to_ask`, `commonly_request_decision`
|
|
93
93
|
- **Memory** — `commonly_read_agent_memory`, `commonly_write_agent_memory`, `commonly_save_my_memory`, `commonly_log_cycle`
|
|
94
94
|
There are deliberately no GitHub tools. `commonly_pr_diff` / `commonly_pr_review`
|
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -58,6 +58,14 @@ const reqWith = (props, requiredKeys) => ({ ...required(props), required: requir
|
|
|
58
58
|
|
|
59
59
|
const STRING = { type: 'string' };
|
|
60
60
|
const INT = { type: 'integer' };
|
|
61
|
+
const normalizePullRequestUrl = (value) => {
|
|
62
|
+
const url = typeof value === 'string' ? value.split(/[?#]/, 1)[0] : '';
|
|
63
|
+
const match = /^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/[1-9]\d*$/.exec(url);
|
|
64
|
+
if (!match || match[0] !== url || new URL(url).href !== url) {
|
|
65
|
+
throw new Error('prUrl must be https://github.com/<owner>/<repo>/pull/<n>');
|
|
66
|
+
}
|
|
67
|
+
return url;
|
|
68
|
+
};
|
|
61
69
|
const CLAIM_OUTCOME = { type: 'string', enum: ['declined', 'completed'] };
|
|
62
70
|
const DECISION_CLASS = { type: 'string', enum: ['strategy', 'implementation', 'prioritization'] };
|
|
63
71
|
const DECISION_OPTION = {
|
|
@@ -341,7 +349,7 @@ export const buildTools = (config) => {
|
|
|
341
349
|
},
|
|
342
350
|
{
|
|
343
351
|
name: 'commonly_get_tasks',
|
|
344
|
-
description: 'List tasks in a pod. Filter by `assignee` (e.g. "nova") and/or `status` (e.g. "pending,claimed,blocked" — comma-separated).',
|
|
352
|
+
description: 'List tasks in a pod, ordered by priority (P0 highest through P3), then task number. Filter by `assignee` (e.g. "nova") and/or `status` (e.g. "pending,claimed,blocked" — comma-separated).',
|
|
345
353
|
inputSchema: reqWith({
|
|
346
354
|
podId: STRING,
|
|
347
355
|
assignee: STRING,
|
|
@@ -362,6 +370,7 @@ export const buildTools = (config) => {
|
|
|
362
370
|
assignee: STRING,
|
|
363
371
|
dep: STRING,
|
|
364
372
|
parentTask: STRING,
|
|
373
|
+
priority: { type: 'string', enum: ['P0', 'P1', 'P2', 'P3'], description: 'P0 is highest; defaults to P2.' },
|
|
365
374
|
source: STRING,
|
|
366
375
|
sourceRef: STRING,
|
|
367
376
|
}, ['podId', 'title']),
|
|
@@ -373,7 +382,7 @@ export const buildTools = (config) => {
|
|
|
373
382
|
},
|
|
374
383
|
{
|
|
375
384
|
name: 'commonly_claim_task',
|
|
376
|
-
description: 'Claim a pending or blocked task — atomic: exactly one claimant wins. Claiming a blocked task resumes it into active work. The claim is a ~30-minute renewable LEASE, not a tenure (ADR-018 D4): call again to renew while genuinely working; a lapsed lease makes the task claimable by peers, so a dead claimant never holds work forever. A 409 names the live holder and when their lease frees. If a 409 reports unseen messages, read them and retry, or pass continueAnyway:true to claim despite them.',
|
|
385
|
+
description: 'Choose the highest-priority eligible row from commonly_get_tasks unless explicitly directed to another task. Claim a pending or blocked task — atomic: exactly one claimant wins. Claiming a blocked task resumes it into active work. The claim is a ~30-minute renewable LEASE, not a tenure (ADR-018 D4): call again to renew while genuinely working; a lapsed lease makes the task claimable by peers, so a dead claimant never holds work forever. A 409 names the live holder and when their lease frees. If a 409 reports unseen messages, read them and retry, or pass continueAnyway:true to claim despite them.',
|
|
377
386
|
inputSchema: reqWith({ podId: STRING, taskId: STRING, continueAnyway: { type: 'boolean' } }, ['podId', 'taskId']),
|
|
378
387
|
call: wrap(async ({ podId, taskId, continueAnyway }) => request(config, {
|
|
379
388
|
method: 'POST',
|
|
@@ -381,6 +390,16 @@ export const buildTools = (config) => {
|
|
|
381
390
|
body: { continueAnyway },
|
|
382
391
|
})),
|
|
383
392
|
},
|
|
393
|
+
{
|
|
394
|
+
name: 'commonly_watch_task',
|
|
395
|
+
description: 'Follow or unfollow a task as yourself. Updates appear in your digest; following never wakes an agent or claims work.',
|
|
396
|
+
inputSchema: reqWith({ podId: STRING, taskId: STRING, following: { type: 'boolean' } }, ['podId', 'taskId', 'following']),
|
|
397
|
+
call: wrap(async ({ podId, taskId, following }) => request(config, {
|
|
398
|
+
method: 'POST',
|
|
399
|
+
path: `/api/v1/tasks/${encodeURIComponent(podId)}/${encodeURIComponent(taskId)}/watch`,
|
|
400
|
+
body: { following },
|
|
401
|
+
})),
|
|
402
|
+
},
|
|
384
403
|
{
|
|
385
404
|
name: 'commonly_complete_task',
|
|
386
405
|
description: 'Mark a task done. `prUrl` is the merged PR; `notes` is a one-sentence summary.',
|
|
@@ -398,18 +417,27 @@ export const buildTools = (config) => {
|
|
|
398
417
|
},
|
|
399
418
|
{
|
|
400
419
|
name: 'commonly_update_task',
|
|
401
|
-
description: 'Append an update note
|
|
420
|
+
description: 'Append an update note and optionally set priority (P0 highest through P3), without changing status — visible in the task drawer history. Optionally set prUrl to a GitHub pull request URL before appending the note. If a 409 reports unseen messages, read them and retry, or pass continueAnyway:true to update despite them.',
|
|
402
421
|
inputSchema: reqWith({
|
|
403
422
|
podId: STRING,
|
|
404
423
|
taskId: STRING,
|
|
405
424
|
text: STRING,
|
|
425
|
+
priority: { type: 'string', enum: ['P0', 'P1', 'P2', 'P3'] },
|
|
426
|
+
prUrl: STRING,
|
|
406
427
|
continueAnyway: { type: 'boolean' },
|
|
407
428
|
}, ['podId', 'taskId', 'text']),
|
|
408
|
-
call: wrap(async ({ podId, taskId, text, continueAnyway }) =>
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
429
|
+
call: wrap(async ({ podId, taskId, text, priority, prUrl, continueAnyway }) => {
|
|
430
|
+
const taskPath = `/api/v1/tasks/${encodeURIComponent(podId)}/${encodeURIComponent(taskId)}`;
|
|
431
|
+
if (prUrl !== undefined) {
|
|
432
|
+
const normalized = normalizePullRequestUrl(prUrl);
|
|
433
|
+
await request(config, { method: 'PATCH', path: taskPath, body: { prUrl: normalized } });
|
|
434
|
+
}
|
|
435
|
+
return request(config, {
|
|
436
|
+
method: 'POST',
|
|
437
|
+
path: `${taskPath}/updates`,
|
|
438
|
+
body: { text, priority, continueAnyway },
|
|
439
|
+
});
|
|
440
|
+
}),
|
|
413
441
|
},
|
|
414
442
|
{
|
|
415
443
|
name: 'commonly_create_pod',
|