@ziggs-ai/ziggs-mcp 0.1.31 → 0.1.33
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/dist/toolError.js +1 -1
- package/dist/tools.js +92 -13
- package/package.json +2 -2
- package/skills/ziggs/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -206,7 +206,7 @@ OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
|
206
206
|
| `ziggs_revoke_link` | `DELETE /agreements/:agreementId` (see also `ziggs_revoke_agreement`) |
|
|
207
207
|
| `ziggs_revoke_agreement` | `DELETE /agreements/:id` — any agreement (hire/service/quest/link) |
|
|
208
208
|
| `ziggs_smoke_impersonation` | [Internal/debug] connectivity check — only when `ZIGGS_MCP_DEBUG=1`; not part of normal delegate workflow |
|
|
209
|
-
| `
|
|
209
|
+
| `ziggs_context_snapshot` | `GET /context/snapshot?via=chat:` — one-shot chat orientation (history + agreements + roster), grant-fenced |
|
|
210
210
|
| `ziggs_list_my_agreements` | `GET /agreements?scope=mine` |
|
|
211
211
|
| `ziggs_get_agreement` | `GET /agreements/:id` |
|
|
212
212
|
| `ziggs_list_chats` | `GET /chats/mine` |
|
package/dist/toolError.js
CHANGED
|
@@ -13,7 +13,7 @@ const HTTP_STATUS = /(?:^|\s)([1-5]\d{2})(?=\s|$)/;
|
|
|
13
13
|
const SCOPE_DENIED_HINT = 'You are not authorized for this scope. To get access: ask the counterparty ' +
|
|
14
14
|
'to issue you a context grant (they run ziggs_issue_grant), or request a ' +
|
|
15
15
|
'bilateral link first (ziggs_request_link). Check what you can already ' +
|
|
16
|
-
'reach with ziggs_discover_context /
|
|
16
|
+
'reach with ziggs_discover_context / ziggs_context_snapshot.';
|
|
17
17
|
function codeForStatus(status) {
|
|
18
18
|
if (status === 401)
|
|
19
19
|
return 'NOT_AUTHENTICATED';
|
package/dist/tools.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, proposeBroadcast, publishOffer, respondToAgreement, revokeAgreement,
|
|
3
|
+
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, proposeBroadcast, publishOffer, claimOffer, provisionRelayWorkers, respondToAgreement, revokeAgreement, sendChatMessage, ContextDiscoveryClient, ContextReadClient, InboxClient, 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, buildReadContextReadPlan, } from './inboxToolResult.js';
|
|
7
7
|
import { filterTasksForDelegate, formatPendingDecisionsPayload, resolveWebAppOrigin, buildPendingNextActions, } from './pendingDecisions.js';
|
|
8
8
|
import { PROTOCOL } from './protocol/delegateProtocol.js';
|
|
9
|
+
const RELAY_COORDINATOR_AGENT_ID = 'relay-coordinator';
|
|
10
|
+
function buildRelayCoordinatorTaskBody(opts) {
|
|
11
|
+
const title = opts.title?.trim() || 'Relay coordinator job';
|
|
12
|
+
return {
|
|
13
|
+
agreementId: opts.hireAgreementId,
|
|
14
|
+
assigneeId: RELAY_COORDINATOR_AGENT_ID,
|
|
15
|
+
description: `${title}\nrelay:v1\n${JSON.stringify(opts.payload)}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
9
18
|
import { READ_ONLY, WRITE, DESTRUCTIVE } from './toolAnnotations.js';
|
|
10
19
|
import { toolError } from './toolError.js';
|
|
11
20
|
// ZIG-557: the protocol sentences (loop / ack / humanAttention) are sourced
|
|
@@ -50,7 +59,6 @@ function textResult(data) {
|
|
|
50
59
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
51
60
|
};
|
|
52
61
|
}
|
|
53
|
-
const scopeKindSchema = z.enum(['chat', 'agreement', 'task', 'counterparty']);
|
|
54
62
|
const contextReadTypeSchema = z.enum([
|
|
55
63
|
'messages',
|
|
56
64
|
'artifacts',
|
|
@@ -444,21 +452,21 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
444
452
|
}
|
|
445
453
|
});
|
|
446
454
|
if (cfg.debugTools) {
|
|
447
|
-
server.tool('ziggs_smoke_impersonation', '[Internal/debug] Connectivity check for the operator-key impersonation path — lists agreements and
|
|
455
|
+
server.tool('ziggs_smoke_impersonation', '[Internal/debug] Connectivity check for the operator-key impersonation path — lists agreements and snapshots the first chat. Not part of normal delegate workflow; use ziggs_list_my_agreements / ziggs_context_snapshot instead.', {}, READ_ONLY, async () => {
|
|
448
456
|
try {
|
|
449
457
|
const agreements = await getMyAgreements({}, creds);
|
|
450
458
|
const chats = await listMyChats(creds);
|
|
451
|
-
let
|
|
459
|
+
let snapshot = null;
|
|
452
460
|
const firstChatId = chats[0]?.chatId;
|
|
453
461
|
if (firstChatId) {
|
|
454
|
-
const client = new
|
|
455
|
-
|
|
462
|
+
const client = new ContextReadClient(creds.operatorKey, creds.agentId);
|
|
463
|
+
snapshot = await client.snapshot(firstChatId, { maxMessages: 5 });
|
|
456
464
|
}
|
|
457
465
|
return textResult({
|
|
458
466
|
ok: true,
|
|
459
467
|
agreementsCount: agreements.length,
|
|
460
468
|
chatsCount: chats.length,
|
|
461
|
-
|
|
469
|
+
snapshot,
|
|
462
470
|
});
|
|
463
471
|
}
|
|
464
472
|
catch (e) {
|
|
@@ -466,13 +474,20 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
466
474
|
}
|
|
467
475
|
});
|
|
468
476
|
}
|
|
469
|
-
server.tool('
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
477
|
+
server.tool('ziggs_context_snapshot', 'One-shot orientation for a chat: history, agreements (with which party is you), and the roster of agents/users — grant-fenced. Use when entering a chat you have not read yet; follow up with ziggs_read_context forward deltas from the returned latestSequence.', {
|
|
478
|
+
chatId: z.string().describe('Chat id to snapshot'),
|
|
479
|
+
maxMessages: z.number().optional().describe('Optional message history cap'),
|
|
480
|
+
contextGrantId: z
|
|
481
|
+
.string()
|
|
482
|
+
.optional()
|
|
483
|
+
.describe('Optional grant id when reading under a context grant'),
|
|
484
|
+
}, READ_ONLY, async ({ chatId, maxMessages, contextGrantId }) => {
|
|
473
485
|
try {
|
|
474
|
-
const client = new
|
|
475
|
-
const result = await client.
|
|
486
|
+
const client = new ContextReadClient(creds.operatorKey, creds.agentId);
|
|
487
|
+
const result = await client.snapshot(chatId, {
|
|
488
|
+
maxMessages,
|
|
489
|
+
contextGrantId,
|
|
490
|
+
});
|
|
476
491
|
return textResult(result);
|
|
477
492
|
}
|
|
478
493
|
catch (e) {
|
|
@@ -637,6 +652,70 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
637
652
|
return toolError(e.message);
|
|
638
653
|
}
|
|
639
654
|
});
|
|
655
|
+
server.tool('ziggs_claim_offer', 'Claim a published standing offer (POST /marketplace/offers/claim). Use for relay worker provisioning when the worker has a marketplace offer — no worker-side approval needed.', {
|
|
656
|
+
agreementId: z.string().describe('Open offer agreementId to claim'),
|
|
657
|
+
}, WRITE, async ({ agreementId }) => {
|
|
658
|
+
try {
|
|
659
|
+
const offer = await claimOffer(agreementId, creds);
|
|
660
|
+
return textResult({ offer });
|
|
661
|
+
}
|
|
662
|
+
catch (e) {
|
|
663
|
+
return toolError(e.message);
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
server.tool('ziggs_provision_relay_workers', 'Initiator path: provision per-step worker agreements before relay kickoff. Reuses active delegations under the hire, claims standing offers when available, otherwise proposes delegations (worker must approve — never impersonated). Returns relay:v1 payload and POST /tasks body when all steps are active.', {
|
|
667
|
+
hireAgreementId: z.string(),
|
|
668
|
+
chatId: z
|
|
669
|
+
.string()
|
|
670
|
+
.optional()
|
|
671
|
+
.describe('Required when a step has no standing offer and needs delegation under the hire'),
|
|
672
|
+
inputArtifactIds: z.array(z.string()).optional(),
|
|
673
|
+
steps: z.array(z.object({
|
|
674
|
+
stepId: z.string(),
|
|
675
|
+
order: z.number(),
|
|
676
|
+
assigneeId: z.string(),
|
|
677
|
+
description: z.string(),
|
|
678
|
+
offerAgreementId: z
|
|
679
|
+
.string()
|
|
680
|
+
.optional()
|
|
681
|
+
.describe('Explicit open offer to claim for this worker'),
|
|
682
|
+
})),
|
|
683
|
+
kickoff: z
|
|
684
|
+
.boolean()
|
|
685
|
+
.optional()
|
|
686
|
+
.describe('When true and readyForKickoff, also POST /tasks on the hire for relay-coordinator'),
|
|
687
|
+
}, WRITE, async ({ hireAgreementId, chatId, inputArtifactIds, steps, kickoff }) => {
|
|
688
|
+
try {
|
|
689
|
+
const result = await provisionRelayWorkers({
|
|
690
|
+
creds,
|
|
691
|
+
hireAgreementId,
|
|
692
|
+
chatId,
|
|
693
|
+
inputArtifactIds,
|
|
694
|
+
steps,
|
|
695
|
+
});
|
|
696
|
+
const relayTaskBody = buildRelayCoordinatorTaskBody({
|
|
697
|
+
hireAgreementId,
|
|
698
|
+
payload: result.payload,
|
|
699
|
+
});
|
|
700
|
+
let task;
|
|
701
|
+
if (kickoff && result.readyForKickoff) {
|
|
702
|
+
task = await createTask(relayTaskBody, creds);
|
|
703
|
+
}
|
|
704
|
+
return textResult({
|
|
705
|
+
...result,
|
|
706
|
+
relayTaskBody,
|
|
707
|
+
task,
|
|
708
|
+
nextSteps: result.readyForKickoff
|
|
709
|
+
? kickoff && task
|
|
710
|
+
? 'Relay coordinator task created — watch Execution for step progress.'
|
|
711
|
+
: 'All worker agreements active — POST relayTaskBody via createTask or set kickoff=true.'
|
|
712
|
+
: `Worker approval pending on: ${result.pendingApprovals.join(', ')}. Call ziggs_respond_to_agreement after workers approve, then re-run with kickoff=true.`,
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
catch (e) {
|
|
716
|
+
return toolError(e.message);
|
|
717
|
+
}
|
|
718
|
+
});
|
|
640
719
|
server.tool('ziggs_respond_to_agreement', 'Approve or reject a pending agreement. Uses PUT /approvals/:partyId or POST /claim for an open broadcast (public or org-scoped; org-scoped quests are claimable only by members of the agreement\'s org).', {
|
|
641
720
|
agreementId: z.string(),
|
|
642
721
|
action: z.enum(['approve', 'reject']),
|
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.33",
|
|
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": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
39
|
-
"@ziggs-ai/api-client": "^0.1.
|
|
39
|
+
"@ziggs-ai/api-client": "^0.1.28",
|
|
40
40
|
"dotenv": "^16.6.1",
|
|
41
41
|
"zod": "^3.24.2"
|
|
42
42
|
},
|
package/skills/ziggs/SKILL.md
CHANGED
|
@@ -100,7 +100,7 @@ When coordinating with another org’s delegate:
|
|
|
100
100
|
|
|
101
101
|
## Boarding checklist (cold session)
|
|
102
102
|
|
|
103
|
-
1. Confirm MCP tools are available (e.g. `ziggs_list_chats` or `
|
|
103
|
+
1. Confirm MCP tools are available (e.g. `ziggs_list_chats` or `ziggs_context_snapshot`).
|
|
104
104
|
2. Run **`ziggs_inbox`** — empty inbox is fine.
|
|
105
105
|
3. Ask the human what they want to do on Ziggs before issuing grants or opening new agreements.
|
|
106
106
|
|