@ggui-ai/mcp-server 0.24.0 → 0.26.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 +2 -2
- package/dist/api-renders-routes.d.ts +46 -5
- package/dist/api-renders-routes.d.ts.map +1 -1
- package/dist/api-renders-routes.js +98 -39
- package/dist/api-renders-stream-route.d.ts +2 -1
- package/dist/api-renders-stream-route.d.ts.map +1 -1
- package/dist/api-renders-stream-route.js +14 -2
- package/dist/build-mcp.d.ts +16 -0
- package/dist/build-mcp.d.ts.map +1 -1
- package/dist/build-mcp.js +82 -12
- package/dist/console-auth.d.ts +10 -10
- package/dist/console-auth.d.ts.map +1 -1
- package/dist/control-service.d.ts.map +1 -1
- package/dist/control-service.js +0 -3
- package/dist/first-seen.d.ts +14 -0
- package/dist/first-seen.d.ts.map +1 -0
- package/dist/first-seen.js +19 -0
- package/dist/ggui-session-channel/action-ingress.d.ts.map +1 -1
- package/dist/ggui-session-channel/action-ingress.js +96 -8
- package/dist/ggui-session-channel/channel-subscriptions.d.ts +0 -1
- package/dist/ggui-session-channel/channel-subscriptions.d.ts.map +1 -1
- package/dist/ggui-session-channel/channel-subscriptions.js +4 -1
- package/dist/ggui-session-channel/internal-types.d.ts +20 -12
- package/dist/ggui-session-channel/internal-types.d.ts.map +1 -1
- package/dist/ggui-session-channel/outbound.d.ts.map +1 -1
- package/dist/ggui-session-channel/outbound.js +18 -6
- package/dist/ggui-session-channel/stream-epoch.d.ts +61 -0
- package/dist/ggui-session-channel/stream-epoch.d.ts.map +1 -0
- package/dist/ggui-session-channel/stream-epoch.js +47 -0
- package/dist/ggui-session-channel/subscribe.d.ts +40 -53
- package/dist/ggui-session-channel/subscribe.d.ts.map +1 -1
- package/dist/ggui-session-channel/subscribe.js +288 -124
- package/dist/ggui-session-channel/subscriber-lifecycle.d.ts.map +1 -1
- package/dist/ggui-session-channel/subscriber-lifecycle.js +17 -7
- package/dist/ggui-session-channel.d.ts +43 -7
- package/dist/ggui-session-channel.d.ts.map +1 -1
- package/dist/ggui-session-channel.js +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/instructions-presets.d.ts +22 -21
- package/dist/instructions-presets.d.ts.map +1 -1
- package/dist/instructions-presets.js +38 -38
- package/dist/llm-backed-negotiator.d.ts +4 -37
- package/dist/llm-backed-negotiator.d.ts.map +1 -1
- package/dist/llm-backed-negotiator.js +28 -210
- package/dist/mcp-apps-outbound.d.ts +40 -91
- package/dist/mcp-apps-outbound.d.ts.map +1 -1
- package/dist/mcp-apps-outbound.js +100 -15
- package/dist/mcp-endpoint-routes.d.ts +1 -0
- package/dist/mcp-endpoint-routes.d.ts.map +1 -1
- package/dist/mcp-endpoint-routes.js +38 -4
- package/dist/runtime-bundle-hash.d.ts +7 -0
- package/dist/runtime-bundle-hash.d.ts.map +1 -1
- package/dist/runtime-bundle-hash.js +8 -2
- package/dist/runtime-bundle-route.d.ts.map +1 -1
- package/dist/runtime-bundle-route.js +15 -0
- package/dist/server.d.ts +143 -85
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +224 -110
- package/dist/storage.d.ts +9 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +4 -3
- package/dist/view-proof-gate.d.ts +96 -0
- package/dist/view-proof-gate.d.ts.map +1 -0
- package/dist/view-proof-gate.js +167 -0
- package/package.json +14 -15
- package/dist/render-read-gate.d.ts +0 -50
- package/dist/render-read-gate.d.ts.map +0 -1
- package/dist/render-read-gate.js +0 -36
|
@@ -25,11 +25,6 @@
|
|
|
25
25
|
* `ensureConformingContract`. Operational errors fail open; programmer
|
|
26
26
|
* errors re-throw. See `decide-handshake.ts` for the full contract.
|
|
27
27
|
*
|
|
28
|
-
* ## selectVariant
|
|
29
|
-
*
|
|
30
|
-
* The optional LLM-driven variant-selection seam is OSS-specific and
|
|
31
|
-
* stays on this binding (it is not part of the shared decide spine).
|
|
32
|
-
*
|
|
33
28
|
* ## Default binding
|
|
34
29
|
*
|
|
35
30
|
* Bound by default in `createGguiServer` when handshake is enabled AND a
|
|
@@ -70,18 +65,17 @@ export function buildLlmCaller(selection, providerKey, options = {}) {
|
|
|
70
65
|
},
|
|
71
66
|
};
|
|
72
67
|
if (isAnthropic) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
68
|
+
const metered = (systemPrompt, userMessage, tool, maxTokens) => anthropicCallStructured({
|
|
69
|
+
apiKey: providerKey.key,
|
|
70
|
+
model: selection.model,
|
|
71
|
+
systemPrompt,
|
|
72
|
+
userMessage,
|
|
73
|
+
tool,
|
|
74
|
+
maxTokens,
|
|
75
|
+
...(options.signal !== undefined ? { signal: options.signal } : {}),
|
|
76
|
+
});
|
|
77
|
+
caller.callStructuredMetered = metered;
|
|
78
|
+
caller.callStructured = async (systemPrompt, userMessage, tool, maxTokens) => (await metered(systemPrompt, userMessage, tool, maxTokens)).value;
|
|
85
79
|
}
|
|
86
80
|
return caller;
|
|
87
81
|
}
|
|
@@ -189,8 +183,10 @@ async function anthropicCallStructured(args) {
|
|
|
189
183
|
}
|
|
190
184
|
const stopReason = typeof json["stop_reason"] === "string" ? json["stop_reason"] : undefined;
|
|
191
185
|
const toolUse = json["content"].find((block) => isRecord(block) && block["type"] === "tool_use" && block["name"] === args.tool.name);
|
|
192
|
-
if (toolUse !== undefined && toolUse["input"] !== undefined)
|
|
193
|
-
|
|
186
|
+
if (toolUse !== undefined && toolUse["input"] !== undefined) {
|
|
187
|
+
const usage = readMessagesUsage(json["usage"]);
|
|
188
|
+
return { value: toolUse["input"], ...(usage !== undefined ? { usage } : {}) };
|
|
189
|
+
}
|
|
194
190
|
if (stopReason === "max_tokens") {
|
|
195
191
|
throw new AnthropicStructuredCallError("max_tokens", `stop_reason=max_tokens before the "${args.tool.name}" tool_use block (max_tokens=${body.max_tokens})`, { stopReason });
|
|
196
192
|
}
|
|
@@ -199,6 +195,19 @@ async function anthropicCallStructured(args) {
|
|
|
199
195
|
}
|
|
200
196
|
throw new AnthropicStructuredCallError("no_tool_call", `the turn ended (stop_reason=${stopReason ?? "absent"}) without a "${args.tool.name}" tool_use block`, stopReason !== undefined ? { stopReason } : {});
|
|
201
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* The token usage of a Messages response, as `{ input, output }`: its
|
|
200
|
+
* `usage.input_tokens` and `usage.output_tokens` when both are numbers,
|
|
201
|
+
* else absent (unmetered, never zeros — ggui#1418). No `cache_control` is
|
|
202
|
+
* sent on this call, so the cache token counts are not added.
|
|
203
|
+
*/
|
|
204
|
+
function readMessagesUsage(usage) {
|
|
205
|
+
if (!isRecord(usage))
|
|
206
|
+
return undefined;
|
|
207
|
+
const input = usage["input_tokens"];
|
|
208
|
+
const output = usage["output_tokens"];
|
|
209
|
+
return typeof input === "number" && typeof output === "number" ? { input, output } : undefined;
|
|
210
|
+
}
|
|
202
211
|
/**
|
|
203
212
|
* Build the handshake pool list: the per-app pool (from `cache`) first —
|
|
204
213
|
* so a deployment's own blueprints win on exact-key first-match — then
|
|
@@ -223,7 +232,6 @@ export function assembleHandshakePools(deps) {
|
|
|
223
232
|
* decision spine (find-similar → coverage guard → judge → atomic
|
|
224
233
|
* reuse, else synth-repair create) is shared verbatim across every
|
|
225
234
|
* negotiator binding; only the injected adapter differs.
|
|
226
|
-
* `selectVariant` is specific to this binding.
|
|
227
235
|
*
|
|
228
236
|
* @public
|
|
229
237
|
*/
|
|
@@ -259,195 +267,5 @@ export function createLlmBackedHandshakeNegotiator(deps) {
|
|
|
259
267
|
};
|
|
260
268
|
return {
|
|
261
269
|
decide: (input) => decideHandshake(adapter, input),
|
|
262
|
-
// LLM-driven variant selection. Reads each candidate's
|
|
263
|
-
// `variance` + `validatorScore` + `isOperatorDefault` + the
|
|
264
|
-
// provenance (`source`), asks the LLM to pick the best fit for
|
|
265
|
-
// the current request's `intent` + `variance`, and returns a
|
|
266
|
-
// calibrated decision. The caller (`selectVariantWithLlm`)
|
|
267
|
-
// thresholds on `confidence`.
|
|
268
|
-
//
|
|
269
|
-
// Errors throw — the caller catches and falls through to the
|
|
270
|
-
// deterministic ladder. The decide() seam uses a more permissive
|
|
271
|
-
// fail-open pattern because there's no fallback higher up; the
|
|
272
|
-
// variant-selector caller owns the fallback path itself.
|
|
273
|
-
async selectVariant({ candidates, context, ctx }) {
|
|
274
|
-
if (candidates.length === 0) {
|
|
275
|
-
throw new Error("selectVariant: empty candidates list — orchestration should short-circuit before calling");
|
|
276
|
-
}
|
|
277
|
-
const creds = await deps.resolveLlm(ctx);
|
|
278
|
-
if (!creds) {
|
|
279
|
-
throw new Error("selectVariant: no BYOK credentials resolved; orchestration falls through to deterministic ladder");
|
|
280
|
-
}
|
|
281
|
-
const llm = buildLlmCaller(creds.selection, creds.providerKey);
|
|
282
|
-
return runVariantSelectionLlm(llm, candidates, context);
|
|
283
|
-
},
|
|
284
270
|
};
|
|
285
271
|
}
|
|
286
|
-
/**
|
|
287
|
-
* The system prompt for the variant-selection LLM call. Calibration
|
|
288
|
-
* is load-bearing — the model is explicitly told to surface low
|
|
289
|
-
* confidence when signals are weak so the deterministic-ladder
|
|
290
|
-
* fallback takes over. The prompt is intentionally short: high
|
|
291
|
-
* token budget on the user message (candidate JSON) is more useful
|
|
292
|
-
* than verbose system framing.
|
|
293
|
-
*/
|
|
294
|
-
export const VARIANT_SELECTION_SYSTEM_PROMPT = `You are the variant selector for the ggui UI matcher. You receive a shortlist of pre-built UI blueprint variants and a request context. Pick the variant that best fits the request.
|
|
295
|
-
|
|
296
|
-
Each variant carries:
|
|
297
|
-
- blueprintId: stable identity (you MUST echo back exactly one of these).
|
|
298
|
-
- source: provenance. {kind:"llm", generator, model} = engine-generated (advanced generators win on visual polish; default generators win on simplicity). {kind:"user"} = operator-registered hand-authored code. {kind:"curated"} = catalog-shipped system blueprint.
|
|
299
|
-
- validatorScore: optional 0-1 self-assessed quality from the advanced generator's validators. Higher is better, undefined ⇒ unknown.
|
|
300
|
-
- isOperatorDefault: true ⇒ the human operator pinned this as the default. Strong signal.
|
|
301
|
-
- variance.persona: free-form tag ("minimalist", "data-dense", "mobile-first"…).
|
|
302
|
-
- variance.aesthetic: optional free-form tag ("glassy", "flat", "editorial"…).
|
|
303
|
-
- variance.context: small structured signal (theme, accent, …).
|
|
304
|
-
- variance.seedPrompt: the operator's original prose that produced this variant.
|
|
305
|
-
|
|
306
|
-
The request context carries the same fields. Match on:
|
|
307
|
-
1. variance.persona equality / closeness (strongest non-pin signal).
|
|
308
|
-
2. variance.aesthetic equality / closeness.
|
|
309
|
-
3. variance.context overlap (shared keys + values).
|
|
310
|
-
4. seedPrompt semantic similarity to context.intent.
|
|
311
|
-
|
|
312
|
-
Honor operator pins (isOperatorDefault: true) unless variance.persona / variance.aesthetic on the request clearly contradicts the pinned variant — that's the only case where you should override the pin.
|
|
313
|
-
|
|
314
|
-
Calibrate confidence honestly. Return high (≥ 0.7) only when a clear best match exists. Return low (< 0.6) when signals are weak — the orchestration falls back to a deterministic ladder in that case. The fallback is safe; over-confident picks are NOT.`;
|
|
315
|
-
const VARIANT_SELECTION_TOOL_NAME = "select_variant";
|
|
316
|
-
const VARIANT_SELECTION_TOOL_DESCRIPTION = "Pick the variant that best fits the request context. Return the chosen blueprintId, a calibrated 0-1 confidence, and a one-sentence reason citing the matching axes (persona / aesthetic / context / seedPrompt / pin / validator).";
|
|
317
|
-
/**
|
|
318
|
-
* JSON Schema for the structured-output tool call. Forces the model
|
|
319
|
-
* to emit `{blueprintId, confidence, reason}` — no free-text prose.
|
|
320
|
-
* Used on Anthropic via `LLMCaller.callStructured`; the text-fallback
|
|
321
|
-
* path parses the same shape from regex-extracted JSON.
|
|
322
|
-
*/
|
|
323
|
-
const VARIANT_SELECTION_TOOL_SCHEMA = {
|
|
324
|
-
type: "object",
|
|
325
|
-
properties: {
|
|
326
|
-
blueprintId: {
|
|
327
|
-
type: "string",
|
|
328
|
-
description: "One of the candidate blueprintIds shown in the request. Echo exactly — must match a candidate.",
|
|
329
|
-
},
|
|
330
|
-
confidence: {
|
|
331
|
-
type: "number",
|
|
332
|
-
minimum: 0,
|
|
333
|
-
maximum: 1,
|
|
334
|
-
description: "Calibrated confidence in this pick on [0, 1]. Use < 0.6 when signals are weak; the orchestration falls back to a deterministic ladder.",
|
|
335
|
-
},
|
|
336
|
-
reason: {
|
|
337
|
-
type: "string",
|
|
338
|
-
description: "One-sentence rationale citing the matching axes (persona, aesthetic, context, seedPrompt, validator, pin).",
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
required: ["blueprintId", "confidence", "reason"],
|
|
342
|
-
};
|
|
343
|
-
/**
|
|
344
|
-
* Build the user-message payload for the variant-selection prompt.
|
|
345
|
-
* The candidate list is projected to a compact JSON shape that
|
|
346
|
-
* surfaces the decision-relevant fields only — full contract
|
|
347
|
-
* embedding is too much surface area for a sub-second pick.
|
|
348
|
-
*
|
|
349
|
-
* Exposed for testing — the prompt structure is load-bearing, so
|
|
350
|
-
* snapshot tests against this output anchor regressions.
|
|
351
|
-
*/
|
|
352
|
-
export function buildVariantSelectionUserMessage(candidates, context) {
|
|
353
|
-
const projectedCandidates = candidates.map((c) => ({
|
|
354
|
-
blueprintId: c.blueprintId,
|
|
355
|
-
source: c.source,
|
|
356
|
-
...(c.validatorScore !== undefined ? { validatorScore: c.validatorScore } : {}),
|
|
357
|
-
...(c.isOperatorDefault === true ? { isOperatorDefault: true } : {}),
|
|
358
|
-
variance: {
|
|
359
|
-
...(c.variance.persona !== undefined ? { persona: c.variance.persona } : {}),
|
|
360
|
-
...(c.variance.context !== undefined ? { context: c.variance.context } : {}),
|
|
361
|
-
...(c.variance.seedPrompt !== undefined ? { seedPrompt: c.variance.seedPrompt } : {}),
|
|
362
|
-
},
|
|
363
|
-
}));
|
|
364
|
-
const requestProjection = {
|
|
365
|
-
contractHash: context.contractHash,
|
|
366
|
-
...(context.intent !== undefined ? { intent: context.intent } : {}),
|
|
367
|
-
...(context.variance !== undefined
|
|
368
|
-
? {
|
|
369
|
-
variance: {
|
|
370
|
-
...(context.variance.persona !== undefined
|
|
371
|
-
? { persona: context.variance.persona }
|
|
372
|
-
: {}),
|
|
373
|
-
...(context.variance.aesthetic !== undefined
|
|
374
|
-
? { aesthetic: context.variance.aesthetic }
|
|
375
|
-
: {}),
|
|
376
|
-
...(context.variance.context !== undefined
|
|
377
|
-
? { context: context.variance.context }
|
|
378
|
-
: {}),
|
|
379
|
-
...(context.variance.seedPrompt !== undefined
|
|
380
|
-
? { seedPrompt: context.variance.seedPrompt }
|
|
381
|
-
: {}),
|
|
382
|
-
},
|
|
383
|
-
}
|
|
384
|
-
: {}),
|
|
385
|
-
};
|
|
386
|
-
return [
|
|
387
|
-
"CANDIDATES:",
|
|
388
|
-
JSON.stringify(projectedCandidates, null, 2),
|
|
389
|
-
"",
|
|
390
|
-
"REQUEST:",
|
|
391
|
-
JSON.stringify(requestProjection, null, 2),
|
|
392
|
-
"",
|
|
393
|
-
"Pick the variant that best fits the REQUEST. Echo the blueprintId exactly, surface calibrated confidence, give a one-sentence rationale.",
|
|
394
|
-
].join("\n");
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Run the LLM call + decode. Anthropic path uses `callStructured`
|
|
398
|
-
* (forced tool use ⇒ guaranteed JSON); other providers fall back to
|
|
399
|
-
* text + regex-extracted JSON. The caller (`selectVariantWithLlm`)
|
|
400
|
-
* catches any throw from this function and routes through the
|
|
401
|
-
* deterministic ladder; this function surfaces detail in the thrown
|
|
402
|
-
* error so telemetry can attribute the fallback cause.
|
|
403
|
-
*/
|
|
404
|
-
async function runVariantSelectionLlm(llm, candidates, context) {
|
|
405
|
-
const userMessage = buildVariantSelectionUserMessage(candidates, context);
|
|
406
|
-
if (llm.callStructured) {
|
|
407
|
-
const decoded = await llm.callStructured(VARIANT_SELECTION_SYSTEM_PROMPT, userMessage, {
|
|
408
|
-
name: VARIANT_SELECTION_TOOL_NAME,
|
|
409
|
-
description: VARIANT_SELECTION_TOOL_DESCRIPTION,
|
|
410
|
-
input_schema: VARIANT_SELECTION_TOOL_SCHEMA,
|
|
411
|
-
}, 512);
|
|
412
|
-
return parseVariantSelectionResponse(decoded);
|
|
413
|
-
}
|
|
414
|
-
// Text-fallback — parse JSON via regex. Lower reliability;
|
|
415
|
-
// operators on non-Anthropic providers get this path until
|
|
416
|
-
// `callStructured` extends to their adapter.
|
|
417
|
-
const text = await llm.call(VARIANT_SELECTION_SYSTEM_PROMPT, `${userMessage}\n\nRespond as ONE LINE of JSON: {"blueprintId":"…","confidence":0.0-1.0,"reason":"…"}`, 512);
|
|
418
|
-
const match = text.match(/\{[\s\S]*?"blueprintId"[\s\S]*?\}/);
|
|
419
|
-
if (!match) {
|
|
420
|
-
throw new Error(`variant-selection: no JSON object found in text response (length ${text.length})`);
|
|
421
|
-
}
|
|
422
|
-
return parseVariantSelectionResponse(JSON.parse(match[0]));
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Parse + validate the LLM-tool-use response shape. Exposed for
|
|
426
|
-
* testing; in production it is only called via `runVariantSelectionLlm`.
|
|
427
|
-
*
|
|
428
|
-
* @throws Error on any shape violation. The caller catches and falls
|
|
429
|
-
* through to the deterministic ladder; the message is surfaced in
|
|
430
|
-
* `VariantSelectionResult.reason` for telemetry.
|
|
431
|
-
*/
|
|
432
|
-
export function parseVariantSelectionResponse(raw) {
|
|
433
|
-
if (!isRecord(raw)) {
|
|
434
|
-
throw new Error("variant-selection: response is not an object");
|
|
435
|
-
}
|
|
436
|
-
const obj = raw;
|
|
437
|
-
const blueprintId = obj["blueprintId"];
|
|
438
|
-
const confidence = obj["confidence"];
|
|
439
|
-
const reason = obj["reason"];
|
|
440
|
-
if (typeof blueprintId !== "string" || blueprintId.length === 0) {
|
|
441
|
-
throw new Error("variant-selection: blueprintId missing or non-string");
|
|
442
|
-
}
|
|
443
|
-
if (typeof confidence !== "number" ||
|
|
444
|
-
!Number.isFinite(confidence) ||
|
|
445
|
-
confidence < 0 ||
|
|
446
|
-
confidence > 1) {
|
|
447
|
-
throw new Error(`variant-selection: confidence missing or out of range: ${JSON.stringify(confidence)}`);
|
|
448
|
-
}
|
|
449
|
-
if (typeof reason !== "string") {
|
|
450
|
-
throw new Error("variant-selection: reason missing or non-string");
|
|
451
|
-
}
|
|
452
|
-
return { blueprintId, confidence, reason };
|
|
453
|
-
}
|
|
@@ -364,6 +364,12 @@ export interface SelfContainedShellInputs {
|
|
|
364
364
|
* route uses, so both transports share replay-cache state.
|
|
365
365
|
*/
|
|
366
366
|
readonly token?: string;
|
|
367
|
+
/**
|
|
368
|
+
* The view key rooted in {@link token} (ggui#1415), inlined as the
|
|
369
|
+
* slice's `viewKey` beside `wsToken`. Only a key-issuing mount sets it;
|
|
370
|
+
* it is dropped without a token.
|
|
371
|
+
*/
|
|
372
|
+
readonly viewKey?: string;
|
|
367
373
|
/**
|
|
368
374
|
* ISO-8601 expiry of {@link token}. Past-due envelopes degrade to
|
|
369
375
|
* static-only mode at parse time; the static UI still mounts, but
|
|
@@ -666,10 +672,43 @@ export interface GguiRenderResourceTemplateOptions {
|
|
|
666
672
|
readonly token: string;
|
|
667
673
|
readonly expiresAt: string;
|
|
668
674
|
};
|
|
675
|
+
/**
|
|
676
|
+
* The key-issuing minter (ggui#1415): the same live credential as
|
|
677
|
+
* {@link mintWsToken}, minted as a view root, with the view key rooted in
|
|
678
|
+
* it (`undefined` when the root is too long to key). The read door mints
|
|
679
|
+
* through it only when it issues the key (see {@link issueViewKeys});
|
|
680
|
+
* every other read mints through {@link mintWsToken}, so a token that
|
|
681
|
+
* carries `kid` and `src` always had a key issued with it. Ignored
|
|
682
|
+
* without {@link mintWsToken}.
|
|
683
|
+
*/
|
|
684
|
+
readonly mintViewRoot?: (sessionId: string, appId: string) => {
|
|
685
|
+
readonly wsUrl: string;
|
|
686
|
+
readonly token: string;
|
|
687
|
+
readonly expiresAt: string;
|
|
688
|
+
readonly viewKey: string | undefined;
|
|
689
|
+
};
|
|
690
|
+
/**
|
|
691
|
+
* Whether this mount's read door may issue a view key (ggui#1415). Only
|
|
692
|
+
* the data plane, which delivers a view to an app-credentialed caller,
|
|
693
|
+
* sets it; `/control` and the isolated services never do. Even there no
|
|
694
|
+
* key is issued when the caller's `authSource` is `anonymous` or absent:
|
|
695
|
+
* such a caller resolves to the builder app and would pass the read gate
|
|
696
|
+
* on every builder-app row. A read that issues no key mints the live
|
|
697
|
+
* credential alone and says why (`view_key_not_issued`).
|
|
698
|
+
*
|
|
699
|
+
* An auth adapter that admits every caller as one identity (the
|
|
700
|
+
* development `InMemoryAuthAdapter({ devAllowAll: true })`, source `dev`)
|
|
701
|
+
* is not an anonymous mount: its callers are keyed, so the view runs its
|
|
702
|
+
* proof end to end in development. There every caller holds the same
|
|
703
|
+
* identity, so a `valid` verdict says the plumbing works and nothing
|
|
704
|
+
* about who signed; the gate's line carries `authSource`, which keeps
|
|
705
|
+
* those verdicts apart from a credentialed deployment's.
|
|
706
|
+
*/
|
|
707
|
+
readonly issueViewKeys?: boolean;
|
|
669
708
|
/**
|
|
670
709
|
* Per-request handler-context accessor — the SAME AsyncLocalStorage
|
|
671
710
|
* read the tool path uses. The per-session resource handler gates
|
|
672
|
-
* reads on it (
|
|
711
|
+
* reads on it (`renderReadAllowed`, in @ggui-ai/mcp-server-handlers/renders). Absent ⇒ the handler fails
|
|
673
712
|
* closed for rows scoped to any app other than the single-app
|
|
674
713
|
* default (compose paths that cannot thread a context keep working
|
|
675
714
|
* for OSS single-app flows only).
|
|
@@ -682,96 +721,6 @@ export interface GguiRenderResourceTemplateOptions {
|
|
|
682
721
|
*/
|
|
683
722
|
readonly logger?: Logger;
|
|
684
723
|
}
|
|
685
|
-
/**
|
|
686
|
-
* Register a `ui://ggui/render/{sessionId}` resource template. Each
|
|
687
|
-
* `resources/read` request is resolved by looking up the render in the
|
|
688
|
-
* store and returning the self-contained shell with that
|
|
689
|
-
* componentCode inlined.
|
|
690
|
-
*
|
|
691
|
-
* Per-call `_meta.ui.resourceUri` (stamped by `ggui_render.resultMeta`)
|
|
692
|
-
* pins the URI to a specific sessionId; hosts fetch THAT URI rather
|
|
693
|
-
* than the static `ui://ggui/render` one. Both registrations co-exist:
|
|
694
|
-
* legacy postMessage shell at the static URI, self-contained shell at
|
|
695
|
-
* the templated URI.
|
|
696
|
-
*
|
|
697
|
-
* # The obligation
|
|
698
|
-
*
|
|
699
|
-
* A read returns EITHER a shell carrying mount material — a static
|
|
700
|
-
* component URL, a live channel, or a system card — OR exactly one
|
|
701
|
-
* typed JSON-RPC error. There is no third outcome, and in particular no
|
|
702
|
-
* successful result wrapping a shell that can never paint anything. A
|
|
703
|
-
* host can check this without trusting the server: if it got
|
|
704
|
-
* `contents`, it got something mountable.
|
|
705
|
-
*
|
|
706
|
-
* The obligation covers outcomes this server can DECIDE. A malfunction
|
|
707
|
-
* still reaches the caller as an internal error (`-32603`) carrying
|
|
708
|
-
* none of the four codes: a template wired with an empty `runtimeUrl`,
|
|
709
|
-
* or a delivery channel that faults **and leaves the read with no other
|
|
710
|
-
* channel to mount through**. A fault the read survives — the usual
|
|
711
|
-
* case on a deployment wiring both channels — is not an outcome at all;
|
|
712
|
-
* the render mounts through whatever is left. That split is deliberate:
|
|
713
|
-
* `-32603` says "something is broken here", which the four codes must
|
|
714
|
-
* never be diluted into claiming, and equally must not be raised over a
|
|
715
|
-
* blip the server routed around.
|
|
716
|
-
*
|
|
717
|
-
* Three resolutions are tried, in this order, and any of them can
|
|
718
|
-
* produce the mount:
|
|
719
|
-
*
|
|
720
|
-
* 1. The render row itself.
|
|
721
|
-
* 2. A re-mint from the durable identity record, when the row is gone
|
|
722
|
-
* and this server keeps one ({@link GguiRenderResourceTemplateOptions.renderIdentityStore}
|
|
723
|
-
* + {@link GguiRenderResourceTemplateOptions.durableBlueprints}).
|
|
724
|
-
* 3. The blueprint registry, keyed by the locator's own `blueprintKey`
|
|
725
|
-
* — the original component with its authoring-time defaults rather
|
|
726
|
-
* than the state the render last held.
|
|
727
|
-
*
|
|
728
|
-
* # Failure modes
|
|
729
|
-
*
|
|
730
|
-
* Which code a given read produces is fully predictable from two facts:
|
|
731
|
-
* whether this server binds a durable substrate (both
|
|
732
|
-
* {@link GguiRenderResourceTemplateOptions.renderIdentityStore} and
|
|
733
|
-
* {@link GguiRenderResourceTemplateOptions.durableBlueprints} — either
|
|
734
|
-
* one alone is as good as neither), and how far the read got.
|
|
735
|
-
*
|
|
736
|
-
* - `NOT_FOUND` (`-32002`) — nothing resolved the locator, **and** the
|
|
737
|
-
* response for a caller who may not read a locator that DOES
|
|
738
|
-
* resolve. Those two are byte-identical by construction: both route
|
|
739
|
-
* through the protocol's projection, which substitutes a constant
|
|
740
|
-
* message and drops `detail`. A distinguishable refusal would turn
|
|
741
|
-
* this read into an oracle for the existence of other callers'
|
|
742
|
-
* renders, so the equality is a security property, not a courtesy.
|
|
743
|
-
* - `NOT_SUPPORTED` (`-32006`) — the same two cases, on a server with
|
|
744
|
-
* no durable substrate: an evicted locator can never be restored
|
|
745
|
-
* here, so saying "not found" would understate it. It takes
|
|
746
|
-
* `NOT_FOUND`'s place WHOLESALE on such a server rather than
|
|
747
|
-
* answering for some locators and not others — a server that said
|
|
748
|
-
* `NOT_FOUND` for a row it refused and `NOT_SUPPORTED` for one that
|
|
749
|
-
* never existed would have rebuilt the same oracle out of the two
|
|
750
|
-
* codes. Correspondingly, a server that DOES bind the substrate
|
|
751
|
-
* never emits it.
|
|
752
|
-
* - `BLUEPRINT_UNRESOLVABLE` (`-32006`) — a record named the render
|
|
753
|
-
* but its component is gone; `detail` names which link broke.
|
|
754
|
-
* Reachable only after the access check.
|
|
755
|
-
* - `NOT_MOUNTABLE` (`-32006`) — something resolved, but nothing
|
|
756
|
-
* mountable can be produced from it: no delivery channel is wired
|
|
757
|
-
* (neither {@link GguiRenderResourceTemplateOptions.codeStore} nor
|
|
758
|
-
* {@link GguiRenderResourceTemplateOptions.mintWsToken}), the row's
|
|
759
|
-
* generation has not committed a component yet, or a registry
|
|
760
|
-
* blueprint matched but cannot be delivered. Unlike the pair above,
|
|
761
|
-
* this one does NOT vary with the substrate: it is what the
|
|
762
|
-
* caller's OWN row gets on every server, because "this server
|
|
763
|
-
* cannot rehydrate" is not the useful truth for a row that is
|
|
764
|
-
* sitting right there. Reachable only after the access check, or —
|
|
765
|
-
* for the registry case — off the caller's own supplied key, so it
|
|
766
|
-
* discloses nothing either way.
|
|
767
|
-
*
|
|
768
|
-
* A URI matching neither template never reaches any of this: the
|
|
769
|
-
* transport rejects it as invalid params, outside these four codes.
|
|
770
|
-
*
|
|
771
|
-
* Returns nothing; mutates the server in place.
|
|
772
|
-
*
|
|
773
|
-
* @public
|
|
774
|
-
*/
|
|
775
724
|
export declare function registerGguiRenderResourceTemplate(server: McpServer, opts: GguiRenderResourceTemplateOptions): void;
|
|
776
725
|
/**
|
|
777
726
|
* Apply the full MCP Apps outbound wiring to a fresh `McpServer` - both
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-apps-outbound.d.ts","sourceRoot":"","sources":["../src/mcp-apps-outbound.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAEhB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAWL,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACpB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAiB,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAmBjF,OAAO,
|
|
1
|
+
{"version":3,"file":"mcp-apps-outbound.d.ts","sourceRoot":"","sources":["../src/mcp-apps-outbound.ts"],"names":[],"mappings":"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"}
|