@ziggs-ai/ziggs-mcp 0.16.0 → 0.17.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 CHANGED
@@ -10,6 +10,15 @@ declare const envSchema: z.ZodObject<{
10
10
  ZIGGS_AGENT_ID: z.ZodOptional<z.ZodString>;
11
11
  /** Human user id for payer-side proposals — defaults the payer on propose/publish tools. */
12
12
  ZIGGS_OWNER_USER_ID: z.ZodOptional<z.ZodString>;
13
+ /**
14
+ * The lane this server's calls belong to — a chat id, or `agrn-<agreementId>`.
15
+ * Sent as `X-Ziggs-Lane` on every fenced call. Unset means the agent acts for
16
+ * itself, which is right for a person who configured this server with their
17
+ * own key, and wrong for a delegate that has been hired: that one holds
18
+ * grants its CUSTOMER gave, and the server refuses those to a wake that
19
+ * states no lane.
20
+ */
21
+ ZIGGS_LANE_ID: z.ZodOptional<z.ZodString>;
13
22
  /** Set to 1/true/yes to register internal/debug-only MCP tools. */
14
23
  ZIGGS_MCP_DEBUG: z.ZodOptional<z.ZodString>;
15
24
  /**
@@ -25,6 +34,7 @@ declare const envSchema: z.ZodObject<{
25
34
  ZIGGS_WEB_URL?: string | undefined;
26
35
  ZIGGS_AGENT_ID?: string | undefined;
27
36
  ZIGGS_OWNER_USER_ID?: string | undefined;
37
+ ZIGGS_LANE_ID?: string | undefined;
28
38
  ZIGGS_MCP_DEBUG?: string | undefined;
29
39
  ZIGGS_MCP_CORE_ONLY?: string | undefined;
30
40
  }, {
@@ -34,6 +44,7 @@ declare const envSchema: z.ZodObject<{
34
44
  ZIGGS_WEB_URL?: string | undefined;
35
45
  ZIGGS_AGENT_ID?: string | undefined;
36
46
  ZIGGS_OWNER_USER_ID?: string | undefined;
47
+ ZIGGS_LANE_ID?: string | undefined;
37
48
  ZIGGS_MCP_DEBUG?: string | undefined;
38
49
  ZIGGS_MCP_CORE_ONLY?: string | undefined;
39
50
  }>;
package/dist/config.js CHANGED
@@ -12,6 +12,15 @@ const envSchema = z.object({
12
12
  ZIGGS_AGENT_ID: z.string().optional(),
13
13
  /** Human user id for payer-side proposals — defaults the payer on propose/publish tools. */
14
14
  ZIGGS_OWNER_USER_ID: z.string().optional(),
15
+ /**
16
+ * The lane this server's calls belong to — a chat id, or `agrn-<agreementId>`.
17
+ * Sent as `X-Ziggs-Lane` on every fenced call. Unset means the agent acts for
18
+ * itself, which is right for a person who configured this server with their
19
+ * own key, and wrong for a delegate that has been hired: that one holds
20
+ * grants its CUSTOMER gave, and the server refuses those to a wake that
21
+ * states no lane.
22
+ */
23
+ ZIGGS_LANE_ID: z.string().optional(),
15
24
  /** Set to 1/true/yes to register internal/debug-only MCP tools. */
16
25
  ZIGGS_MCP_DEBUG: z.string().optional(),
17
26
  /**
@@ -37,6 +46,7 @@ export function loadConfig() {
37
46
  ZIGGS_OPERATOR_KEY: process.env.ZIGGS_OPERATOR_KEY,
38
47
  ZIGGS_AGENT_ID: process.env.ZIGGS_AGENT_ID,
39
48
  ZIGGS_OWNER_USER_ID: process.env.ZIGGS_OWNER_USER_ID,
49
+ ZIGGS_LANE_ID: process.env.ZIGGS_LANE_ID,
40
50
  ZIGGS_MCP_DEBUG: process.env.ZIGGS_MCP_DEBUG,
41
51
  ZIGGS_MCP_CORE_ONLY: process.env.ZIGGS_MCP_CORE_ONLY,
42
52
  };
@@ -1,8 +1,16 @@
1
1
  import { type Creds } from '@ziggs-ai/api-client';
2
2
  import type { ZiggsMcpConfig } from './config.js';
3
3
  export declare function parseBearerAuthorization(header: string | string[] | undefined): string;
4
- /** Per-connection credentials from HTTP Authorization. */
5
- export declare function connectionFromBearer(bearer: string, httpBaseUrl: string, ownerUserId?: string): {
4
+ /**
5
+ * Per-connection credentials from HTTP Authorization.
6
+ *
7
+ * `laneId` is the wake's lane, read off `X-Ziggs-Lane` by the caller that
8
+ * mounts this server, exactly as `ownerUserId` is read off its own header. A
9
+ * connection that states none is fenced to the agent's own estate — right for
10
+ * a person who pasted their key, wrong for a delegate holding grants its
11
+ * customer gave.
12
+ */
13
+ export declare function connectionFromBearer(bearer: string, httpBaseUrl: string, ownerUserId?: string, laneId?: string): {
6
14
  creds: Creds;
7
15
  cfg: ZiggsMcpConfig;
8
16
  };
@@ -11,8 +11,16 @@ export function parseBearerAuthorization(header) {
11
11
  }
12
12
  return token;
13
13
  }
14
- /** Per-connection credentials from HTTP Authorization. */
15
- export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId) {
14
+ /**
15
+ * Per-connection credentials from HTTP Authorization.
16
+ *
17
+ * `laneId` is the wake's lane, read off `X-Ziggs-Lane` by the caller that
18
+ * mounts this server, exactly as `ownerUserId` is read off its own header. A
19
+ * connection that states none is fenced to the agent's own estate — right for
20
+ * a person who pasted their key, wrong for a delegate holding grants its
21
+ * customer gave.
22
+ */
23
+ export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId, laneId) {
16
24
  const resolvedAgentId = resolveDelegateAgentId(bearer, undefined);
17
25
  if (httpBaseUrl) {
18
26
  process.env.HTTP_URL = httpBaseUrl;
@@ -26,6 +34,7 @@ export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId) {
26
34
  HTTP_URL: httpBaseUrl,
27
35
  ZIGGS_AGENT_ID: undefined,
28
36
  ZIGGS_OWNER_USER_ID: ownerUserId,
37
+ ZIGGS_LANE_ID: laneId,
29
38
  resolvedAgentId,
30
39
  debugTools: false,
31
40
  coreOnly: false,
@@ -36,7 +45,11 @@ export function connectionFromBearer(bearer, httpBaseUrl, ownerUserId) {
36
45
  directConnection: !isDirectoryBoarded(decodeOperatorKeyClaims(bearer)),
37
46
  };
38
47
  return {
39
- creds: { operatorKey: bearer, agentId: resolvedAgentId },
48
+ creds: {
49
+ operatorKey: bearer,
50
+ agentId: resolvedAgentId,
51
+ ...(laneId ? { laneId } : {}),
52
+ },
40
53
  cfg,
41
54
  };
42
55
  }
package/dist/creds.js CHANGED
@@ -2,5 +2,9 @@ export function credsFromConfig(cfg) {
2
2
  return {
3
3
  operatorKey: cfg.ZIGGS_OPERATOR_KEY,
4
4
  agentId: cfg.resolvedAgentId,
5
+ // The lane, so a hired delegate can spend the grants its customer gave it.
6
+ // Every client in this package reads it off `Creds`, so leaving it unset
7
+ // here silently fences all of them to the agent's own estate.
8
+ ...(cfg.ZIGGS_LANE_ID ? { laneId: cfg.ZIGGS_LANE_ID } : {}),
5
9
  };
6
10
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
10
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
11
- import { ConnectionsClient, getBackendUrl, } from '@ziggs-ai/api-client';
11
+ import { ConnectionsClient, getBackendUrl, laneHeader, } from '@ziggs-ai/api-client';
12
12
  export function resolveMcpGatewayTarget(opts) {
13
13
  if (!opts.connectionId)
14
14
  throw new Error('connectionId is required');
@@ -25,7 +25,8 @@ export function resolveMcpGatewayTarget(opts) {
25
25
  authorization: `Bearer ${opts.operatorKey}`,
26
26
  'x-agent-id': opts.agentId,
27
27
  'x-grant-id': opts.grantId,
28
- ...(opts.laneId ? { 'x-ziggs-lane': opts.laneId } : {}),
28
+ // one helper for the lane, shared with every other door.
29
+ ...laneHeader(opts.laneId),
29
30
  },
30
31
  };
31
32
  }
package/dist/tools.js CHANGED
@@ -68,7 +68,7 @@ function loadSessionReads(creds) {
68
68
  // #4 — tasks and payments are independent; overlap them.
69
69
  return Promise.allSettled([
70
70
  listTasks({ state: 'active', limit: 20 }, creds),
71
- new PaymentsClient(creds.operatorKey, creds.agentId).approvals({
71
+ new PaymentsClient(creds.operatorKey, creds.agentId, undefined, creds.laneId).approvals({
72
72
  status: 'pending',
73
73
  }),
74
74
  ]);
@@ -207,7 +207,7 @@ function registerConnectionTools(server, creds, cfg) {
207
207
  ? 'How to use a row: provider "mcp" → ziggs_mcp_tools_list / ziggs_mcp_tool_call; named connectors (github, jira, …) → ziggs_connection_proxy.'
208
208
  : 'Rows are readable here but not callable over this connection: using a connection (an MCP server or a named connector such as github or jira) is only on a self-configured Ziggs MCP connection with an operator key.'), {}, readOnly('List connections you can use'), async () => {
209
209
  try {
210
- const connections = await new ConnectionsClient(creds.operatorKey, creds.agentId).listForHolder();
210
+ const connections = await new ConnectionsClient(creds.operatorKey, creds.agentId, undefined, creds.laneId).listForHolder();
211
211
  return textResult({ connections });
212
212
  }
213
213
  catch (e) {
@@ -321,7 +321,7 @@ export function registerZiggsTools(server, creds, cfg) {
321
321
  let snapshot = null;
322
322
  const firstChatId = chats[0]?.chatId;
323
323
  if (firstChatId) {
324
- const client = new ContextReadClient(creds.operatorKey, creds.agentId);
324
+ const client = new ContextReadClient(creds.operatorKey, creds.agentId, undefined, firstChatId);
325
325
  snapshot = await client.snapshot(firstChatId, { maxMessages: 5 });
326
326
  }
327
327
  return textResult({
@@ -345,7 +345,11 @@ export function registerZiggsTools(server, creds, cfg) {
345
345
  .describe('Optional grant id when reading under a context grant'),
346
346
  }, readOnly('Catch up on a chat'), async ({ chatId, maxMessages, contextGrantId }) => {
347
347
  try {
348
- const client = new ContextReadClient(creds.operatorKey, creds.agentId);
348
+ // The chat being read IS the lane: a snapshot of someone else's room
349
+ // is a call inside that engagement, and stating it is what lets a hired
350
+ // delegate read the room it was hired into. Falls back to the
351
+ // connection's lane when no chat is named.
352
+ const client = new ContextReadClient(creds.operatorKey, creds.agentId, undefined, chatId || creds.laneId);
349
353
  const result = await client.snapshot(chatId, {
350
354
  maxMessages,
351
355
  contextGrantId,
@@ -633,7 +637,7 @@ export function registerZiggsTools(server, creds, cfg) {
633
637
  // own held context grants. Best-effort — the inbox still works
634
638
  // untagged. All pages of live grants only (GET /grants also returns
635
639
  // expired/revoked and paginates).
636
- reach = await new GrantsClient(creds.operatorKey, creds.agentId).listAllGrants({
640
+ reach = await new GrantsClient(creds.operatorKey, creds.agentId, undefined, creds.laneId).listAllGrants({
637
641
  // Every context scope kind — a literal subset here is how the CLI
638
642
  // silently dropped a whole kind when `artifact` was added.
639
643
  scopeKind: [...CONTEXT_GRANT_SCOPE_KINDS],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/ziggs-mcp",
3
- "version": "0.16.0",
3
+ "version": "0.17.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.16.0",
42
+ "@ziggs-ai/api-client": "0.17.0",
43
43
  "dotenv": "^16.6.1",
44
44
  "zod": "^3.24.2",
45
45
  "zod-to-json-schema": "^3.25.1"