@jini-ai/mcp 0.1.2 → 0.3.1

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.
Files changed (39) hide show
  1. package/README.md +124 -0
  2. package/dist/bin/serve.d.ts +25 -0
  3. package/dist/bin/serve.d.ts.map +1 -1
  4. package/dist/bin/serve.js +51 -5
  5. package/dist/bin/serve.js.map +1 -1
  6. package/dist/index.d.ts +4 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +6 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/server/index.d.ts +5 -1
  11. package/dist/server/index.d.ts.map +1 -1
  12. package/dist/server/index.js +5 -1
  13. package/dist/server/index.js.map +1 -1
  14. package/dist/server/resources/active-resource.d.ts.map +1 -1
  15. package/dist/server/resources/active-resource.js +3 -2
  16. package/dist/server/resources/active-resource.js.map +1 -1
  17. package/dist/server/tool-protocol.d.ts +48 -9
  18. package/dist/server/tool-protocol.d.ts.map +1 -1
  19. package/dist/server/tool-protocol.js +142 -10
  20. package/dist/server/tool-protocol.js.map +1 -1
  21. package/dist/server/tool-server.d.ts +6 -0
  22. package/dist/server/tool-server.d.ts.map +1 -1
  23. package/dist/server/tool-server.js +1 -0
  24. package/dist/server/tool-server.js.map +1 -1
  25. package/dist/server/tools/component-catalog-tools.d.ts +8 -0
  26. package/dist/server/tools/component-catalog-tools.d.ts.map +1 -0
  27. package/dist/server/tools/component-catalog-tools.js +71 -0
  28. package/dist/server/tools/component-catalog-tools.js.map +1 -0
  29. package/dist/server/tools/delegated-tool.d.ts +72 -0
  30. package/dist/server/tools/delegated-tool.d.ts.map +1 -1
  31. package/dist/server/tools/delegated-tool.js +148 -14
  32. package/dist/server/tools/delegated-tool.js.map +1 -1
  33. package/dist/server/tools/run-tools.d.ts.map +1 -1
  34. package/dist/server/tools/run-tools.js +8 -8
  35. package/dist/server/tools/run-tools.js.map +1 -1
  36. package/dist/server/tools/tool-catalog-tools.d.ts.map +1 -1
  37. package/dist/server/tools/tool-catalog-tools.js +43 -9
  38. package/dist/server/tools/tool-catalog-tools.js.map +1 -1
  39. package/package.json +10 -5
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @module @jini-ai/mcp/server/tools/delegated-tool
3
3
  *
4
- * `execute_delegated_tool` the MCP-callback half of gap 3's continuation transport (see
4
+ * `execute_delegated_tool` and its read-only companion `execute_readonly_delegated_tool` the
5
+ * MCP-callback half of gap 3's continuation transport (see
5
6
  * `packages/daemon/source-map.md`'s "run/chat orchestration gap 3, part 1" addition and this
6
7
  * package's own dated section in `source-map.md` for the rest of the spike). The swarm-consensus
7
8
  * Final Recommendation asked for exactly this: "inject the already-shipped MCP host into one
@@ -23,22 +24,93 @@
23
24
  * confused-deputy path (one run's MCP subprocess executing a tool call "as" a different run).
24
25
  * `toolUseId` is likewise generated per call (`randomUUID` by default), not model-supplied — a
25
26
  * model has no legitimate reason to choose its own correlation id either.
27
+ *
28
+ * TWO defs, ONE code path. `createDelegatedGateway` builds both; the factories differ only in the
29
+ * name/title/description they present and in whether the request carries `requireReadOnly: true`.
30
+ * The read-only companion exists because MCP annotations are static per tool declaration — a
31
+ * surface that promises "this only reads" can only be a second declaration, never a per-call mode —
32
+ * and it ENFORCES that promise daemon-side rather than asserting it, because a `readOnlyHint: true`
33
+ * tool that could still reach writes would launder a write past its caller's own safety gate. See
34
+ * {@link createExecuteReadonlyDelegatedToolTool} for the failure that motivated it.
26
35
  */
27
36
  import { randomUUID } from 'node:crypto';
28
37
  import { postDaemonJson } from '../daemon-client.js';
29
- import { requireString } from '../tool-protocol.js';
38
+ import { daemonCallOptions, requireString } from '../tool-protocol.js';
39
+ function isRecord(value) {
40
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
41
+ }
30
42
  /**
31
- * Builds the `execute_delegated_tool` tool def for one specific `runId`. A fresh MCP server
32
- * process (one per spawned `claude` run, see `../../bin/serve.js`) calls this once at startup;
33
- * every `tools/call` for the returned def's `name` during that process's lifetime executes
34
- * against the same run.
43
+ * Unwraps a completed delegated call's `{executionId, status, output, ...}` envelope down to just
44
+ * `output` when and only when — `output` is itself an MCP content envelope (`{content: [...]}`).
45
+ * Every other shape (a non-completed status, a plain JSON `output` like a string or a list, no
46
+ * `output` at all) is returned byte-identical to `result` — this is an additive unwrap, not a new
47
+ * general response shape, so the existing "surfaces the result envelope unchanged" contract for an
48
+ * ordinary tool call is untouched.
49
+ *
50
+ * Why unwrap at all: `../tool-protocol.js`'s `okResult()` only recognizes an already-well-formed
51
+ * content envelope AT THE TOP LEVEL of what a handler returns. Left wrapped inside
52
+ * `{executionId, status, output}`, a genuine `image` block in `output.content` (kept there by
53
+ * `@jini-ai/daemon`'s `delegated-tool-bridge.ts`, which treats `image` as model-safe — see that
54
+ * package's `tool-result-surfaces.ts`) would still get JSON.stringified into inert text by
55
+ * `okResult()`'s fallback path, because the wrapper object itself has no top-level `content` field
56
+ * for it to recognize. Unwrapping here is what lets `okResult()`'s whitelist actually reach the
57
+ * block the bridge already preserved.
35
58
  */
36
- export function createExecuteDelegatedToolTool(options) {
59
+ function unwrapMcpContentEnvelope(result) {
60
+ if (!isRecord(result) || result['status'] !== 'completed')
61
+ return result;
62
+ const output = result['output'];
63
+ if (!isRecord(output) || !Array.isArray(output['content']))
64
+ return result;
65
+ return output;
66
+ }
67
+ /**
68
+ * Request deadline for one delegated tool call, overriding `daemon-client.ts`'s 15 s default.
69
+ *
70
+ * That default is sized for "a slow tool call" — a tool doing work. It is the wrong shape for this
71
+ * route, which is the one path in the system where a registered handler may legitimately be waiting
72
+ * on a *person*: a tool that raises an MCP-UI surface parks until the human answers it, and a human
73
+ * reading a dialog does not answer in fifteen seconds. Left at the default, every human-in-the-loop
74
+ * tool call fails at 15 s regardless of what the human eventually clicks.
75
+ *
76
+ * Six minutes is a *backstop*, not a budget. It assumes the host runs a tighter total-lifetime
77
+ * ceiling on the exchange itself, which ends the call with an explicit "no answer" outcome first;
78
+ * the extra headroom here just guarantees the exchange is always what gives up. Six minutes also
79
+ * stays inside every measured agent-CLI ceiling (Claude Code 30 min idle, Gemini CLI 10 min),
80
+ * which is what keeps this hop from becoming the binding constraint.
81
+ *
82
+ * A host whose exchange ceiling differs should override it via `delegatedToolTimeoutMs` rather
83
+ * than have its number encoded here — the engine has no way to know a given host's exchange
84
+ * policy, and hard-coding one host's value in generic engine source is what this default replaced.
85
+ *
86
+ * This is also, transitively, the hard cap on a multi-turn human conversation driven from one tool
87
+ * call: however many turns an exchange takes, they all happen inside this one request. Raising that
88
+ * ceiling starts here, not in the exchange store.
89
+ *
90
+ * The cost is real and accepted: a genuinely hung daemon now hangs this call for six minutes rather
91
+ * than fifteen seconds. The daemon-side alternative does not exist to lean on — `ToolDescriptor.timeoutMs`
92
+ * is unset on every registration today, so `ToolExecutor` arms no timer of its own.
93
+ */
94
+ export const DEFAULT_DELEGATED_TOOL_TIMEOUT_MS = 6 * 60 * 1000;
95
+ /**
96
+ * Builds one gateway def. Both exported factories call this; there is no second copy of the
97
+ * request body, the timeout rule, or the unwrap.
98
+ *
99
+ * @param variant - The presentation/constraint half (see {@link DelegatedGatewayVariant}).
100
+ * @param options - The per-process run scope and its optional overrides.
101
+ * @returns The `McpToolDef` to host.
102
+ * @complexity O(1) at construction; each call is one HTTP round trip.
103
+ */
104
+ function createDelegatedGateway(variant, options) {
37
105
  const { runId } = options;
38
106
  const generateToolUseId = options.generateToolUseId ?? randomUUID;
107
+ const requested = options.delegatedToolTimeoutMs;
108
+ const timeoutMs = typeof requested === 'number' && Number.isFinite(requested) && requested > 0
109
+ ? requested
110
+ : DEFAULT_DELEGATED_TOOL_TIMEOUT_MS;
39
111
  return {
40
- name: 'execute_delegated_tool',
41
- description: 'Execute a Jini-registered tool (never an agent-vendor-specific tool name) against the current run, routed through the daemon\'s ToolExecutor deny-by-default gate — the same authorization/confirmation/audit path every other tool-execution mechanism in this host uses. Returns {result}, a ToolExecutionResult: {status, output?, truncated?, error?} where status is one of completed|denied|confirmation-denied|timed-out|cancelled|failed.',
112
+ name: variant.name,
113
+ description: variant.description,
42
114
  inputSchema: {
43
115
  type: 'object',
44
116
  properties: {
@@ -66,11 +138,11 @@ export function createExecuteDelegatedToolTool(options) {
66
138
  additionalProperties: false,
67
139
  },
68
140
  annotations: {
69
- readOnlyHint: false,
70
- idempotentHint: false,
141
+ readOnlyHint: variant.readOnlyHint,
142
+ idempotentHint: variant.idempotentHint,
71
143
  destructiveHint: false,
72
144
  openWorldHint: false,
73
- title: 'Execute a Jini-registered tool',
145
+ title: variant.title,
74
146
  },
75
147
  handler: async (args, ctx) => {
76
148
  requireString(args.toolId, 'toolId');
@@ -79,12 +151,74 @@ export function createExecuteDelegatedToolTool(options) {
79
151
  toolUseId: generateToolUseId(),
80
152
  toolId: args.toolId,
81
153
  input: args.input,
154
+ ...(variant.requireReadOnly === undefined ? {} : { requireReadOnly: variant.requireReadOnly }),
82
155
  };
83
156
  const data = await postDaemonJson(ctx.baseUrl, '/api/delegated-tool-calls', body, {
84
- fetchImpl: ctx.fetchImpl,
157
+ ...daemonCallOptions(ctx),
158
+ timeoutMs,
85
159
  });
86
- return data.result;
160
+ return unwrapMcpContentEnvelope(data.result);
87
161
  },
88
162
  };
89
163
  }
164
+ /**
165
+ * Builds the `execute_delegated_tool` tool def for one specific `runId`. A fresh MCP server
166
+ * process (one per spawned `claude` run, see `../../bin/serve.js`) calls this once at startup;
167
+ * every `tools/call` for the returned def's `name` during that process's lifetime executes
168
+ * against the same run.
169
+ *
170
+ * Declares `readOnlyHint: false`, which is the truth about a gateway that reaches the entire
171
+ * registry — reads and writes alike. See {@link createExecuteReadonlyDelegatedToolTool} for what
172
+ * that costs under a host that gates on the annotation, and for the companion that answers it.
173
+ */
174
+ export function createExecuteDelegatedToolTool(options) {
175
+ return createDelegatedGateway({
176
+ name: 'execute_delegated_tool',
177
+ title: 'Execute a Jini-registered tool',
178
+ description: 'Execute a Jini-registered tool (never an agent-vendor-specific tool name) against the current run, routed through the daemon\'s ToolExecutor deny-by-default gate — the same authorization/confirmation/audit path every other tool-execution mechanism in this host uses. On a completed outcome, returns {result} normally. Any other outcome surfaces as an HTTP error the caller must catch, not a status field in a 200 body: denied/confirmation-denied raise a 403 TOOL_OPERATION_DENIED; timed-out/cancelled/failed raise a 500 INTERNAL_ERROR.',
179
+ readOnlyHint: false,
180
+ idempotentHint: false,
181
+ }, options);
182
+ }
183
+ /**
184
+ * Builds the `execute_readonly_delegated_tool` companion for one specific `runId` — the same
185
+ * gateway, narrowed to tools whose registration declares them read-only, and annotated
186
+ * `readOnlyHint: true`.
187
+ *
188
+ * WHY IT EXISTS. `execute_delegated_tool` is the sole route from an externally-injected MCP client
189
+ * into this host's entire native tool catalog, and it correctly annotates itself
190
+ * `readOnlyHint: false`. A runtime that auto-denies any MCP tool lacking `readOnlyHint: true`
191
+ * (headless `codex exec`, observed) therefore kills 100% of delegated calls — reads included —
192
+ * before they leave the client process. Nothing reaches the daemon, so no execution row is written
193
+ * and no error surfaces; the model, given no grounding signal at all, narrates a tool call that
194
+ * never happened. Meanwhile `search_tools`/`describe_tool` work, so discovery succeeds and only
195
+ * execution silently dies, which is the worst possible shape for the failure.
196
+ *
197
+ * WHY IT ENFORCES RATHER THAN ASSERTS. MCP annotations are static per tool declaration — the
198
+ * protocol has no way to vary one per call — so a read-only surface can only be a SECOND
199
+ * declaration, never a mode of the first. And a tool that declared `readOnlyHint: true` while
200
+ * still reaching writes would be worse than the bug it fixes: it would launder a write past a
201
+ * caller's own safety gate, and that caller has no way to audit the claim. The check is therefore
202
+ * made where it can be a fact rather than a claim — the daemon, via
203
+ * `@jini-ai/http-kit`'s `requireReadOnly`, resolving the id against the live `ToolRegistry` and
204
+ * `@jini-ai/core`'s `isReadOnlyTool`. Refusal is deny-by-default: an id that is unregistered, or
205
+ * registered without a read-only classification, is refused with a message naming the tool and
206
+ * pointing at `execute_delegated_tool`.
207
+ *
208
+ * Flipping the existing tool's annotation instead was rejected for the same reason: it would lie to
209
+ * every caller, including the ones the annotation exists to protect.
210
+ */
211
+ export function createExecuteReadonlyDelegatedToolTool(options) {
212
+ return createDelegatedGateway({
213
+ name: 'execute_readonly_delegated_tool',
214
+ title: 'Execute a read-only Jini-registered tool',
215
+ description: 'Execute a READ-ONLY Jini-registered tool (never an agent-vendor-specific tool name) against the current run. Identical to execute_delegated_tool — same ToolExecutor deny-by-default authorization/confirmation/audit path, same {result} envelope, same errors — except that the daemon first checks the requested toolId against the live registry and refuses anything not registered as read-only, with a 403 TOOL_OPERATION_DENIED naming the tool. Use this for any tool that only reads. For a tool that creates, updates, deletes, publishes, or mints anything, call execute_delegated_tool instead; this one will refuse it.',
216
+ readOnlyHint: true,
217
+ // A read-only call has no state to advance, so repeating it is the same call. Matches
218
+ // `tool-catalog-tools.ts`'s and `run-tools.ts`'s own read annotations rather than inventing a
219
+ // third convention for the same claim.
220
+ idempotentHint: true,
221
+ requireReadOnly: true,
222
+ }, options);
223
+ }
90
224
  //# sourceMappingURL=delegated-tool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delegated-tool.js","sourceRoot":"","sources":["../../../src/server/tools/delegated-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAcrE;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAAC,OAA8C;IAC3F,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC1B,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,UAAU,CAAC;IAElE,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EACT,mbAAmb;QACrb,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,4CAA4C;iBAC1D;gBACD,KAAK,EAAE;oBACL,qFAAqF;oBACrF,kFAAkF;oBAClF,oFAAoF;oBACpF,kFAAkF;oBAClF,uFAAuF;oBACvF,8EAA8E;oBAC9E,EAAE;oBACF,mFAAmF;oBACnF,sFAAsF;oBACtF,gFAAgF;oBAChF,IAAI,EAAE,QAAQ;oBACd,oBAAoB,EAAE,IAAI;oBAC1B,WAAW,EAAE,wIAAwI;iBACtJ;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;YACpB,oBAAoB,EAAE,KAAK;SAC5B;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;YACtB,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,gCAAgC;SACxC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrC,MAAM,IAAI,GAA4B;gBACpC,KAAK;gBACL,SAAS,EAAE,iBAAiB,EAAE;gBAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,cAAc,CAA+B,GAAG,CAAC,OAAO,EAAE,2BAA2B,EAAE,IAAI,EAAE;gBAC9G,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"delegated-tool.js","sourceRoot":"","sources":["../../../src/server/tools/delegated-tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAmBrE,uFAAuF;AACvF,eAAO,MAAM,YAAY,EAAE,UAiC1B,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,UAAU,EAAE,UAgBxB,CAAC;AAEF,uGAAuG;AACvG,eAAO,MAAM,aAAa,EAAE,UAoB3B,CAAC;AAOF,4GAA4G;AAC5G,eAAO,MAAM,oBAAoB,EAAE,UAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,cAAc,EAAE,UAM5B,CAAC;AAEF,wHAAwH;AACxH,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAM1C,CAAC"}
1
+ {"version":3,"file":"run-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAmBxF,uFAAuF;AACvF,eAAO,MAAM,YAAY,EAAE,UAiC1B,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,UAAU,EAAE,UAgBxB,CAAC;AAEF,uGAAuG;AACvG,eAAO,MAAM,aAAa,EAAE,UAoB3B,CAAC;AAOF,4GAA4G;AAC5G,eAAO,MAAM,oBAAoB,EAAE,UAgBlC,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,cAAc,EAAE,UAM5B,CAAC;AAEF,wHAAwH;AACxH,eAAO,MAAM,SAAS,EAAE,SAAS,UAAU,EAM1C,CAAC"}
@@ -2,19 +2,19 @@
2
2
  * @module @jini-ai/mcp/server/tools/run-tools
3
3
  *
4
4
  * The first real, concrete `McpToolDef`s hosted by `createMcpToolServer`
5
- * (`../tool-server.js`) — a proxy over `@jini-ai/http`'s already-gated `Run`
5
+ * (`../tool-server.js`) — a proxy over `@jini-ai/http-kit`'s already-gated `Run`
6
6
  * transport (`packages/http/src/runs.ts`) plus the generic active-resource
7
7
  * channel (`packages/http/src/active-context.ts`) and the agent-def listing
8
8
  * (`packages/http/src/agents.ts`). Each tool's `handler` does nothing but
9
9
  * validate its own arguments and proxy a single HTTP call via
10
10
  * `../daemon-client.js` — no separate authorization mechanism, no caching,
11
- * no state: whatever `@jini-ai/http`'s same-origin guard / bearer-auth
11
+ * no state: whatever `@jini-ai/http-kit`'s same-origin guard / bearer-auth
12
12
  * middleware already enforces on the target route is the only gate a call
13
13
  * here passes through (see `source-map.md`'s 2026-07-21 addition for the
14
14
  * full origin-mapping and what was deliberately not ported).
15
15
  */
16
16
  import { getDaemonJson, postDaemonJson } from '../daemon-client.js';
17
- import { requireString } from '../tool-protocol.js';
17
+ import { daemonCallOptions, requireString } from '../tool-protocol.js';
18
18
  const READ_ANNOTATIONS = {
19
19
  readOnlyHint: true,
20
20
  idempotentHint: true,
@@ -62,7 +62,7 @@ export const startRunTool = {
62
62
  const idempotencyKey = optionalNonEmptyString(args.idempotencyKey);
63
63
  if (idempotencyKey !== undefined)
64
64
  body.idempotencyKey = idempotencyKey;
65
- return postDaemonJson(ctx.baseUrl, '/api/runs', body, { fetchImpl: ctx.fetchImpl });
65
+ return postDaemonJson(ctx.baseUrl, '/api/runs', body, daemonCallOptions(ctx));
66
66
  },
67
67
  };
68
68
  /** `get_run` -> `GET /api/runs/:runId` (`packages/http/src/runs.ts`'s `runStatusRoute`). */
@@ -80,7 +80,7 @@ export const getRunTool = {
80
80
  annotations: { ...READ_ANNOTATIONS, title: 'Check a run' },
81
81
  handler: async (args, ctx) => {
82
82
  requireString(args.runId, 'runId');
83
- return getDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}`, { fetchImpl: ctx.fetchImpl });
83
+ return getDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}`, daemonCallOptions(ctx));
84
84
  },
85
85
  };
86
86
  /** `cancel_run` -> `POST /api/runs/:runId/cancel` (`packages/http/src/runs.ts`'s `runCancelRoute`). */
@@ -103,7 +103,7 @@ export const cancelRunTool = {
103
103
  const reason = optionalNonEmptyString(args.reason);
104
104
  if (reason !== undefined)
105
105
  body.reason = reason;
106
- return postDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}/cancel`, body, { fetchImpl: ctx.fetchImpl });
106
+ return postDaemonJson(ctx.baseUrl, `/api/runs/${encodeURIComponent(args.runId)}/cancel`, body, daemonCallOptions(ctx));
107
107
  },
108
108
  };
109
109
  /** `get_active_context` -> `GET /api/active` (`packages/http/src/active-context.ts`'s `getActiveRoute`). */
@@ -113,7 +113,7 @@ export const getActiveContextTool = {
113
113
  inputSchema: { type: 'object', properties: {}, additionalProperties: false },
114
114
  annotations: { ...READ_ANNOTATIONS, title: 'What is the caller focused on?' },
115
115
  handler: async (_args, ctx) => {
116
- const data = await getDaemonJson(ctx.baseUrl, '/api/active', { fetchImpl: ctx.fetchImpl });
116
+ const data = await getDaemonJson(ctx.baseUrl, '/api/active', daemonCallOptions(ctx));
117
117
  if (data.active !== true) {
118
118
  return {
119
119
  active: false,
@@ -129,7 +129,7 @@ export const listAgentsTool = {
129
129
  description: 'List every agent def registered with this host\'s @jini-ai/agent-runtime — {id, name} pairs suitable for start_run\'s optional agentId argument. Static registration data only: this does not probe which agent binaries are actually installed on the host machine.',
130
130
  inputSchema: { type: 'object', properties: {}, additionalProperties: false },
131
131
  annotations: { ...READ_ANNOTATIONS, title: 'List registered agents' },
132
- handler: async (_args, ctx) => getDaemonJson(ctx.baseUrl, '/api/agents', { fetchImpl: ctx.fetchImpl }),
132
+ handler: async (_args, ctx) => getDaemonJson(ctx.baseUrl, '/api/agents', daemonCallOptions(ctx)),
133
133
  };
134
134
  /** The full set of kernel-run tool defs this package ships, ready to pass as `createMcpToolServer`'s `tools` option. */
135
135
  export const RUN_TOOLS = [
@@ -1 +1 @@
1
- {"version":3,"file":"run-tools.js","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-tools.js","sourceRoot":"","sources":["../../../src/server/tools/run-tools.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-catalog-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAcA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiBrE,kHAAkH;AAClH,eAAO,MAAM,eAAe,EAAE,UAuB7B,CAAC;AAEF,kHAAkH;AAClH,eAAO,MAAM,gBAAgB,EAAE,UAiB9B,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,EAAE,SAAS,UAAU,EAAwC,CAAC"}
1
+ {"version":3,"file":"tool-catalog-tools.d.ts","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAcA,OAAO,EAAoC,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiBxF,kHAAkH;AAClH,eAAO,MAAM,eAAe,EAAE,UA2D7B,CAAC;AAEF,kHAAkH;AAClH,eAAO,MAAM,gBAAgB,EAAE,UAiB9B,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,kBAAkB,EAAE,SAAS,UAAU,EAAwC,CAAC"}
@@ -2,7 +2,7 @@
2
2
  * @module @jini-ai/mcp/server/tools/tool-catalog-tools
3
3
  *
4
4
  * `search_tools` / `describe_tool` — the discovery half of `ai-control-plane.md` §29 /
5
- * `PROP-tool-catalog-discovery-2026-07-26.md` §6.1, proxying `@jini-ai/http`'s
5
+ * `PROP-tool-catalog-discovery-2026-07-26.md` §6.1, proxying `@jini-ai/http-kit`'s
6
6
  * `GET /api/tools/search` / `GET /api/tools/:id` exactly as `run-tools.ts`'s tools proxy
7
7
  * `runs.ts` — no separate authorization mechanism, no caching, no state.
8
8
  *
@@ -12,7 +12,7 @@
12
12
  * Finding a tool id here grants nothing (`PROP` §6.3).
13
13
  */
14
14
  import { getDaemonJson } from '../daemon-client.js';
15
- import { requireString } from '../tool-protocol.js';
15
+ import { daemonCallOptions, requireString } from '../tool-protocol.js';
16
16
  const READ_ANNOTATIONS = {
17
17
  readOnlyHint: true,
18
18
  idempotentHint: true,
@@ -21,12 +21,48 @@ const READ_ANNOTATIONS = {
21
21
  /** `search_tools` -> `GET /api/tools/search` (`packages/http/src/tool-catalog.ts`'s `toolCatalogSearchRoute`). */
22
22
  export const searchToolsTool = {
23
23
  name: 'search_tools',
24
- description: 'Search the durable tool catalog by keyword. Returns ranked {id, description, source, score} candidates only — no input schemas, so this stays cheap to call broadly. Call describe_tool on the 1-3 candidates that look right before calling execute_delegated_tool.',
24
+ description: 'Search the durable tool catalog. Returns ranked {id, description, source, score} candidates only — no input schemas, so this stays cheap to call broadly. Call describe_tool on the 1-3 candidates that look right before calling execute_delegated_tool. If nothing in the results fits, re-search with a higher limit or different phrasing rather than assuming the tool does not exist.',
25
25
  inputSchema: {
26
26
  type: 'object',
27
27
  properties: {
28
- query: { type: 'string', description: 'Keywords to search for, e.g. "navigate page" or "fill form". Required.' },
29
- limit: { type: 'number', description: 'Max hits to return (1-25). Optional, defaults to 10.' },
28
+ // Descriptive phrasing, NOT keywords and the example matters as much as the instruction.
29
+ // The catalog is matched on tool *descriptions* (BM25 over description text), so a query
30
+ // written in the register of a description retrieves far better than a keyword bag. Measured
31
+ // on an independent n=130 blind set: terse keywords 25% top-1, descriptive phrasing 72%.
32
+ // This field previously read 'Keywords to search for, e.g. "navigate page" or "fill form"',
33
+ // which is the 25% form. It also directly contradicted the descriptive guidance a host server
34
+ // may inject upstream (a host's agent-daemon systemOverlay said the opposite), so a caller was
35
+ // given two conflicting instructions — with this one sitting on the parameter itself, read at
36
+ // the moment the query is composed.
37
+ //
38
+ // NOT measured: which instruction won. The hypothesis was that a two-word example outranks
39
+ // prose guidance, but the conflict was removed before anyone measured it, so treat that as
40
+ // untested rather than established. What IS measured, on the coherent state after this fix:
41
+ // 35/35 real search_tools calls across 24 live CLI sessions used descriptive phrasing.
42
+ // Keep the example long-form; shortening it re-creates the 25% form.
43
+ query: {
44
+ type: 'string',
45
+ description: 'Describe what the tool you need DOES, the way its own documentation would describe it — a full phrase, not a keyword bag. Name the thing being acted on and the action, and include likely synonyms for both. Example: for a request like "how many people visited last week", write "retrieve site traffic and visitor analytics counts for a date range" rather than "visitors last week". Descriptive phrasing retrieves substantially better than terse keywords, because the catalog is matched on tool descriptions. Required.',
46
+ },
47
+ // Bounds mirror `packages/http-kit/src/tool-catalog.ts`'s `parseSearchInput`
48
+ // exactly (`MAX_SEARCH_LIMIT = 25`, `DEFAULT_SEARCH_LIMIT = 10`, integers only,
49
+ // `>= 1`). Declared rather than left as a bare `number` so MCP validation and the
50
+ // route agree: otherwise `0`/`1.5` pass here and are refused downstream, and `26`
51
+ // passes here and is silently clamped — the caller is told one contract and given
52
+ // another.
53
+ // The escalation clause is the cheap half of a measured ceiling. On the same n=130 blind set,
54
+ // with the host's operator-vocabulary + doc2query index folded in, the right tool is in the
55
+ // default top 10 for 98% of cases and in the top 20 for 100% — so the residual misses are
56
+ // ranked just below the cutoff, never absent. Raising the DEFAULT to 20 would buy those 2
57
+ // cases at ~900 extra tokens on every single call; telling the caller to escalate on demand
58
+ // buys the same ceiling only when it is needed. Same lever as the descriptive-phrasing fix
59
+ // above: a prompt change, not an LLM call.
60
+ limit: {
61
+ type: 'integer',
62
+ minimum: 1,
63
+ maximum: 25,
64
+ description: 'Max hits to return (1-25). Optional, defaults to 10. If none of the returned candidates fit what you need, search again with a HIGHER limit (try 25) before concluding no tool exists — the right tool is in the top 10 about 98% of the time and in the top 20 100% of the time, so a near-miss is ranked just below the default cutoff rather than missing.',
65
+ },
30
66
  },
31
67
  required: ['query'],
32
68
  additionalProperties: false,
@@ -37,9 +73,7 @@ export const searchToolsTool = {
37
73
  const params = new URLSearchParams({ q: args.query });
38
74
  if (typeof args.limit === 'number')
39
75
  params.set('limit', String(args.limit));
40
- const data = await getDaemonJson(ctx.baseUrl, `/api/tools/search?${params.toString()}`, {
41
- fetchImpl: ctx.fetchImpl,
42
- });
76
+ const data = await getDaemonJson(ctx.baseUrl, `/api/tools/search?${params.toString()}`, daemonCallOptions(ctx));
43
77
  return data.hits;
44
78
  },
45
79
  };
@@ -58,7 +92,7 @@ export const describeToolTool = {
58
92
  annotations: { ...READ_ANNOTATIONS, title: 'Describe a tool' },
59
93
  handler: async (args, ctx) => {
60
94
  requireString(args.id, 'id');
61
- return getDaemonJson(ctx.baseUrl, `/api/tools/${encodeURIComponent(args.id)}`, { fetchImpl: ctx.fetchImpl });
95
+ return getDaemonJson(ctx.baseUrl, `/api/tools/${encodeURIComponent(args.id)}`, daemonCallOptions(ctx));
62
96
  },
63
97
  };
64
98
  /** Both tool-catalog discovery tools, ready to pass as `createMcpToolServer`'s `tools` option. */
@@ -1 +1 @@
1
- {"version":3,"file":"tool-catalog-tools.js","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAErE,MAAM,gBAAgB,GAAG;IACvB,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;CACZ,CAAC;AAWX,kHAAkH;AAClH,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,sQAAsQ;IACxQ,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wEAAwE,EAAE;YAChH,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sDAAsD,EAAE;SAC/F;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,aAAa,CAA4B,GAAG,CAAC,OAAO,EAAE,qBAAqB,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE;YACjH,SAAS,EAAE,GAAG,CAAC,SAAS;SACzB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF,CAAC;AAEF,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,sMAAsM;IACxM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;SACnF;QACD,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC9D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/G,CAAC;CACF,CAAC;AAEF,kGAAkG;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAA0B,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"tool-catalog-tools.js","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;AAExF,MAAM,gBAAgB,GAAG;IACvB,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,KAAK;CACZ,CAAC;AAWX,kHAAkH;AAClH,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,IAAI,EAAE,cAAc;IACpB,WAAW,EACT,6XAA6X;IAC/X,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,2FAA2F;YAC3F,yFAAyF;YACzF,6FAA6F;YAC7F,yFAAyF;YACzF,4FAA4F;YAC5F,8FAA8F;YAC9F,+FAA+F;YAC/F,8FAA8F;YAC9F,oCAAoC;YACpC,EAAE;YACF,2FAA2F;YAC3F,2FAA2F;YAC3F,4FAA4F;YAC5F,uFAAuF;YACvF,qEAAqE;YACrE,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,sgBAAsgB;aACzgB;YACD,6EAA6E;YAC7E,gFAAgF;YAChF,kFAAkF;YAClF,kFAAkF;YAClF,kFAAkF;YAClF,WAAW;YACX,8FAA8F;YAC9F,4FAA4F;YAC5F,0FAA0F;YAC1F,0FAA0F;YAC1F,4FAA4F;YAC5F,2FAA2F;YAC3F,2CAA2C;YAC3C,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,EAAE;gBACX,WAAW,EACT,+VAA+V;aAClW;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,yBAAyB,EAAE;IACtE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,MAAM,aAAa,CAA4B,GAAG,CAAC,OAAO,EAAE,qBAAqB,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3I,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF,CAAC;AAEF,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,eAAe;IACrB,WAAW,EACT,sMAAsM;IACxM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;SACnF;QACD,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,oBAAoB,EAAE,KAAK;KAC5B;IACD,WAAW,EAAE,EAAE,GAAG,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC9D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC3B,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACzG,CAAC;CACF,CAAC;AAEF,kGAAkG;AAClG,MAAM,CAAC,MAAM,kBAAkB,GAA0B,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@jini-ai/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.3.1",
4
+ "description": "Model Context Protocol adapters: server config schema and IO, an MCP client, and agent-side MCP server installation.",
4
5
  "license": "Apache-2.0",
5
6
  "repository": {
6
7
  "type": "git",
@@ -10,10 +11,10 @@
10
11
  "jini": {
11
12
  "domain": "integration",
12
13
  "kind": "protocol-adapter",
13
- "runtime": "node",
14
- "admission": "incubating"
14
+ "runtime": "node"
15
15
  },
16
16
  "type": "module",
17
+ "sideEffects": false,
17
18
  "main": "./dist/index.js",
18
19
  "types": "./dist/index.d.ts",
19
20
  "exports": {
@@ -21,6 +22,9 @@
21
22
  "types": "./dist/index.d.ts",
22
23
  "import": "./dist/index.js",
23
24
  "default": "./dist/index.js"
25
+ },
26
+ "./bin": {
27
+ "default": "./dist/bin/serve.js"
24
28
  }
25
29
  },
26
30
  "bin": {
@@ -39,10 +43,11 @@
39
43
  "registry": "https://registry.npmjs.org"
40
44
  },
41
45
  "dependencies": {
46
+ "@cfworker/json-schema": "^4.1.1",
42
47
  "@modelcontextprotocol/sdk": "^1.29.0",
43
48
  "undici": "^7.25.0",
44
- "@jini-ai/cli": "0.1.2",
45
- "@jini-ai/platform": "0.1.2"
49
+ "@jini-ai/cli": "0.3.0",
50
+ "@jini-ai/platform": "0.3.0"
46
51
  },
47
52
  "scripts": {
48
53
  "build": "tsc -p tsconfig.json && chmod +x dist/bin/serve.js",