@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.
- package/README.md +124 -0
- package/dist/bin/serve.d.ts +25 -0
- package/dist/bin/serve.d.ts.map +1 -1
- package/dist/bin/serve.js +51 -5
- package/dist/bin/serve.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +5 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +5 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/resources/active-resource.d.ts.map +1 -1
- package/dist/server/resources/active-resource.js +3 -2
- package/dist/server/resources/active-resource.js.map +1 -1
- package/dist/server/tool-protocol.d.ts +48 -9
- package/dist/server/tool-protocol.d.ts.map +1 -1
- package/dist/server/tool-protocol.js +142 -10
- package/dist/server/tool-protocol.js.map +1 -1
- package/dist/server/tool-server.d.ts +6 -0
- package/dist/server/tool-server.d.ts.map +1 -1
- package/dist/server/tool-server.js +1 -0
- package/dist/server/tool-server.js.map +1 -1
- package/dist/server/tools/component-catalog-tools.d.ts +8 -0
- package/dist/server/tools/component-catalog-tools.d.ts.map +1 -0
- package/dist/server/tools/component-catalog-tools.js +71 -0
- package/dist/server/tools/component-catalog-tools.js.map +1 -0
- package/dist/server/tools/delegated-tool.d.ts +72 -0
- package/dist/server/tools/delegated-tool.d.ts.map +1 -1
- package/dist/server/tools/delegated-tool.js +148 -14
- package/dist/server/tools/delegated-tool.js.map +1 -1
- package/dist/server/tools/run-tools.d.ts.map +1 -1
- package/dist/server/tools/run-tools.js +8 -8
- package/dist/server/tools/run-tools.js.map +1 -1
- package/dist/server/tools/tool-catalog-tools.d.ts.map +1 -1
- package/dist/server/tools/tool-catalog-tools.js +43 -9
- package/dist/server/tools/tool-catalog-tools.js.map +1 -1
- 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`
|
|
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
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
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
|
-
|
|
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:
|
|
41
|
-
description:
|
|
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:
|
|
70
|
-
idempotentHint:
|
|
141
|
+
readOnlyHint: variant.readOnlyHint,
|
|
142
|
+
idempotentHint: variant.idempotentHint,
|
|
71
143
|
destructiveHint: false,
|
|
72
144
|
openWorldHint: false,
|
|
73
|
-
title:
|
|
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
|
-
|
|
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
|
|
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,
|
|
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,
|
|
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)}`,
|
|
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,
|
|
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',
|
|
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',
|
|
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":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAmB,MAAM,qBAAqB,CAAC;
|
|
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,
|
|
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
|
|
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
|
-
|
|
29
|
-
|
|
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)}`,
|
|
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;
|
|
1
|
+
{"version":3,"file":"tool-catalog-tools.js","sourceRoot":"","sources":["../../../src/server/tools/tool-catalog-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/mcp",
|
|
3
|
-
"version": "0.1
|
|
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.
|
|
45
|
-
"@jini-ai/platform": "0.
|
|
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",
|