@aiwayds/dsh-mcp-adapter 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/README.zh.md +82 -0
- package/cordis.patch.yml +33 -0
- package/lib/index.d.ts +342 -0
- package/lib/index.js +623 -0
- package/lib/index.js.map +1 -0
- package/package.json +46 -0
- package/scripts/link-dsh-closure.mjs +91 -0
package/lib/index.js
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-mcp-adapter — prompt-side MCP folding shim for dsh.
|
|
3
|
+
*
|
|
4
|
+
* The official `@deepseek-ai/dsh-mcp-client` registers every discovered MCP
|
|
5
|
+
* tool natively (`mcp__<server>__<tool>`), so every assembled prompt carries
|
|
6
|
+
* the full JSON Schema of every MCP tool. This plugin keeps that client as
|
|
7
|
+
* the connection layer (transport, reconnect, `list_changed` re-sync — all
|
|
8
|
+
* upstream) and intervenes only at prompt assembly:
|
|
9
|
+
*
|
|
10
|
+
* - every prefix-matching tool schema is folded out of the assembled prompt
|
|
11
|
+
* (`system-prompt/assemble` waterfall), so standing prompt cost is O(1) in
|
|
12
|
+
* the number of servers and tools, and the tool list stays KV-prefix
|
|
13
|
+
* stable across server re-syncs. The prefix is a naming convention, not a
|
|
14
|
+
* trust boundary — third-party tools that happen to use it fold too; set
|
|
15
|
+
* `servers` to restrict folding (and cataloging/dispatch) to named servers;
|
|
16
|
+
* - two constant meta-tools replace them:
|
|
17
|
+
* - `mcp_list` — compact catalog grouped by server; `tool` expands one
|
|
18
|
+
* full schema on demand, `server` filters, `verbose` inlines everything;
|
|
19
|
+
* - `mcp_call` — dispatches `{ tool, arguments }` to the still-registered
|
|
20
|
+
* definition, forwarding the run context.
|
|
21
|
+
*
|
|
22
|
+
* Tools stay registered in `ctx.tools`, so TUI rendering and
|
|
23
|
+
* `tools.restrict()` masking keep working — only the prompt payload changes.
|
|
24
|
+
* Pipeline nuance: pre-execute/guard/post-execute stages that match by the
|
|
25
|
+
* child tool's name never fire for folded calls (the registry only sees the
|
|
26
|
+
* outer `mcp_call`) — gate MCP usage by guarding `mcp_call` itself.
|
|
27
|
+
*
|
|
28
|
+
* Child-owned projections are preserved: `mcp_call` delegates its
|
|
29
|
+
* `output.render` to the dispatched child and forwards the child's
|
|
30
|
+
* `finalizeContent` with the exact same run-execution object, so
|
|
31
|
+
* image-bearing MCP results still project to durable attachment references
|
|
32
|
+
* instead of inlining base64 into the context.
|
|
33
|
+
*
|
|
34
|
+
* Fail-open: unless BOTH meta-tools resolve (in the assembling scope) to
|
|
35
|
+
* exactly this plugin's definitions, assemblies pass through untouched — a
|
|
36
|
+
* broken adapter must never make MCP tools undiscoverable. Under Code Mode
|
|
37
|
+
* the wire already collapses to `run_code`, so this plugin is a natural no-op.
|
|
38
|
+
*
|
|
39
|
+
* All decision logic is exported as pure functions; the only Cordis calls
|
|
40
|
+
* live in {@link apply}.
|
|
41
|
+
*
|
|
42
|
+
* @module @aiwayds/dsh-mcp-adapter
|
|
43
|
+
*/
|
|
44
|
+
import z from '@deepseek-ai/schemastery';
|
|
45
|
+
/** Cordis plugin name used by loader diagnostics. */
|
|
46
|
+
export const name = 'mcp-adapter';
|
|
47
|
+
/** Services required by this plugin. */
|
|
48
|
+
export const inject = ['tools'];
|
|
49
|
+
/** Registered name of the catalog meta-tool. */
|
|
50
|
+
export const MCP_LIST_TOOL_NAME = 'mcp_list';
|
|
51
|
+
/** Registered name of the dispatch meta-tool. */
|
|
52
|
+
export const MCP_CALL_TOOL_NAME = 'mcp_call';
|
|
53
|
+
/** Default catalog description truncation. */
|
|
54
|
+
const DEFAULT_DESCRIPTION_LIMIT = 200;
|
|
55
|
+
/** Default tool-name prefix to fold. */
|
|
56
|
+
const DEFAULT_PREFIX = 'mcp__';
|
|
57
|
+
/** Valid fold prefix: non-empty, tool-name characters only. */
|
|
58
|
+
const PREFIX_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
59
|
+
export const Config = z.object({
|
|
60
|
+
prefix: z.string().pattern(PREFIX_PATTERN).default(DEFAULT_PREFIX),
|
|
61
|
+
keep: z.array(String).default([]),
|
|
62
|
+
servers: z.array(String).default([]),
|
|
63
|
+
descriptionLimit: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER).default(DEFAULT_DESCRIPTION_LIMIT),
|
|
64
|
+
});
|
|
65
|
+
// ---- Keep-pattern matching (pure) ----
|
|
66
|
+
/** Compiled keep patterns, keyed by source pattern. */
|
|
67
|
+
const keepPatternCache = new Map();
|
|
68
|
+
/**
|
|
69
|
+
* Compile one keep pattern into an anchored RegExp: `*` matches any run,
|
|
70
|
+
* every other character is literal.
|
|
71
|
+
*/
|
|
72
|
+
function keepPattern(pattern) {
|
|
73
|
+
let compiled = keepPatternCache.get(pattern);
|
|
74
|
+
if (compiled === undefined) {
|
|
75
|
+
const source = pattern
|
|
76
|
+
.split('*')
|
|
77
|
+
.map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
78
|
+
.join('.*');
|
|
79
|
+
compiled = new RegExp(`^${source}$`);
|
|
80
|
+
keepPatternCache.set(pattern, compiled);
|
|
81
|
+
}
|
|
82
|
+
return compiled;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether a tool name matches any keep pattern ("*" wildcard, anchored;
|
|
86
|
+
* a pattern without wildcards is an exact name).
|
|
87
|
+
* @param name - the registered tool name.
|
|
88
|
+
* @param patterns - keep patterns from config.
|
|
89
|
+
* @returns whether the tool stays native in the prompt.
|
|
90
|
+
*/
|
|
91
|
+
export function matchesKeep(name, patterns) {
|
|
92
|
+
return patterns.some(pattern => keepPattern(pattern).test(name));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Whether the server segment of one prefix-matching tool name passes the
|
|
96
|
+
* optional servers whitelist. An empty list admits every server (the prefix
|
|
97
|
+
* is a naming convention, not a trust boundary); a non-empty list admits
|
|
98
|
+
* only the named servers.
|
|
99
|
+
* @param name - the registered tool name.
|
|
100
|
+
* @param prefix - the configured MCP prefix.
|
|
101
|
+
* @param servers - server-name whitelist from config.
|
|
102
|
+
* @returns whether the tool's server is admitted.
|
|
103
|
+
*/
|
|
104
|
+
export function isAllowedServer(name, prefix, servers) {
|
|
105
|
+
if (servers.length === 0)
|
|
106
|
+
return true;
|
|
107
|
+
return servers.includes(serverOfToolName(name, prefix));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Whether one tool's schema should be folded out of the prompt: it must
|
|
111
|
+
* carry the configured prefix, belong to a whitelisted server, not match the
|
|
112
|
+
* keep list — and it must never be one of this plugin's own meta-tools,
|
|
113
|
+
* whatever the prefix is configured to (folding them would make every folded
|
|
114
|
+
* MCP tool undiscoverable).
|
|
115
|
+
* @param name - the registered tool name.
|
|
116
|
+
* @param prefix - tool-name prefix to fold.
|
|
117
|
+
* @param keep - keep patterns from config.
|
|
118
|
+
* @param servers - server-name whitelist from config (default: no filtering).
|
|
119
|
+
* @returns whether the schema leaves the prompt (the tool stays callable).
|
|
120
|
+
*/
|
|
121
|
+
export function shouldFold(name, prefix, keep, servers = []) {
|
|
122
|
+
if (name === MCP_LIST_TOOL_NAME || name === MCP_CALL_TOOL_NAME)
|
|
123
|
+
return false;
|
|
124
|
+
return prefix !== '' && name.startsWith(prefix) && !matchesKeep(name, keep)
|
|
125
|
+
&& isAllowedServer(name, prefix, servers);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Rewrite one assembled prompt: drop the schemas of foldable tools, keep
|
|
129
|
+
* everything else (sections, contexts, variables, non-MCP tools, meta-tools)
|
|
130
|
+
* untouched.
|
|
131
|
+
*
|
|
132
|
+
* Fail-open contract: with `metaToolsLive` false the assembly object is
|
|
133
|
+
* returned AS-IS (same reference) — folding is only safe while the model can
|
|
134
|
+
* still discover MCP tools through the meta-tools.
|
|
135
|
+
*
|
|
136
|
+
* @param assembly - the post-waterfall assembly.
|
|
137
|
+
* @param options - folding knobs.
|
|
138
|
+
* @param metaToolsLive - whether both meta-tools currently resolve to this
|
|
139
|
+
* plugin's own definitions in the assembling scope.
|
|
140
|
+
* @returns the folded assembly, or the input unchanged when nothing folds.
|
|
141
|
+
*/
|
|
142
|
+
export function foldPromptAssembly(assembly, options, metaToolsLive) {
|
|
143
|
+
if (!metaToolsLive)
|
|
144
|
+
return assembly;
|
|
145
|
+
const servers = options.servers ?? [];
|
|
146
|
+
const tools = assembly.tools.filter(tool => !shouldFold(tool.name, options.prefix, options.keep, servers));
|
|
147
|
+
if (tools.length === assembly.tools.length)
|
|
148
|
+
return assembly;
|
|
149
|
+
return { ...assembly, tools };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Narrow arbitrary model arguments to the `mcp_list` shape, dropping
|
|
153
|
+
* unknown or mistyped keys instead of throwing (the model misbehaves).
|
|
154
|
+
* @param args - raw model arguments.
|
|
155
|
+
* @returns the normalized catalog query.
|
|
156
|
+
*/
|
|
157
|
+
export function normalizeMcpListArgs(args) {
|
|
158
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args))
|
|
159
|
+
return {};
|
|
160
|
+
const raw = args;
|
|
161
|
+
return {
|
|
162
|
+
...typeof raw.tool === 'string' ? { tool: raw.tool } : {},
|
|
163
|
+
...typeof raw.server === 'string' ? { server: raw.server } : {},
|
|
164
|
+
...raw.verbose === true ? { verbose: true } : {},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Derive the server segment of a registered MCP tool name: the first
|
|
169
|
+
* `__`-delimited segment after the prefix. Heuristic, not a parse: server
|
|
170
|
+
* names are constrained to `[A-Za-z0-9_-]{1,32}` by the official client, so
|
|
171
|
+
* a literal `__` inside a server name (impossible there) would mis-group.
|
|
172
|
+
* @param name - the registered tool name.
|
|
173
|
+
* @param prefix - the configured MCP prefix.
|
|
174
|
+
* @returns the server segment ('' for degenerate names).
|
|
175
|
+
*/
|
|
176
|
+
export function serverOfToolName(name, prefix) {
|
|
177
|
+
return name.slice(prefix.length).split('__')[0];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Truncate one description to the catalog limit, marking the cut with an
|
|
181
|
+
* ellipsis character (so one char of headroom is reserved). A cut that would
|
|
182
|
+
* land on the LOW half of a surrogate pair backs off one code unit so no
|
|
183
|
+
* orphaned high surrogate is emitted.
|
|
184
|
+
* @param text - the full tool description.
|
|
185
|
+
* @param limit - max chars in the catalog.
|
|
186
|
+
* @returns the truncated description.
|
|
187
|
+
*/
|
|
188
|
+
export function truncateDescription(text, limit) {
|
|
189
|
+
if (text.length <= limit)
|
|
190
|
+
return text;
|
|
191
|
+
let end = Math.max(0, limit - 1);
|
|
192
|
+
// slice(0, end) excludes text[end]: when that first excluded code unit is
|
|
193
|
+
// a low surrogate, the last included one is its now-orphaned high half.
|
|
194
|
+
const cut = text.charCodeAt(end);
|
|
195
|
+
if (cut >= 0xDC00 && cut <= 0xDFFF && end > 0)
|
|
196
|
+
end -= 1;
|
|
197
|
+
return `${text.slice(0, end)}…`;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Build the `mcp_list` result over the currently visible schemas.
|
|
201
|
+
*
|
|
202
|
+
* Priority: `tool` (full single-tool expansion) > catalog (optionally
|
|
203
|
+
* filtered by `server`, optionally `verbose`). Unknown or non-MCP `tool`,
|
|
204
|
+
* and any query that selects nothing, return a structured error — never a
|
|
205
|
+
* throw — so the model can correct itself.
|
|
206
|
+
*
|
|
207
|
+
* @param args - the normalized catalog query.
|
|
208
|
+
* @param schemas - schemas visible to the calling agent.
|
|
209
|
+
* @param options - catalog knobs.
|
|
210
|
+
* @returns the canonical result value.
|
|
211
|
+
*/
|
|
212
|
+
export function buildMcpListResult(args, schemas, options) {
|
|
213
|
+
const { prefix, descriptionLimit } = options;
|
|
214
|
+
const servers = options.servers ?? [];
|
|
215
|
+
if (args.tool !== undefined) {
|
|
216
|
+
// The meta-tools are visible schemas like any other and can match a
|
|
217
|
+
// pathological prefix (e.g. "mcp_") — never expand them; they are this
|
|
218
|
+
// adapter's own surface, not MCP tools.
|
|
219
|
+
if (args.tool === MCP_LIST_TOOL_NAME || args.tool === MCP_CALL_TOOL_NAME) {
|
|
220
|
+
return { error: `refusing to expand "${args.tool}": meta-tools are not expandable through ${MCP_LIST_TOOL_NAME}` };
|
|
221
|
+
}
|
|
222
|
+
if (!args.tool.startsWith(prefix)) {
|
|
223
|
+
return { error: `"${args.tool}" is not an MCP tool (expected the "${prefix}" prefix) — call ${MCP_LIST_TOOL_NAME} without arguments for the catalog` };
|
|
224
|
+
}
|
|
225
|
+
if (!isAllowedServer(args.tool, prefix, servers)) {
|
|
226
|
+
return { error: `"${args.tool}" belongs to server "${serverOfToolName(args.tool, prefix)}", which is not in the configured servers list` };
|
|
227
|
+
}
|
|
228
|
+
const schema = schemas.find(candidate => candidate.name === args.tool);
|
|
229
|
+
if (schema === undefined) {
|
|
230
|
+
return { error: `unknown MCP tool "${args.tool}" — the server may have re-synced; call ${MCP_LIST_TOOL_NAME} to refresh` };
|
|
231
|
+
}
|
|
232
|
+
// On-demand expansion: the FULL description and schema, not truncated.
|
|
233
|
+
return { tool: { name: schema.name, description: schema.description, parameters: schema.parameters } };
|
|
234
|
+
}
|
|
235
|
+
const serversOut = [];
|
|
236
|
+
for (const schema of schemas) {
|
|
237
|
+
// Never catalog the meta-tools themselves, even under a prefix that
|
|
238
|
+
// matches their names.
|
|
239
|
+
if (schema.name === MCP_LIST_TOOL_NAME || schema.name === MCP_CALL_TOOL_NAME)
|
|
240
|
+
continue;
|
|
241
|
+
if (!schema.name.startsWith(prefix))
|
|
242
|
+
continue;
|
|
243
|
+
if (!isAllowedServer(schema.name, prefix, servers))
|
|
244
|
+
continue;
|
|
245
|
+
const server = serverOfToolName(schema.name, prefix);
|
|
246
|
+
if (args.server !== undefined && server !== args.server)
|
|
247
|
+
continue;
|
|
248
|
+
let group = serversOut.find(entry => entry.server === server);
|
|
249
|
+
if (group === undefined) {
|
|
250
|
+
group = { server, tools: [] };
|
|
251
|
+
serversOut.push(group);
|
|
252
|
+
}
|
|
253
|
+
group.tools.push({
|
|
254
|
+
name: schema.name,
|
|
255
|
+
description: truncateDescription(schema.description, descriptionLimit),
|
|
256
|
+
...args.verbose === true ? { parameters: schema.parameters } : {},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
if (serversOut.length === 0) {
|
|
260
|
+
return args.server === undefined
|
|
261
|
+
? { error: `no MCP tools are registered under the "${prefix}" prefix` }
|
|
262
|
+
: { error: `no MCP tools match server "${args.server}"` };
|
|
263
|
+
}
|
|
264
|
+
return { servers: serversOut };
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Dispatch one `mcp_call` to the resolved child tool.
|
|
268
|
+
*
|
|
269
|
+
* Validation: `tool` must be a non-empty string matching the configured
|
|
270
|
+
* prefix, must not name a meta-tool, must belong to a whitelisted server
|
|
271
|
+
* (when `servers` is non-empty), and must resolve through `resolve`
|
|
272
|
+
* (scope-aware — a restricted-away tool does not resolve, so whitelists are
|
|
273
|
+
* respected naturally). Non-MCP tools are REFUSED outright: dispatching them
|
|
274
|
+
* here would bypass their own pre-execute pipeline (guards, approvals).
|
|
275
|
+
*
|
|
276
|
+
* Execution: `definition.execute(args.arguments ?? {}, exec)` with the
|
|
277
|
+
* meta-tool's own run context passed through verbatim — the official MCP
|
|
278
|
+
* executor consumes `exec.signal` (per-request abort) and `exec.agent`
|
|
279
|
+
* (model-route resolution for image admission), both carried by that same
|
|
280
|
+
* context object.
|
|
281
|
+
*
|
|
282
|
+
* Timeout: no timer is raced for the official mcp-client tools — their
|
|
283
|
+
* executor already self-times every MCP request (`tools/call` is sent with
|
|
284
|
+
* `timeout: toolCallTimeoutMs`, verified in the upstream bridge source), and
|
|
285
|
+
* they never declare `timeoutMs`. Only a definition that DECLARED
|
|
286
|
+
* `timeoutMs` gets a raced deadline, because calling `definition.execute()`
|
|
287
|
+
* directly bypasses the registry's timeout policy wrapper.
|
|
288
|
+
*
|
|
289
|
+
* Errors never throw out of dispatch: a child rejection (or raced timeout)
|
|
290
|
+
* is wrapped into a structured `{ error }` the model can correct and retry.
|
|
291
|
+
*
|
|
292
|
+
* @param args - raw model arguments (`{ tool, arguments? }`, validated here).
|
|
293
|
+
* @param prefix - the configured MCP prefix.
|
|
294
|
+
* @param resolve - scope-aware tool resolver (production: `ctx.tools.get`).
|
|
295
|
+
* @param exec - the meta-tool's run context, forwarded to the child.
|
|
296
|
+
* @param servers - server-name whitelist (default: no filtering).
|
|
297
|
+
* @returns the child's resolved value verbatim, or a structured error.
|
|
298
|
+
*/
|
|
299
|
+
export async function dispatchMcpCall(args, prefix, resolve, exec, servers = []) {
|
|
300
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
301
|
+
return { error: `${MCP_CALL_TOOL_NAME} expects an object { "tool": string, "arguments"?: object }` };
|
|
302
|
+
}
|
|
303
|
+
const raw = args;
|
|
304
|
+
const tool = raw.tool;
|
|
305
|
+
if (typeof tool !== 'string' || tool === '') {
|
|
306
|
+
return { error: `${MCP_CALL_TOOL_NAME} requires a string "tool" — discover names with ${MCP_LIST_TOOL_NAME}` };
|
|
307
|
+
}
|
|
308
|
+
if (!tool.startsWith(prefix)) {
|
|
309
|
+
return { error: `refusing to call "${tool}": ${MCP_CALL_TOOL_NAME} dispatches only tools named with the "${prefix}" prefix` };
|
|
310
|
+
}
|
|
311
|
+
if (tool === MCP_LIST_TOOL_NAME || tool === MCP_CALL_TOOL_NAME) {
|
|
312
|
+
return { error: `refusing to call "${tool}": meta-tools are not dispatchable through ${MCP_CALL_TOOL_NAME}` };
|
|
313
|
+
}
|
|
314
|
+
if (!isAllowedServer(tool, prefix, servers)) {
|
|
315
|
+
return { error: `refusing to call "${tool}": server "${serverOfToolName(tool, prefix)}" is not in the configured servers list` };
|
|
316
|
+
}
|
|
317
|
+
const definition = resolve(tool);
|
|
318
|
+
if (definition === undefined) {
|
|
319
|
+
return { error: `tool "${tool}" is not registered or not visible in this scope — call ${MCP_LIST_TOOL_NAME} to see the catalog` };
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
// `?? {}` lets a missing/null arguments object reach the server, which
|
|
323
|
+
// then produces its own "missing required param" error to learn from.
|
|
324
|
+
const toolArgs = raw.arguments ?? {};
|
|
325
|
+
if (definition.timeoutMs === undefined) {
|
|
326
|
+
return await definition.execute(toolArgs, exec);
|
|
327
|
+
}
|
|
328
|
+
return await raceToolTimeout(definition, definition.timeoutMs, toolArgs, exec);
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
332
|
+
return { error: `MCP tool "${tool}" failed: ${message}` };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/** Race one declared-timeout tool body against its own budget. */
|
|
336
|
+
async function raceToolTimeout(definition, timeoutMs, args, exec) {
|
|
337
|
+
let timer;
|
|
338
|
+
try {
|
|
339
|
+
return await Promise.race([
|
|
340
|
+
definition.execute(args, exec),
|
|
341
|
+
new Promise((_, reject) => {
|
|
342
|
+
// Cooperative, like the registry's own timeout policy: the losing
|
|
343
|
+
// promise keeps running (same-process code cannot be hard-killed),
|
|
344
|
+
// the caller just stops waiting for it.
|
|
345
|
+
timer = setTimeout(() => reject(new Error(`timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
346
|
+
}),
|
|
347
|
+
]);
|
|
348
|
+
}
|
|
349
|
+
finally {
|
|
350
|
+
if (timer !== undefined)
|
|
351
|
+
clearTimeout(timer);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// ---- Meta-tool definitions (factories; Cordis-free) ----
|
|
355
|
+
/**
|
|
356
|
+
* Whether a value is this plugin's structured-error wrap (single `error`
|
|
357
|
+
* string key) — rendered as plain text, never delegated to a child.
|
|
358
|
+
*/
|
|
359
|
+
function isStructuredError(value) {
|
|
360
|
+
return typeof value === 'object' && value !== null
|
|
361
|
+
&& Object.keys(value).length === 1
|
|
362
|
+
&& typeof value.error === 'string';
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Render a canonical meta-tool value as model-facing text: structured
|
|
366
|
+
* errors read best plain, everything else round-trips as pretty JSON.
|
|
367
|
+
*/
|
|
368
|
+
function renderValue(value) {
|
|
369
|
+
if (isStructuredError(value)) {
|
|
370
|
+
return [{ type: 'text', text: value.error }];
|
|
371
|
+
}
|
|
372
|
+
const text = JSON.stringify(value, null, 2);
|
|
373
|
+
return [{ type: 'text', text: text === undefined ? '(no JSON result)' : text }];
|
|
374
|
+
}
|
|
375
|
+
/** Parse the child tool name out of one mcp_call argument object. */
|
|
376
|
+
function childToolName(args) {
|
|
377
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args))
|
|
378
|
+
return undefined;
|
|
379
|
+
const tool = args.tool;
|
|
380
|
+
return typeof tool === 'string' && tool !== '' ? tool : undefined;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Extract the arguments payload mcp_call forwards (or would forward) to the
|
|
384
|
+
* child — the exact `?? {}` fallback {@link dispatchMcpCall} applies.
|
|
385
|
+
*/
|
|
386
|
+
function childArguments(args) {
|
|
387
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args))
|
|
388
|
+
return {};
|
|
389
|
+
return args.arguments ?? {};
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Render one mcp_call outcome by delegating to the dispatched child's own
|
|
393
|
+
* `output.render`, so model-facing text is exactly what a native call of the
|
|
394
|
+
* child would produce. Falls back to the generic JSON rendering whenever the
|
|
395
|
+
* value is this plugin's structured-error wrap, the child cannot be resolved
|
|
396
|
+
* from the arguments, or the child's render throws (the value's shape is the
|
|
397
|
+
* child's contract, not this tool's).
|
|
398
|
+
* @param metaArgs - the frozen mcp_call arguments (`{ tool, arguments? }`).
|
|
399
|
+
* @param value - the dispatched child's resolved value (or an error wrap).
|
|
400
|
+
* @param resolveChild - definition resolver (unscoped view is fine here —
|
|
401
|
+
* render is a pure display projection).
|
|
402
|
+
* @returns the model-facing content blocks.
|
|
403
|
+
*/
|
|
404
|
+
export function renderDispatched(metaArgs, value, resolveChild) {
|
|
405
|
+
if (isStructuredError(value))
|
|
406
|
+
return renderValue(value);
|
|
407
|
+
const name = childToolName(metaArgs);
|
|
408
|
+
if (name === undefined)
|
|
409
|
+
return renderValue(value);
|
|
410
|
+
const child = resolveChild(name);
|
|
411
|
+
if (child === undefined)
|
|
412
|
+
return renderValue(value);
|
|
413
|
+
try {
|
|
414
|
+
return child.output.render(childArguments(metaArgs), value);
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return renderValue(value);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Forward one successful mcp_call outcome to the dispatched child's own
|
|
422
|
+
* `finalizeContent`, restoring child-owned rich projections (image
|
|
423
|
+
* attachments).
|
|
424
|
+
*
|
|
425
|
+
* Why this is needed: the official mcp-client stages image projections in a
|
|
426
|
+
* `WeakMap<ToolExecution, PreparedProjection>` filled by its executor
|
|
427
|
+
* (`packages/mcp/mcp-client/src/tools.ts:255`, `:354-358`) and hands them
|
|
428
|
+
* back from `finalizeContent` (`:262-270`) — but the registry invokes
|
|
429
|
+
* `finalizeContent` only for the OUTER executed definition
|
|
430
|
+
* (`packages/core/tools/src/index.ts:1649-1654`), which here is `mcp_call`.
|
|
431
|
+
* Without forwarding, the child's projection never runs and image results
|
|
432
|
+
* degrade to their base64-in-text fallback.
|
|
433
|
+
*
|
|
434
|
+
* Mechanics: the child is re-resolved from `metaArgs.tool`; a child-view
|
|
435
|
+
* success result is synthesized with `content` computed by the child's own
|
|
436
|
+
* `output.render` (the same fallback the registry would have produced for a
|
|
437
|
+
* native call, so the child's value/fallback equality guards still pass);
|
|
438
|
+
* and the child's `finalizeContent` is invoked with the EXACT `exec` object
|
|
439
|
+
* dispatch forwarded to `child.execute` — same object identity, so the
|
|
440
|
+
* child's WeakMap lookup hits.
|
|
441
|
+
*
|
|
442
|
+
* Failure paths never project: an `isError` result and this plugin's
|
|
443
|
+
* structured-error wraps return `undefined` immediately; a child without
|
|
444
|
+
* `finalizeContent`, an unresolvable child, or a throwing child callback
|
|
445
|
+
* (the contract demands total callbacks) also degrade to `undefined`, which
|
|
446
|
+
* preserves the registry-computed content.
|
|
447
|
+
*
|
|
448
|
+
* @param metaArgs - the frozen mcp_call arguments (`{ tool, arguments? }`).
|
|
449
|
+
* @param result - the registry-normalized mcp_call outcome.
|
|
450
|
+
* @param exec - the mcp_call execution object that was forwarded verbatim
|
|
451
|
+
* to the child body — the child's projection WeakMap key.
|
|
452
|
+
* @param resolveChild - scope-aware definition resolver.
|
|
453
|
+
* @returns replacement content from the child's finalizer, or `undefined`
|
|
454
|
+
* to preserve the registry-computed content.
|
|
455
|
+
*/
|
|
456
|
+
export function delegateFinalizeContent(metaArgs, result, exec, resolveChild) {
|
|
457
|
+
try {
|
|
458
|
+
if (result.isError)
|
|
459
|
+
return undefined;
|
|
460
|
+
if (isStructuredError(result.value))
|
|
461
|
+
return undefined;
|
|
462
|
+
const name = childToolName(metaArgs);
|
|
463
|
+
if (name === undefined)
|
|
464
|
+
return undefined;
|
|
465
|
+
const child = resolveChild(name);
|
|
466
|
+
if (child === undefined || child.finalizeContent === undefined)
|
|
467
|
+
return undefined;
|
|
468
|
+
// The registry renders result.content through mcp_call's output.render,
|
|
469
|
+
// which delegates to this same child render — recompute it here so the
|
|
470
|
+
// child sees the identical fallback a native call would have produced.
|
|
471
|
+
const fallback = child.output.render(childArguments(metaArgs), result.value);
|
|
472
|
+
return child.finalizeContent(exec, { isError: false, value: result.value, content: fallback });
|
|
473
|
+
}
|
|
474
|
+
catch {
|
|
475
|
+
return undefined;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Build the `mcp_list` meta-tool definition.
|
|
480
|
+
* @param options - catalog knobs (prefix, description limit).
|
|
481
|
+
* @param listSchemas - visible-schemas source (production: `ctx.tools.schemas`,
|
|
482
|
+
* called with the calling agent so restrictions are respected).
|
|
483
|
+
* @returns the complete tool definition.
|
|
484
|
+
*/
|
|
485
|
+
export function createMcpListTool(options, listSchemas) {
|
|
486
|
+
const { prefix } = options;
|
|
487
|
+
return {
|
|
488
|
+
name: MCP_LIST_TOOL_NAME,
|
|
489
|
+
description: [
|
|
490
|
+
'Browse MCP tools registered by the built-in MCP client, without their schemas.',
|
|
491
|
+
`With no arguments: a compact catalog grouped by server — full tool names (like "${prefix}<server>__<tool>") plus short descriptions.`,
|
|
492
|
+
`Pass { "tool": "<full name>" } to expand that tool's complete input schema on demand.`,
|
|
493
|
+
'Pass { "server": "<name>" } to filter the catalog to one server.',
|
|
494
|
+
'Pass { "verbose": true } to inline every tool\'s full schema (expensive — request it only when you actually need many schemas).',
|
|
495
|
+
`Workflow: call ${MCP_LIST_TOOL_NAME} to discover a tool and its schema, then invoke it with ${MCP_CALL_TOOL_NAME}.`,
|
|
496
|
+
].join(' '),
|
|
497
|
+
parameters: {
|
|
498
|
+
type: 'object',
|
|
499
|
+
properties: {
|
|
500
|
+
tool: { type: 'string', description: 'Full registered tool name whose schema to expand' },
|
|
501
|
+
server: { type: 'string', description: 'Only list tools of this server' },
|
|
502
|
+
verbose: { type: 'boolean', description: 'Inline every tool\'s full schema' },
|
|
503
|
+
},
|
|
504
|
+
additionalProperties: false,
|
|
505
|
+
},
|
|
506
|
+
output: {
|
|
507
|
+
// Accepts every canonical result shape: { servers }, { tool }, { error }.
|
|
508
|
+
schema: {
|
|
509
|
+
type: 'object',
|
|
510
|
+
properties: {
|
|
511
|
+
servers: { type: 'array', items: {} },
|
|
512
|
+
tool: {},
|
|
513
|
+
error: { type: 'string' },
|
|
514
|
+
},
|
|
515
|
+
additionalProperties: false,
|
|
516
|
+
},
|
|
517
|
+
render: (_args, value) => renderValue(value),
|
|
518
|
+
},
|
|
519
|
+
execute: (args, exec) => {
|
|
520
|
+
const query = normalizeMcpListArgs(args);
|
|
521
|
+
// The calling agent's view: restricted-away tools stay out of the catalog.
|
|
522
|
+
const schemas = listSchemas(exec.agent);
|
|
523
|
+
return Promise.resolve(buildMcpListResult(query, schemas, options));
|
|
524
|
+
},
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Build the `mcp_call` meta-tool definition.
|
|
529
|
+
* @param prefix - the configured MCP prefix (dispatch boundary).
|
|
530
|
+
* @param resolve - scope-aware definition resolver (production:
|
|
531
|
+
* `ctx.tools.get`, called with the calling agent).
|
|
532
|
+
* @param servers - server-name whitelist (default: no filtering).
|
|
533
|
+
* @returns the complete tool definition.
|
|
534
|
+
*/
|
|
535
|
+
export function createMcpCallTool(prefix, resolve, servers = []) {
|
|
536
|
+
return {
|
|
537
|
+
name: MCP_CALL_TOOL_NAME,
|
|
538
|
+
description: [
|
|
539
|
+
`Invoke one MCP tool by its full registered name (like "${prefix}<server>__<tool>").`,
|
|
540
|
+
`First call ${MCP_LIST_TOOL_NAME} to discover tool names and expand the exact input schema,`,
|
|
541
|
+
'then pass { "tool": "<full name>", "arguments": { ... } }.',
|
|
542
|
+
`Only tools named with the "${prefix}" prefix are dispatchable — anything else is refused.`,
|
|
543
|
+
'The result is the invoked tool\'s own return value, or a structured { "error": ... } you can correct and retry.',
|
|
544
|
+
].join(' '),
|
|
545
|
+
parameters: {
|
|
546
|
+
type: 'object',
|
|
547
|
+
properties: {
|
|
548
|
+
tool: { type: 'string', description: `Full registered name (see ${MCP_LIST_TOOL_NAME})` },
|
|
549
|
+
arguments: { type: 'object', description: 'Arguments matching the tool\'s expanded schema' },
|
|
550
|
+
},
|
|
551
|
+
required: ['tool'],
|
|
552
|
+
additionalProperties: false,
|
|
553
|
+
},
|
|
554
|
+
output: {
|
|
555
|
+
// Permissive on purpose: the canonical value is the child tool's own
|
|
556
|
+
// resolved value (or a structured { error }); its shape is the child's
|
|
557
|
+
// contract, not this tool's. Rendering delegates to the dispatched
|
|
558
|
+
// child's own output.render so text output matches a native call.
|
|
559
|
+
schema: {},
|
|
560
|
+
render: (args, value) => renderDispatched(args, value, name => resolve(name)),
|
|
561
|
+
},
|
|
562
|
+
execute: (args, exec) => dispatchMcpCall(args, prefix, name => resolve(name, exec.agent), exec, servers),
|
|
563
|
+
// Restore child-owned projections (image attachments): the registry
|
|
564
|
+
// invokes THIS definition's finalizer, so it must forward to the child's
|
|
565
|
+
// with the same exec object dispatch passed to child.execute.
|
|
566
|
+
finalizeContent: (exec, result) => delegateFinalizeContent(exec.arguments, result, exec, name => resolve(name, exec.agent)),
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
// ---- Plugin apply (the only Cordis-touching code) ----
|
|
570
|
+
/**
|
|
571
|
+
* Register the two meta-tools and install the assembly folding listener.
|
|
572
|
+
*
|
|
573
|
+
* Failure safety: if either meta-tool registration fails (name collision),
|
|
574
|
+
* both registrations are rolled back, a warning is logged, and NO listener
|
|
575
|
+
* is installed — the official full-schema passthrough stays intact.
|
|
576
|
+
*
|
|
577
|
+
* @param ctx - plugin context carrying the tool registry.
|
|
578
|
+
* @param config - resolved adapter configuration.
|
|
579
|
+
*/
|
|
580
|
+
export function apply(ctx, config) {
|
|
581
|
+
const foldOptions = {
|
|
582
|
+
prefix: config.prefix,
|
|
583
|
+
keep: config.keep,
|
|
584
|
+
servers: config.servers,
|
|
585
|
+
};
|
|
586
|
+
const listOptions = {
|
|
587
|
+
prefix: config.prefix,
|
|
588
|
+
descriptionLimit: config.descriptionLimit,
|
|
589
|
+
servers: config.servers,
|
|
590
|
+
};
|
|
591
|
+
const listDefinition = createMcpListTool(listOptions, scope => ctx.tools.schemas(scope));
|
|
592
|
+
const callDefinition = createMcpCallTool(config.prefix, (name, scope) => ctx.tools.get(name, scope), config.servers);
|
|
593
|
+
const disposers = [];
|
|
594
|
+
try {
|
|
595
|
+
disposers.push(ctx.tools.register(listDefinition));
|
|
596
|
+
disposers.push(ctx.tools.register(callDefinition));
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
for (const dispose of disposers)
|
|
600
|
+
dispose();
|
|
601
|
+
ctx.logger.warn(`mcp-adapter: meta-tool registration failed (${error instanceof Error ? error.message : String(error)}) `
|
|
602
|
+
+ '— keeping the official full-schema prompt passthrough');
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
ctx.effect(() => () => {
|
|
606
|
+
for (const dispose of disposers)
|
|
607
|
+
dispose();
|
|
608
|
+
}, 'mcp-adapter.metaTools');
|
|
609
|
+
// Registered on this plugin's (host-level) context, so the listener sees
|
|
610
|
+
// every scope's assemblies — the same pattern as the upstream invariant
|
|
611
|
+
// companion. Listener return values are authoritative: rewrite `tools`
|
|
612
|
+
// AFTER `next()` so the fold observes the fully assembled state.
|
|
613
|
+
ctx.on('system-prompt/assemble', async (assembly, context, next) => {
|
|
614
|
+
const assembled = await next();
|
|
615
|
+
// Fail-open per scope: fold only while BOTH meta-tools resolve (in the
|
|
616
|
+
// assembling scope) to exactly this plugin's own definitions — a
|
|
617
|
+
// missing, shadowed, or foreign `mcp_list`/`mcp_call` means passthrough.
|
|
618
|
+
const metaToolsLive = ctx.tools.get(MCP_LIST_TOOL_NAME, context.scope) === listDefinition
|
|
619
|
+
&& ctx.tools.get(MCP_CALL_TOOL_NAME, context.scope) === callDefinition;
|
|
620
|
+
return foldPromptAssembly(assembled, foldOptions, metaToolsLive);
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|