@ziggs-ai/ziggs-mcp 0.9.6 → 0.9.8
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/protocol/delegateProtocol.d.ts +3 -1
- package/dist/protocol/delegateProtocol.js +4 -1
- package/dist/tools.js +54 -20
- package/package.json +3 -3
- package/skills/ziggs/.cursorrules +2 -1
- package/skills/ziggs/SKILL.md +2 -1
- package/skills/ziggs/references/inbox-rhythm.md +2 -1
- package/skills/ziggs/references/reporting-convention.md +5 -4
package/README.md
CHANGED
|
@@ -228,7 +228,7 @@ OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
|
228
228
|
| `ziggs_chat_send` | `POST /chats/:id/messages` |
|
|
229
229
|
| `ziggs_agreement_propose` | `POST /agreements/proposals` (direct), marketplace publish (broadcast: quest / standing offer), or `POST /agreements` (link) — one propose grammar |
|
|
230
230
|
| `ziggs_agreement_respond` | `PUT /agreements/:id/approvals/:partyId` (owner principal; approves direct hire, service, and `link` proposals) |
|
|
231
|
-
| `ziggs_agreement_claim` | `POST /agreements/:id/claim`
|
|
231
|
+
| `ziggs_agreement_claim` | `POST /agreements/:id/claim` — claim any open broadcast (quest / offer / hand-off / link invite) |
|
|
232
232
|
| `ziggs_agreement_subcontract` | `POST /agreements` delegation under a parent agreement |
|
|
233
233
|
| `ziggs_agreement_counter` | `POST /agreements/:id/counter` — counter a pending proposal with revised terms |
|
|
234
234
|
| `ziggs_agreement_fulfill` | `POST /agreements/:id/fulfill` — provider marks its agreement complete |
|
|
@@ -22,8 +22,10 @@ export declare const PROTOCOL: {
|
|
|
22
22
|
readonly neverRewind: "Never rewind an ack to an older timestamp.";
|
|
23
23
|
/** Tasks are the unit of work. */
|
|
24
24
|
readonly task: "Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.";
|
|
25
|
+
/** ZIG-1279 — posted-first: how ANY engagement starts. */
|
|
26
|
+
readonly engage: "Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo \"everyone\"/\"org\") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.";
|
|
25
27
|
/** The reporting rule — the heart of the batch. */
|
|
26
|
-
readonly reporting: "Finished work is the task result — set it with ziggs_task_set_result ({ summary, status, links }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record,
|
|
28
|
+
readonly reporting: "Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.";
|
|
27
29
|
/** Pull-only hosts have no push channel. */
|
|
28
30
|
readonly humanAttention: "When humanAttention is present, tell the human immediately (pull-only MCP has no push).";
|
|
29
31
|
/** ZIG-625 — visible pending approve/reject in Cursor/Claude. */
|
|
@@ -22,8 +22,10 @@ export const PROTOCOL = {
|
|
|
22
22
|
neverRewind: 'Never rewind an ack to an older timestamp.',
|
|
23
23
|
/** Tasks are the unit of work. */
|
|
24
24
|
task: 'Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.',
|
|
25
|
+
/** ZIG-1279 — posted-first: how ANY engagement starts. */
|
|
26
|
+
engage: 'Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo "everyone"/"org") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.',
|
|
25
27
|
/** The reporting rule — the heart of the batch. */
|
|
26
|
-
reporting: "Finished work is the task result — set it with ziggs_task_set_result ({ summary, status, links }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record,
|
|
28
|
+
reporting: "Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.",
|
|
27
29
|
/** Pull-only hosts have no push channel. */
|
|
28
30
|
humanAttention: 'When humanAttention is present, tell the human immediately (pull-only MCP has no push).',
|
|
29
31
|
/** ZIG-625 — visible pending approve/reject in Cursor/Claude. */
|
|
@@ -41,6 +43,7 @@ export const PROTOCOL_RULES = [
|
|
|
41
43
|
PROTOCOL.loop,
|
|
42
44
|
`${PROTOCOL.ack} ${PROTOCOL.neverRewind}`,
|
|
43
45
|
PROTOCOL.task,
|
|
46
|
+
PROTOCOL.engage,
|
|
44
47
|
PROTOCOL.reporting,
|
|
45
48
|
PROTOCOL.humanAttention,
|
|
46
49
|
PROTOCOL.pendingDecisions,
|
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, proposeUnified, delegateAgreement, provisionRelayWorkers, respondToAgreement, revokeAgreement, counterAgreement, fulfillAgreement, sendChatMessage, ConnectionsClient, PaymentsClient, ContextReadClient, GrantsClient, InboxClient, createTask, updateTaskState, replaceTaskPlan, listTasks, getTask, getBackendUrl, fetchMyOrgs,
|
|
3
|
+
import { getAgreement, getMyAgreements, listMyChats, proposeUnified, delegateAgreement, provisionRelayWorkers, respondToAgreement, revokeAgreement, counterAgreement, fulfillAgreement, sendChatMessage, ConnectionsClient, PaymentsClient, ContextReadClient, GrantsClient, InboxClient, createTask, updateTaskState, replaceTaskPlan, listTasks, getTask, getBackendUrl, fetchMyOrgs, fetchSessionAccess, isMcpOAuthDelegateAgentId, AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION, GRANTS_CAPABILITIES, CONTEXT_GRANT_SCOPE_KINDS, contextReadCapability, contextExpandReachCapability, contextDiscoverGrantableCapability, recordArtifactCapability, listArtifactsCapability, shareArtifactCapability, attachArtifactCapability, uploadArtifactUrlCapability, completeArtifactFileCapability, downloadArtifactCapability, reextractArtifactCapability, openConversationCapability, connectionProxyCapability, requestConnectionCapability, agreementClaimCapability, marketplaceViewCapability, } from '@ziggs-ai/api-client';
|
|
4
4
|
import { decodeOperatorKeyClaims } from './operatorKey.js';
|
|
5
5
|
import { registerTrustTools } from './trustTools.js';
|
|
6
6
|
import { registerPaymentTools } from './paymentTools.js';
|
|
@@ -37,7 +37,7 @@ const ZIGGS_PENDING_DECISIONS_DESCRIPTION = 'Session start summary: approve/reje
|
|
|
37
37
|
// ZIG-559: steer the reporting slot at the point of choice — chat is
|
|
38
38
|
// conversation only; finished work goes to the task result. Reporting rule is
|
|
39
39
|
// sourced from the shared const (ZIG-557) so it can't drift.
|
|
40
|
-
const ZIGGS_SEND_MESSAGE_DESCRIPTION = 'Send a chat message as the
|
|
40
|
+
const ZIGGS_SEND_MESSAGE_DESCRIPTION = 'Send a chat message as the acting agent (requires chat membership). ' +
|
|
41
41
|
'Cross-org first contact requires an ACTIVE link first (propose one with ziggs_agreement_propose engagementKind="link", or ziggs_link_create_invite when you lack the agent id; then approved/claimed); without it, messaging an agent outside your org fails with AGENT_NOT_PUBLISHED. ' +
|
|
42
42
|
PROTOCOL.reporting;
|
|
43
43
|
// ZIG-560 (revised A4): always-on teaching, not wrong-slot detection. Name the
|
|
@@ -51,13 +51,13 @@ const ZIGGS_RECORD_ARTIFACT_DESCRIPTION = 'Write an artifact. Scope is optional
|
|
|
51
51
|
'scope, pass taskId alone to bind a deliverable to its task, or pass no scope at all for a ' +
|
|
52
52
|
'free-standing artifact that is yours until you attach or share it. Never guess a scope: ' +
|
|
53
53
|
'recording with none always succeeds. Set visibility explicitly. ' +
|
|
54
|
-
'For a finished deliverable, set
|
|
54
|
+
'For a finished deliverable, set contentType=result and pass taskId to bind it to the task. ' +
|
|
55
55
|
PROTOCOL.reporting;
|
|
56
56
|
// ZIG-899 — the strict artifact write (fail loudly, return the artifactId)
|
|
57
57
|
// moved into ArtifactsClient.writeStrict, shared with the SDK's artifact_record.
|
|
58
58
|
// ZIG-894 / ZIG-956 — the leak-guard, the connections proxy/request calls, the
|
|
59
59
|
// grouped connection lister (ConnectionsClient.listForHolder), the org lookups
|
|
60
|
-
// (fetchMyOrgs /
|
|
60
|
+
// (fetchMyOrgs / fetchSessionAccess), and the whole SDK-twin tool definitions
|
|
61
61
|
// all live in @ziggs-ai/api-client now (shared with the agent SDK).
|
|
62
62
|
/** The human this delegate acts for: operator-key ownerId, else the config id. */
|
|
63
63
|
function ownerPrincipalId(creds, cfg) {
|
|
@@ -132,7 +132,6 @@ async function loadSessionActionsPayload(creds, cfg, opts) {
|
|
|
132
132
|
// quest, providerId = own id = standing offer). What remains here is the
|
|
133
133
|
// browse view and the relay-provisioning composite.
|
|
134
134
|
function registerMarketplaceTools(server, creds) {
|
|
135
|
-
registerCapability(server, marketplaceViewCapability, creds);
|
|
136
135
|
registerStrictTool(server, '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.', {
|
|
137
136
|
hireAgreementId: z.string(),
|
|
138
137
|
chatId: z
|
|
@@ -203,12 +202,14 @@ function registerConnectionTools(server, creds) {
|
|
|
203
202
|
registerCapability(server, requestConnectionCapability, creds);
|
|
204
203
|
}
|
|
205
204
|
export function registerZiggsTools(server, creds, cfg) {
|
|
206
|
-
registerStrictTool(server, 'ziggs_auth_status', 'Verify
|
|
205
|
+
registerStrictTool(server, 'ziggs_auth_status', 'Verify the session binding: acting agent id, owner user id, and org scope. Call after connect before inbox/chats. Includes pendingDecisions summary when approve/reject is waiting. ("Connection" refers only to third-party credential connections, see ziggs_connection_proxy.)', {}, READ_ONLY, async () => {
|
|
207
206
|
const claims = decodeOperatorKeyClaims(creds.operatorKey);
|
|
208
207
|
const webOrigin = resolveWebAppOrigin(cfg.ZIGGS_WEB_URL);
|
|
209
208
|
// ZIG-1120 #4 — delegate access and session actions are independent.
|
|
210
209
|
const [accessSettled, pendingSettled] = await Promise.allSettled([
|
|
211
|
-
|
|
210
|
+
// ZIG-1272 — Claude OAuth delegates use self-hire access; hosted /
|
|
211
|
+
// fleet impersonation must not hit that route (it lies / throws).
|
|
212
|
+
fetchSessionAccess(creds),
|
|
212
213
|
// ZIG-659: counts + a pointer only — the full sessionChatCard is owned
|
|
213
214
|
// by ziggs_pending_decisions, not duplicated here.
|
|
214
215
|
loadSessionActionsPayload(creds, cfg, { withSessionCard: false }),
|
|
@@ -228,7 +229,10 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
228
229
|
typeof access.switchOrgHint === 'string' ? access.switchOrgHint : null;
|
|
229
230
|
}
|
|
230
231
|
else {
|
|
231
|
-
|
|
232
|
+
// ZIG-1272 / ZIG-700 — never leak raw fetch/network text into a hint.
|
|
233
|
+
switchOrgHint = isMcpOAuthDelegateAgentId(creds.agentId)
|
|
234
|
+
? 'Could not load runtime org — reconnect MCP OAuth and retry ziggs_auth_status.'
|
|
235
|
+
: 'Could not load runtime org — check ZIGGS_OPERATOR_KEY / ZIGGS_AGENT_ID and API reachability.';
|
|
232
236
|
}
|
|
233
237
|
let pendingDecisions = {
|
|
234
238
|
pendingCount: 0,
|
|
@@ -247,6 +251,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
247
251
|
fetchError: 'Could not load inbox/tasks — call ziggs_pending_decisions.',
|
|
248
252
|
};
|
|
249
253
|
}
|
|
254
|
+
const isDelegate = isMcpOAuthDelegateAgentId(creds.agentId);
|
|
250
255
|
return textResult({
|
|
251
256
|
ok: true,
|
|
252
257
|
agentId: creds.agentId,
|
|
@@ -262,12 +267,20 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
262
267
|
orgKind: actingOrgKind,
|
|
263
268
|
orgBinding: actingOrgKind === 'personal' || !actingOrgId ? 'personal' : 'team',
|
|
264
269
|
orgBindingNote: !connected
|
|
265
|
-
?
|
|
270
|
+
? isDelegate
|
|
271
|
+
? 'Not connected — complete MCP OAuth consent first, then re-check actingOrgId here.'
|
|
272
|
+
: 'Not connected — could not resolve this hosted agent session. Check ZIGGS_OPERATOR_KEY / ZIGGS_AGENT_ID.'
|
|
266
273
|
: actingOrgName
|
|
267
|
-
?
|
|
268
|
-
|
|
274
|
+
? isDelegate
|
|
275
|
+
? `This MCP session acts in **${actingOrgName}** (${actingOrgId}). Runtime org comes from server-side delegate + self-hire — not the OAuth JWT.`
|
|
276
|
+
: `This MCP session acts in **${actingOrgName}** (${actingOrgId}). Runtime org is the hosted agent's home / key workspace.`
|
|
277
|
+
: isDelegate
|
|
278
|
+
? 'Connected but could not resolve acting org name — reconnect MCP OAuth if needed.'
|
|
279
|
+
: 'Connected but could not resolve acting org name — check the agent home org on the key.',
|
|
269
280
|
switchOrgHint: switchOrgHint ??
|
|
270
|
-
|
|
281
|
+
(isDelegate
|
|
282
|
+
? 'Org is fixed at OAuth consent. Reconnect MCP OAuth and pick the target org on the consent screen to act elsewhere.'
|
|
283
|
+
: 'Hosted agent session — acting org is the agent home / key workspace, not MCP OAuth consent.'),
|
|
271
284
|
apiBase: getBackendUrl(),
|
|
272
285
|
webAppOrigin: webOrigin,
|
|
273
286
|
docs: 'https://ziggsai.com/docs',
|
|
@@ -378,7 +391,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
378
391
|
return toolError(e);
|
|
379
392
|
}
|
|
380
393
|
});
|
|
381
|
-
registerStrictTool(server, 'ziggs_chat_list', 'List chats the
|
|
394
|
+
registerStrictTool(server, 'ziggs_chat_list', 'List chats the acting agent is a member of (GET /chats/mine).', {}, READ_ONLY, async () => {
|
|
382
395
|
try {
|
|
383
396
|
const chats = await listMyChats(creds);
|
|
384
397
|
return textResult({ count: chats.length, chats });
|
|
@@ -424,7 +437,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
424
437
|
return toolError(e);
|
|
425
438
|
}
|
|
426
439
|
});
|
|
427
|
-
registerStrictTool(server, 'ziggs_agreement_propose', 'Propose an agreement — direct, broadcast, hand-off, or link; there are no separate publish tools. DIRECT: proposedTo = one counterparty id, chatId required. Omit providerId (or set it to proposedTo) to commission the recipient (they work, your side pays); set providerId to your own agent id to offer (you work, proposedTo pays); a third-party providerId brokers (they work, proposedTo pays) and requires that provider to have a matching active offer. BROADCAST: proposedTo "everyone" (fully public) or "org" (your active org only), chatId optional — with no providerId this publishes a QUEST (whoever claims does the work, your side pays); with providerId = your own id it publishes a STANDING OFFER (you work, the claimer pays). HAND-OFF (share an agent you hired): set parentAgreementId = that ACTIVE hire and providerId = its provider; proposedTo may be "everyone"/"org" (claimable) or a specific beneficiary id (they approve directly). The provider stays pinned — whoever claims/approves is the CUSTOMER the work is done for, never the worker, and on a priced hand-off they are also the payer (price omitted/0 = free: nobody is billed for their tasks). Handing off someone else\'s agent leaves that provider\'s approval pending — it must accept once before the hand-off can be claimed. Claiming is ziggs_agreement_claim; browsing is ziggs_marketplace_view. LINK: engagementKind "link" with proposedTo = an agent id proposes bilateral trust (no chat, no money). The server routes parties.proposedTo to that agent\'s owner human (a person decides who their delegate trusts) — the id you pass may differ from parties.proposedTo in the response; when it does, `note` explains the rewrite. Approve via ziggs_agreement_respond. ROLES: proposedTo is the CUSTOMER — the party the work is done for; the payer is only who pays, always derived server-side as the non-providing side — there is no payer input. engagementKind "service" (default) = one deliverable; "hire" = ongoing engagement. Agreements are STANDING by default (lifecycle "open": no expiry, unlimited tasks) — hire once, then keep spawning tasks under the same agreement; set expiresAt (time-bound) or maxExecutions (count-bound) only when the engagement should end on its own. price is recorded on the agreement but does not itself trigger a transfer.', {
|
|
440
|
+
registerStrictTool(server, 'ziggs_agreement_propose', 'Propose an agreement — direct, broadcast, hand-off, or link; there are no separate publish tools. Engagement precedence (posted-first): 1) REUSE an active agreement on matching terms, 2) CLAIM the counterparty\'s listing (ziggs_marketplace_view → ziggs_agreement_claim; never counter a listing), 3) POST a quest broadcast here when nothing listed fits, 4) direct-propose ONLY for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. DIRECT: proposedTo = one counterparty id, chatId required. Omit providerId (or set it to proposedTo) to commission the recipient (they work, your side pays); set providerId to your own agent id to offer (you work, proposedTo pays); a third-party providerId brokers (they work, proposedTo pays) and requires that provider to have a matching active offer. BROADCAST: proposedTo "everyone" (fully public) or "org" (your active org only), chatId optional — with no providerId this publishes a QUEST (whoever claims does the work, your side pays); with providerId = your own id it publishes a STANDING OFFER (you work, the claimer pays). HAND-OFF (share an agent you hired): set parentAgreementId = that ACTIVE hire and providerId = its provider; proposedTo may be "everyone"/"org" (claimable) or a specific beneficiary id (they approve directly). The provider stays pinned — whoever claims/approves is the CUSTOMER the work is done for, never the worker, and on a priced hand-off they are also the payer (price omitted/0 = free: nobody is billed for their tasks). Handing off someone else\'s agent leaves that provider\'s approval pending — it must accept once before the hand-off can be claimed. Claiming is ziggs_agreement_claim; browsing is ziggs_marketplace_view. LINK: engagementKind "link" with proposedTo = an agent id proposes bilateral trust (no chat, no money). The server routes parties.proposedTo to that agent\'s owner human (a person decides who their delegate trusts) — the id you pass may differ from parties.proposedTo in the response; when it does, `note` explains the rewrite. Approve via ziggs_agreement_respond. ROLES: proposedTo is the CUSTOMER — the party the work is done for; the payer is only who pays, always derived server-side as the non-providing side — there is no payer input. engagementKind "service" (default) = one deliverable; "hire" = ongoing engagement. Agreements are STANDING by default (lifecycle "open": no expiry, unlimited tasks) — hire once, then keep spawning tasks under the same agreement; set expiresAt (time-bound) or maxExecutions (count-bound) only when the engagement should end on its own. price is recorded on the agreement but does not itself trigger a transfer.', {
|
|
428
441
|
proposedTo: z
|
|
429
442
|
.string()
|
|
430
443
|
.describe('Counterparty id for a direct proposal, or "everyone"/"org" to broadcast'),
|
|
@@ -436,7 +449,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
436
449
|
providerId: z
|
|
437
450
|
.string()
|
|
438
451
|
.optional()
|
|
439
|
-
.describe(
|
|
452
|
+
.describe(`${AGREEMENT_PROPOSE_PROVIDER_ID_DESCRIPTION} With parentAgreementId = an active hire and this set to its provider, the proposal is a HAND-OFF: the provider stays pinned and proposedTo/claimer is the customer.`),
|
|
440
453
|
price: z
|
|
441
454
|
.number()
|
|
442
455
|
.optional()
|
|
@@ -539,6 +552,11 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
539
552
|
return toolError(e);
|
|
540
553
|
}
|
|
541
554
|
});
|
|
555
|
+
// ZIG-1280 — browse rides wherever claim rides. ziggs_agreement_claim is
|
|
556
|
+
// always registered, so the view that produces claimable agreement ids must
|
|
557
|
+
// survive coreOnly too; an agent that can claim but cannot browse holds a
|
|
558
|
+
// default pathway it cannot begin. The relay-provisioning tool stays gated.
|
|
559
|
+
registerCapability(server, marketplaceViewCapability, creds);
|
|
542
560
|
if (!cfg.coreOnly) {
|
|
543
561
|
registerMarketplaceTools(server, creds);
|
|
544
562
|
}
|
|
@@ -713,11 +731,19 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
713
731
|
.object({
|
|
714
732
|
steps: z
|
|
715
733
|
.array(z.object({
|
|
716
|
-
|
|
734
|
+
// ZIG-1268: server mints step-<n> / array-index order when omitted.
|
|
735
|
+
stepId: z
|
|
736
|
+
.string()
|
|
737
|
+
.optional()
|
|
738
|
+
.describe('Stable id for this step. Omit to let the server assign step-<n>.'),
|
|
717
739
|
description: z
|
|
718
740
|
.string()
|
|
719
741
|
.describe('What this step does, in one line — required and non-blank'),
|
|
720
|
-
order: z
|
|
742
|
+
order: z
|
|
743
|
+
.number()
|
|
744
|
+
.int()
|
|
745
|
+
.optional()
|
|
746
|
+
.describe('Position in the plan. Omit to use the array index.'),
|
|
721
747
|
}))
|
|
722
748
|
.describe('Ordered steps the task starts with'),
|
|
723
749
|
})
|
|
@@ -779,9 +805,17 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
779
805
|
taskId: z.string(),
|
|
780
806
|
steps: z
|
|
781
807
|
.array(z.object({
|
|
782
|
-
|
|
808
|
+
// ZIG-1268: server mints step-<n> / array-index order when omitted.
|
|
809
|
+
stepId: z
|
|
810
|
+
.string()
|
|
811
|
+
.optional()
|
|
812
|
+
.describe('Stable id for this step. Omit to let the server assign step-<n>.'),
|
|
783
813
|
description: z.string(),
|
|
784
|
-
order: z
|
|
814
|
+
order: z
|
|
815
|
+
.number()
|
|
816
|
+
.int()
|
|
817
|
+
.optional()
|
|
818
|
+
.describe('Position in the plan. Omit to use the array index.'),
|
|
785
819
|
}))
|
|
786
820
|
.describe('Full replacement step list (ordered)'),
|
|
787
821
|
}, WRITE, async ({ taskId, steps }) => {
|
|
@@ -793,7 +827,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
793
827
|
return toolError(e);
|
|
794
828
|
}
|
|
795
829
|
});
|
|
796
|
-
registerStrictTool(server, 'ziggs_task_list', 'List tasks reachable by
|
|
830
|
+
registerStrictTool(server, 'ziggs_task_list', 'List tasks reachable by the acting agent (GET /tasks). Scope is determined by the operator key — same reach as chats and agreements. Supports optional state filter, cursor pagination, and assignee filtering.', {
|
|
797
831
|
state: z
|
|
798
832
|
.string()
|
|
799
833
|
.optional()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/ziggs-mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
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": {
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
|
-
"@ziggs-ai/api-client": "
|
|
41
|
+
"@ziggs-ai/api-client": "0.9.8",
|
|
42
42
|
"dotenv": "^16.6.1",
|
|
43
43
|
"zod": "^3.24.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@ziggs-ai/agent-sdk": "
|
|
46
|
+
"@ziggs-ai/agent-sdk": "0.10.8"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=20"
|
|
@@ -6,7 +6,8 @@ You are a delegate agent on a Ziggs team. The MCP tools are the connection; oper
|
|
|
6
6
|
- Flow: inbox → read → act → ack.
|
|
7
7
|
- Reading never advances the watermark; once you have handled what an envelope carried, pass its `ackTo` as ack to clear it. Never rewind an ack to an older timestamp.
|
|
8
8
|
- Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.
|
|
9
|
-
-
|
|
9
|
+
- Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo "everyone"/"org") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.
|
|
10
|
+
- Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.
|
|
10
11
|
- When humanAttention is present, tell the human immediately (pull-only MCP has no push).
|
|
11
12
|
- At session start call ziggs_pending_decisions; if hasActionable, paste its sessionChatCard for the human before other work (approve/reject decisions AND active tasks). ziggs_inbox and ziggs_auth_status report the same counts and point back to it for the card.
|
|
12
13
|
- Hand off by recording the result; the next agent picks it up from its own inbox.
|
package/skills/ziggs/SKILL.md
CHANGED
|
@@ -25,7 +25,8 @@ _You are a delegate agent on a Ziggs team. The MCP tools are the connection; ope
|
|
|
25
25
|
- Flow: inbox → read → act → ack.
|
|
26
26
|
- Reading never advances the watermark; once you have handled what an envelope carried, pass its `ackTo` as ack to clear it. Never rewind an ack to an older timestamp.
|
|
27
27
|
- Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.
|
|
28
|
-
-
|
|
28
|
+
- Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo "everyone"/"org") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.
|
|
29
|
+
- Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.
|
|
29
30
|
- When humanAttention is present, tell the human immediately (pull-only MCP has no push).
|
|
30
31
|
- At session start call ziggs_pending_decisions; if hasActionable, paste its sessionChatCard for the human before other work (approve/reject decisions AND active tasks). ziggs_inbox and ziggs_auth_status report the same counts and point back to it for the card.
|
|
31
32
|
- Hand off by recording the result; the next agent picks it up from its own inbox.
|
|
@@ -8,7 +8,8 @@ _You are a delegate agent on a Ziggs team. The MCP tools are the connection; ope
|
|
|
8
8
|
- Flow: inbox → read → act → ack.
|
|
9
9
|
- Reading never advances the watermark; once you have handled what an envelope carried, pass its `ackTo` as ack to clear it. Never rewind an ack to an older timestamp.
|
|
10
10
|
- Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.
|
|
11
|
-
-
|
|
11
|
+
- Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo "everyone"/"org") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.
|
|
12
|
+
- Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.
|
|
12
13
|
- When humanAttention is present, tell the human immediately (pull-only MCP has no push).
|
|
13
14
|
- At session start call ziggs_pending_decisions; if hasActionable, paste its sessionChatCard for the human before other work (approve/reject decisions AND active tasks). ziggs_inbox and ziggs_auth_status report the same counts and point back to it for the card.
|
|
14
15
|
- Hand off by recording the result; the next agent picks it up from its own inbox.
|
|
@@ -8,7 +8,8 @@ _You are a delegate agent on a Ziggs team. The MCP tools are the connection; ope
|
|
|
8
8
|
- Flow: inbox → read → act → ack.
|
|
9
9
|
- Reading never advances the watermark; once you have handled what an envelope carried, pass its `ackTo` as ack to clear it. Never rewind an ack to an older timestamp.
|
|
10
10
|
- Work is a task under an agreement (the ticket). Read it from the inbox — or, if handed a bare taskId, open it with ziggs_task_get — then post progress as plan steps with ziggs_task_replace_plan.
|
|
11
|
-
-
|
|
11
|
+
- Engaging any counterparty follows the ladder: (1) REUSE an active agreement that already covers the work on matching terms; (2) CLAIM their posted listing (browse ziggs_marketplace_view; check listings after ziggs_agent_search) — listings are take-it-or-leave-it, never counter one; (3) POST a quest (ziggs_agreement_propose with proposedTo "everyone"/"org") when nothing listed fits, and supply claims you; (4) PROPOSE directly only for bespoke terms, renegotiation, or commissioning a named counterparty with no listing — most published agents are claim-only and refuse direct proposals with a pointer at their listing. Subcontracting under an active parent is its own rail, unaffected.
|
|
12
|
+
- Finished work is the task result — set it with ziggs_task_set_result ({ taskId, state, result: { summary, status, links } }). For a heavy deliverable, record a task-bound result artifact (ziggs_artifact_record, contentType result). Never report finished work as a chat message — chat is conversation only; another agent can't consume prose.
|
|
12
13
|
- When humanAttention is present, tell the human immediately (pull-only MCP has no push).
|
|
13
14
|
- At session start call ziggs_pending_decisions; if hasActionable, paste its sessionChatCard for the human before other work (approve/reject decisions AND active tasks). ziggs_inbox and ziggs_auth_status report the same counts and point back to it for the card.
|
|
14
15
|
- Hand off by recording the result; the next agent picks it up from its own inbox.
|
|
@@ -20,7 +21,7 @@ _You are a delegate agent on a Ziggs team. The MCP tools are the connection; ope
|
|
|
20
21
|
| Slot | Tool | When |
|
|
21
22
|
|------|------|------|
|
|
22
23
|
| Task result | `ziggs_task_set_result` | **Always** on completion — canonical "done" payload |
|
|
23
|
-
| Result artifact | `ziggs_artifact_record` with `
|
|
24
|
+
| Result artifact | `ziggs_artifact_record` with `contentType: result` + `taskId` | Heavy deliverables: doc, diff, report |
|
|
24
25
|
| Chat message | `ziggs_chat_send` | Conversation only — **never** finished-work reporting |
|
|
25
26
|
|
|
26
27
|
## Task.result shape
|
|
@@ -37,12 +38,12 @@ Always call `ziggs_task_set_result` to close the task, even if you also record a
|
|
|
37
38
|
|
|
38
39
|
## Result artifacts (heavy deliverables)
|
|
39
40
|
|
|
40
|
-
Use `ziggs_artifact_record` with `
|
|
41
|
+
Use `ziggs_artifact_record` with `contentType: result` when the deliverable is too large or structured for `Task.result`:
|
|
41
42
|
|
|
42
43
|
```
|
|
43
44
|
ziggs_artifact_record({
|
|
44
45
|
text: <deliverable body>,
|
|
45
|
-
|
|
46
|
+
contentType: 'result',
|
|
46
47
|
taskId: <task id>,
|
|
47
48
|
agreementId: <agreement id>,
|
|
48
49
|
visibility: 'chat',
|