@bevel-software/platform-mcp-core 0.11.2 → 0.12.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/THIRD-PARTY-NOTICES.md +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/meta-tools.d.ts.map +1 -1
- package/dist/meta-tools.js +8 -2
- package/dist/meta-tools.js.map +1 -1
- package/dist/results.d.ts +74 -0
- package/dist/results.d.ts.map +1 -1
- package/dist/results.js +514 -0
- package/dist/results.js.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +5 -0
- package/src/meta-tools.ts +8 -2
- package/src/results.ts +549 -0
package/dist/results.js
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discriminator for {@link McpImageResult}. The slash + version suffix make it
|
|
3
|
+
* a value no ordinary tool result carries by accident — a domain object with a
|
|
4
|
+
* `kind` field holds things like `'image'` or `'file'`, never this string —
|
|
5
|
+
* so the result shaping below can act on the shape without ever mistaking
|
|
6
|
+
* caller data for it.
|
|
7
|
+
*/
|
|
8
|
+
export const MCP_IMAGE_RESULT_KIND = 'bevel/mcp-image@v1';
|
|
9
|
+
/** Build a {@link McpImageResult} for a handler to return. */
|
|
10
|
+
export function mcpImageResult(data, mimeType, note) {
|
|
11
|
+
return { kind: MCP_IMAGE_RESULT_KIND, data, mimeType, ...(note !== undefined ? { note } : {}) };
|
|
12
|
+
}
|
|
13
|
+
export function isMcpImageResult(value) {
|
|
14
|
+
if (typeof value !== 'object' || value === null)
|
|
15
|
+
return false;
|
|
16
|
+
// The field reads are defensive: this guard runs on every candidate value
|
|
17
|
+
// (toCallToolResult, the scrub's probe), and a candidate can carry a
|
|
18
|
+
// THROWING getter on any of these names. Answering "not a sentinel" is the
|
|
19
|
+
// safe verdict — the value then rides the ordinary serialization fallback
|
|
20
|
+
// instead of turning a completed call into a handler failure.
|
|
21
|
+
try {
|
|
22
|
+
return (value.kind === MCP_IMAGE_RESULT_KIND &&
|
|
23
|
+
typeof value.data === 'string' &&
|
|
24
|
+
typeof value.mimeType === 'string' &&
|
|
25
|
+
// A sentinel may have crossed a transport, so its shape is not this
|
|
26
|
+
// process's to assume: a non-string `note` would be accepted here and then
|
|
27
|
+
// emitted as a text block whose `text` is not a string — an invalid block.
|
|
28
|
+
['undefined', 'string'].includes(typeof value.note));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** A spec-shaped MCP image content block (`{type:'image', data, mimeType}`). */
|
|
35
|
+
function isMcpImageBlockObject(value) {
|
|
36
|
+
if (typeof value !== 'object' || value === null)
|
|
37
|
+
return false;
|
|
38
|
+
// Defensive like isMcpImageResult: a throwing getter means "not a block".
|
|
39
|
+
try {
|
|
40
|
+
return (value.type === 'image' &&
|
|
41
|
+
typeof value.data === 'string' &&
|
|
42
|
+
typeof value.mimeType === 'string');
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
1
48
|
/**
|
|
2
49
|
* Extract a human-meaningful failure message from a tool-call error. UTCP's
|
|
3
50
|
* HTTP protocol surfaces a non-2xx as an axios-style error whose `.response.data`
|
|
@@ -98,7 +145,78 @@ function safeJsonText(value) {
|
|
|
98
145
|
return '(unserializable tool output)';
|
|
99
146
|
}
|
|
100
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* A note that survived a remote hop, whatever it decoded to.
|
|
150
|
+
*
|
|
151
|
+
* `@utcp/mcp` JSON-PARSES a text block's text, so a note that happens to read
|
|
152
|
+
* as JSON comes back as what it denotes — `42` for "42", null for "null" —
|
|
153
|
+
* not as a string. Insisting on strings meant such a result was not recognized
|
|
154
|
+
* as the image it is, and the fallback stringified the whole thing, base64 and
|
|
155
|
+
* all, into the transcript.
|
|
156
|
+
*/
|
|
157
|
+
function noteText(value) {
|
|
158
|
+
if (value === null || ['number', 'boolean'].includes(typeof value))
|
|
159
|
+
return String(value);
|
|
160
|
+
if (typeof value === 'string')
|
|
161
|
+
return value;
|
|
162
|
+
// An OBJECT or an ARRAY: the note was JSON to begin with, and re-serializing
|
|
163
|
+
// it is the only faithful way back to the text block it left as. Refusing
|
|
164
|
+
// these sent the whole result — base64 included — through the fallback.
|
|
165
|
+
if (typeof value === 'object') {
|
|
166
|
+
try {
|
|
167
|
+
return JSON.stringify(value);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return undefined; // cyclic: not a note this hop produced
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
101
175
|
export function toCallToolResult(value) {
|
|
176
|
+
// An image sentinel (see McpImageResult): the tool's result IS a picture.
|
|
177
|
+
// Emit a native image content block so a multimodal client renders it, plus
|
|
178
|
+
// the note as a text block so the transcript stays self-describing.
|
|
179
|
+
if (isMcpImageResult(value)) {
|
|
180
|
+
// Read every field ONCE, here: the guard above proved their shapes, but a
|
|
181
|
+
// getter is free to answer differently the next time — or to throw — and
|
|
182
|
+
// the block would then carry something the guard never validated.
|
|
183
|
+
const snapshot = { data: value.data, mimeType: value.mimeType, note: value.note };
|
|
184
|
+
if (typeof snapshot.data !== 'string' || typeof snapshot.mimeType !== 'string') {
|
|
185
|
+
return { content: [{ type: 'text', text: safeJsonText(value) }] };
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
content: [
|
|
189
|
+
{ type: 'image', data: snapshot.data, mimeType: snapshot.mimeType },
|
|
190
|
+
...(typeof snapshot.note === 'string' ? [{ type: 'text', text: snapshot.note }] : []),
|
|
191
|
+
],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// The same image result AFTER a remote MCP hop. The local stdio server
|
|
195
|
+
// (hexis-mcp) reaches the deployment's MCP endpoint through @utcp/mcp, whose
|
|
196
|
+
// `_processMcpToolResult` unwraps a CallToolResult's `content` array: text
|
|
197
|
+
// blocks are JSON-parsed (our prose note comes back as a bare string; a note
|
|
198
|
+
// that was JSON to begin with comes back as the value it denotes — see
|
|
199
|
+
// `noteText`), other blocks pass through verbatim, and a single-entry list
|
|
200
|
+
// collapses to the entry itself. So the hosted proxy's `[image, text]`
|
|
201
|
+
// result arrives here as `[imageBlock, note]` — or, noteless, as the bare
|
|
202
|
+
// image block. Recognize both and reassemble the spec-shaped result instead
|
|
203
|
+
// of JSON-stringifying megabytes of base64 into a text block. ONLY those
|
|
204
|
+
// exact hop shapes qualify — a lone image block, or one image block plus
|
|
205
|
+
// one note — so a caller's ordinary array that merely holds an image-shaped
|
|
206
|
+
// object beside its own data still takes the stringify path below and keeps
|
|
207
|
+
// its structure.
|
|
208
|
+
if (isMcpImageBlockObject(value)) {
|
|
209
|
+
return { content: [value] };
|
|
210
|
+
}
|
|
211
|
+
if (Array.isArray(value) &&
|
|
212
|
+
value.length === 2 &&
|
|
213
|
+
isMcpImageBlockObject(value[0]) &&
|
|
214
|
+
!isMcpImageBlockObject(value[1])) {
|
|
215
|
+
const note = noteText(value[1]);
|
|
216
|
+
if (note !== undefined) {
|
|
217
|
+
return { content: [value[0], { type: 'text', text: note }] };
|
|
218
|
+
}
|
|
219
|
+
}
|
|
102
220
|
// Already in MCP agentic format — pass through untouched, but only when every
|
|
103
221
|
// `content` entry is a real content block (has a string `type`).
|
|
104
222
|
const content = value?.content;
|
|
@@ -108,6 +226,402 @@ export function toCallToolResult(value) {
|
|
|
108
226
|
const text = typeof value === 'string' ? value : safeJsonText(value ?? null);
|
|
109
227
|
return { content: [{ type: 'text', text: text || '(tool produced no output)' }] };
|
|
110
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Replace image payloads inside a `call_tool_chain` result with a short note.
|
|
231
|
+
*
|
|
232
|
+
* A chain's return value is JSON that gets STRINGIFIED into the transcript
|
|
233
|
+
* (or spilled), so an image result reaching it would either flood the context
|
|
234
|
+
* with base64 or burn a spill for bytes no one can see — a chain has no way to
|
|
235
|
+
* deliver a native image block. Policy (v1): images are returned directly,
|
|
236
|
+
* never through tool chains. This walk swaps every image sentinel — and every
|
|
237
|
+
* spec-shaped image content block, which is what the local server's remote
|
|
238
|
+
* MCP hop hands a chain (see `toCallToolResult`) — for
|
|
239
|
+
* `{ image_omitted: true, note }`, keeping whatever structure the chain built
|
|
240
|
+
* around it. The walk is ITERATIVE (explicit stack) and cycle-safe with no
|
|
241
|
+
* depth cutoff — nesting depth can never smuggle a payload past the scrub.
|
|
242
|
+
* Arrays and plain records are rebuilt; a NON-plain object (class instance,
|
|
243
|
+
* Map-like with enumerable props) is judged by its JSON shape — `toJSON()`
|
|
244
|
+
* output when it defines one, enumerable own properties otherwise — because
|
|
245
|
+
* that is exactly what `JSON.stringify` will emit downstream: when that shape
|
|
246
|
+
* holds an image the object is rebuilt as a plain sanitized copy, and when it
|
|
247
|
+
* does not the original reference is preserved untouched (RegExp, Map, Date
|
|
248
|
+
* and friends are never mangled).
|
|
249
|
+
*
|
|
250
|
+
* The one thing never preserved by reference is a USER `toJSON`. The scrubbed
|
|
251
|
+
* result is stringified into the transcript AFTER this returns, so a hook left
|
|
252
|
+
* live in it fires a second time there, unscrubbed: an impure one — clean when
|
|
253
|
+
* probed, an image payload on the next call — would slip base64 straight past
|
|
254
|
+
* the walk. Every object carrying one is therefore rebuilt from the single
|
|
255
|
+
* view this scrub cached for it, and nothing reachable in the returned value
|
|
256
|
+
* carries a hook the walk did not already resolve. Best-effort by design:
|
|
257
|
+
* chain code that EXTRACTS the base64 string itself escapes the walk, and then
|
|
258
|
+
* the ordinary max_output_size spill bounds the damage.
|
|
259
|
+
*
|
|
260
|
+
* `rootKey` is the JSON property name the SCRUBBED value will be serialized
|
|
261
|
+
* under afterwards — '' (the default) when it is stringified standalone, the
|
|
262
|
+
* envelope key (e.g. `call_tool_chain`'s 'result') when a caller embeds it —
|
|
263
|
+
* so a key-sensitive root `toJSON` answers this scrub with the same view the
|
|
264
|
+
* transcript serializer will ask it for.
|
|
265
|
+
*/
|
|
266
|
+
export function omitImagePayloads(value, rootKey = '') {
|
|
267
|
+
const omittedNote = (what) => ({
|
|
268
|
+
image_omitted: true,
|
|
269
|
+
note: `${what} — images are returned directly to you as native MCP image content, not through ` +
|
|
270
|
+
'`call_tool_chain`. Call `read_file` on the image path as a DIRECT tool call (outside the chain) to see it.',
|
|
271
|
+
});
|
|
272
|
+
// Plain records (Object.prototype or null prototype) are always rebuilt.
|
|
273
|
+
// Anything else — Date, Map, Buffer, class instances, other JSON-friendly
|
|
274
|
+
// oddities — is preserved BY REFERENCE unless its JSON shape actually holds
|
|
275
|
+
// an image (see subtreeHasImage below): rebuilding would mangle it.
|
|
276
|
+
const isPlainRecord = (v) => {
|
|
277
|
+
const proto = Object.getPrototypeOf(v);
|
|
278
|
+
return proto === Object.prototype || proto === null;
|
|
279
|
+
};
|
|
280
|
+
const toJsonHook = (v) => {
|
|
281
|
+
try {
|
|
282
|
+
const hook = v.toJSON;
|
|
283
|
+
return typeof hook === 'function' ? hook : undefined;
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
// The ONE hook trusted to fire again after the scrub, so an ordinary `Date`
|
|
290
|
+
// keeps passing through by reference instead of collapsing to its ISO
|
|
291
|
+
// string. `Date.prototype.toJSON` returns null or the result of invoking the
|
|
292
|
+
// object's own `toISOString`, so when BOTH are the built-ins its result can
|
|
293
|
+
// only ever be null or a string — there is no object for an image to hide
|
|
294
|
+
// in, and no second call can differ in kind. (A non-Date receiver makes the
|
|
295
|
+
// built-in throw, which is likewise harmless.) Every other `toJSON` is user
|
|
296
|
+
// code and gets no such benefit of the doubt.
|
|
297
|
+
const isBuiltinDateHook = (v, hook) => {
|
|
298
|
+
if (hook !== Date.prototype.toJSON)
|
|
299
|
+
return false;
|
|
300
|
+
try {
|
|
301
|
+
return v.toISOString === Date.prototype.toISOString;
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
/** Does this object define an enumerable own property backed by a GETTER? */
|
|
308
|
+
const hasAccessor = (v) => {
|
|
309
|
+
for (const key of Object.keys(v)) {
|
|
310
|
+
const d = Object.getOwnPropertyDescriptor(v, key);
|
|
311
|
+
if (d !== undefined && d.get !== undefined)
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* The USER `toJSON` an object would be serialized through, or undefined.
|
|
318
|
+
*
|
|
319
|
+
* A user hook must never survive into the returned structure: the scrubbed
|
|
320
|
+
* result is stringified into the transcript AFTERWARDS, and a hook left live
|
|
321
|
+
* fires a SECOND time there — an impure one (clean when probed, an image
|
|
322
|
+
* payload on the next call) would hand the transcript base64 the scrub never
|
|
323
|
+
* saw. So every object carrying one is rebuilt from the single cached view
|
|
324
|
+
* below, and the rebuilt copy is a plain array/record with no hook attached.
|
|
325
|
+
*/
|
|
326
|
+
const userToJson = (v) => {
|
|
327
|
+
const hook = toJsonHook(v);
|
|
328
|
+
return hook !== undefined && !isBuiltinDateHook(v, hook) ? hook : undefined;
|
|
329
|
+
};
|
|
330
|
+
// A value's JSON view: what JSON.stringify would serialize for it — the
|
|
331
|
+
// toJSON() result when it defines one (a throwing toJSON falls back to the
|
|
332
|
+
// value itself, matching safeJsonText's degraded path), the value otherwise.
|
|
333
|
+
//
|
|
334
|
+
// `key` is the JSON property name the value is being serialized UNDER, and
|
|
335
|
+
// it is passed to the hook because JSON.stringify passes it: the spec calls
|
|
336
|
+
// `toJSON(key)` — '' at the root, the property name inside an object, the
|
|
337
|
+
// stringified index inside an array. Calling it with NO argument made a
|
|
338
|
+
// key-dependent hook return one thing to this scrub and a different thing
|
|
339
|
+
// to the transcript serializer that runs afterwards, which is precisely the
|
|
340
|
+
// divergence the scrub exists to close.
|
|
341
|
+
//
|
|
342
|
+
// JSON.stringify UNBOXES a primitive wrapper object (`new String(…)` /
|
|
343
|
+
// `new Number(…)` / `new Boolean(…)`) to its primitive before serializing.
|
|
344
|
+
// A boxed VIEW must get the same treatment: rebuilding `new String('abc')`
|
|
345
|
+
// from its enumerable keys would emit {"0":"a","1":"b","2":"c"} where JSON
|
|
346
|
+
// emits "abc".
|
|
347
|
+
const unboxed = (view) => {
|
|
348
|
+
if (view instanceof String)
|
|
349
|
+
return String(view);
|
|
350
|
+
if (view instanceof Number)
|
|
351
|
+
return Number(view);
|
|
352
|
+
if (view instanceof Boolean)
|
|
353
|
+
return view.valueOf();
|
|
354
|
+
return view;
|
|
355
|
+
};
|
|
356
|
+
// Cached per (object, key), not per object: the same object reachable under
|
|
357
|
+
// two different keys genuinely HAS two views, and one cache slot would let
|
|
358
|
+
// the second site emit the first site's answer. Within one (object, key)
|
|
359
|
+
// the hook still fires at most once, so the rebuild emits exactly the view
|
|
360
|
+
// it inspected even when the hook is impure.
|
|
361
|
+
const viewCache = new WeakMap();
|
|
362
|
+
const jsonView = (v, key) => {
|
|
363
|
+
let byKey = viewCache.get(v);
|
|
364
|
+
if (byKey === undefined) {
|
|
365
|
+
byKey = new Map();
|
|
366
|
+
viewCache.set(v, byKey);
|
|
367
|
+
}
|
|
368
|
+
if (byKey.has(key))
|
|
369
|
+
return byKey.get(key);
|
|
370
|
+
let view = v;
|
|
371
|
+
const hook = userToJson(v);
|
|
372
|
+
if (hook !== undefined) {
|
|
373
|
+
try {
|
|
374
|
+
view = Reflect.apply(hook, v, [key]);
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
/* keep the value itself */
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
byKey.set(key, view);
|
|
381
|
+
return view;
|
|
382
|
+
};
|
|
383
|
+
// Must the subtree reachable from `root` be rebuilt rather than preserved by
|
|
384
|
+
// reference? Two things force a rebuild, and the probe answers them in ONE
|
|
385
|
+
// walk because the only caller needs both: an image sentinel / spec-shaped
|
|
386
|
+
// image block anywhere in the shape, and any object carrying a user `toJSON`
|
|
387
|
+
// (which must not stay live in the output — see `userToJson`). A hook is
|
|
388
|
+
// reason enough on its own, so the probe never has to CALL one: it stops at
|
|
389
|
+
// the bearer, and an object without a hook IS its own JSON view.
|
|
390
|
+
//
|
|
391
|
+
// Iterative and cycle-safe (a visited set suffices for a boolean probe).
|
|
392
|
+
// Verdicts are memoized, but only the NEGATIVE one generalizes: a walk that
|
|
393
|
+
// finishes clean proves every object it visited clean too, since each one's
|
|
394
|
+
// reachable shape is a subset of what was just explored — so a nested object
|
|
395
|
+
// is probed once, not re-walked by every enclosing probe. A hit stops the
|
|
396
|
+
// walk early, which leaves the visited set half-explored and proves nothing
|
|
397
|
+
// about those objects (the image or hook may sit outside an inner object's
|
|
398
|
+
// own subtree), so only the root's verdict is recorded then.
|
|
399
|
+
const probeCache = new WeakMap();
|
|
400
|
+
const subtreeNeedsRebuild = (root) => {
|
|
401
|
+
const known = probeCache.get(root);
|
|
402
|
+
if (known !== undefined)
|
|
403
|
+
return known;
|
|
404
|
+
const visited = new Set();
|
|
405
|
+
const stack = [root];
|
|
406
|
+
let found = false;
|
|
407
|
+
while (stack.length > 0) {
|
|
408
|
+
const v = stack.pop();
|
|
409
|
+
if (v === null || typeof v !== 'object')
|
|
410
|
+
continue;
|
|
411
|
+
if (isMcpImageResult(v) || isMcpImageBlockObject(v)) {
|
|
412
|
+
found = true;
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
if (visited.has(v))
|
|
416
|
+
continue;
|
|
417
|
+
const cached = probeCache.get(v);
|
|
418
|
+
if (cached === true) {
|
|
419
|
+
found = true;
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
visited.add(v);
|
|
423
|
+
if (cached === false)
|
|
424
|
+
continue;
|
|
425
|
+
// An ACCESSOR is user code too, and it runs again every time the value is
|
|
426
|
+
// read: a getter may answer the probe with something clean and hand the
|
|
427
|
+
// serializer an image. Preserving such an object by reference would let
|
|
428
|
+
// that second answer past the scrub, so its subtree is rebuilt from the
|
|
429
|
+
// values read HERE, once.
|
|
430
|
+
if (hasAccessor(v)) {
|
|
431
|
+
found = true;
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
if (userToJson(v) !== undefined) {
|
|
435
|
+
found = true;
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
if (Array.isArray(v)) {
|
|
439
|
+
for (const entry of v)
|
|
440
|
+
stack.push(entry);
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
for (const key of Object.keys(v))
|
|
444
|
+
stack.push(v[key]);
|
|
445
|
+
}
|
|
446
|
+
probeCache.set(root, found);
|
|
447
|
+
if (!found)
|
|
448
|
+
for (const v of visited)
|
|
449
|
+
probeCache.set(v, false);
|
|
450
|
+
return found;
|
|
451
|
+
};
|
|
452
|
+
// `out[key] = …` would be a prototype-pollution hazard for keys like
|
|
453
|
+
// `__proto__`; defineProperty makes every rebuilt key an ordinary own data
|
|
454
|
+
// property (JSON.stringify then serializes it exactly like the original).
|
|
455
|
+
const defineKey = (out, key, val) => {
|
|
456
|
+
Object.defineProperty(out, key, { value: val, enumerable: true, writable: true, configurable: true });
|
|
457
|
+
};
|
|
458
|
+
/**
|
|
459
|
+
* The own enumerable keys to rebuild a record from — every key
|
|
460
|
+
* `JSON.stringify` would visit EXCEPT a function-valued `toJSON`.
|
|
461
|
+
*
|
|
462
|
+
* A rebuilt record is a plain object, and `JSON.stringify` consults exactly
|
|
463
|
+
* one method on a plain object: `toJSON`. Copying that key across therefore
|
|
464
|
+
* re-arms the hook on the sanitized value, and the transcript serializer
|
|
465
|
+
* that runs after this scrub calls it — an impure hook (clean when the
|
|
466
|
+
* scrub probed it, an image payload on the next call) hands the transcript
|
|
467
|
+
* base64 the walk never saw. It is reachable through a VIEW: a `toJSON()`
|
|
468
|
+
* that returns `{ data: …, toJSON() { …image… } }` is rebuilt from that
|
|
469
|
+
* view's keys, and `toJSON` is one of them.
|
|
470
|
+
*
|
|
471
|
+
* No other function-valued own key can do this. `toISOString` matters only
|
|
472
|
+
* because `Date.prototype.toJSON` calls it, and a rebuilt plain object has
|
|
473
|
+
* `Object.prototype` — no inherited `toJSON` to reach it — so the copied
|
|
474
|
+
* function is simply an own property `JSON.stringify` SKIPS, as it skips
|
|
475
|
+
* every function value. Same for `valueOf`, `toString` and friends:
|
|
476
|
+
* stringify consults none of them on an object.
|
|
477
|
+
*/
|
|
478
|
+
const rebuildKeys = (src) => Object.keys(src).filter((k) => {
|
|
479
|
+
if (k !== 'toJSON')
|
|
480
|
+
return true;
|
|
481
|
+
try {
|
|
482
|
+
return typeof src[k] !== 'function';
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
return false; // a throwing accessor named toJSON: never copy it
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
const active = new WeakSet();
|
|
489
|
+
/**
|
|
490
|
+
* Resolve one value: a leaf to emit as-is, or a container frame to walk.
|
|
491
|
+
* `key` is the JSON property name `v` is serialized under — '' at the root,
|
|
492
|
+
* the property name in a record, the stringified index in an array — and is
|
|
493
|
+
* threaded through only so a `toJSON` hook receives the argument
|
|
494
|
+
* `JSON.stringify` would give it (see `jsonView`).
|
|
495
|
+
*/
|
|
496
|
+
const resolve = (v, key) => {
|
|
497
|
+
if (v === null || typeof v !== 'object')
|
|
498
|
+
return { leaf: v };
|
|
499
|
+
if (isMcpImageResult(v))
|
|
500
|
+
return { leaf: omittedNote(v.note ?? `an image (${v.mimeType})`) };
|
|
501
|
+
if (isMcpImageBlockObject(v))
|
|
502
|
+
return { leaf: omittedNote(`an image (${v.mimeType})`) };
|
|
503
|
+
if (active.has(v))
|
|
504
|
+
return { leaf: '[Circular]' };
|
|
505
|
+
// A user `toJSON` is handled FIRST — before the array/plain-record split,
|
|
506
|
+
// exactly as JSON.stringify applies it before looking at the value's
|
|
507
|
+
// shape. Such an object is ALWAYS rebuilt from its one cached view, never
|
|
508
|
+
// preserved by reference and never rebuilt from its own keys: leaving the
|
|
509
|
+
// hook live (or copying it across as a `toJSON` property of a rebuilt
|
|
510
|
+
// record) would let it fire again during transcript serialization and
|
|
511
|
+
// return a payload this scrub never inspected.
|
|
512
|
+
const hook = userToJson(v);
|
|
513
|
+
if (hook !== undefined) {
|
|
514
|
+
// Unboxing first mirrors stringify's own order: a hook returning a boxed
|
|
515
|
+
// primitive serializes as that primitive, never as a record of index keys.
|
|
516
|
+
const view = unboxed(jsonView(v, key));
|
|
517
|
+
// The view can BE the image shape — a toJSON() returning a sentinel or
|
|
518
|
+
// image block directly. Scrub it here: falling through would build a
|
|
519
|
+
// record frame from the view and copy its base64 `data` field, key by
|
|
520
|
+
// key, straight into the rebuilt result.
|
|
521
|
+
if (isMcpImageResult(view))
|
|
522
|
+
return { leaf: omittedNote(view.note ?? `an image (${view.mimeType})`) };
|
|
523
|
+
if (isMcpImageBlockObject(view))
|
|
524
|
+
return { leaf: omittedNote(`an image (${view.mimeType})`) };
|
|
525
|
+
if (view === null || typeof view !== 'object')
|
|
526
|
+
return { leaf: view };
|
|
527
|
+
if (active.has(view))
|
|
528
|
+
return { leaf: '[Circular]' };
|
|
529
|
+
active.add(v);
|
|
530
|
+
const release = view === v ? [v] : [v, view];
|
|
531
|
+
if (view !== v)
|
|
532
|
+
active.add(view);
|
|
533
|
+
if (Array.isArray(view)) {
|
|
534
|
+
return { frame: { kind: 'array', src: view, out: new Array(view.length), i: 0, release } };
|
|
535
|
+
}
|
|
536
|
+
return {
|
|
537
|
+
frame: {
|
|
538
|
+
kind: 'record',
|
|
539
|
+
src: view,
|
|
540
|
+
out: {},
|
|
541
|
+
keys: rebuildKeys(view),
|
|
542
|
+
i: 0,
|
|
543
|
+
release,
|
|
544
|
+
},
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
if (Array.isArray(v)) {
|
|
548
|
+
active.add(v);
|
|
549
|
+
return { frame: { kind: 'array', src: v, out: new Array(v.length), i: 0, release: [v] } };
|
|
550
|
+
}
|
|
551
|
+
if (isPlainRecord(v)) {
|
|
552
|
+
active.add(v);
|
|
553
|
+
return { frame: { kind: 'record', src: v, out: {}, keys: rebuildKeys(v), i: 0, release: [v] } };
|
|
554
|
+
}
|
|
555
|
+
// Non-plain object with no hook of its own: it IS its own JSON view, so it
|
|
556
|
+
// passes through untouched (by reference) unless the shape below it needs
|
|
557
|
+
// rebuilding — an image to scrub, or a nested object whose user `toJSON`
|
|
558
|
+
// must not stay live in the result. Only then is a plain sanitized copy
|
|
559
|
+
// built from its enumerable own properties, exactly what JSON.stringify
|
|
560
|
+
// would have emitted.
|
|
561
|
+
if (!subtreeNeedsRebuild(v))
|
|
562
|
+
return { leaf: v };
|
|
563
|
+
active.add(v);
|
|
564
|
+
return {
|
|
565
|
+
frame: {
|
|
566
|
+
kind: 'record',
|
|
567
|
+
src: v,
|
|
568
|
+
out: {},
|
|
569
|
+
keys: rebuildKeys(v),
|
|
570
|
+
i: 0,
|
|
571
|
+
release: [v],
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
};
|
|
575
|
+
// '' is the root key JSON.stringify uses for a standalone value (it
|
|
576
|
+
// serializes through a synthetic wrapper `{ '': value }`); a caller that
|
|
577
|
+
// embeds the scrubbed value under an envelope key passes that key instead
|
|
578
|
+
// (see `rootKey` above).
|
|
579
|
+
const seed = resolve(value, rootKey);
|
|
580
|
+
if ('leaf' in seed)
|
|
581
|
+
return seed.leaf;
|
|
582
|
+
const stack = [seed.frame];
|
|
583
|
+
while (stack.length > 0) {
|
|
584
|
+
const top = stack[stack.length - 1];
|
|
585
|
+
if (top.kind === 'array') {
|
|
586
|
+
if (top.i >= top.src.length) {
|
|
587
|
+
for (const held of top.release)
|
|
588
|
+
active.delete(held);
|
|
589
|
+
stack.pop();
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const idx = top.i++;
|
|
593
|
+
// An array element's JSON key is its stringified index — what
|
|
594
|
+
// JSON.stringify hands the element's own `toJSON`.
|
|
595
|
+
const r = resolve(top.src[idx], String(idx));
|
|
596
|
+
if ('leaf' in r) {
|
|
597
|
+
top.out[idx] = r.leaf;
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
// The child's `out` fills in place as its frame drains.
|
|
601
|
+
top.out[idx] = r.frame.out;
|
|
602
|
+
stack.push(r.frame);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
if (top.i >= top.keys.length) {
|
|
607
|
+
for (const held of top.release)
|
|
608
|
+
active.delete(held);
|
|
609
|
+
stack.pop();
|
|
610
|
+
continue;
|
|
611
|
+
}
|
|
612
|
+
const key = top.keys[top.i++];
|
|
613
|
+
const r = resolve(top.src[key], key);
|
|
614
|
+
if ('leaf' in r) {
|
|
615
|
+
defineKey(top.out, key, r.leaf);
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
defineKey(top.out, key, r.frame.out);
|
|
619
|
+
stack.push(r.frame);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return seed.frame.out;
|
|
624
|
+
}
|
|
111
625
|
export function renderProgress(chunk) {
|
|
112
626
|
const s = typeof chunk === 'string' ? chunk : safeJsonText(chunk);
|
|
113
627
|
return s.length > 500 ? s.slice(0, 497) + '...' : s;
|
package/dist/results.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"results.js","sourceRoot":"","sources":["../src/results.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"results.js","sourceRoot":"","sources":["../src/results.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bevel-software/platform-mcp-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "The transport-agnostic half of Bevel's MCP surface: UTCP manual registration, tool discovery, MCP listing/dispatch and the code-mode meta-tools. Shared by the hosted proxy and the local stdio server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"THIRD-PARTY-NOTICES.md"
|
|
21
21
|
],
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=22 <23"
|
|
23
|
+
"node": ">=22.13 <23"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
27
|
-
"@utcp/code-mode": "^1.2.
|
|
27
|
+
"@utcp/code-mode": "^1.2.13",
|
|
28
28
|
"@utcp/http": "^1.1.11",
|
|
29
|
-
"@utcp/mcp": "^1.1.
|
|
29
|
+
"@utcp/mcp": "^1.1.6",
|
|
30
30
|
"@utcp/sdk": "^1.1.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
package/src/index.ts
CHANGED
package/src/meta-tools.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Tool as McpTool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import type { CodeModeUtcpClient } from '@utcp/code-mode';
|
|
3
3
|
import { utcpNameToTsInterfaceName, findToolsByNames } from './code-mode-names.js';
|
|
4
|
-
import { toCallToolResult, toolError, describeToolFailure } from './results.js';
|
|
4
|
+
import { toCallToolResult, toolError, describeToolFailure, omitImagePayloads } from './results.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Code-mode meta-tools exposed ALONGSIDE the direct tools. They let an external
|
|
@@ -25,6 +25,7 @@ const CALL_TOOL_CHAIN_DESCRIPTION = [
|
|
|
25
25
|
'Execute a short JavaScript program with direct access to every registered UTCP tool as a synchronous function. Call tools as `KNOWLEDGE_BASE.<tool>({ body: { ...args } })` with NO `await` (results are already resolved), and `return` the final value. The runtime is plain JavaScript (no type annotations / no TypeScript-only syntax).',
|
|
26
26
|
'Discover first: `list_tools` lists every tool in callable form (e.g. `KNOWLEDGE_BASE.read_file`); `tools_info` returns their exact argument + return shapes — do not guess. Batch multiple tool calls into one chain to avoid a round-trip per call. The chain runs with your own connection key, so it can only reach the tools you can already call directly.',
|
|
27
27
|
'Large results: if the combined result+logs exceed `max_output_size` (default 200000 chars) the full JSON is spilled to a shared store and you get back a `__tool_chain_spill__/…` ref instead. Read it with `read_file` (pass that ref as `path` — `branch` is ignored — plus `offset`/`limit` to slice it), or better, re-run a narrower chain that returns only what you need.',
|
|
28
|
+
'Images: image files are returned as native MCP image content on a DIRECT `read_file` call only — a chained `read_file` of an image yields `{ image_omitted: true, note }` instead of the picture, so call it outside the chain to actually see the image.',
|
|
28
29
|
].join('\n\n');
|
|
29
30
|
|
|
30
31
|
export const CODE_MODE_META_TOOLS: McpTool[] = [
|
|
@@ -151,7 +152,12 @@ export async function dispatchMetaTool(
|
|
|
151
152
|
typeof args.max_output_size === 'number' && Number.isFinite(args.max_output_size)
|
|
152
153
|
? Math.min(1_000_000, Math.max(1_000, Math.trunc(args.max_output_size)))
|
|
153
154
|
: CALL_TOOL_CHAIN_MAX_OUTPUT;
|
|
154
|
-
const { result, logs } = await client.callToolChain(code, timeout);
|
|
155
|
+
const { result: rawResult, logs } = await client.callToolChain(code, timeout);
|
|
156
|
+
// Images never ride a chain result: the chain's value is stringified JSON,
|
|
157
|
+
// where base64 is context flood, not a picture. A chained `read_file` of an
|
|
158
|
+
// image comes back as an omitted-image note instead (see omitImagePayloads);
|
|
159
|
+
// the direct tool call is the sanctioned way to SEE an image.
|
|
160
|
+
const result = omitImagePayloads(rawResult, 'result');
|
|
155
161
|
// Bound the payload: an external session has no ambient workspace, so an
|
|
156
162
|
// oversized result spills to the shared store and we return only a ref —
|
|
157
163
|
// parity with the in-process agent's `call_tool_chain`.
|