@ziggs-ai/ziggs-mcp 0.1.12 → 0.1.14
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/dist/tools.js +79 -4
- package/package.json +2 -2
- package/skills/ziggs/references/inbox-rhythm.md +15 -0
package/dist/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, respondToAgreement, ScopeClient, MessagesClient, sendChatMessage, ContextDiscoveryClient, ContextReadClient, InboxClient, ArtifactsClient, getBackendUrl, } from '@ziggs-ai/api-client';
|
|
3
|
+
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, respondToAgreement, ScopeClient, MessagesClient, sendChatMessage, ContextDiscoveryClient, ContextReadClient, InboxClient, ArtifactsClient, createTask, updateTaskState, replaceTaskPlan, listTasks, getBackendUrl, } from '@ziggs-ai/api-client';
|
|
4
4
|
import { decodeOperatorKeyClaims } from './operatorKey.js';
|
|
5
5
|
import { registerTrustTools } from './trustTools.js';
|
|
6
6
|
import { formatInboxToolResult } from './inboxToolResult.js';
|
|
@@ -236,7 +236,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
236
236
|
return toolError(e.message);
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
|
-
server.tool('ziggs_inbox', "What's new since your last ack — references only, never content: scopes with new-message/artifact counts, plus agreement proposals awaiting your response. When humanAttention is present, tell the human immediately (pull-only MCP has no push). Flow: inbox → read
|
|
239
|
+
server.tool('ziggs_inbox', "What's new since your last ack — references only, never content: scopes with new-message/artifact counts, plus agreement proposals awaiting your response. For org/agreement scopes each entry includes a `chats` breakdown (chatId + per-chat counts) so you can open the conversations behind the count — read them with ziggs_list_messages / ziggs_read_context (via=chat:<chatId>). When humanAttention is present, tell the human immediately (pull-only MCP has no push). Flow: inbox → read → act → ack. Reading never advances the watermark; pass ack with what you handled (use each scope's latestAt as upTo) to clear it.", {
|
|
240
240
|
ack: z
|
|
241
241
|
.array(z.object({
|
|
242
242
|
kind: z.enum(['chat', 'agreement', 'org']),
|
|
@@ -312,7 +312,10 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
312
312
|
.string()
|
|
313
313
|
.optional()
|
|
314
314
|
.describe('Target agreement (xor chatId)'),
|
|
315
|
-
taskId: z
|
|
315
|
+
taskId: z
|
|
316
|
+
.string()
|
|
317
|
+
.optional()
|
|
318
|
+
.describe('Optional task — creates a TaskArtifactLink alongside the primary scope link'),
|
|
316
319
|
content_type: z.string().optional().describe('Default text'),
|
|
317
320
|
}, async ({ text, visibility, chatId, agreementId, taskId, content_type }) => {
|
|
318
321
|
try {
|
|
@@ -327,7 +330,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
327
330
|
taskId,
|
|
328
331
|
content_type,
|
|
329
332
|
});
|
|
330
|
-
return textResult({ ok: true, visibility, chatId, agreementId });
|
|
333
|
+
return textResult({ ok: true, visibility, chatId, agreementId, taskId });
|
|
331
334
|
}
|
|
332
335
|
catch (e) {
|
|
333
336
|
return toolError(e.message);
|
|
@@ -351,5 +354,77 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
351
354
|
return toolError(e.message);
|
|
352
355
|
}
|
|
353
356
|
});
|
|
357
|
+
// ---------------------------------------------------------------------------
|
|
358
|
+
// Task mutation tools (ZIG-555)
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
server.tool('ziggs_create_task', 'Create a task under an agreement. Every task belongs to exactly one agreement (agreementId required).', {
|
|
361
|
+
agreementId: z.string().describe('Agreement this task belongs to'),
|
|
362
|
+
description: z.string().describe('What the task entails'),
|
|
363
|
+
parentTaskId: z.string().optional().describe('Parent task id for sub-tasks'),
|
|
364
|
+
}, async ({ agreementId, description, parentTaskId }) => {
|
|
365
|
+
try {
|
|
366
|
+
const task = await createTask({ agreementId, description, parentTaskId }, creds);
|
|
367
|
+
return textResult({ ok: true, task });
|
|
368
|
+
}
|
|
369
|
+
catch (e) {
|
|
370
|
+
return toolError(e.message);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
server.tool('ziggs_set_task_result', 'Transition a task to a terminal state (completed / failed / cancelled) and record the result. Enforces the state machine — only active tasks can be transitioned.', {
|
|
374
|
+
taskId: z.string(),
|
|
375
|
+
state: z.enum(['completed', 'failed', 'cancelled']),
|
|
376
|
+
result: z
|
|
377
|
+
.object({
|
|
378
|
+
summary: z.string().optional(),
|
|
379
|
+
status: z.string().optional(),
|
|
380
|
+
links: z.array(z.string()).optional(),
|
|
381
|
+
})
|
|
382
|
+
.passthrough()
|
|
383
|
+
.optional()
|
|
384
|
+
.describe('Outcome payload (summary, status, links, …)'),
|
|
385
|
+
errorMessage: z.string().optional().describe('Required when state=failed'),
|
|
386
|
+
}, async ({ taskId, state, result, errorMessage }) => {
|
|
387
|
+
try {
|
|
388
|
+
const task = await updateTaskState(taskId, state, { result, errorMessage }, creds);
|
|
389
|
+
return textResult({ ok: true, task });
|
|
390
|
+
}
|
|
391
|
+
catch (e) {
|
|
392
|
+
return toolError(e.message);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
server.tool('ziggs_post_task_plan_step', 'Replace / advance the plan for a task. Provide the full ordered step list — existing steps are replaced. Use this to post progress as plan steps.', {
|
|
396
|
+
taskId: z.string(),
|
|
397
|
+
steps: z
|
|
398
|
+
.array(z.object({
|
|
399
|
+
stepId: z.string().describe('Stable id for this step (e.g. uuid)'),
|
|
400
|
+
description: z.string(),
|
|
401
|
+
order: z.number().int(),
|
|
402
|
+
}))
|
|
403
|
+
.describe('Full replacement step list (ordered)'),
|
|
404
|
+
}, async ({ taskId, steps }) => {
|
|
405
|
+
try {
|
|
406
|
+
const task = await replaceTaskPlan(taskId, steps, creds);
|
|
407
|
+
return textResult({ ok: true, task });
|
|
408
|
+
}
|
|
409
|
+
catch (e) {
|
|
410
|
+
return toolError(e.message);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
server.tool('ziggs_list_tasks', 'List tasks reachable by this delegate agent (GET /tasks). Scope is determined by the operator key — same reach as chats and agreements. Supports optional state filter and cursor pagination.', {
|
|
414
|
+
state: z
|
|
415
|
+
.string()
|
|
416
|
+
.optional()
|
|
417
|
+
.describe('Filter by state: active, completed, failed, cancelled'),
|
|
418
|
+
cursor: z.string().optional().describe('Opaque cursor from prior nextCursor'),
|
|
419
|
+
limit: z.number().optional().describe('Max rows (default server-side)'),
|
|
420
|
+
}, async ({ state, cursor, limit }) => {
|
|
421
|
+
try {
|
|
422
|
+
const result = await listTasks({ state, cursor, limit }, creds);
|
|
423
|
+
return textResult(result);
|
|
424
|
+
}
|
|
425
|
+
catch (e) {
|
|
426
|
+
return toolError(e.message);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
354
429
|
registerTrustTools(server, creds, cfg);
|
|
355
430
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/ziggs-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "MCP server for Claude Code, Cursor, and other MCP hosts — act as your Ziggs delegate agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
|
-
"@ziggs-ai/api-client": "^0.1.
|
|
37
|
+
"@ziggs-ai/api-client": "^0.1.15",
|
|
38
38
|
"dotenv": "^16.6.1",
|
|
39
39
|
"zod": "^3.24.2"
|
|
40
40
|
},
|
|
@@ -25,6 +25,21 @@ Counterparty sent 3 chat messages and 1 agreement proposal while you were offlin
|
|
|
25
25
|
|
|
26
26
|
5. **`ziggs_inbox`** again — scoped news for handled chat should be empty. Proposals clear when responded, not on ack alone.
|
|
27
27
|
|
|
28
|
+
## Org / agreement scopes — which chats? (ZIG-543)
|
|
29
|
+
|
|
30
|
+
A `chat` scope's id *is* the chatId. For an **org** or **agreement** scope the
|
|
31
|
+
count spans many chats, so the entry includes a **`chats`** breakdown:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
{ scope: { kind: "org", id: "<orgId>" }, newMessages: 12, chats: [
|
|
35
|
+
{ chatId: "<id>", newMessages: 5, newArtifacts: 0, latestAt: "…" }, … ] }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Open each conversation by its `chatId` — `ziggs_list_messages` or
|
|
39
|
+
`ziggs_read_context` (`via: chat:<chatId>`). Your org/scope grant covers those
|
|
40
|
+
chats without explicit membership. If **`truncatedChats`** is set, more chats
|
|
41
|
+
have news than are listed — handle and ack the listed ones, then re-run inbox.
|
|
42
|
+
|
|
28
43
|
## Deduping push + inbox
|
|
29
44
|
|
|
30
45
|
If the host delivers a push notification and you also poll inbox:
|