@ziggs-ai/ziggs-mcp 0.1.17 → 0.1.18
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 +0 -2
- package/dist/toolAnnotations.d.ts +7 -0
- package/dist/toolAnnotations.js +16 -0
- package/dist/tools.js +26 -63
- package/dist/trustTools.js +11 -10
- package/package.json +1 -1
- package/skills/ziggs/references/inbox-rhythm.md +2 -2
package/README.md
CHANGED
|
@@ -197,7 +197,6 @@ OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
|
197
197
|
| `ziggs_discover_context` | `GET /context/discovery` |
|
|
198
198
|
| `ziggs_read_context` | `GET /context/read/:type` |
|
|
199
199
|
| `ziggs_record_artifact` | `POST /artifacts` |
|
|
200
|
-
| `ziggs_list_artifacts` | `GET /artifacts` |
|
|
201
200
|
| `ziggs_search_agents` | Agent search (ZIG-433) |
|
|
202
201
|
| `ziggs_list_my_grants` | `GET /context/grants` |
|
|
203
202
|
| `ziggs_issue_grant` | Chat admission or `POST /context/grants` |
|
|
@@ -212,7 +211,6 @@ OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
|
212
211
|
| `ziggs_get_agreement` | `GET /agreements/:id` |
|
|
213
212
|
| `ziggs_list_chats` | `GET /chats/mine` |
|
|
214
213
|
| `ziggs_open_conversation` | `POST /chats` |
|
|
215
|
-
| `ziggs_list_messages` | `GET /chats/:id/messages` |
|
|
216
214
|
| `ziggs_send_message` | `POST /chats/:id/messages` |
|
|
217
215
|
| `ziggs_propose_agreement` | `POST /agreements/proposals` |
|
|
218
216
|
| `ziggs_respond_to_agreement` | `PUT /agreements/:id/approvals/:partyId` (owner principal; approves hire, service, and `link` proposals) |
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
/** Reads state, never mutates. */
|
|
3
|
+
export declare const READ_ONLY: ToolAnnotations;
|
|
4
|
+
/** Writes state, but additively/reversibly (create, send, grant). */
|
|
5
|
+
export declare const WRITE: ToolAnnotations;
|
|
6
|
+
/** Mutates state irreversibly (revoke). */
|
|
7
|
+
export declare const DESTRUCTIVE: ToolAnnotations;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// MCP annotation hints so connector UIs (Claude, Cursor, …) can bucket Ziggs
|
|
2
|
+
// tools into "Read only" vs "Actions" instead of one undefined group.
|
|
3
|
+
// `readOnlyHint` drives that split; `destructiveHint` flags the irreversible
|
|
4
|
+
// ones so hosts can warn before running them.
|
|
5
|
+
/** Reads state, never mutates. */
|
|
6
|
+
export const READ_ONLY = { readOnlyHint: true };
|
|
7
|
+
/** Writes state, but additively/reversibly (create, send, grant). */
|
|
8
|
+
export const WRITE = {
|
|
9
|
+
readOnlyHint: false,
|
|
10
|
+
destructiveHint: false,
|
|
11
|
+
};
|
|
12
|
+
/** Mutates state irreversibly (revoke). */
|
|
13
|
+
export const DESTRUCTIVE = {
|
|
14
|
+
readOnlyHint: false,
|
|
15
|
+
destructiveHint: true,
|
|
16
|
+
};
|
package/dist/tools.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, proposeBroadcast, publishOffer, respondToAgreement, ScopeClient,
|
|
3
|
+
import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDirectTo, proposeBroadcast, publishOffer, respondToAgreement, ScopeClient, 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 } from './inboxToolResult.js';
|
|
7
7
|
import { formatPendingDecisionsPayload, resolveWebAppOrigin, buildPendingNextActions, } from './pendingDecisions.js';
|
|
8
8
|
import { PROTOCOL } from './protocol/delegateProtocol.js';
|
|
9
|
+
import { READ_ONLY, WRITE } from './toolAnnotations.js';
|
|
9
10
|
// ZIG-557: the protocol sentences (loop / ack / humanAttention) are sourced
|
|
10
11
|
// from the shared const so this description can't drift from SKILL / server
|
|
11
12
|
// instructions / .cursorrules.
|
|
12
13
|
const ZIGGS_INBOX_DESCRIPTION = "What's new since your last ack — references only, never content: scopes with new-message/artifact counts, plus agreement proposals awaiting your response. " +
|
|
13
|
-
'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
|
|
14
|
+
'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_read_context (type=messages, via=chat:<chatId>). ' +
|
|
14
15
|
`${PROTOCOL.humanAttention} ${PROTOCOL.pendingDecisions} ` +
|
|
15
16
|
'When hasActionable the response includes sessionChatCard (decisions + active tasks), decisionChatCard, workChatCard, and nextActions. ' +
|
|
16
17
|
`${PROTOCOL.loop} ${PROTOCOL.ack}`;
|
|
@@ -152,7 +153,7 @@ async function loadSessionActionsPayload(creds, cfg) {
|
|
|
152
153
|
return formatPendingDecisionsPayload(inbox, webOrigin, { activeTasks });
|
|
153
154
|
}
|
|
154
155
|
export function registerZiggsTools(server, creds, cfg) {
|
|
155
|
-
server.tool('ziggs_connection_status', 'ZIG-503 — Verify MCP OAuth binding: delegate agent id, owner user id, and org scope. Call after connect before inbox/chats. Includes pendingDecisions summary when approve/reject is waiting (ZIG-625).', {}, async () => {
|
|
156
|
+
server.tool('ziggs_connection_status', 'ZIG-503 — Verify MCP OAuth binding: delegate agent id, owner user id, and org scope. Call after connect before inbox/chats. Includes pendingDecisions summary when approve/reject is waiting (ZIG-625).', {}, READ_ONLY, async () => {
|
|
156
157
|
const claims = decodeOperatorKeyClaims(creds.operatorKey);
|
|
157
158
|
const boundOrgId = claims?.boundOrgId?.trim() || null;
|
|
158
159
|
const webOrigin = resolveWebAppOrigin(cfg.ZIGGS_WEB_URL);
|
|
@@ -194,7 +195,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
194
195
|
: 'Next: ziggs_inbox or ziggs_pending_decisions at session start.',
|
|
195
196
|
});
|
|
196
197
|
});
|
|
197
|
-
server.tool('ziggs_pending_decisions', ZIGGS_PENDING_DECISIONS_DESCRIPTION, {}, async () => {
|
|
198
|
+
server.tool('ziggs_pending_decisions', ZIGGS_PENDING_DECISIONS_DESCRIPTION, {}, READ_ONLY, async () => {
|
|
198
199
|
try {
|
|
199
200
|
const payload = await loadSessionActionsPayload(creds, cfg);
|
|
200
201
|
const decisions = (payload.decisions ?? []);
|
|
@@ -211,7 +212,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
211
212
|
return toolError(e.message);
|
|
212
213
|
}
|
|
213
214
|
});
|
|
214
|
-
server.tool('ziggs_smoke_impersonation', 'ZIG-222 smoke (1): list agreements and optionally resolve scope from the first chat.', {}, async () => {
|
|
215
|
+
server.tool('ziggs_smoke_impersonation', 'ZIG-222 smoke (1): list agreements and optionally resolve scope from the first chat.', {}, READ_ONLY, async () => {
|
|
215
216
|
try {
|
|
216
217
|
const agreements = await getMyAgreements({}, creds);
|
|
217
218
|
const chats = await listMyChats(creds);
|
|
@@ -235,7 +236,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
235
236
|
server.tool('ziggs_get_scope', 'Resolve the access graph for the delegate agent from a chat, agreement, task, or counterparty entry point.', {
|
|
236
237
|
viaKind: scopeKindSchema.describe('Entry kind'),
|
|
237
238
|
viaId: z.string().describe('Entry id'),
|
|
238
|
-
}, async ({ viaKind, viaId }) => {
|
|
239
|
+
}, READ_ONLY, async ({ viaKind, viaId }) => {
|
|
239
240
|
try {
|
|
240
241
|
const client = new ScopeClient(creds.operatorKey, creds.agentId);
|
|
241
242
|
const result = await client.get(viaKind, viaId);
|
|
@@ -250,7 +251,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
250
251
|
.string()
|
|
251
252
|
.optional()
|
|
252
253
|
.describe('Optional filter: pending, approved, rejected, …'),
|
|
253
|
-
}, async ({ proposalStatus }) => {
|
|
254
|
+
}, READ_ONLY, async ({ proposalStatus }) => {
|
|
254
255
|
try {
|
|
255
256
|
const agreements = await getMyAgreements(proposalStatus ? { proposalStatus } : {}, creds);
|
|
256
257
|
return textResult({ count: agreements.length, agreements });
|
|
@@ -259,7 +260,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
259
260
|
return toolError(e.message);
|
|
260
261
|
}
|
|
261
262
|
});
|
|
262
|
-
server.tool('ziggs_get_agreement', 'Fetch a single agreement by id.', { agreementId: z.string() }, async ({ agreementId }) => {
|
|
263
|
+
server.tool('ziggs_get_agreement', 'Fetch a single agreement by id.', { agreementId: z.string() }, READ_ONLY, async ({ agreementId }) => {
|
|
263
264
|
try {
|
|
264
265
|
const agreement = await getAgreement(agreementId, creds);
|
|
265
266
|
if (!agreement)
|
|
@@ -270,7 +271,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
270
271
|
return toolError(e.message);
|
|
271
272
|
}
|
|
272
273
|
});
|
|
273
|
-
server.tool('ziggs_list_chats', 'List chats the delegate agent is a member of (GET /chats/mine).', {}, async () => {
|
|
274
|
+
server.tool('ziggs_list_chats', 'List chats the delegate agent is a member of (GET /chats/mine).', {}, READ_ONLY, async () => {
|
|
274
275
|
try {
|
|
275
276
|
const chats = await listMyChats(creds);
|
|
276
277
|
return textResult({ count: chats.length, chats });
|
|
@@ -281,7 +282,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
281
282
|
});
|
|
282
283
|
server.tool('ziggs_open_conversation', 'Open or reuse a chat with a user or agent participant. To reach an agent in ANOTHER org, an unpublished delegate must establish a link first — call ziggs_request_link (if you have its agent id) or ziggs_create_link_invite (if you do not) and have it approved/claimed — otherwise this fails with AGENT_NOT_PUBLISHED.', {
|
|
283
284
|
participantId: z.string().describe('User or agent id to converse with'),
|
|
284
|
-
}, async ({ participantId }) => {
|
|
285
|
+
}, WRITE, async ({ participantId }) => {
|
|
285
286
|
try {
|
|
286
287
|
const out = await openConversation(participantId, creds);
|
|
287
288
|
return textResult(out);
|
|
@@ -290,26 +291,6 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
290
291
|
return toolError(e.message);
|
|
291
292
|
}
|
|
292
293
|
});
|
|
293
|
-
server.tool('ziggs_list_messages', 'Forward-delta message read for a chat.', {
|
|
294
|
-
chatId: z.string(),
|
|
295
|
-
after: z
|
|
296
|
-
.string()
|
|
297
|
-
.optional()
|
|
298
|
-
.describe('ISO timestamp; default epoch (all messages)'),
|
|
299
|
-
limit: z.number().optional().describe('Max messages (default 100)'),
|
|
300
|
-
}, async ({ chatId, after, limit }) => {
|
|
301
|
-
try {
|
|
302
|
-
const client = new MessagesClient(creds.operatorKey, creds.agentId);
|
|
303
|
-
const result = await client.list(chatId, {
|
|
304
|
-
after,
|
|
305
|
-
limit,
|
|
306
|
-
});
|
|
307
|
-
return textResult(result);
|
|
308
|
-
}
|
|
309
|
-
catch (e) {
|
|
310
|
-
return toolError(e.message);
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
294
|
server.tool('ziggs_send_message', ZIGGS_SEND_MESSAGE_DESCRIPTION, {
|
|
314
295
|
chatId: z.string(),
|
|
315
296
|
receiverId: z
|
|
@@ -321,7 +302,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
321
302
|
.string()
|
|
322
303
|
.optional()
|
|
323
304
|
.describe('Usually "message" for user-visible chat'),
|
|
324
|
-
}, async ({ chatId, receiverId, text, entryType }) => {
|
|
305
|
+
}, WRITE, async ({ chatId, receiverId, text, entryType }) => {
|
|
325
306
|
try {
|
|
326
307
|
const result = await sendChatMessage({
|
|
327
308
|
chatId,
|
|
@@ -346,7 +327,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
346
327
|
.optional()
|
|
347
328
|
.describe('Human user id = payer (ZIG-222: your userId)'),
|
|
348
329
|
price: z.number().optional().describe('Optional; does not trigger transfer by itself'),
|
|
349
|
-
}, async ({ proposedTo, chatId, description, payerId, price }) => {
|
|
330
|
+
}, WRITE, async ({ proposedTo, chatId, description, payerId, price }) => {
|
|
350
331
|
try {
|
|
351
332
|
const resolvedPayer = payerId ?? cfg.ZIGGS_OWNER_USER_ID;
|
|
352
333
|
if (!resolvedPayer) {
|
|
@@ -378,7 +359,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
378
359
|
.enum(['everyone', 'org'])
|
|
379
360
|
.optional()
|
|
380
361
|
.describe("'everyone' (default, public) or 'org' (visible/claimable only within your org)"),
|
|
381
|
-
}, async ({ description, chatId, payerId, price, audience }) => {
|
|
362
|
+
}, WRITE, async ({ description, chatId, payerId, price, audience }) => {
|
|
382
363
|
try {
|
|
383
364
|
const resolvedPayer = payerId ?? cfg.ZIGGS_OWNER_USER_ID;
|
|
384
365
|
if (!resolvedPayer) {
|
|
@@ -408,7 +389,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
408
389
|
.enum(['everyone', 'org'])
|
|
409
390
|
.optional()
|
|
410
391
|
.describe("'everyone' (default, public) or 'org' (visible/claimable only within your org)"),
|
|
411
|
-
}, async ({ description, price, engagementKind, audience }) => {
|
|
392
|
+
}, WRITE, async ({ description, price, engagementKind, audience }) => {
|
|
412
393
|
try {
|
|
413
394
|
const agreement = await publishOffer({
|
|
414
395
|
description,
|
|
@@ -425,7 +406,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
425
406
|
server.tool('ziggs_respond_to_agreement', 'Approve or reject a pending agreement (ZIG-524). 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).', {
|
|
426
407
|
agreementId: z.string(),
|
|
427
408
|
action: z.enum(['approve', 'reject']),
|
|
428
|
-
}, async ({ agreementId, action }) => {
|
|
409
|
+
}, WRITE, async ({ agreementId, action }) => {
|
|
429
410
|
try {
|
|
430
411
|
const claims = decodeOperatorKeyClaims(creds.operatorKey);
|
|
431
412
|
const ownerId = claims?.ownerId ?? cfg.ZIGGS_OWNER_USER_ID;
|
|
@@ -447,7 +428,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
447
428
|
}))
|
|
448
429
|
.optional()
|
|
449
430
|
.describe('Scopes you finished handling — acked before fetching, monotonic'),
|
|
450
|
-
}, async ({ ack }) => {
|
|
431
|
+
}, READ_ONLY, async ({ ack }) => {
|
|
451
432
|
try {
|
|
452
433
|
const client = new InboxClient(creds.operatorKey, creds.agentId);
|
|
453
434
|
const acked = ack?.length ? await client.ack(ack) : null;
|
|
@@ -466,7 +447,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
466
447
|
return toolError(e.message);
|
|
467
448
|
}
|
|
468
449
|
});
|
|
469
|
-
server.tool('ziggs_discover_context', 'List scope descriptors this delegate can reach (grants only — no content).', {}, async () => {
|
|
450
|
+
server.tool('ziggs_discover_context', 'List scope descriptors this delegate can reach (grants only — no content).', {}, READ_ONLY, async () => {
|
|
470
451
|
try {
|
|
471
452
|
const client = new ContextDiscoveryClient(creds.operatorKey, creds.agentId);
|
|
472
453
|
const reach = await client.discover();
|
|
@@ -476,7 +457,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
476
457
|
return toolError(e.message);
|
|
477
458
|
}
|
|
478
459
|
});
|
|
479
|
-
server.tool('ziggs_read_context', '
|
|
460
|
+
server.tool('ziggs_read_context', 'Read the contents of a scope you already hold: messages | artifacts | agreements | tasks (the type param), under via=chat:<id>, agreement:<id>, or task:<id>. Forward-delta with after+direction=forward; cursor pagination; contextGrantId pins a grant. This is the single read path for all four types — to discover which scopes exist (your chats / tasks / agreements / grants / links), use the ziggs_list_* tools.', {
|
|
480
461
|
type: contextReadTypeSchema.describe('Resource type to read'),
|
|
481
462
|
via: z
|
|
482
463
|
.string()
|
|
@@ -496,7 +477,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
496
477
|
.string()
|
|
497
478
|
.optional()
|
|
498
479
|
.describe('Pin a specific grant when holding several'),
|
|
499
|
-
}, async ({ type, via, cursor, after, direction, limit, state, contextGrantId }) => {
|
|
480
|
+
}, READ_ONLY, async ({ type, via, cursor, after, direction, limit, state, contextGrantId }) => {
|
|
500
481
|
try {
|
|
501
482
|
const client = new ContextReadClient(creds.operatorKey, creds.agentId);
|
|
502
483
|
const result = await client.read(type, {
|
|
@@ -527,7 +508,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
527
508
|
.optional()
|
|
528
509
|
.describe('Optional task — creates a TaskArtifactLink alongside the primary scope link'),
|
|
529
510
|
content_type: z.string().optional().describe('Default text'),
|
|
530
|
-
}, async ({ text, visibility, chatId, agreementId, taskId, content_type }) => {
|
|
511
|
+
}, WRITE, async ({ text, visibility, chatId, agreementId, taskId, content_type }) => {
|
|
531
512
|
try {
|
|
532
513
|
if ((chatId && agreementId) || (!chatId && !agreementId)) {
|
|
533
514
|
return toolError('Pass exactly one of chatId or agreementId');
|
|
@@ -553,24 +534,6 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
553
534
|
return toolError(e.message);
|
|
554
535
|
}
|
|
555
536
|
});
|
|
556
|
-
server.tool('ziggs_list_artifacts', 'List artifacts for a chat or agreement (GET /artifacts). Prefer ziggs_read_context type=artifacts for grant-pinned reads.', {
|
|
557
|
-
chatId: z.string().optional().describe('Chat scope (xor agreementId)'),
|
|
558
|
-
agreementId: z
|
|
559
|
-
.string()
|
|
560
|
-
.optional()
|
|
561
|
-
.describe('Agreement scope (xor chatId)'),
|
|
562
|
-
after: z.string().optional().describe('ISO timestamp forward-delta'),
|
|
563
|
-
limit: z.number().optional().describe('Max rows'),
|
|
564
|
-
}, async ({ chatId, agreementId, after, limit }) => {
|
|
565
|
-
try {
|
|
566
|
-
const client = new ArtifactsClient(creds.operatorKey, creds.agentId);
|
|
567
|
-
const result = await client.list({ chatId, agreementId }, { after, limit });
|
|
568
|
-
return textResult(result);
|
|
569
|
-
}
|
|
570
|
-
catch (e) {
|
|
571
|
-
return toolError(e.message);
|
|
572
|
-
}
|
|
573
|
-
});
|
|
574
537
|
// ---------------------------------------------------------------------------
|
|
575
538
|
// Task mutation tools (ZIG-555)
|
|
576
539
|
// ---------------------------------------------------------------------------
|
|
@@ -578,7 +541,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
578
541
|
agreementId: z.string().describe('Agreement this task belongs to'),
|
|
579
542
|
description: z.string().describe('What the task entails'),
|
|
580
543
|
parentTaskId: z.string().optional().describe('Parent task id for sub-tasks'),
|
|
581
|
-
}, async ({ agreementId, description, parentTaskId }) => {
|
|
544
|
+
}, WRITE, async ({ agreementId, description, parentTaskId }) => {
|
|
582
545
|
try {
|
|
583
546
|
const task = await createTask({ agreementId, description, parentTaskId }, creds);
|
|
584
547
|
return textResult({ ok: true, task });
|
|
@@ -600,7 +563,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
600
563
|
.optional()
|
|
601
564
|
.describe('Outcome payload (summary, status, links, …)'),
|
|
602
565
|
errorMessage: z.string().optional().describe('Required when state=failed'),
|
|
603
|
-
}, async ({ taskId, state, result, errorMessage }) => {
|
|
566
|
+
}, WRITE, async ({ taskId, state, result, errorMessage }) => {
|
|
604
567
|
try {
|
|
605
568
|
const task = await updateTaskState(taskId, state, { result, errorMessage }, creds);
|
|
606
569
|
return textResult({ ok: true, task });
|
|
@@ -618,7 +581,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
618
581
|
order: z.number().int(),
|
|
619
582
|
}))
|
|
620
583
|
.describe('Full replacement step list (ordered)'),
|
|
621
|
-
}, async ({ taskId, steps }) => {
|
|
584
|
+
}, WRITE, async ({ taskId, steps }) => {
|
|
622
585
|
try {
|
|
623
586
|
const task = await replaceTaskPlan(taskId, steps, creds);
|
|
624
587
|
return textResult({ ok: true, task });
|
|
@@ -634,7 +597,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
634
597
|
.describe('Filter by state: active, completed, failed, cancelled'),
|
|
635
598
|
cursor: z.string().optional().describe('Opaque cursor from prior nextCursor'),
|
|
636
599
|
limit: z.number().optional().describe('Max rows (default server-side)'),
|
|
637
|
-
}, async ({ state, cursor, limit }) => {
|
|
600
|
+
}, READ_ONLY, async ({ state, cursor, limit }) => {
|
|
638
601
|
try {
|
|
639
602
|
const result = await listTasks({ state, cursor, limit }, creds);
|
|
640
603
|
return textResult(result);
|
|
@@ -659,7 +622,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
659
622
|
.record(z.unknown())
|
|
660
623
|
.optional()
|
|
661
624
|
.describe('Action-specific arguments (provider-defined)'),
|
|
662
|
-
}, async ({ connectionId, grantId, action, payload }) => {
|
|
625
|
+
}, WRITE, async ({ connectionId, grantId, action, payload }) => {
|
|
663
626
|
try {
|
|
664
627
|
const result = await proxyConnection(creds, {
|
|
665
628
|
connectionId,
|
package/dist/trustTools.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { AgentSearchClient, ContextGrantsClient, createAgreement, listAgreements, revokeAgreement, claimLink, addChatMember, } from '@ziggs-ai/api-client';
|
|
3
|
+
import { READ_ONLY, WRITE, DESTRUCTIVE } from './toolAnnotations.js';
|
|
3
4
|
function textResult(data) {
|
|
4
5
|
return {
|
|
5
6
|
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
@@ -21,7 +22,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
21
22
|
query: z.string().describe('Keyword/natural-language search (published agents) OR an exact agent id (resolves that agent even if unpublished)'),
|
|
22
23
|
limit: z.number().optional().describe('Max results (default server-side)'),
|
|
23
24
|
minScore: z.number().optional().describe('Minimum match score filter'),
|
|
24
|
-
}, async ({ query, limit, minScore }) => {
|
|
25
|
+
}, READ_ONLY, async ({ query, limit, minScore }) => {
|
|
25
26
|
try {
|
|
26
27
|
const client = new AgentSearchClient(creds.operatorKey, creds.agentId);
|
|
27
28
|
const result = await client.searchAgents(query, { limit, minScore });
|
|
@@ -42,7 +43,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
42
43
|
.string()
|
|
43
44
|
.optional()
|
|
44
45
|
.describe('Admin only: list grants for another agent id'),
|
|
45
|
-
}, async ({ holderId }) => {
|
|
46
|
+
}, READ_ONLY, async ({ holderId }) => {
|
|
46
47
|
try {
|
|
47
48
|
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
48
49
|
const grants = await client.listGrants(holderId);
|
|
@@ -64,7 +65,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
64
65
|
.optional()
|
|
65
66
|
.nullable()
|
|
66
67
|
.describe('ISO-8601 expiry; omit for platform default TTL'),
|
|
67
|
-
}, async ({ holderId, scopeKind, scopeId, temporal, expiresAt }) => {
|
|
68
|
+
}, WRITE, async ({ holderId, scopeKind, scopeId, temporal, expiresAt }) => {
|
|
68
69
|
const resolvedTemporal = temporal ?? 'from-now';
|
|
69
70
|
try {
|
|
70
71
|
if (scopeKind === 'chat') {
|
|
@@ -128,7 +129,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
128
129
|
.string()
|
|
129
130
|
.optional()
|
|
130
131
|
.describe('from-now watermark ISO-8601 (optional; server may default)'),
|
|
131
|
-
}, async ({ parentGrantId, holderId, scopeKind, scopeId, temporal, expiresAt, watermarkAt, }) => {
|
|
132
|
+
}, WRITE, async ({ parentGrantId, holderId, scopeKind, scopeId, temporal, expiresAt, watermarkAt, }) => {
|
|
132
133
|
try {
|
|
133
134
|
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
134
135
|
const grant = await client.delegateGrant(parentGrantId, {
|
|
@@ -161,7 +162,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
161
162
|
.string()
|
|
162
163
|
.optional()
|
|
163
164
|
.describe('Optional note shown to the counterparty human on approval (agreement description)'),
|
|
164
|
-
}, async ({ providerId, message }) => {
|
|
165
|
+
}, WRITE, async ({ providerId, message }) => {
|
|
165
166
|
try {
|
|
166
167
|
const { agreement } = await createAgreement({ engagementKind: 'link', providerId, description: message }, creds);
|
|
167
168
|
return textResult({
|
|
@@ -179,7 +180,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
179
180
|
.string()
|
|
180
181
|
.optional()
|
|
181
182
|
.describe('Optional note shown to whoever opens the invite (agreement description)'),
|
|
182
|
-
}, async ({ message }) => {
|
|
183
|
+
}, WRITE, async ({ message }) => {
|
|
183
184
|
try {
|
|
184
185
|
const { agreement } = await createAgreement({ engagementKind: 'link', description: message }, creds);
|
|
185
186
|
return textResult({
|
|
@@ -198,7 +199,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
198
199
|
agreementId: z
|
|
199
200
|
.string()
|
|
200
201
|
.describe('The invite id (agreementId) shared by the issuer'),
|
|
201
|
-
}, async ({ agreementId }) => {
|
|
202
|
+
}, WRITE, async ({ agreementId }) => {
|
|
202
203
|
try {
|
|
203
204
|
const { agreement } = await claimLink(agreementId, creds);
|
|
204
205
|
return textResult({
|
|
@@ -211,7 +212,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
211
212
|
return toolError(e.message);
|
|
212
213
|
}
|
|
213
214
|
});
|
|
214
|
-
server.tool('ziggs_list_links', 'List link agreements for this delegate (GET /agreements?engagementKind=link, ZIG-481). Each item exposes parties.creatorAgent (requester), parties.providerAgent (target), parties.proposedTo (target owner), proposal.status and status. Approve pending links via ziggs_respond_to_agreement.', {}, async () => {
|
|
215
|
+
server.tool('ziggs_list_links', 'List link agreements for this delegate (GET /agreements?engagementKind=link, ZIG-481). Each item exposes parties.creatorAgent (requester), parties.providerAgent (target), parties.proposedTo (target owner), proposal.status and status. Approve pending links via ziggs_respond_to_agreement.', {}, READ_ONLY, async () => {
|
|
215
216
|
try {
|
|
216
217
|
const links = await listAgreements({ engagementKind: 'link' }, creds);
|
|
217
218
|
const hasActive = links.some((a) => a.status === 'active');
|
|
@@ -233,7 +234,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
233
234
|
agreementId: z
|
|
234
235
|
.string()
|
|
235
236
|
.describe('agreementId of the link agreement (from ziggs_list_links)'),
|
|
236
|
-
}, async ({ agreementId }) => {
|
|
237
|
+
}, DESTRUCTIVE, async ({ agreementId }) => {
|
|
237
238
|
try {
|
|
238
239
|
const result = await revokeAgreement(agreementId, creds);
|
|
239
240
|
return textResult({
|
|
@@ -249,7 +250,7 @@ export function registerTrustTools(server, creds, cfg) {
|
|
|
249
250
|
});
|
|
250
251
|
server.tool('ziggs_revoke_grant', 'Revoke a context grant and its descendants (DELETE /context/grants/:id). Requires context:admin on the operator key.', {
|
|
251
252
|
grantId: z.string(),
|
|
252
|
-
}, async ({ grantId }) => {
|
|
253
|
+
}, DESTRUCTIVE, async ({ grantId }) => {
|
|
253
254
|
try {
|
|
254
255
|
const client = new ContextGrantsClient(creds.operatorKey, creds.agentId);
|
|
255
256
|
const result = await client.revokeGrant(grantId);
|
package/package.json
CHANGED
|
@@ -50,8 +50,8 @@ count spans many chats, so the entry includes a **`chats`** breakdown:
|
|
|
50
50
|
{ chatId: "<id>", newMessages: 5, newArtifacts: 0, latestAt: "…" }, … ] }
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Open each conversation by its `chatId`
|
|
54
|
-
`
|
|
53
|
+
Open each conversation by its `chatId` with `ziggs_read_context`
|
|
54
|
+
(`type: messages, via: chat:<chatId>`). Your org/scope grant covers those
|
|
55
55
|
chats without explicit membership. If **`truncatedChats`** is set, more chats
|
|
56
56
|
have news than are listed — handle and ack the listed ones, then re-run inbox.
|
|
57
57
|
|