@ziggs-ai/ziggs-mcp 0.17.0 → 0.18.0
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 +13 -0
- package/dist/config.js +12 -0
- package/dist/connectionCreds.js +13 -1
- package/dist/creds.js +4 -0
- package/dist/tools.js +30 -3
- package/package.json +2 -2
package/dist/config.d.ts
CHANGED
|
@@ -19,6 +19,17 @@ declare const envSchema: z.ZodObject<{
|
|
|
19
19
|
* states no lane.
|
|
20
20
|
*/
|
|
21
21
|
ZIGGS_LANE_ID: z.ZodOptional<z.ZodString>;
|
|
22
|
+
/**
|
|
23
|
+
* Pins this server's inbox host identity (`X-Ziggs-Instance`).
|
|
24
|
+
*
|
|
25
|
+
* One host owns an agent's inbox and a second is refused for 330 seconds, so
|
|
26
|
+
* a stdio server that a SCHEDULER respawns per run — the NanoClaw
|
|
27
|
+
* one-minute task starting `npx @ziggs-ai/ziggs-mcp` — is a new host every
|
|
28
|
+
* run and is refused by the previous run's lease. Set this to the same value
|
|
29
|
+
* on every run and they are one host. A server that stays up needs nothing:
|
|
30
|
+
* its process is its host.
|
|
31
|
+
*/
|
|
32
|
+
ZIGGS_INSTANCE_ID: z.ZodOptional<z.ZodString>;
|
|
22
33
|
/** Set to 1/true/yes to register internal/debug-only MCP tools. */
|
|
23
34
|
ZIGGS_MCP_DEBUG: z.ZodOptional<z.ZodString>;
|
|
24
35
|
/**
|
|
@@ -35,6 +46,7 @@ declare const envSchema: z.ZodObject<{
|
|
|
35
46
|
ZIGGS_AGENT_ID?: string | undefined;
|
|
36
47
|
ZIGGS_OWNER_USER_ID?: string | undefined;
|
|
37
48
|
ZIGGS_LANE_ID?: string | undefined;
|
|
49
|
+
ZIGGS_INSTANCE_ID?: string | undefined;
|
|
38
50
|
ZIGGS_MCP_DEBUG?: string | undefined;
|
|
39
51
|
ZIGGS_MCP_CORE_ONLY?: string | undefined;
|
|
40
52
|
}, {
|
|
@@ -45,6 +57,7 @@ declare const envSchema: z.ZodObject<{
|
|
|
45
57
|
ZIGGS_AGENT_ID?: string | undefined;
|
|
46
58
|
ZIGGS_OWNER_USER_ID?: string | undefined;
|
|
47
59
|
ZIGGS_LANE_ID?: string | undefined;
|
|
60
|
+
ZIGGS_INSTANCE_ID?: string | undefined;
|
|
48
61
|
ZIGGS_MCP_DEBUG?: string | undefined;
|
|
49
62
|
ZIGGS_MCP_CORE_ONLY?: string | undefined;
|
|
50
63
|
}>;
|
package/dist/config.js
CHANGED
|
@@ -21,6 +21,17 @@ const envSchema = z.object({
|
|
|
21
21
|
* states no lane.
|
|
22
22
|
*/
|
|
23
23
|
ZIGGS_LANE_ID: z.string().optional(),
|
|
24
|
+
/**
|
|
25
|
+
* Pins this server's inbox host identity (`X-Ziggs-Instance`).
|
|
26
|
+
*
|
|
27
|
+
* One host owns an agent's inbox and a second is refused for 330 seconds, so
|
|
28
|
+
* a stdio server that a SCHEDULER respawns per run — the NanoClaw
|
|
29
|
+
* one-minute task starting `npx @ziggs-ai/ziggs-mcp` — is a new host every
|
|
30
|
+
* run and is refused by the previous run's lease. Set this to the same value
|
|
31
|
+
* on every run and they are one host. A server that stays up needs nothing:
|
|
32
|
+
* its process is its host.
|
|
33
|
+
*/
|
|
34
|
+
ZIGGS_INSTANCE_ID: z.string().optional(),
|
|
24
35
|
/** Set to 1/true/yes to register internal/debug-only MCP tools. */
|
|
25
36
|
ZIGGS_MCP_DEBUG: z.string().optional(),
|
|
26
37
|
/**
|
|
@@ -47,6 +58,7 @@ export function loadConfig() {
|
|
|
47
58
|
ZIGGS_AGENT_ID: process.env.ZIGGS_AGENT_ID,
|
|
48
59
|
ZIGGS_OWNER_USER_ID: process.env.ZIGGS_OWNER_USER_ID,
|
|
49
60
|
ZIGGS_LANE_ID: process.env.ZIGGS_LANE_ID,
|
|
61
|
+
ZIGGS_INSTANCE_ID: process.env.ZIGGS_INSTANCE_ID,
|
|
50
62
|
ZIGGS_MCP_DEBUG: process.env.ZIGGS_MCP_DEBUG,
|
|
51
63
|
ZIGGS_MCP_CORE_ONLY: process.env.ZIGGS_MCP_CORE_ONLY,
|
|
52
64
|
};
|
package/dist/connectionCreds.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { configureApiClient } from '@ziggs-ai/api-client';
|
|
1
|
+
import { configureApiClient, mcpConnectionIdentity, } from '@ziggs-ai/api-client';
|
|
2
2
|
import { MINT_KEY_HELP, decodeOperatorKeyClaims, isDirectoryBoarded, resolveDelegateAgentId, } from './operatorKey.js';
|
|
3
3
|
export function parseBearerAuthorization(header) {
|
|
4
4
|
const raw = Array.isArray(header) ? header[0] : header;
|
|
@@ -44,11 +44,23 @@ export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId, laneId) {
|
|
|
44
44
|
// ZiggsMcpConfig.directConnection.
|
|
45
45
|
directConnection: !isDirectoryBoarded(decodeOperatorKeyClaims(bearer)),
|
|
46
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* The inbox host is this CONNECTION, not the process serving it.
|
|
49
|
+
*
|
|
50
|
+
* This server also runs inside the API process, which serves every connected
|
|
51
|
+
* assistant and gets a new identity on every deploy. Stamping that made all
|
|
52
|
+
* of them one host and moved it under all of them at once, so a hosted
|
|
53
|
+
* `ziggs_inbox` read answered 409 for up to 330 seconds after each restart.
|
|
54
|
+
* The key is what stays put across both. Undefined only for a credential
|
|
55
|
+
* carrying no `keyId`, which then falls back to the process default.
|
|
56
|
+
*/
|
|
57
|
+
const instanceId = mcpConnectionIdentity(bearer);
|
|
47
58
|
return {
|
|
48
59
|
creds: {
|
|
49
60
|
operatorKey: bearer,
|
|
50
61
|
agentId: resolvedAgentId,
|
|
51
62
|
...(laneId ? { laneId } : {}),
|
|
63
|
+
...(instanceId ? { instanceId } : {}),
|
|
52
64
|
},
|
|
53
65
|
cfg,
|
|
54
66
|
};
|
package/dist/creds.js
CHANGED
|
@@ -6,5 +6,9 @@ export function credsFromConfig(cfg) {
|
|
|
6
6
|
// Every client in this package reads it off `Creds`, so leaving it unset
|
|
7
7
|
// here silently fences all of them to the agent's own estate.
|
|
8
8
|
...(cfg.ZIGGS_LANE_ID ? { laneId: cfg.ZIGGS_LANE_ID } : {}),
|
|
9
|
+
// Unset means this process is the host, which is right for a server that
|
|
10
|
+
// stays up and wrong for one a scheduler respawns per run — that one pins
|
|
11
|
+
// ZIGGS_INSTANCE_ID so every run is the same host.
|
|
12
|
+
...(cfg.ZIGGS_INSTANCE_ID ? { instanceId: cfg.ZIGGS_INSTANCE_ID } : {}),
|
|
9
13
|
};
|
|
10
14
|
}
|
package/dist/tools.js
CHANGED
|
@@ -605,7 +605,9 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
605
605
|
.describe('Long-poll: hold up to this many seconds (server-clamped, ~110 max) and return as soon as something new arrives — same response shape, no busy re-polling. Omit for an immediate snapshot.'),
|
|
606
606
|
}, readOnly('Check your inbox'), async ({ ack, handledResourceIds, waitSeconds }) => {
|
|
607
607
|
try {
|
|
608
|
-
|
|
608
|
+
// Unset on stdio: that process IS the host, and a scheduler that
|
|
609
|
+
// respawns it per run pins ZIGGS_INSTANCE_ID instead.
|
|
610
|
+
const client = new InboxClient(creds.operatorKey, creds.agentId, undefined, creds.instanceId);
|
|
609
611
|
// Ack-before-fetch is load-bearing; everything else is independent of
|
|
610
612
|
// the envelope until we know whether there are deliveries to tag.
|
|
611
613
|
const acked = ack
|
|
@@ -720,7 +722,7 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
720
722
|
// ---------------------------------------------------------------------------
|
|
721
723
|
// Task mutation tools
|
|
722
724
|
// ---------------------------------------------------------------------------
|
|
723
|
-
registerStrictTool(server, 'ziggs_task_create', 'Create one task, or atomically declare a native work graph under a root task. Every task and graph node cites exactly one active agreement (agreementId required). A plan is one assignee\'s checklist for its own task: pass plan to give the task its checklist in the same call — every step needs a non-blank description, since that is the label whoever is watching reads before anything closes — or leave it off and post it later with ziggs_task_replace_plan. Tick progress with ziggs_task_update_steps (name the steps that changed); do not resend the whole plan to mark one step done. Reach for graph instead of plan when work changes hands, contracts, or dependencies.', {
|
|
725
|
+
registerStrictTool(server, 'ziggs_task_create', 'Create one task, or atomically declare a native work graph under a root task. Every task and graph node cites exactly one active agreement (agreementId required). A plan is one assignee\'s checklist for its own task: pass plan to give the task its checklist in the same call — every step needs a non-blank description, since that is the label whoever is watching reads before anything closes — or leave it off and post it later with ziggs_task_replace_plan. Tick progress with ziggs_task_update_steps (name the steps that changed); do not resend the whole plan to mark one step done. Reach for graph instead of plan when work changes hands, contracts, or dependencies. For work that means getting an answer out of somebody, set dueAt and checkBack so whoever holds it knows when to stop and how often it may remind.', {
|
|
724
726
|
agreementId: z.string().describe('Agreement this task belongs to'),
|
|
725
727
|
description: z.string().describe('What the task entails'),
|
|
726
728
|
title: z
|
|
@@ -793,7 +795,30 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
793
795
|
.boolean()
|
|
794
796
|
.optional()
|
|
795
797
|
.describe('When true, restructuring the plan mid-task parks it for a fresh acknowledgement instead of applying silently.'),
|
|
796
|
-
|
|
798
|
+
// For work that means chasing an answer out of somebody.
|
|
799
|
+
// Nothing on the server makes the holder keep to these yet, so the
|
|
800
|
+
// wording here is the contract: it is what the holder reads.
|
|
801
|
+
dueAt: z
|
|
802
|
+
.string()
|
|
803
|
+
.optional()
|
|
804
|
+
.describe('Deadline, ISO 8601 (e.g. 2026-09-12T17:00:00Z). Whoever holds this task posts what it has and where it is stuck at the deadline, in the room where the question was asked, and then stops. A deadline already past is refused.'),
|
|
805
|
+
checkBack: z
|
|
806
|
+
.object({
|
|
807
|
+
everyMinutes: z
|
|
808
|
+
.number()
|
|
809
|
+
.int()
|
|
810
|
+
.min(5)
|
|
811
|
+
.describe('Minimum minutes between two reminders to the same person. A floor, not a schedule — reminding later is fine, sooner is not.'),
|
|
812
|
+
maxReminders: z
|
|
813
|
+
.number()
|
|
814
|
+
.int()
|
|
815
|
+
.min(1)
|
|
816
|
+
.max(20)
|
|
817
|
+
.describe('Total reminders allowed per person asked, after the first ask. Then the holder stops and reports.'),
|
|
818
|
+
})
|
|
819
|
+
.optional()
|
|
820
|
+
.describe('How often the holder may remind, and how many times at most. Both halves are required together: a cadence with no budget is refused, because one reminder is one wake and a rule that never says stop is an open-ended loop. Omit entirely for a task nobody needs reminding about.'),
|
|
821
|
+
}, write('Create a task'), async ({ agreementId, description, title, parentTaskId, assigneeId, inputArtifactIds, waitsOn, graph, plan, planReviewTiming, requireMidWorkPlanAck, dueAt, checkBack, }) => {
|
|
797
822
|
try {
|
|
798
823
|
const task = await createTask({
|
|
799
824
|
agreementId,
|
|
@@ -807,6 +832,8 @@ export function registerZiggsTools(server, creds, cfg) {
|
|
|
807
832
|
plan,
|
|
808
833
|
planReviewTiming,
|
|
809
834
|
requireMidWorkPlanAck,
|
|
835
|
+
dueAt,
|
|
836
|
+
checkBack,
|
|
810
837
|
}, creds);
|
|
811
838
|
return textResult({ ok: true, task });
|
|
812
839
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ziggs-ai/ziggs-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
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": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
42
|
-
"@ziggs-ai/api-client": "0.
|
|
42
|
+
"@ziggs-ai/api-client": "0.18.0",
|
|
43
43
|
"dotenv": "^16.6.1",
|
|
44
44
|
"zod": "^3.24.2",
|
|
45
45
|
"zod-to-json-schema": "^3.25.1"
|