@ziggs-ai/ziggs-mcp 0.22.1 → 0.22.3

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.
@@ -21,7 +21,7 @@ export declare const PROTOCOL: {
21
21
  * because a client that never calls ziggs_tools would otherwise conclude the
22
22
  * everyday set is all there is.
23
23
  */
24
- readonly surface: "Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=[\"<name>\"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.";
24
+ readonly surface: "Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=[\"<name>\"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.";
25
25
  /** The working loop, as the `ziggs_inbox` description phrases it. */
26
26
  readonly loop: "Flow: inbox → read → act → ack.";
27
27
  /**
@@ -21,7 +21,7 @@ export const PROTOCOL = {
21
21
  * because a client that never calls ziggs_tools would otherwise conclude the
22
22
  * everyday set is all there is.
23
23
  */
24
- surface: 'Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=["<name>"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.',
24
+ surface: 'Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=["<name>"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.',
25
25
  /** The working loop, as the `ziggs_inbox` description phrases it. */
26
26
  loop: 'Flow: inbox → read → act → ack.',
27
27
  /**
package/dist/surface.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { type CatalogEntry } from './toolCatalog.js';
2
3
  /**
3
4
  * The tools a cold session gets natively, with their full schemas.
4
5
  *
@@ -13,6 +14,7 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
13
14
  * - `ziggs_open` is how it opens a returned artifact/chat/task/agreement id.
14
15
  * The inbox returns references, never content; `readPlan` names this tool
15
16
  * with the ordinary id. `ziggs_context_read` remains the paged/via listing.
17
+ * - `ziggs_chat_open` starts or reuses contact; an absent room is not a refusal.
16
18
  * - `ziggs_chat_send` and `ziggs_task_set_result` are the two ways to answer:
17
19
  * conversation, and finished work. An agent that can read its mail and
18
20
  * cannot reply is worse off than one that pays for a schema it never used.
@@ -56,6 +58,8 @@ export declare const DESTRUCTIVE_STAY_NATIVE: readonly string[];
56
58
  * when it refuses.
57
59
  */
58
60
  export declare const CATALOG_TOOLS: readonly string[];
61
+ /** Per-tool how-to-call, derived from NATIVE_TOOLS and the annotations. */
62
+ export declare function callLine(entry: CatalogEntry): string;
59
63
  /**
60
64
  * Narrow `tools/list` to the native set, then register the tools that make the
61
65
  * rest reachable: the catalog, and one dispatcher per annotation lane.
package/dist/surface.js CHANGED
@@ -20,6 +20,7 @@ import { catalogEntry, catalogFor, catalogRow, describeEntry, removeCatalogEntry
20
20
  * - `ziggs_open` is how it opens a returned artifact/chat/task/agreement id.
21
21
  * The inbox returns references, never content; `readPlan` names this tool
22
22
  * with the ordinary id. `ziggs_context_read` remains the paged/via listing.
23
+ * - `ziggs_chat_open` starts or reuses contact; an absent room is not a refusal.
23
24
  * - `ziggs_chat_send` and `ziggs_task_set_result` are the two ways to answer:
24
25
  * conversation, and finished work. An agent that can read its mail and
25
26
  * cannot reply is worse off than one that pays for a schema it never used.
@@ -40,6 +41,7 @@ export const NATIVE_TOOLS = [
40
41
  'ziggs_inbox_ack',
41
42
  'ziggs_open',
42
43
  'ziggs_context_read',
44
+ 'ziggs_chat_open',
43
45
  'ziggs_chat_send',
44
46
  'ziggs_task_set_result',
45
47
  // And every irreversible tool — see DESTRUCTIVE_STAY_NATIVE below.
@@ -96,18 +98,39 @@ const CATALOG_TOOL_NAMES = new Set(CATALOG_TOOLS);
96
98
  */
97
99
  const ZIGGS_API = 'the Ziggs API (https://api.ziggsai.com, reference at https://ziggsai.com/docs)';
98
100
  const TOOLS_DESCRIPTION = 'Every Ziggs tool that exists: name plus one line, for the whole surface. ' +
99
- 'A handful of everyday tools are already loaded natively; the rest live here. Each row says whether the tool is read-only: call read-only tools with ziggs_tool_read and the others with ziggs_tool_write. ' +
100
- 'Pass `describe` with one or more tool names to get their full descriptions and input schemas — do that before calling a tool you have not used in this session, so you pass the right arguments. ' +
101
- 'Pass `search` to filter the listing by a word in the name or title (e.g. "agreement", "artifact"). ' +
101
+ 'A handful of everyday tools are already loaded natively; the rest live here. Each row says whether the tool is read-only, whether the host already holds it (`native`), and how to call it (`call`). ' +
102
+ 'Pass `describe` with one or more tool names to get their full descriptions, input schemas, and the same `call` line — do that before calling a tool you have not used in this session, so you pass the right arguments. ' +
103
+ 'Pass `search` to filter by name, title, or common intent (e.g. "contact", "permission", "grant", "artifact"). If a narrow search misses what you need, omit search to see the complete catalog. ' +
102
104
  'Nothing is hidden: if a capability exists, its name is in this list.';
103
105
  const TOOL_READ_DESCRIPTION = `Call a read-only Ziggs tool by name, against ${ZIGGS_API}. ` +
104
- 'This reaches every read-only tool ziggs_tools lists that is not natively loaded, and it never changes anything: a tool that writes is refused here and pointed at ziggs_tool_write. ' +
106
+ 'This reaches every read-only tool ziggs_tools lists, native or not. It never changes anything: a tool that writes is refused here and pointed at ziggs_tool_write. ' +
105
107
  'Look the tool up with ziggs_tools describe=[<name>] first when you do not already know its parameters: `args` is validated against the real schema and a wrong key is refused, not silently dropped. ' +
106
108
  'The result is exactly what the tool itself returns.';
107
109
  const TOOL_WRITE_DESCRIPTION = `Call a Ziggs tool that creates or changes something, by name, against ${ZIGGS_API}. ` +
108
- 'This reaches every writing tool ziggs_tools lists that is not natively loaded. Read-only tools are refused here and pointed at ziggs_tool_read; irreversible tools are loaded natively and are called by their own name. ' +
110
+ 'This reaches every reversible writing tool ziggs_tools lists, native or not. Read-only tools are refused here and pointed at ziggs_tool_read; irreversible tools are called by their own name only — the dispatchers refuse them. ' +
109
111
  'Look the tool up with ziggs_tools describe=[<name>] first when you do not already know its parameters: `args` is validated against the real schema and a wrong key is refused, not silently dropped. ' +
110
112
  'The result is exactly what the tool itself returns.';
113
+ function isNative(name) {
114
+ return NATIVE_TOOLS.includes(name);
115
+ }
116
+ /** Per-tool how-to-call, derived from NATIVE_TOOLS and the annotations. */
117
+ export function callLine(entry) {
118
+ if (entry.annotations.destructiveHint) {
119
+ return `call it by name only: ${entry.name}; the dispatchers refuse it`;
120
+ }
121
+ const dispatcher = laneOf(entry);
122
+ if (isNative(entry.name)) {
123
+ return `call it by name: ${entry.name}; ${dispatcher} { tool: "${entry.name}", args } also works`;
124
+ }
125
+ return `call via ${dispatcher} { tool, args }`;
126
+ }
127
+ function withCall(entry, base) {
128
+ return {
129
+ ...base,
130
+ ...(isNative(entry.name) ? { native: true } : {}),
131
+ call: callLine(entry),
132
+ };
133
+ }
111
134
  function sortRows(entries) {
112
135
  return [...entries].sort((a, b) => a.name.localeCompare(b.name));
113
136
  }
@@ -115,15 +138,6 @@ function sortRows(entries) {
115
138
  function laneOf(entry) {
116
139
  return entry.annotations.readOnlyHint ? TOOL_READ_NAME : TOOL_WRITE_NAME;
117
140
  }
118
- /** The hint under a describe: the dispatcher to call next, named when one fits all. */
119
- function nextCall(entries) {
120
- const lanes = new Set(entries.map(laneOf));
121
- if (lanes.size === 1) {
122
- for (const lane of lanes)
123
- return `Call it with ${lane} { tool, args }.`;
124
- }
125
- return `Call read-only tools with ${TOOL_READ_NAME} { tool, args } and the rest with ${TOOL_WRITE_NAME} { tool, args }.`;
126
- }
127
141
  /**
128
142
  * Keep `tools/list` to `listed` (plus the catalog tools, registered after this
129
143
  * runs) by filtering the response the SDK's own handler builds.
@@ -238,7 +252,7 @@ export function applySurfacePolicy(server) {
238
252
  search: z
239
253
  .string()
240
254
  .optional()
241
- .describe('Only list tools whose name or title contains this word.'),
255
+ .describe('Filter tools by name, title, or common intent such as contact, teammate, permission, or grant. Omit to list every tool.'),
242
256
  }, readOnly('List every Ziggs tool'), async ({ describe, search }) => {
243
257
  try {
244
258
  if (describe?.length) {
@@ -259,9 +273,8 @@ export function applySurfacePolicy(server) {
259
273
  return toolError(`No such tool: ${unknown.join(', ')}. Call ${TOOLS_CATALOG_NAME} with no arguments for the full list of names.`);
260
274
  }
261
275
  return textResult({
262
- tools: found.map(describeEntry),
276
+ tools: found.map((entry) => withCall(entry, describeEntry(entry))),
263
277
  ...(unknown.length ? { unknown } : {}),
264
- next: nextCall(found),
265
278
  });
266
279
  }
267
280
  const all = sortRows(catalogFor(server));
@@ -270,7 +283,7 @@ export function applySurfacePolicy(server) {
270
283
  ? all.filter((e) => e.name.toLowerCase().includes(needle) ||
271
284
  e.title.toLowerCase().includes(needle) ||
272
285
  aliasMatches(e.name, needle))
273
- : all).map(catalogRow);
286
+ : all).map((entry) => withCall(entry, catalogRow(entry)));
274
287
  return textResult({
275
288
  count: rows.length,
276
289
  ...(needle ? { search: needle, total: all.length } : {}),
@@ -23,6 +23,9 @@
23
23
  * nothing.
24
24
  */
25
25
  export const SEARCH_ALIASES = {
26
+ ziggs_chat_open: ['contact', 'teammate', 'colleague', 'start conversation', 'create chat', 'message someone'],
27
+ ziggs_agent_search: ['teammate', 'colleague', 'directory', 'find person'],
28
+ ziggs_context_request: ['grant', 'permission', 'restricted', 'request access', 'unlock document'],
26
29
  ziggs_agreement_buy: [
27
30
  'hire',
28
31
  'commission', // retired name
package/dist/tools.js CHANGED
@@ -422,6 +422,7 @@ export function registerZiggsTools(server, creds, cfg) {
422
422
  return textResult({
423
423
  count: chats.length,
424
424
  chats: projectChatListRows(chats, fields),
425
+ note: 'These are existing rooms, not everyone you can contact. To contact a known person or agent, use ziggs_chat_open with their returned participant id; use ziggs_agent_search to find a teammate by name. The server checks whether contact is allowed. No existing room does not mean contact is forbidden.',
425
426
  });
426
427
  }
427
428
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/ziggs-mcp",
3
- "version": "0.22.1",
3
+ "version": "0.22.3",
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.22.1",
42
+ "@ziggs-ai/api-client": "0.22.3",
43
43
  "dotenv": "^16.6.1",
44
44
  "zod": "^3.24.2",
45
45
  "zod-to-json-schema": "^3.25.1"
@@ -3,7 +3,7 @@
3
3
 
4
4
  You are a delegate agent on a Ziggs team. The MCP tools are the connection; operate by this protocol.
5
5
 
6
- - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=["<name>"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
6
+ - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=["<name>"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
7
7
  - Flow: inbox → read → act → ack.
8
8
  - Reading never advances the watermark; once you have handled what an envelope carried, hand it back with ziggs_inbox_ack — pass its `ackTo` VERBATIM (it is opaque — never construct or edit one) together with `handledResourceIds` for every delivery ASSIGNED to you (assigneeId = you; requests too) in that window. Rows without your stamp are context another window handles — read them, never ack them as yours. Never rewind an ack to an older value.
9
9
  - 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 by naming the steps that changed with ziggs_task_update_steps. Restructure the checklist with ziggs_task_replace_plan (full list).
@@ -22,7 +22,7 @@ You represent a **delegate agent** on Ziggs. MCP tools are the connection; this
22
22
  <!-- BEGIN GENERATED: delegate-protocol — generated file, do not edit by hand -->
23
23
  _You are a delegate agent on a Ziggs team. The MCP tools are the connection; operate by this protocol._
24
24
 
25
- - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=["<name>"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
25
+ - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=["<name>"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
26
26
  - Flow: inbox → read → act → ack.
27
27
  - Reading never advances the watermark; once you have handled what an envelope carried, hand it back with ziggs_inbox_ack — pass its `ackTo` VERBATIM (it is opaque — never construct or edit one) together with `handledResourceIds` for every delivery ASSIGNED to you (assigneeId = you; requests too) in that window. Rows without your stamp are context another window handles — read them, never ack them as yours. Never rewind an ack to an older value.
28
28
  - 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 by naming the steps that changed with ziggs_task_update_steps. Restructure the checklist with ziggs_task_replace_plan (full list).
@@ -5,7 +5,7 @@
5
5
  <!-- BEGIN GENERATED: delegate-protocol — generated file, do not edit by hand -->
6
6
  _You are a delegate agent on a Ziggs team. The MCP tools are the connection; operate by this protocol._
7
7
 
8
- - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=["<name>"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
8
+ - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=["<name>"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
9
9
  - Flow: inbox → read → act → ack.
10
10
  - Reading never advances the watermark; once you have handled what an envelope carried, hand it back with ziggs_inbox_ack — pass its `ackTo` VERBATIM (it is opaque — never construct or edit one) together with `handledResourceIds` for every delivery ASSIGNED to you (assigneeId = you; requests too) in that window. Rows without your stamp are context another window handles — read them, never ack them as yours. Never rewind an ack to an older value.
11
11
  - 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 by naming the steps that changed with ziggs_task_update_steps. Restructure the checklist with ziggs_task_replace_plan (full list).
@@ -5,7 +5,7 @@
5
5
  <!-- BEGIN GENERATED: delegate-protocol — generated file, do not edit by hand -->
6
6
  _You are a delegate agent on a Ziggs team. The MCP tools are the connection; operate by this protocol._
7
7
 
8
- - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, and whether it is read-only), ziggs_tools describe=["<name>"] returns its full schema, ziggs_tool_read { tool, args } calls a read-only tool and ziggs_tool_write { tool, args } calls one that changes something. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
8
+ - Only the everyday tools are loaded; the rest of the surface is one call away. ziggs_tools lists every tool that exists (name + one line, whether it is read-only, whether the host already holds it, and how to call it), ziggs_tools describe=["<name>"] returns its full schema and a call line, ziggs_tool_read and ziggs_tool_write reach every reversible tool by name native or not and irreversible tools are called by their own name only. Nothing is hidden: check ziggs_tools before concluding a capability is missing.
9
9
  - Flow: inbox → read → act → ack.
10
10
  - Reading never advances the watermark; once you have handled what an envelope carried, hand it back with ziggs_inbox_ack — pass its `ackTo` VERBATIM (it is opaque — never construct or edit one) together with `handledResourceIds` for every delivery ASSIGNED to you (assigneeId = you; requests too) in that window. Rows without your stamp are context another window handles — read them, never ack them as yours. Never rewind an ack to an older value.
11
11
  - 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 by naming the steps that changed with ziggs_task_update_steps. Restructure the checklist with ziggs_task_replace_plan (full list).