@ziggs-ai/ziggs-mcp 0.1.24 → 0.1.25

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.
@@ -1,17 +1,22 @@
1
1
  import type { InboxEnvelope, Task } from '@ziggs-ai/api-client';
2
- export type PendingDecisionKind = 'proposal' | 'link_request';
2
+ export type PendingDecisionKind = 'proposal' | 'link_request' | 'mcp_server_request';
3
3
  export interface PendingDecisionItem {
4
4
  kind: PendingDecisionKind;
5
+ /** Agreement id for proposals; requestId for link / MCP server requests. */
5
6
  agreementId: string;
6
7
  title: string;
7
8
  subtitle: string | null;
8
9
  proposedAt: string | null;
9
10
  proposedAtLabel: string | null;
10
11
  appUrl: string;
11
- respondApprove: string;
12
- respondReject: string;
13
- sayApprove: string;
14
- sayReject: string;
12
+ /**
13
+ * Null for mcp_server_request — connecting a server (OAuth) happens in the
14
+ * browser at /app/settings/connections; there is no MCP respond tool.
15
+ */
16
+ respondApprove: string | null;
17
+ respondReject: string | null;
18
+ sayApprove: string | null;
19
+ sayReject: string | null;
15
20
  }
16
21
  export interface ActiveWorkItem {
17
22
  taskId: string;
@@ -26,11 +31,14 @@ export interface ActiveWorkItem {
26
31
  export declare function resolveWebAppOrigin(webUrl?: string | null): string;
27
32
  export declare function agreementAppUrl(origin: string, agreementId: string): string;
28
33
  export declare function agreementsListAppUrl(origin: string): string;
34
+ /** Where the human connects MCP servers and grants tools (ZIG-686). */
35
+ export declare function connectionsSettingsAppUrl(origin: string): string;
29
36
  export declare function buildPendingDecisionItems(inbox: InboxEnvelope, webOrigin: string): PendingDecisionItem[];
30
37
  export declare function buildActiveWorkItems(tasks: Task[], webOrigin: string): ActiveWorkItem[];
31
38
  export declare function buildDecisionChatCard(items: PendingDecisionItem[], opts: {
32
39
  truncatedProposals?: number;
33
40
  truncatedConnectionRequests?: number;
41
+ truncatedMcpServerRequests?: number;
34
42
  agreementsListAppUrl?: string;
35
43
  }): string;
36
44
  export declare function buildWorkChatCard(work: ActiveWorkItem[], listUrl?: string): string;
@@ -38,6 +46,7 @@ export declare function buildWorkChatCard(work: ActiveWorkItem[], listUrl?: stri
38
46
  export declare function buildSessionChatCard(decisions: PendingDecisionItem[], work: ActiveWorkItem[], opts: {
39
47
  truncatedProposals?: number;
40
48
  truncatedConnectionRequests?: number;
49
+ truncatedMcpServerRequests?: number;
41
50
  agreementsListAppUrl?: string;
42
51
  }): string;
43
52
  /** Structured session payload for MCP tools (ZIG-625 + active work). */
@@ -9,6 +9,10 @@ export function agreementAppUrl(origin, agreementId) {
9
9
  export function agreementsListAppUrl(origin) {
10
10
  return `${origin}/app/agreements`;
11
11
  }
12
+ /** Where the human connects MCP servers and grants tools (ZIG-686). */
13
+ export function connectionsSettingsAppUrl(origin) {
14
+ return `${origin}/app/settings/connections`;
15
+ }
12
16
  function truncateText(text, max = TITLE_MAX) {
13
17
  const oneLine = text.replace(/\s+/g, ' ').trim();
14
18
  if (oneLine.length <= max)
@@ -75,6 +79,23 @@ function linkToItem(c, origin) {
75
79
  sayReject: `reject link ${id}`,
76
80
  };
77
81
  }
82
+ function mcpServerRequestToItem(r, origin) {
83
+ const tools = r.tools?.length ? r.tools.join(', ') : 'no tools listed';
84
+ const reason = r.reason?.trim() || null;
85
+ return {
86
+ kind: 'mcp_server_request',
87
+ agreementId: r.requestId,
88
+ title: truncateText(`Connect MCP server · ${r.serverUrl}`),
89
+ subtitle: truncateText(reason ? `${reason} — tools: ${tools}` : `Tools: ${tools}`, 160),
90
+ proposedAt: r.requestedAt,
91
+ proposedAtLabel: formatWhen(r.requestedAt),
92
+ appUrl: connectionsSettingsAppUrl(origin),
93
+ respondApprove: null,
94
+ respondReject: null,
95
+ sayApprove: null,
96
+ sayReject: null,
97
+ };
98
+ }
78
99
  export function buildPendingDecisionItems(inbox, webOrigin) {
79
100
  const items = [];
80
101
  for (const p of inbox.proposalsAwaitingMe ?? []) {
@@ -83,6 +104,9 @@ export function buildPendingDecisionItems(inbox, webOrigin) {
83
104
  for (const c of inbox.connectionRequestsAwaitingMe ?? []) {
84
105
  items.push(linkToItem(c, webOrigin));
85
106
  }
107
+ for (const r of inbox.mcpServerRequestsAwaitingMe ?? []) {
108
+ items.push(mcpServerRequestToItem(r, webOrigin));
109
+ }
86
110
  return items;
87
111
  }
88
112
  export function buildActiveWorkItems(tasks, webOrigin) {
@@ -105,17 +129,26 @@ export function buildActiveWorkItems(tasks, webOrigin) {
105
129
  });
106
130
  }
107
131
  function kindLabel(kind) {
108
- return kind === 'proposal' ? 'Agreement proposal' : 'Agent link request';
132
+ if (kind === 'proposal')
133
+ return 'Agreement proposal';
134
+ if (kind === 'link_request')
135
+ return 'Agent link request';
136
+ return 'MCP server request';
109
137
  }
110
138
  function kindHint(kind) {
111
- return kind === 'proposal'
112
- ? 'Someone proposed work or terms — your approval opens or rejects it.'
113
- : 'Another agent wants to link — your approval enables cross-org reach.';
139
+ if (kind === 'proposal') {
140
+ return 'Someone proposed work or terms — your approval opens or rejects it.';
141
+ }
142
+ if (kind === 'link_request') {
143
+ return 'Another agent wants to link — your approval enables cross-org reach.';
144
+ }
145
+ return 'Your agent asks you to connect an MCP server and grant it the listed tools — connect (OAuth) or reject in the browser.';
114
146
  }
115
147
  function buildDecisionSection(items, opts) {
116
148
  const truncatedProposals = opts.truncatedProposals ?? 0;
117
149
  const truncatedConnectionRequests = opts.truncatedConnectionRequests ?? 0;
118
- const truncated = truncatedProposals + truncatedConnectionRequests;
150
+ const truncatedMcpServerRequests = opts.truncatedMcpServerRequests ?? 0;
151
+ const truncated = truncatedProposals + truncatedConnectionRequests + truncatedMcpServerRequests;
119
152
  if (!items.length && truncated === 0)
120
153
  return [];
121
154
  const lines = [];
@@ -136,18 +169,27 @@ function buildDecisionSection(items, opts) {
136
169
  lines.push(`> ${item.subtitle}`);
137
170
  }
138
171
  lines.push('');
139
- lines.push(`[Review in Ziggs →](${item.appUrl})`);
140
- lines.push('');
141
- lines.push('| You say in chat | What the agent runs |');
142
- lines.push('|:----------------|:--------------------|');
143
- lines.push(`| \`${item.sayApprove}\` | \`${item.respondApprove}\` |`);
144
- lines.push(`| \`${item.sayReject}\` | \`${item.respondReject}\` |`);
172
+ if (item.sayApprove && item.respondApprove && item.sayReject && item.respondReject) {
173
+ lines.push(`[Review in Ziggs →](${item.appUrl})`);
174
+ lines.push('');
175
+ lines.push('| You say in chat | What the agent runs |');
176
+ lines.push('|:----------------|:--------------------|');
177
+ lines.push(`| \`${item.sayApprove}\` | \`${item.respondApprove}\` |`);
178
+ lines.push(`| \`${item.sayReject}\` | \`${item.respondReject}\` |`);
179
+ }
180
+ else {
181
+ // Browser-only decision (mcp_server_request): connecting a server runs
182
+ // OAuth consent — no MCP tool can approve it from chat.
183
+ lines.push(`[Connect or reject in Ziggs →](${item.appUrl})`);
184
+ lines.push('');
185
+ lines.push('_This one is decided in the browser — nothing to approve from chat._');
186
+ }
145
187
  lines.push('');
146
188
  }
147
189
  if (truncated > 0) {
148
190
  lines.push('---');
149
191
  lines.push('');
150
- lines.push(`_+${truncated} more pending (${truncatedProposals} proposal(s), ${truncatedConnectionRequests} link(s)) — not listed here._`);
192
+ lines.push(`_+${truncated} more pending (${truncatedProposals} proposal(s), ${truncatedConnectionRequests} link(s), ${truncatedMcpServerRequests} MCP server request(s)) — not listed here._`);
151
193
  lines.push('');
152
194
  }
153
195
  return lines;
@@ -188,11 +230,13 @@ function buildWorkSection(work, startIndex = 1) {
188
230
  export function buildDecisionChatCard(items, opts) {
189
231
  const truncatedProposals = opts.truncatedProposals ?? 0;
190
232
  const truncatedConnectionRequests = opts.truncatedConnectionRequests ?? 0;
191
- const truncated = truncatedProposals + truncatedConnectionRequests;
233
+ const truncatedMcpServerRequests = opts.truncatedMcpServerRequests ?? 0;
234
+ const truncated = truncatedProposals + truncatedConnectionRequests + truncatedMcpServerRequests;
192
235
  if (!items.length && truncated === 0)
193
236
  return '';
194
237
  const proposals = items.filter((i) => i.kind === 'proposal').length;
195
238
  const links = items.filter((i) => i.kind === 'link_request').length;
239
+ const mcpRequests = items.filter((i) => i.kind === 'mcp_server_request').length;
196
240
  const listedTotal = items.length + truncated;
197
241
  const lines = [
198
242
  `### 🔔 Ziggs — **${listedTotal}** ${listedTotal === 1 ? 'item needs' : 'items need'} your decision`,
@@ -201,9 +245,12 @@ export function buildDecisionChatCard(items, opts) {
201
245
  '|:--|--:|',
202
246
  `| Agreement proposals | **${proposals}** |`,
203
247
  `| Agent link requests | **${links}** |`,
248
+ ...(mcpRequests + truncatedMcpServerRequests > 0
249
+ ? [`| MCP server requests | **${mcpRequests}** |`]
250
+ : []),
204
251
  ...(truncated > 0 ? [`| _Not shown (inbox cap)_ | _+${truncated}_ |`] : []),
205
252
  '',
206
- '> **Heads-up:** Ziggs MCP is pull-only — nothing pops up in Cursor until inbox is checked. **You** approve or reject in this chat; the agent calls `ziggs_respond_to_agreement` only after you say so.',
253
+ '> **Heads-up:** Ziggs MCP is pull-only — nothing pops up in Cursor until inbox is checked. **You** approve or reject in this chat; the agent calls `ziggs_respond_to_agreement` only after you say so. MCP server requests are the exception — those are connected or rejected in the browser.',
207
254
  '',
208
255
  ...buildDecisionSection(items, opts),
209
256
  ];
@@ -232,12 +279,15 @@ export function buildWorkChatCard(work, listUrl) {
232
279
  export function buildSessionChatCard(decisions, work, opts) {
233
280
  const truncatedProposals = opts.truncatedProposals ?? 0;
234
281
  const truncatedConnectionRequests = opts.truncatedConnectionRequests ?? 0;
235
- const truncated = truncatedProposals + truncatedConnectionRequests;
282
+ const truncatedMcpServerRequests = opts.truncatedMcpServerRequests ?? 0;
283
+ const truncated = truncatedProposals + truncatedConnectionRequests + truncatedMcpServerRequests;
236
284
  const decisionListed = decisions.length + truncated;
237
285
  const workCount = work.length;
238
286
  const total = decisionListed + workCount;
239
287
  if (total === 0)
240
288
  return '';
289
+ const mcpRequestCount = decisions.filter((d) => d.kind === 'mcp_server_request').length +
290
+ truncatedMcpServerRequests;
241
291
  const lines = [
242
292
  `### 🔔 Ziggs — **${total}** ${total === 1 ? 'thing needs' : 'things need'} you`,
243
293
  '',
@@ -248,11 +298,16 @@ export function buildSessionChatCard(decisions, work, opts) {
248
298
  `| Approve / reject | **${decisionListed}** |`,
249
299
  `| — proposals | ${decisions.filter((d) => d.kind === 'proposal').length}${truncatedProposals ? ` (+${truncatedProposals} hidden)` : ''} |`,
250
300
  `| — link requests | ${decisions.filter((d) => d.kind === 'link_request').length}${truncatedConnectionRequests ? ` (+${truncatedConnectionRequests} hidden)` : ''} |`,
301
+ ...(mcpRequestCount > 0
302
+ ? [
303
+ `| — MCP server requests | ${decisions.filter((d) => d.kind === 'mcp_server_request').length}${truncatedMcpServerRequests ? ` (+${truncatedMcpServerRequests} hidden)` : ''} |`,
304
+ ]
305
+ : []),
251
306
  ]
252
307
  : []),
253
308
  ...(workCount > 0 ? [`| Active tasks (your work) | **${workCount}** |`] : []),
254
309
  '',
255
- '> **Heads-up:** MCP is pull-only — check at session start. **Decisions:** you say approve/reject. **Tasks:** say `work on <taskId>` — the agent implements and reports on Ziggs.',
310
+ '> **Heads-up:** MCP is pull-only — check at session start. **Decisions:** you say approve/reject (MCP server requests are connected in the browser instead). **Tasks:** say `work on <taskId>` — the agent implements and reports on Ziggs.',
256
311
  '',
257
312
  ];
258
313
  let sectionIndex = 1;
@@ -275,13 +330,18 @@ export function formatPendingDecisionsPayload(inbox, webOrigin, opts) {
275
330
  const activeWork = buildActiveWorkItems(opts?.activeTasks ?? [], webOrigin);
276
331
  const truncatedProposals = inbox.truncatedProposals ?? 0;
277
332
  const truncatedConnectionRequests = inbox.truncatedConnectionRequests ?? 0;
278
- const pendingCount = decisions.length + truncatedProposals + truncatedConnectionRequests;
333
+ const truncatedMcpServerRequests = inbox.truncatedMcpServerRequests ?? 0;
334
+ const pendingCount = decisions.length +
335
+ truncatedProposals +
336
+ truncatedConnectionRequests +
337
+ truncatedMcpServerRequests;
279
338
  const activeWorkCount = activeWork.length;
280
339
  const actionCount = pendingCount + activeWorkCount;
281
340
  const listUrl = agreementsListAppUrl(webOrigin);
282
341
  const cardOpts = {
283
342
  truncatedProposals,
284
343
  truncatedConnectionRequests,
344
+ truncatedMcpServerRequests,
285
345
  agreementsListAppUrl: listUrl,
286
346
  };
287
347
  const decisionChatCard = buildDecisionChatCard(decisions, cardOpts);
@@ -289,6 +349,7 @@ export function formatPendingDecisionsPayload(inbox, webOrigin, opts) {
289
349
  const sessionChatCard = buildSessionChatCard(decisions, activeWork, cardOpts);
290
350
  const proposalCount = decisions.filter((d) => d.kind === 'proposal').length;
291
351
  const linkCount = decisions.filter((d) => d.kind === 'link_request').length;
352
+ const mcpServerRequestCount = decisions.filter((d) => d.kind === 'mcp_server_request').length;
292
353
  const instruction = actionCount > 0
293
354
  ? 'Paste sessionChatCard at the top of your reply. Decisions: wait for explicit approve/reject before ziggs_respond_to_agreement. Tasks: when the human says work on <taskId>, read context and implement.'
294
355
  : 'No pending decisions or active tasks — continue with ziggs_inbox for scope news.';
@@ -302,15 +363,20 @@ export function formatPendingDecisionsPayload(inbox, webOrigin, opts) {
302
363
  summary: {
303
364
  proposals: proposalCount + truncatedProposals,
304
365
  linkRequests: linkCount + truncatedConnectionRequests,
366
+ mcpServerRequests: mcpServerRequestCount + truncatedMcpServerRequests,
305
367
  activeTasks: activeWorkCount,
306
368
  listed: decisions.length,
307
- truncated: truncatedProposals + truncatedConnectionRequests,
369
+ truncated: truncatedProposals +
370
+ truncatedConnectionRequests +
371
+ truncatedMcpServerRequests,
308
372
  },
309
373
  decisions,
310
374
  activeWork,
311
375
  truncatedProposals,
312
376
  truncatedConnectionRequests,
377
+ truncatedMcpServerRequests,
313
378
  agreementsListAppUrl: listUrl,
379
+ connectionsSettingsAppUrl: connectionsSettingsAppUrl(webOrigin),
314
380
  ...(decisionChatCard ? { decisionChatCard } : {}),
315
381
  ...(workChatCard ? { workChatCard } : {}),
316
382
  ...(sessionChatCard ? { sessionChatCard } : {}),
@@ -327,7 +393,12 @@ export function buildPendingNextActions(decisions, work = []) {
327
393
  actions.push('Wait for the human to say approve/reject (e.g. `approve agr-…`) — do not auto-respond.');
328
394
  }
329
395
  for (const d of decisions.slice(0, 4)) {
330
- actions.push(`${kindLabel(d.kind)} ${d.agreementId}: \`${d.sayApprove}\` or \`${d.sayReject}\``);
396
+ if (d.sayApprove && d.sayReject) {
397
+ actions.push(`${kindLabel(d.kind)} ${d.agreementId}: \`${d.sayApprove}\` or \`${d.sayReject}\``);
398
+ }
399
+ else {
400
+ actions.push(`${kindLabel(d.kind)} ${d.agreementId}: connect or reject in the browser → ${d.appUrl}`);
401
+ }
331
402
  }
332
403
  for (const w of work.slice(0, 4)) {
333
404
  actions.push(`Active task ${w.taskId}: human says \`${w.sayWork}\` to start implementation.`);
package/dist/tools.js CHANGED
@@ -4,7 +4,7 @@ import { getAgreement, getMyAgreements, listMyChats, openConversation, proposeDi
4
4
  import { decodeOperatorKeyClaims } from './operatorKey.js';
5
5
  import { registerTrustTools } from './trustTools.js';
6
6
  import { formatInboxToolResult, buildReadContextReadPlan, } from './inboxToolResult.js';
7
- import { formatPendingDecisionsPayload, resolveWebAppOrigin, buildPendingNextActions, } from './pendingDecisions.js';
7
+ import { connectionsSettingsAppUrl, formatPendingDecisionsPayload, resolveWebAppOrigin, buildPendingNextActions, } from './pendingDecisions.js';
8
8
  import { PROTOCOL } from './protocol/delegateProtocol.js';
9
9
  import { READ_ONLY, WRITE, DESTRUCTIVE } from './toolAnnotations.js';
10
10
  // ZIG-557: the protocol sentences (loop / ack / humanAttention) are sourced
@@ -205,6 +205,50 @@ async function listConnectionsForHolder(creds) {
205
205
  }
206
206
  return parsed?.['connections'] ?? [];
207
207
  }
208
+ /**
209
+ * ZIG-686 — agent-initiated MCP connection request: ask the principal to
210
+ * connect a remote MCP server and grant this agent the listed tools. Creates a
211
+ * pending decision the human resolves in the browser (OAuth consent or a grant
212
+ * from an existing connection) — never from chat.
213
+ */
214
+ async function createMcpConnectionRequest(creds, input) {
215
+ const url = `${getBackendUrl()}/connections/mcp/requests`;
216
+ const res = await fetch(url, {
217
+ method: 'POST',
218
+ headers: {
219
+ 'content-type': 'application/json',
220
+ Authorization: `Bearer ${creds.operatorKey}`,
221
+ 'X-Agent-Id': creds.agentId,
222
+ },
223
+ body: JSON.stringify({
224
+ serverUrl: input.serverUrl,
225
+ tools: input.tools,
226
+ reason: input.reason,
227
+ }),
228
+ });
229
+ const body = await res.text().catch(() => '');
230
+ if (!res.ok) {
231
+ throw new Error(`POST /connections/mcp/requests ${res.status} ${body.slice(0, 200)}`);
232
+ }
233
+ return body ? JSON.parse(body) : {};
234
+ }
235
+ /** ZIG-686 — the requests this agent made, each with status / connectionId / grantId. */
236
+ async function listMcpConnectionRequests(creds) {
237
+ const url = `${getBackendUrl()}/connections/mcp/requests`;
238
+ const res = await fetch(url, {
239
+ method: 'GET',
240
+ headers: {
241
+ Authorization: `Bearer ${creds.operatorKey}`,
242
+ 'X-Agent-Id': creds.agentId,
243
+ },
244
+ });
245
+ const body = await res.text().catch(() => '');
246
+ if (!res.ok) {
247
+ throw new Error(`GET /connections/mcp/requests ${res.status} ${body.slice(0, 200)}`);
248
+ }
249
+ const parsed = body ? JSON.parse(body) : null;
250
+ return parsed?.['requests'] ?? [];
251
+ }
208
252
  async function loadSessionActionsPayload(creds, cfg) {
209
253
  const webOrigin = resolveWebAppOrigin(cfg.ZIGGS_WEB_URL);
210
254
  const client = new InboxClient(creds.operatorKey, creds.agentId);
@@ -287,7 +331,7 @@ export function registerZiggsTools(server, creds, cfg) {
287
331
  : 'Next: ziggs_inbox or ziggs_pending_decisions at session start.',
288
332
  });
289
333
  });
290
- server.tool('ziggs_switch_org', 'ZIG-640 — Switch which org this MCP OAuth session acts in without reconnecting. Existing Bearer unchanged; runtime org flips server-side. Requires confirm=true (party-identity change). Target org must be one you belong to. Call ziggs_auth_status after to verify actingOrgId.', {
334
+ server.tool('ziggs_switch_org', 'Switch which org this MCP OAuth session acts in without reconnecting. Existing Bearer unchanged; runtime org flips server-side. Requires confirm=true (party-identity change). Target org must be one you belong to. Call ziggs_auth_status after to verify actingOrgId.', {
291
335
  orgId: z.string().describe('Organization id to act in'),
292
336
  confirm: z
293
337
  .literal(true)
@@ -796,5 +840,46 @@ export function registerZiggsTools(server, creds, cfg) {
796
840
  return toolError(e.message);
797
841
  }
798
842
  });
843
+ server.tool('ziggs_request_connection', 'Ask your principal (the human) to connect a remote MCP server and grant you the listed tools. ' +
844
+ 'Creates a pending decision — the human connects (OAuth) or rejects it in the browser under Settings → Connections; there is no MCP tool to approve it, so tell them and link the returned approveUrl. ' +
845
+ 'Check the outcome with ziggs_request_connection_status: a fulfilled request carries the connectionId + grantId to use with ziggs_connection_proxy.', {
846
+ serverUrl: z.string().describe('Remote MCP server URL (https)'),
847
+ tools: z
848
+ .array(z.string())
849
+ .describe("Tool names you want — become the grant's allowed_actions caveats"),
850
+ reason: z
851
+ .string()
852
+ .optional()
853
+ .describe('Plain-language reason shown to the human deciding'),
854
+ }, WRITE, async ({ serverUrl, tools, reason }) => {
855
+ try {
856
+ const result = await createMcpConnectionRequest(creds, {
857
+ serverUrl,
858
+ tools,
859
+ reason,
860
+ });
861
+ const approveUrl = connectionsSettingsAppUrl(resolveWebAppOrigin(cfg.ZIGGS_WEB_URL));
862
+ return textResult({
863
+ ok: true,
864
+ ...result,
865
+ approveUrl,
866
+ note: 'Pending your principal\'s decision. Tell the human now (pull-only MCP has no push) and link the approveUrl — they connect or reject there. ' +
867
+ 'Poll ziggs_request_connection_status for the outcome; fulfilled requests carry connectionId + grantId for ziggs_connection_proxy.',
868
+ });
869
+ }
870
+ catch (e) {
871
+ return toolError(e.message);
872
+ }
873
+ });
874
+ server.tool('ziggs_request_connection_status', 'List the MCP server connection requests this agent made with ziggs_request_connection, each with status pending | fulfilled | rejected. ' +
875
+ 'A fulfilled request carries the connectionId + grantId to feed into ziggs_connection_proxy (it also appears in ziggs_list_my_connections).', {}, READ_ONLY, async () => {
876
+ try {
877
+ const requests = await listMcpConnectionRequests(creds);
878
+ return textResult({ requests });
879
+ }
880
+ catch (e) {
881
+ return toolError(e.message);
882
+ }
883
+ });
799
884
  registerTrustTools(server, creds, cfg);
800
885
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/ziggs-mcp",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
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.19",
39
+ "@ziggs-ai/api-client": "^0.1.20",
40
40
  "dotenv": "^16.6.1",
41
41
  "zod": "^3.24.2"
42
42
  },