@ziggs-ai/ziggs-mcp 0.1.11 → 0.1.13
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/config.d.ts +4 -0
- package/dist/config.js +3 -0
- package/dist/tools.js +80 -8
- package/dist/trustTools.d.ts +2 -1
- package/dist/trustTools.js +5 -2
- package/package.json +2 -2
- package/skills/ziggs/references/inbox-rhythm.md +15 -0
package/dist/config.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { z } from 'zod';
|
|
|
3
3
|
declare const envSchema: z.ZodObject<{
|
|
4
4
|
ZIGGS_API_URL: z.ZodOptional<z.ZodString>;
|
|
5
5
|
HTTP_URL: z.ZodOptional<z.ZodString>;
|
|
6
|
+
/** Web app base URL for constructing shareable links. Defaults to https://ziggsai.com. */
|
|
7
|
+
ZIGGS_WEB_URL: z.ZodOptional<z.ZodString>;
|
|
6
8
|
ZIGGS_OPERATOR_KEY: z.ZodString;
|
|
7
9
|
/** Optional when the operator key is agent-scoped (ZIG-279). */
|
|
8
10
|
ZIGGS_AGENT_ID: z.ZodOptional<z.ZodString>;
|
|
@@ -12,12 +14,14 @@ declare const envSchema: z.ZodObject<{
|
|
|
12
14
|
ZIGGS_OPERATOR_KEY: string;
|
|
13
15
|
ZIGGS_API_URL?: string | undefined;
|
|
14
16
|
HTTP_URL?: string | undefined;
|
|
17
|
+
ZIGGS_WEB_URL?: string | undefined;
|
|
15
18
|
ZIGGS_AGENT_ID?: string | undefined;
|
|
16
19
|
ZIGGS_OWNER_USER_ID?: string | undefined;
|
|
17
20
|
}, {
|
|
18
21
|
ZIGGS_OPERATOR_KEY: string;
|
|
19
22
|
ZIGGS_API_URL?: string | undefined;
|
|
20
23
|
HTTP_URL?: string | undefined;
|
|
24
|
+
ZIGGS_WEB_URL?: string | undefined;
|
|
21
25
|
ZIGGS_AGENT_ID?: string | undefined;
|
|
22
26
|
ZIGGS_OWNER_USER_ID?: string | undefined;
|
|
23
27
|
}>;
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,8 @@ import { MINT_KEY_HELP, resolveDelegateAgentId } from './operatorKey.js';
|
|
|
4
4
|
const envSchema = z.object({
|
|
5
5
|
ZIGGS_API_URL: z.string().optional(),
|
|
6
6
|
HTTP_URL: z.string().optional(),
|
|
7
|
+
/** Web app base URL for constructing shareable links. Defaults to https://ziggsai.com. */
|
|
8
|
+
ZIGGS_WEB_URL: z.string().optional(),
|
|
7
9
|
ZIGGS_OPERATOR_KEY: z.string().min(1, 'ZIGGS_OPERATOR_KEY is required'),
|
|
8
10
|
/** Optional when the operator key is agent-scoped (ZIG-279). */
|
|
9
11
|
ZIGGS_AGENT_ID: z.string().optional(),
|
|
@@ -15,6 +17,7 @@ export function loadConfig() {
|
|
|
15
17
|
const raw = {
|
|
16
18
|
ZIGGS_API_URL: process.env.ZIGGS_API_URL,
|
|
17
19
|
HTTP_URL: process.env.HTTP_URL ?? process.env.ZIGGS_API_URL,
|
|
20
|
+
ZIGGS_WEB_URL: process.env.ZIGGS_WEB_URL,
|
|
18
21
|
ZIGGS_OPERATOR_KEY: process.env.ZIGGS_OPERATOR_KEY,
|
|
19
22
|
ZIGGS_AGENT_ID: process.env.ZIGGS_AGENT_ID,
|
|
20
23
|
ZIGGS_OWNER_USER_ID: process.env.ZIGGS_OWNER_USER_ID,
|
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';
|
|
@@ -38,7 +38,6 @@ async function writeArtifactStrict(creds, input) {
|
|
|
38
38
|
visibility: input.visibility,
|
|
39
39
|
chatId: input.chatId,
|
|
40
40
|
agreementId: input.agreementId,
|
|
41
|
-
taskId: input.taskId,
|
|
42
41
|
}),
|
|
43
42
|
});
|
|
44
43
|
if (!res.ok) {
|
|
@@ -166,7 +165,10 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
166
165
|
});
|
|
167
166
|
server.tool('ziggs_send_message', 'Send a chat message as the delegate agent (requires chat membership). Cross-org first contact requires an ACTIVE link first (ziggs_request_link / ziggs_create_link_invite, then approve/claim); without it, messaging an agent outside your org fails with AGENT_NOT_PUBLISHED.', {
|
|
168
167
|
chatId: z.string(),
|
|
169
|
-
receiverId: z
|
|
168
|
+
receiverId: z
|
|
169
|
+
.string()
|
|
170
|
+
.optional()
|
|
171
|
+
.describe('User or agent id receiving the message. Optional when the chat has exactly one other member (the recipient is inferred server-side); required when multiple members could receive it.'),
|
|
170
172
|
text: z.string(),
|
|
171
173
|
entryType: z
|
|
172
174
|
.string()
|
|
@@ -233,7 +235,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
233
235
|
return toolError(e.message);
|
|
234
236
|
}
|
|
235
237
|
});
|
|
236
|
-
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
|
|
238
|
+
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.", {
|
|
237
239
|
ack: z
|
|
238
240
|
.array(z.object({
|
|
239
241
|
kind: z.enum(['chat', 'agreement', 'org']),
|
|
@@ -309,9 +311,8 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
309
311
|
.string()
|
|
310
312
|
.optional()
|
|
311
313
|
.describe('Target agreement (xor chatId)'),
|
|
312
|
-
taskId: z.string().optional().describe('Optional task link'),
|
|
313
314
|
content_type: z.string().optional().describe('Default text'),
|
|
314
|
-
}, async ({ text, visibility, chatId, agreementId,
|
|
315
|
+
}, async ({ text, visibility, chatId, agreementId, content_type }) => {
|
|
315
316
|
try {
|
|
316
317
|
if ((chatId && agreementId) || (!chatId && !agreementId)) {
|
|
317
318
|
return toolError('Pass exactly one of chatId or agreementId');
|
|
@@ -321,7 +322,6 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
321
322
|
visibility,
|
|
322
323
|
chatId,
|
|
323
324
|
agreementId,
|
|
324
|
-
taskId,
|
|
325
325
|
content_type,
|
|
326
326
|
});
|
|
327
327
|
return textResult({ ok: true, visibility, chatId, agreementId });
|
|
@@ -348,5 +348,77 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
348
348
|
return toolError(e.message);
|
|
349
349
|
}
|
|
350
350
|
});
|
|
351
|
-
|
|
351
|
+
// ---------------------------------------------------------------------------
|
|
352
|
+
// Task mutation tools (ZIG-555)
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
server.tool('ziggs_create_task', 'Create a task under an agreement. Every task belongs to exactly one agreement (agreementId required).', {
|
|
355
|
+
agreementId: z.string().describe('Agreement this task belongs to'),
|
|
356
|
+
description: z.string().describe('What the task entails'),
|
|
357
|
+
parentTaskId: z.string().optional().describe('Parent task id for sub-tasks'),
|
|
358
|
+
}, async ({ agreementId, description, parentTaskId }) => {
|
|
359
|
+
try {
|
|
360
|
+
const task = await createTask({ agreementId, description, parentTaskId }, creds);
|
|
361
|
+
return textResult({ ok: true, task });
|
|
362
|
+
}
|
|
363
|
+
catch (e) {
|
|
364
|
+
return toolError(e.message);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
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.', {
|
|
368
|
+
taskId: z.string(),
|
|
369
|
+
state: z.enum(['completed', 'failed', 'cancelled']),
|
|
370
|
+
result: z
|
|
371
|
+
.object({
|
|
372
|
+
summary: z.string().optional(),
|
|
373
|
+
status: z.string().optional(),
|
|
374
|
+
links: z.array(z.string()).optional(),
|
|
375
|
+
})
|
|
376
|
+
.passthrough()
|
|
377
|
+
.optional()
|
|
378
|
+
.describe('Outcome payload (summary, status, links, …)'),
|
|
379
|
+
errorMessage: z.string().optional().describe('Required when state=failed'),
|
|
380
|
+
}, async ({ taskId, state, result, errorMessage }) => {
|
|
381
|
+
try {
|
|
382
|
+
const task = await updateTaskState(taskId, state, { result, errorMessage }, creds);
|
|
383
|
+
return textResult({ ok: true, task });
|
|
384
|
+
}
|
|
385
|
+
catch (e) {
|
|
386
|
+
return toolError(e.message);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
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.', {
|
|
390
|
+
taskId: z.string(),
|
|
391
|
+
steps: z
|
|
392
|
+
.array(z.object({
|
|
393
|
+
stepId: z.string().describe('Stable id for this step (e.g. uuid)'),
|
|
394
|
+
description: z.string(),
|
|
395
|
+
order: z.number().int(),
|
|
396
|
+
}))
|
|
397
|
+
.describe('Full replacement step list (ordered)'),
|
|
398
|
+
}, async ({ taskId, steps }) => {
|
|
399
|
+
try {
|
|
400
|
+
const task = await replaceTaskPlan(taskId, steps, creds);
|
|
401
|
+
return textResult({ ok: true, task });
|
|
402
|
+
}
|
|
403
|
+
catch (e) {
|
|
404
|
+
return toolError(e.message);
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
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.', {
|
|
408
|
+
state: z
|
|
409
|
+
.string()
|
|
410
|
+
.optional()
|
|
411
|
+
.describe('Filter by state: active, completed, failed, cancelled'),
|
|
412
|
+
cursor: z.string().optional().describe('Opaque cursor from prior nextCursor'),
|
|
413
|
+
limit: z.number().optional().describe('Max rows (default server-side)'),
|
|
414
|
+
}, async ({ state, cursor, limit }) => {
|
|
415
|
+
try {
|
|
416
|
+
const result = await listTasks({ state, cursor, limit }, creds);
|
|
417
|
+
return textResult(result);
|
|
418
|
+
}
|
|
419
|
+
catch (e) {
|
|
420
|
+
return toolError(e.message);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
registerTrustTools(server, creds, cfg);
|
|
352
424
|
}
|
package/dist/trustTools.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { type Creds } from '@ziggs-ai/api-client';
|
|
3
|
+
import type { ZiggsMcpConfig } from './config.js';
|
|
3
4
|
/** ZIG-433 — agent search + context grant management through MCP. */
|
|
4
|
-
export declare function registerTrustTools(server: McpServer, creds: Creds): void;
|
|
5
|
+
export declare function registerTrustTools(server: McpServer, creds: Creds, cfg?: ZiggsMcpConfig): void;
|
package/dist/trustTools.js
CHANGED
|
@@ -13,8 +13,10 @@ function toolError(message) {
|
|
|
13
13
|
}
|
|
14
14
|
const grantScopeKindSchema = z.enum(['chat', 'agreement', 'org']);
|
|
15
15
|
const contextTemporalSchema = z.enum(['from-now', 'from-start']);
|
|
16
|
+
const DEFAULT_WEB_URL = 'https://ziggsai.com';
|
|
16
17
|
/** ZIG-433 — agent search + context grant management through MCP. */
|
|
17
|
-
export function registerTrustTools(server, creds) {
|
|
18
|
+
export function registerTrustTools(server, creds, cfg) {
|
|
19
|
+
const webUrl = cfg?.ZIGGS_WEB_URL?.replace(/\/$/, '') ?? DEFAULT_WEB_URL;
|
|
18
20
|
server.tool('ziggs_search_agents', 'Find agents (AgentSearchClient). A keyword/natural-language query searches PUBLISHED agents only. Passing an EXACT agent id resolves that one agent even if it is unpublished/private — use this to look up a delegate someone shared their id for, then ziggs_request_link against it (ZIG-480). Use returned agentId in grant/issue tools — do not guess ids.', {
|
|
19
21
|
query: z.string().describe('Keyword/natural-language search (published agents) OR an exact agent id (resolves that agent even if unpublished)'),
|
|
20
22
|
limit: z.number().optional().describe('Max results (default server-side)'),
|
|
@@ -183,7 +185,8 @@ export function registerTrustTools(server, creds) {
|
|
|
183
185
|
return textResult({
|
|
184
186
|
status: 'open',
|
|
185
187
|
inviteId: agreement.agreementId,
|
|
186
|
-
|
|
188
|
+
claimUrl: `${webUrl}/app/link-invites/${agreement.agreementId}`,
|
|
189
|
+
message: 'Open link invite created. Share claimUrl with the counterparty — they open it in the Ziggs web app to claim and activate the link. No agent id needed on either side.',
|
|
187
190
|
agreement,
|
|
188
191
|
});
|
|
189
192
|
}
|
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.13",
|
|
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.14",
|
|
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:
|