@ggui-ai/mcp-server 0.7.0 → 0.9.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/dist/api-renders-routes.d.ts.map +1 -1
- package/dist/api-renders-routes.js +32 -23
- package/dist/api-renders-stream-route.d.ts +80 -0
- package/dist/api-renders-stream-route.d.ts.map +1 -0
- package/dist/api-renders-stream-route.js +311 -0
- package/dist/build-mcp.d.ts +10 -0
- package/dist/build-mcp.d.ts.map +1 -1
- package/dist/build-mcp.js +64 -4
- package/dist/console-session-routes.d.ts +10 -5
- package/dist/console-session-routes.d.ts.map +1 -1
- package/dist/console-session-routes.js +21 -5
- package/dist/ggui-session-channel/action-ingress.d.ts +2 -2
- package/dist/ggui-session-channel/action-ingress.d.ts.map +1 -1
- package/dist/ggui-session-channel/channel-subscriptions.d.ts +4 -4
- package/dist/ggui-session-channel/channel-subscriptions.d.ts.map +1 -1
- package/dist/ggui-session-channel/internal-types.d.ts +63 -9
- package/dist/ggui-session-channel/internal-types.d.ts.map +1 -1
- package/dist/ggui-session-channel/outbound.d.ts +15 -5
- package/dist/ggui-session-channel/outbound.d.ts.map +1 -1
- package/dist/ggui-session-channel/outbound.js +64 -24
- package/dist/ggui-session-channel/socket-router.d.ts +8 -3
- package/dist/ggui-session-channel/socket-router.d.ts.map +1 -1
- package/dist/ggui-session-channel/socket-router.js +6 -1
- package/dist/ggui-session-channel/subscribe.d.ts +48 -3
- package/dist/ggui-session-channel/subscribe.d.ts.map +1 -1
- package/dist/ggui-session-channel/subscribe.js +97 -36
- package/dist/ggui-session-channel/subscriber-lifecycle.d.ts +23 -13
- package/dist/ggui-session-channel/subscriber-lifecycle.d.ts.map +1 -1
- package/dist/ggui-session-channel/subscriber-lifecycle.js +24 -11
- package/dist/ggui-session-channel.d.ts +58 -11
- package/dist/ggui-session-channel.d.ts.map +1 -1
- package/dist/ggui-session-channel.js +55 -19
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/instructions-presets.js +10 -10
- package/dist/mcp-apps-outbound.d.ts +93 -4
- package/dist/mcp-apps-outbound.d.ts.map +1 -1
- package/dist/mcp-apps-outbound.js +460 -105
- package/dist/mcp-endpoint-routes.d.ts +17 -5
- package/dist/mcp-endpoint-routes.d.ts.map +1 -1
- package/dist/mcp-endpoint-routes.js +2 -0
- package/dist/oauth-as-routes.d.ts.map +1 -1
- package/dist/oauth-as-routes.js +36 -0
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +8 -1
- package/dist/runtime-bundle-hash.d.ts +43 -0
- package/dist/runtime-bundle-hash.d.ts.map +1 -0
- package/dist/runtime-bundle-hash.js +66 -0
- package/dist/runtime-bundle-route.d.ts +15 -0
- package/dist/runtime-bundle-route.d.ts.map +1 -1
- package/dist/runtime-bundle-route.js +21 -5
- package/dist/server.d.ts +83 -14
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +167 -15
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -30,9 +30,10 @@ export type { GadgetDescriptor, McpUiDisplayMode, GguiSession, SystemGguiSession
|
|
|
30
30
|
export type { GenerationDeps } from '@ggui-ai/mcp-server-handlers';
|
|
31
31
|
export { buildNoCredentialsGguiSession } from '@ggui-ai/mcp-server-handlers';
|
|
32
32
|
export { buildOpsBundleHandlers, createGguiServer, defaultHandlers } from './server.js';
|
|
33
|
-
export type { CreateGguiServerOptions, GguiServer, OpsBundleDeps, } from './server.js';
|
|
33
|
+
export type { CreateGguiServerOptions, ErrorMapperResult, GguiServer, OpsBundleDeps, } from './server.js';
|
|
34
34
|
export { buildControlService, CONTROL_PATH, filterHandlersByAudience, SINGLE_CALL_OPS, } from './control-service.js';
|
|
35
35
|
export type { AudienceTag, BuildControlServiceArgs } from './control-service.js';
|
|
36
|
+
export { computeRuntimeBundleHash, insertRuntimeBundleHash, resolveHashedRuntimeBundleUrl, } from './runtime-bundle-hash.js';
|
|
36
37
|
export { FileSystemCodeStore } from './code-store-fs.js';
|
|
37
38
|
export type { FileSystemCodeStoreOptions } from './code-store-fs.js';
|
|
38
39
|
export type { McpServerMount } from './mcp-mounts.js';
|
|
@@ -45,8 +46,8 @@ export type { ServerInfo } from './build-mcp.js';
|
|
|
45
46
|
export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
|
|
46
47
|
export { createConsoleLogger } from './logger.js';
|
|
47
48
|
export type { Logger } from './logger.js';
|
|
48
|
-
export { createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
49
|
-
export type { GguiSessionChannelOptions, GguiSessionChannelServer, } from './ggui-session-channel.js';
|
|
49
|
+
export { ChannelSessionNotFoundError, createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
50
|
+
export type { GguiSessionChannelOptions, GguiSessionChannelServer, SubscriberSink, } from './ggui-session-channel.js';
|
|
50
51
|
export { resolveStorageFromConfig } from './storage.js';
|
|
51
52
|
export type { ResolveStorageFromConfigOptions, ResolvedStorageStores, } from './storage.js';
|
|
52
53
|
export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAKlF,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAKnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACxF,YAAY,EACV,uBAAuB,EACvB,UAAU,EACV,aAAa,GACd,MAAM,aAAa,CAAC;AAMrB,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,wBAAwB,EACxB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,12 @@ export { buildOpsBundleHandlers, createGguiServer, defaultHandlers } from './ser
|
|
|
37
37
|
// mounts it automatically; the pieces are exported so deployments can
|
|
38
38
|
// assert their own control surface at boot.
|
|
39
39
|
export { buildControlService, CONTROL_PATH, filterHandlersByAudience, SINGLE_CALL_OPS, } from './control-service.js';
|
|
40
|
+
// Content-hashed runtime-bundle URL naming (#472). `createGguiServer`
|
|
41
|
+
// stamps the hashed name itself; these are exported for deployments
|
|
42
|
+
// that compose their own render handler (replacing the factory's
|
|
43
|
+
// default set) and therefore mint an absolute `runtimeUrl` directly —
|
|
44
|
+
// one derivation, no drift against the route the factory mounts.
|
|
45
|
+
export { computeRuntimeBundleHash, insertRuntimeBundleHash, resolveHashedRuntimeBundleUrl, } from './runtime-bundle-hash.js';
|
|
40
46
|
// Content-addressable code delivery (2026-05-03). FileSystemCodeStore
|
|
41
47
|
// is the OSS dev default; in-memory variant ships in
|
|
42
48
|
// `@ggui-ai/mcp-server-core/in-memory` for tests + ephemeral runs.
|
|
@@ -56,7 +62,7 @@ export { composePreviewReservedValidator, mergeReservedValidators, } from './res
|
|
|
56
62
|
export { checkRenderSchemaCompat, DEFAULT_SCHEMA_COMPAT_MODE, hasErrorFinding, SchemaCompatError, } from './schema-compat.js';
|
|
57
63
|
export { UnauthenticatedError, DEFAULT_BUILDER_APP_ID, defaultAppIdFromIdentity, } from './auth.js';
|
|
58
64
|
export { createConsoleLogger } from './logger.js';
|
|
59
|
-
export { createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
65
|
+
export { ChannelSessionNotFoundError, createGguiSessionChannelServer, DEFAULT_RENDER_CHANNEL_PATH, } from './ggui-session-channel.js';
|
|
60
66
|
export { resolveStorageFromConfig } from './storage.js';
|
|
61
67
|
export { DEFAULT_PAIRING_ADMIN_INIT_PATH, DEFAULT_PAIRING_PATH, mountPairingTransport, } from './pairing-transport.js';
|
|
62
68
|
// End-user browser-session cookie + login routes. Cookie + endpoints
|
|
@@ -64,7 +64,7 @@ const DEFAULT_PRESET_BODY = [
|
|
|
64
64
|
'',
|
|
65
65
|
'Every UI you render is described by a DataContract — a typed declaration of four data surfaces. You author the contract at handshake time; the contract is what the renderer compiles + the agent later interacts with. Four specs, each with one job:',
|
|
66
66
|
'',
|
|
67
|
-
' • propsSpec — agent → client (one-shot data). The initial values the rendered UI displays. Push sends these as `props`; ggui_update
|
|
67
|
+
' • propsSpec — agent → client (one-shot data). The initial values the rendered UI displays. Push sends these as `props`; ggui_amend / ggui_update mutate them after delivery. e.g. a weather card has {temperature, condition, city} on propsSpec.',
|
|
68
68
|
'',
|
|
69
69
|
' • actionSpec — client → agent (discrete events). User gestures (clicks, submits) that drive the agent\'s NEXT TURN. Each entry has a `label`, optional `schema` for the payload, and optional `nextStep: "<toolName>"`. When `nextStep` is present, it names the tool the agent SHOULD call next AND the same name MUST also appear in `agentCapabilities.tools` (cross-ref invariant; rejection code `cross_reference_unresolved`). Omit `nextStep` entirely when the agent should decide freely from broader context (open-ended form submits). e.g. a feedback form has `submit` on actionSpec with `nextStep:"record_feedback"` (and `record_feedback` listed under `agentCapabilities.tools`).',
|
|
70
70
|
'',
|
|
@@ -80,8 +80,8 @@ const DEFAULT_PRESET_BODY = [
|
|
|
80
80
|
'',
|
|
81
81
|
'TOOL PREREQUISITES (read once, internalize):',
|
|
82
82
|
' • `ggui_handshake` is a prerequisite for `ggui_render` ONLY. It returns the contract+code negotiation state (`handshakeId`) that `ggui_render` consumes. Call it BEFORE rendering a NEW UI.',
|
|
83
|
-
' • `ggui_consume` and `ggui_update` operate on EXISTING sessions identified by `sessionId` and require NO handshake. The `sessionId` was minted by an earlier `ggui_render` call; it identifies the live iframe the user is interacting with. Calling `ggui_handshake` before `ggui_consume`/`ggui_update` is a category error — it would mint a SEPARATE new session that the user can\'t see, orphaning whichever live iframe the gesture targeted.',
|
|
84
|
-
' • Each `sessionId` is the agent\'s persistent handle to one specific live iframe. Reuse it across consume/update for as long as the user is interacting with that UI; only call `ggui_handshake` again when you need to spawn a genuinely new UI surface.',
|
|
83
|
+
' • `ggui_consume`, `ggui_amend`, and `ggui_update` operate on EXISTING sessions identified by `sessionId` and require NO handshake. The `sessionId` was minted by an earlier `ggui_render` call; it identifies the live iframe the user is interacting with. Calling `ggui_handshake` before `ggui_consume`/`ggui_amend`/`ggui_update` is a category error — it would mint a SEPARATE new session that the user can\'t see, orphaning whichever live iframe the gesture targeted.',
|
|
84
|
+
' • Each `sessionId` is the agent\'s persistent handle to one specific live iframe. Reuse it across consume/amend/update for as long as the user is interacting with that UI; only call `ggui_handshake` again when you need to spawn a genuinely new UI surface.',
|
|
85
85
|
'',
|
|
86
86
|
' 1. ggui_handshake — FIRST CALL for any UI. Negotiate a contract for the next render. Post {intent, blueprintDraft: {contract, variance?, generator?}}. `variance` is optional and steers cache lookup + gen by axis: `persona` ("minimalist", "playful"), `aesthetic` ("dense", "spacious"), `seedPrompt` (deterministic seed). HANDSHAKE IS FORGIVING — it ALWAYS returns a handshakeId + a CONFORMING contract, even when your draft is malformed: the server cache-matches an existing blueprint OR repairs your draft until it passes validation. The suggestion carries origin: cache (an existing blueprint matched — delivered instantly) | agent (your draft was already clean) | synth (your draft had problems and the server repaired it; `suggestion.validationFindings` lists exactly what was wrong so you learn for next time). CRITICAL: a synth result is NOT an error and NOT a request to retry — the returned contract is READY. Accept it and call ggui_render. Do NOT re-call ggui_handshake hoping for a different origin — that is a loop that wastes turns and changes nothing.',
|
|
87
87
|
'',
|
|
@@ -89,9 +89,9 @@ const DEFAULT_PRESET_BODY = [
|
|
|
89
89
|
'',
|
|
90
90
|
' 3. NEXT STEP — read the render response. If it carries a `nextStep` field, call that tool with the given args. Render only emits `nextStep` when the contract declared a non-empty actionSpec (i.e., the UI has interactive buttons/forms); in that case nextStep names ggui_consume and your job is to long-poll for the user\'s gesture. If the render response has NO nextStep, the UI is pure-display (props only, no actionSpec) — you can end your turn; the user reads the UI and types their next prompt when they\'re ready.',
|
|
91
91
|
'',
|
|
92
|
-
' 4. ggui_consume (when render said to) — long-poll for user interaction. Keyed by sessionId.
|
|
92
|
+
' 4. ggui_consume (when render said to) — long-poll for user interaction. Keyed by sessionId. Pass `timeout: 25` — each call long-polls up to 25 seconds (the server-enforced per-call cap; the default is 0, an instant non-blocking drain) and returns when an actionSpec event arrives or the window lapses. On an empty `events` array you may re-call once, then end your turn — when nobody is polling, a user gesture rings the chat as a new user message carrying its own consume directive. Each return carries `{events, status}`: `events[]` is the discrete action(s) the user just took. Each event is an envelope `{intent, actionData, uiContext, actionId, firedAt}` — `actionData` is WHAT the user did (action name + validated payload, plus `nextStep` hint if the author declared one); `uiContext` is the iframe-local snapshot of every declared contextSpec slot AT THE MOMENT the action fired (form fields, selected tab, slider value, scroll position — whatever the contract declared). Both inform your reaction without a second round trip. Honor each event\'s `actionData.nextStep` hint if the tool is available, then loop back to step 1 to render the response. Continue until consume returns status:"expired" (the render is gone) or no further follow-up is needed.',
|
|
93
93
|
'',
|
|
94
|
-
' 5.
|
|
94
|
+
' 5. ggui_amend — reflect the new state in the UI, in place. After ANY domain-tool call whose result changed data the rendered UI displays (e.g. `todo_toggle` flips a todo\'s `done`, `cart_add_item` extends a cart, `note_save` persists text), you MUST immediately call `ggui_amend` with the refreshed props so the user sees what just happened. The rendered UI does NOT auto-refresh — it only shows the props it was last given. Skipping this after a state-mutating tool call leaves the user staring at stale state and is the #1 wire bug. Pattern: `consume → domain-tool → ggui_amend → loop to consume`. Two modes: `{sessionId, kind:"replace", props}` sends the FULL new props map (use when most fields changed or you want deterministic restoration); `{sessionId, kind:"merge", patch}` sends ONLY the delta as RFC 7396 JSON Merge Patch (shallow merge, recurse on nested objects, `null` deletes a key, arrays fully replace — use when most props stay the same and only one or two fields changed). Prefer `merge` after a single domain-tool mutation. The only times you skip it: (a) the domain tool was pure-read (todo_list, search, etc.) AND its result wasn\'t for the UI, or (b) the contract has no propsSpec (pure-display with no mutable state). AMEND vs UPDATE vs NEW RENDER: `ggui_amend` repaints the SAME card quietly — no new card, the history number does not advance; it is the default move in gesture loops. `ggui_update` renders the updated state as a NEW card in the conversation and advances the history number — use it for state MILESTONES worth a card in the transcript, or when the original card is no longer visible/usable. When the user\'s gesture asks for a structurally DIFFERENT surface (picking from a menu, opening a detail view, navigating), run ggui_handshake + ggui_render for the next UI instead. If amend/update returns `updated: false` with a warning, your patch changed nothing: either send genuinely different values or render the next surface.',
|
|
95
95
|
'',
|
|
96
96
|
'In short: let the protocol\'s `nextStep` fields drive routing. Every ggui_* tool whose response logically chains forwards (handshake → render → consume) emits a nextStep when there IS a next step; the absence of nextStep means "you\'re done with this thread for now."',
|
|
97
97
|
'',
|
|
@@ -100,7 +100,7 @@ const DEFAULT_PRESET_BODY = [
|
|
|
100
100
|
'When the user reloads the page after interacting with a rendered UI, the iframe re-mounts but the agent process may have lost its `ggui_consume` long-poll. Subsequent clicks in the rehydrated iframe arrive as a USER MESSAGE that carries an explicit `sessionId` — either as a structured directive block (host-synthesized prefix wrapping the user prose) or as a typed slice the host passes through. EITHER WAY, the rule is the same:',
|
|
101
101
|
'',
|
|
102
102
|
' • The named `sessionId` identifies an EXISTING live iframe. Treat the message as a continuation of THAT session, not as a fresh request.',
|
|
103
|
-
' • REQUIRED first tool call: `ggui_consume({sessionId: <the-named-id>})` to drain the queued gesture. This returns the event the user fired; act on it with the appropriate domain tool, then `
|
|
103
|
+
' • REQUIRED first tool call: `ggui_consume({sessionId: <the-named-id>})` to drain the queued gesture. This returns the event the user fired; act on it with the appropriate domain tool, then `ggui_amend({sessionId, ...})` on the SAME sessionId — the card the user is looking at repaints in place.',
|
|
104
104
|
' • DO NOT call `ggui_handshake` for a rehydrated-gesture message. Handshaking mints a SEPARATE new session the user can\'t see, orphaning the live iframe they actually clicked. This is the most common reload-flow regression — when in doubt and you see a `sessionId` named in the user message, your first tool call is `ggui_consume({sessionId})`, full stop.',
|
|
105
105
|
'',
|
|
106
106
|
'Worked example — user reload + click:',
|
|
@@ -110,13 +110,13 @@ const DEFAULT_PRESET_BODY = [
|
|
|
110
110
|
' 3. Agent receives a user message containing `sessionId: s_abc123` (in a host-synthesized directive or as a structured slice).',
|
|
111
111
|
' 4. Agent calls `ggui_consume({sessionId: "s_abc123"})` — NOT `ggui_handshake`.',
|
|
112
112
|
' 5. Consume returns the click event; agent calls `todo_toggle({id: 1, done: false})`.',
|
|
113
|
-
' 6. Agent calls `
|
|
113
|
+
' 6. Agent calls `ggui_amend({sessionId: "s_abc123", kind: "merge", patch: {todos: [...]}})` — the mounted card repaints in place.',
|
|
114
114
|
'',
|
|
115
115
|
'The same flow applies whether the message arrives mid-conversation or as the very first turn after the user opens a saved chat URL — the sessionId is the source of truth for which iframe to address.',
|
|
116
116
|
'',
|
|
117
117
|
'═══ COMPLEMENTARY TOOLS ═══',
|
|
118
118
|
'',
|
|
119
|
-
' •
|
|
119
|
+
' • ggui_amend — repaint the delivered UI in place with new props (no new card, history number unchanged). Two modes: `kind:"replace"` (full props) or `kind:"merge"` (RFC 7396 delta — see step 5). ALWAYS call this after any state-mutating tool call; re-rendering would lose scroll position, focus, and uncommitted input. Forgetting it after a mutation is the most common protocol bug.\n • ggui_update — render the updated state as a NEW card and advance the history number. For milestones worth showing in the transcript, or when the original card is gone/far away.',
|
|
120
120
|
'',
|
|
121
121
|
' • ggui_emit — push frames to a streamSpec channel on a delivered UI. Use when the contract declared streamSpec (chat tokens, progress bars, live data). Frames must match the channel\'s declared `schema`. The live channel of the wire carries these.',
|
|
122
122
|
'',
|
|
@@ -134,9 +134,9 @@ const DEFAULT_PRESET_BODY = [
|
|
|
134
134
|
'',
|
|
135
135
|
'═══ TOOL DISCOVERY (lazy-loading hosts) ═══',
|
|
136
136
|
'',
|
|
137
|
-
'Some MCP hosts (notably claude.ai\'s connector model) use PROGRESSIVE tool discovery — only a small priority subset of tools is warmed at conversation start; the rest must be explicitly discovered via `tool_search` before they\'re callable. The ggui_* loop crosses this boundary on every render: handshake/render warm easily because you call them early, but `ggui_consume` and `ggui_update` are needed AFTER render and the host may not have loaded them yet.',
|
|
137
|
+
'Some MCP hosts (notably claude.ai\'s connector model) use PROGRESSIVE tool discovery — only a small priority subset of tools is warmed at conversation start; the rest must be explicitly discovered via `tool_search` before they\'re callable. The ggui_* loop crosses this boundary on every render: handshake/render warm easily because you call them early, but `ggui_consume`, `ggui_amend`, and `ggui_update` are needed AFTER render and the host may not have loaded them yet.',
|
|
138
138
|
'',
|
|
139
|
-
'SYMPTOM: a tool call fails with a message like "tool has not been loaded yet — call tool_search first" or "you do not have the correct parameter names." RECOVERY: call `tool_search` with the tool name as a query (e.g. `tool_search({ query: "ggui_consume" })`), wait for the load to complete, then retry the original call with the same args. Same pattern for `ggui_update`. After one successful `tool_search` per tool per conversation, subsequent calls work directly.',
|
|
139
|
+
'SYMPTOM: a tool call fails with a message like "tool has not been loaded yet — call tool_search first" or "you do not have the correct parameter names." RECOVERY: call `tool_search` with the tool name as a query (e.g. `tool_search({ query: "ggui_consume" })`), wait for the load to complete, then retry the original call with the same args. Same pattern for `ggui_amend` / `ggui_update`. After one successful `tool_search` per tool per conversation, subsequent calls work directly.',
|
|
140
140
|
'',
|
|
141
141
|
'WHEN IN DOUBT: if the render response carries `nextStep`, the host has effectively asked you to call that tool. Don\'t skip ggui_consume because the host whined about it being unloaded — `tool_search` first, then call. Skipping it leaves the user staring at a UI whose actions silently never reach the agent — the worst protocol failure mode.',
|
|
142
142
|
];
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* The thin shell is static content; it depends on nothing except the
|
|
28
28
|
* MIME constant and the HTML. Keeping it next to the registration
|
|
29
29
|
* means a future refactor of the shell edits one file. The
|
|
30
|
-
* `@ggui-ai/react` package does NOT ship the shell as a separate
|
|
30
|
+
* `@ggui-ai/mcp-apps-react` package does NOT ship the shell as a separate
|
|
31
31
|
* build target — per the design lock, the shell is served by the
|
|
32
32
|
* same `@ggui-ai/mcp-server` instance that mints the bootstrap.
|
|
33
33
|
*/
|
|
@@ -37,7 +37,7 @@ import { type McpAppAiGguiRenderMeta } from "@ggui-ai/protocol/integrations/mcp-
|
|
|
37
37
|
import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
38
38
|
import type { HandlerContext } from "@ggui-ai/mcp-server-handlers";
|
|
39
39
|
import type { Logger } from "./logger.js";
|
|
40
|
-
export declare const GGUI_RENDER_SHELL_HTML = "<!doctype html>\n<html lang=\"en\" style=\"height:100%;background-color:var(--ggui-color-surface, #1e293b)\"><head><meta charset=\"utf-8\"><title>ggui render</title></head>\n<body style=\"margin:0;height:100%;min-height:480px;background-color:var(--ggui-color-surface, #1e293b)\"><div id=\"ggui-root\" data-ggui-shell=\"thin\" style=\"height:100%;min-height:480px\"></div>\n<script>\n(function(){'use strict';\n// MCP Apps shell. Speaks the canonical postMessage protocol from\n// @modelcontextprotocol/ext-apps:\n// 1. iframe -> host: ui/initialize\n// 2. iframe -> host: ui/notifications/initialized\n// 3. host -> iframe: ui/notifications/tool-result (per CallToolResult)\n// On tool-result, read the slice envelope from _meta (spec-canonical\n// CallToolResult _meta at the top level), set window.__GGUI_META__ to\n// the envelope, fetch runtime as blob, inject as script.\n// Runtime auto-mounts inline. No nested iframe (claudemcpcontent.com\n// CSP frame-src forbids cross-origin frames). State machine matches\n// buildSelfContainedShell so the same runtime mounts both paths.\n//\n// R5 (2026-05-26): the historic /r/<shortCode> HTTP fallback was\n// removed along with the bearer-by-obscurity model -- hosts that strip\n// _meta no longer have a recovery path here. Spec-canonical hosts\n// deliver _meta inline and are unaffected.\n//\n// Phase B (2026-05-27): the historic two-slice envelope\n// (`ai.ggui/session` + `ai.ggui/stack-item`) collapsed to ONE flat\n// `ai.ggui/render` slice. runtimeUrl now lives directly on the\n// render slice; sessionId is the canonical identity.\nvar rpcId=1,pending={};\nvar rootEl=document.getElementById('ggui-root');\nrootEl.style.cssText='display:flex;flex-direction:column;height:100%;min-height:300px;margin:0';\nvar mounted=false;\nfunction setOverlay(text){\n if(mounted)return;\n rootEl.innerHTML='<div style=\"font:14px system-ui,sans-serif;padding:24px;color:#666\">'+text+'</div>';\n}\nfunction postNotification(method,params){\n try{window.parent.postMessage({jsonrpc:'2.0',method:method,params:params||{}},'*');}catch(e){}\n}\nfunction postRpc(method,params){\n return new Promise(function(res,rej){\n var id=rpcId++;pending[id]={res:res,rej:rej};\n try{window.parent.postMessage({jsonrpc:'2.0',id:id,method:method,params:params||{}},'*');}\n catch(e){delete pending[id];rej(e);}\n });\n}\nfunction postBootstrapFailed(reason,message){\n // Surface every shell-layer bootstrap-failure path as a typed\n // RendererBootFailedMessage envelope so hosts pinning the C9\n // error pane (McpAppIframe onError, IframeErrorPane) see the\n // failure instead of staring at the inert overlay until the test\n // times out. Reason codes match BootstrapFailureReason.\n try{window.parent.postMessage({type:'ggui:bootstrap-failed',reason:reason,message:message},'*');}catch(e){}\n}\nasync function mountFromMeta(envelope){\n if(mounted)return;\n // Slice envelope shape (Phase B): { \"ai.ggui/render\": { sessionId,\n // appId, runtimeUrl, ... } }. runtimeUrl on the render slice is\n // the only load-bearing field at the shell layer \u2014 it tells us\n // which iframe-runtime bundle to fetch. Everything else is\n // optional; the runtime decides at boot time based on the meta\n // it reads from window.__GGUI_META__.\n var renderSlice=envelope&&envelope['ai.ggui/render'];\n var runtimeUrl=renderSlice&&renderSlice.runtimeUrl;\n if(!envelope||typeof runtimeUrl!=='string'){\n setOverlay('Bootstrap payload malformed.');\n postBootstrapFailed('MALFORMED_BOOTSTRAP','Bootstrap payload malformed.');\n return;\n }\n setOverlay('Loading UI\u2026');\n window.__GGUI_META__=envelope;\n // Load the runtime bundle via a direct cross-origin script tag\n // (governed by CSP script-src) instead of fetch + Blob (governed by\n // CSP connect-src). claude.ai's claudemcpcontent.com iframe CSP\n // forbids cross-origin connect-src so fetch throws TypeError\n // 'Failed to fetch', but allows cross-origin script-src when the\n // bundle responds with the right CORS headers (the iframe-runtime\n // mount sets them). The self-contained shell already uses this\n // pattern; legacy postMessage shell now matches it.\n try{\n var s=document.createElement('script');\n s.type='module';\n // crossorigin=anonymous opts into CORS-mode error reporting.\n // Without it, cross-origin script tags get a sanitized\n // \"script error\" with no details, masking the real cause\n // (CSP block, CORS reject, module-evaluation throw). With it,\n // the error event surfaces the actual message in the iframe\n // console -- the bundle ships ACAO=* so credentialed mode is\n // unnecessary.\n s.crossOrigin='anonymous';\n s.src=runtimeUrl;\n s.onload=function(){mounted=true;};\n s.onerror=function(e){\n var msg='Runtime bundle failed to load: '+(e&&e.message||'script error');\n setOverlay(msg);\n postBootstrapFailed('BUNDLE_FETCH_FAILED',msg);\n };\n rootEl.innerHTML='';\n document.body.appendChild(s);\n }catch(e){\n var msg='Runtime bundle failed to load: '+(e&&e.message||e);\n setOverlay(msg);\n postBootstrapFailed('BUNDLE_FETCH_FAILED',msg);\n }\n}\nfunction readMetaFromCallToolResult(params){\n // MCP Apps spec (specification/2026-01-26/apps.mdx:1145-1155):\n // ui/notifications/tool-result\n // params: CallToolResult // Standard MCP type\n // So params IS the CallToolResult and _meta lives at the top\n // level. Spec-compliant hosts (Claude Desktop, claude.ai\n // Connector, Claude Code) deliver slice-envelope material here.\n // Single slice-envelope key (Phase B: ai.ggui/render). Only the\n // render slice's runtimeUrl is load-bearing at the shell layer;\n // the runtime reads everything else off window.__GGUI_META__\n // after we set it.\n if(!params||typeof params!=='object')return null;\n var meta=params._meta;\n if(!meta||typeof meta!=='object')return null;\n var renderSlice=meta['ai.ggui/render'];\n if(!renderSlice||typeof renderSlice!=='object')return null;\n if(typeof renderSlice.runtimeUrl!=='string')return null;\n return meta;\n}\nwindow.addEventListener('message',function(ev){\n var m=ev&&ev.data;\n if(!m||m.jsonrpc!=='2.0')return;\n if(m.id!=null&&pending[m.id]){\n var p=pending[m.id];delete pending[m.id];\n if(m.error)p.rej(m.error);else p.res(m.result);\n return;\n }\n if(m.method==='ui/notifications/tool-result'){\n // Spec-compliant hosts: m.params IS the CallToolResult; _meta is\n // at the top level.\n var specMeta=readMetaFromCallToolResult(m.params);\n if(specMeta){mountFromMeta(specMeta);return;}\n // R5 (2026-05-26) -- the /r/<shortCode> HTTP fallback was removed\n // along with the bearer-by-obscurity model. Hosts that strip\n // _meta on the tool-result wire have no fallback path here;\n // spec-canonical hosts deliver meta inline and land in the branch\n // above.\n }\n});\nsetOverlay('Initializing\u2026');\nvar initTimer=setTimeout(function(){\n setOverlay('Host did not respond to ui/initialize within 3s.');\n},3000);\npostRpc('ui/initialize',{\n appCapabilities:{},\n appInfo:{name:'ggui-render',version:'1.0.0'},\n protocolVersion:'2026-01-26'\n}).then(function(){\n clearTimeout(initTimer);\n postNotification('ui/notifications/initialized',{});\n // Wait for the host to send ui/notifications/tool-result carrying\n // the slice envelope in _meta \u2014 the spec-canonical delivery channel.\n // The ui/initialize result itself carries no slice meta (the\n // McpUiInitializeResult schema defines no such field).\n setOverlay('Waiting for tool result\u2026');\n}).catch(function(e){\n clearTimeout(initTimer);\n setOverlay('ui/initialize failed: '+(e&&e.message||JSON.stringify(e)));\n});\n})();\n</script></body></html>";
|
|
40
|
+
export declare const GGUI_RENDER_SHELL_HTML = "<!doctype html>\n<html lang=\"en\" style=\"height:100%;background-color:var(--ggui-color-surface, #1e293b)\"><head><meta charset=\"utf-8\"><title>ggui render</title></head>\n<body style=\"margin:0;height:100%;min-height:480px;background-color:var(--ggui-color-surface, #1e293b)\"><div id=\"ggui-root\" data-ggui-shell=\"thin\" style=\"height:100%;min-height:480px\"></div>\n<script>\n(function(){'use strict';\n// MCP Apps shell. Speaks the canonical postMessage protocol from\n// @modelcontextprotocol/ext-apps:\n// 1. iframe -> host: ui/initialize\n// 2. iframe -> host: ui/notifications/initialized\n// 3. host -> iframe: ui/notifications/tool-result (per CallToolResult)\n// On tool-result, read the slice envelope from _meta (spec-canonical\n// CallToolResult _meta at the top level), set window.__GGUI_META__ to\n// the envelope, fetch runtime as blob, inject as script.\n// Runtime auto-mounts inline. No nested iframe (claudemcpcontent.com\n// CSP frame-src forbids cross-origin frames). State machine matches\n// buildSelfContainedShell so the same runtime mounts both paths.\n//\n// R5 (2026-05-26): the historic /r/<shortCode> HTTP fallback was\n// removed along with the bearer-by-obscurity model -- hosts that strip\n// _meta no longer have a recovery path here. Spec-canonical hosts\n// deliver _meta inline and are unaffected.\n//\n// Phase B (2026-05-27): the historic two-slice envelope\n// (`ai.ggui/session` + `ai.ggui/stack-item`) collapsed to ONE flat\n// `ai.ggui/render` slice. runtimeUrl now lives directly on the\n// render slice; sessionId is the canonical identity.\nvar rpcId=1,pending={};\nvar rootEl=document.getElementById('ggui-root');\nrootEl.style.cssText='display:flex;flex-direction:column;height:100%;min-height:300px;margin:0';\nvar mounted=false;\nvar lastEnvelope=null;\n// Text color pairs with the shell surface: themed var when the runtime\n// injected theme CSS, else the light-on-dark fallback matching the\n// shell's static #1e293b pre-theme surface. The old hardcoded #666 was\n// illegible on that dark fallback (#481).\nvar SHELL_FG='var(--ggui-color-onSurface,#e2e8f0)';\nfunction setOverlay(text){\n if(mounted)return;\n rootEl.innerHTML='<div style=\"font:13px system-ui,sans-serif;padding:24px;color:'+SHELL_FG+';opacity:.55\">'+text+'</div>';\n}\nfunction escText(s){\n return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/\"/g,'"');\n}\n// Terminal failure card (#481): plain-language summary, diagnostic\n// reachable but collapsed, Retry only when a retry can actually work.\n// Same visual vocabulary as the runtime's React error boundary so the\n// two error surfaces read as one system.\nfunction showFailure(summary,detail,retry){\n if(mounted)return;\n rootEl.innerHTML=''+\n '<div style=\"display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:32px 24px;min-height:160px;font-family:system-ui,sans-serif;color:'+SHELL_FG+';text-align:center\">'+\n '<div style=\"font-size:14px;font-weight:600\">'+escText(summary)+'</div>'+\n '<div style=\"font-size:12px;opacity:.65;max-width:320px;line-height:1.45\">The interface could not start. The conversation is unaffected \u2014 you can also just ask for the view again.</div>'+\n (retry?'<button id=\"ggui-shell-retry\" style=\"margin-top:2px;padding:7px 18px;border-radius:8px;border:1px solid currentColor;background:transparent;color:inherit;opacity:.75;font:500 13px system-ui,sans-serif;cursor:pointer\">Retry</button>':'')+\n '<details style=\"margin-top:6px;max-width:340px;width:100%;text-align:left;opacity:.75\">'+\n '<summary style=\"cursor:pointer;font-size:12px\">Details</summary>'+\n '<pre style=\"margin:6px 0 0;font:11px/1.5 ui-monospace,Menlo,monospace;white-space:pre-wrap;word-break:break-word\">'+escText(detail)+'</pre>'+\n '</details>'+\n '</div>';\n if(retry){\n var b=document.getElementById('ggui-shell-retry');\n if(b)b.onclick=retry;\n }\n}\nfunction postNotification(method,params){\n try{window.parent.postMessage({jsonrpc:'2.0',method:method,params:params||{}},'*');}catch(e){}\n}\nfunction postRpc(method,params){\n return new Promise(function(res,rej){\n var id=rpcId++;pending[id]={res:res,rej:rej};\n try{window.parent.postMessage({jsonrpc:'2.0',id:id,method:method,params:params||{}},'*');}\n catch(e){delete pending[id];rej(e);}\n });\n}\nfunction postBootstrapFailed(reason,message){\n // Surface every shell-layer bootstrap-failure path as a typed\n // RendererBootFailedMessage envelope so hosts pinning the C9\n // error pane (McpAppIframe onError, IframeErrorPane) see the\n // failure instead of staring at the inert overlay until the test\n // times out. Reason codes match BootstrapFailureReason.\n try{window.parent.postMessage({type:'ggui:bootstrap-failed',reason:reason,message:message},'*');}catch(e){}\n}\nasync function mountFromMeta(envelope){\n if(mounted)return;\n // Slice envelope shape (Phase B): { \"ai.ggui/render\": { sessionId,\n // appId, runtimeUrl, ... } }. runtimeUrl on the render slice is\n // the only load-bearing field at the shell layer \u2014 it tells us\n // which iframe-runtime bundle to fetch. Everything else is\n // optional; the runtime decides at boot time based on the meta\n // it reads from window.__GGUI_META__.\n var renderSlice=envelope&&envelope['ai.ggui/render'];\n var runtimeUrl=renderSlice&&renderSlice.runtimeUrl;\n if(!envelope||typeof runtimeUrl!=='string'){\n // No retry: without a valid envelope there is nothing to re-run.\n showFailure('This view could not start','MALFORMED_BOOTSTRAP: bootstrap payload malformed (no ai.ggui/render slice with a runtimeUrl).',null);\n postBootstrapFailed('MALFORMED_BOOTSTRAP','Bootstrap payload malformed.');\n return;\n }\n lastEnvelope=envelope;\n setOverlay('Loading UI\u2026');\n window.__GGUI_META__=envelope;\n // Load the runtime bundle via a direct cross-origin script tag\n // (governed by CSP script-src) instead of fetch + Blob (governed by\n // CSP connect-src). claude.ai's claudemcpcontent.com iframe CSP\n // forbids cross-origin connect-src so fetch throws TypeError\n // 'Failed to fetch', but allows cross-origin script-src when the\n // bundle responds with the right CORS headers (the iframe-runtime\n // mount sets them). The self-contained shell already uses this\n // pattern; legacy postMessage shell now matches it.\n try{\n var s=document.createElement('script');\n s.type='module';\n // crossorigin=anonymous opts into CORS-mode error reporting.\n // Without it, cross-origin script tags get a sanitized\n // \"script error\" with no details, masking the real cause\n // (CSP block, CORS reject, module-evaluation throw). With it,\n // the error event surfaces the actual message in the iframe\n // console -- the bundle ships ACAO=* so credentialed mode is\n // unnecessary.\n s.crossOrigin='anonymous';\n s.src=runtimeUrl;\n s.onload=function(){mounted=true;};\n s.onerror=function(e){\n var msg='Runtime bundle failed to load: '+(e&&e.message||'script error');\n showFailure('This view could not load','BUNDLE_FETCH_FAILED: '+msg,function(){mountFromMeta(lastEnvelope);});\n postBootstrapFailed('BUNDLE_FETCH_FAILED',msg);\n };\n rootEl.innerHTML='';\n document.body.appendChild(s);\n }catch(e){\n var msg='Runtime bundle failed to load: '+(e&&e.message||e);\n showFailure('This view could not load','BUNDLE_FETCH_FAILED: '+msg,function(){mountFromMeta(lastEnvelope);});\n postBootstrapFailed('BUNDLE_FETCH_FAILED',msg);\n }\n}\nfunction readMetaFromCallToolResult(params){\n // MCP Apps spec (specification/2026-01-26/apps.mdx:1145-1155):\n // ui/notifications/tool-result\n // params: CallToolResult // Standard MCP type\n // So params IS the CallToolResult and _meta lives at the top\n // level. Spec-compliant hosts (Claude Desktop, claude.ai\n // Connector, Claude Code) deliver slice-envelope material here.\n // Single slice-envelope key (Phase B: ai.ggui/render). Only the\n // render slice's runtimeUrl is load-bearing at the shell layer;\n // the runtime reads everything else off window.__GGUI_META__\n // after we set it.\n if(!params||typeof params!=='object')return null;\n var meta=params._meta;\n if(!meta||typeof meta!=='object')return null;\n var renderSlice=meta['ai.ggui/render'];\n if(!renderSlice||typeof renderSlice!=='object')return null;\n if(typeof renderSlice.runtimeUrl!=='string')return null;\n return meta;\n}\nwindow.addEventListener('message',function(ev){\n var m=ev&&ev.data;\n if(!m||m.jsonrpc!=='2.0')return;\n if(m.id!=null&&pending[m.id]){\n var p=pending[m.id];delete pending[m.id];\n if(m.error)p.rej(m.error);else p.res(m.result);\n return;\n }\n if(m.method==='ui/notifications/tool-result'){\n // Spec-compliant hosts: m.params IS the CallToolResult; _meta is\n // at the top level.\n var specMeta=readMetaFromCallToolResult(m.params);\n if(specMeta){mountFromMeta(specMeta);return;}\n // R5 (2026-05-26) -- the /r/<shortCode> HTTP fallback was removed\n // along with the bearer-by-obscurity model. Hosts that strip\n // _meta on the tool-result wire have no fallback path here;\n // spec-canonical hosts deliver meta inline and land in the branch\n // above.\n }\n});\n// Named so the failure card's Retry can re-run the whole handshake \u2014\n// a host that missed or rejected the first ui/initialize may answer a\n// second (observed with hosts that attach their listener late).\nfunction startInit(){\n setOverlay('Initializing\u2026');\n var initTimer=setTimeout(function(){\n showFailure('This view did not hear back from its host','INIT_TIMEOUT: no response to ui/initialize within 3s.',startInit);\n },3000);\n postRpc('ui/initialize',{\n appCapabilities:{},\n appInfo:{name:'ggui-render',version:'1.0.0'},\n protocolVersion:'2026-01-26'\n }).then(function(){\n clearTimeout(initTimer);\n postNotification('ui/notifications/initialized',{});\n // Wait for the host to send ui/notifications/tool-result carrying\n // the slice envelope in _meta \u2014 the spec-canonical delivery channel.\n // The ui/initialize result itself carries no slice meta (the\n // McpUiInitializeResult schema defines no such field).\n setOverlay('Waiting for tool result\u2026');\n }).catch(function(e){\n clearTimeout(initTimer);\n showFailure('This view could not connect to its host','ui/initialize failed: '+(e&&e.message||JSON.stringify(e)),startInit);\n });\n}\nstartInit();\n})();\n</script></body></html>";
|
|
41
41
|
/**
|
|
42
42
|
* CSP `script-src` source expression that authorises the inline
|
|
43
43
|
* `<script>` block of {@link GGUI_RENDER_SHELL_HTML} when it executes
|
|
@@ -78,7 +78,56 @@ export declare const GGUI_RENDER_SHELL_HTML = "<!doctype html>\n<html lang=\"en\
|
|
|
78
78
|
* the CSP it inherits.
|
|
79
79
|
*/
|
|
80
80
|
export declare const GGUI_RENDER_SHELL_SCRIPT_HASH: string;
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Build the INLINE-RUNTIME static shell: a standalone document carrying
|
|
83
|
+
* the iframe-runtime bundle in its own bytes instead of an external
|
|
84
|
+
* `<script src>` tag. For MCP Apps hosts whose iframe CSP forbids
|
|
85
|
+
* external `script-src` while permitting inline scripts — the thin
|
|
86
|
+
* postMessage shell can never load its runtime there, so the shell IS
|
|
87
|
+
* the runtime.
|
|
88
|
+
*
|
|
89
|
+
* Per-render state does NOT live here (same posture as the thin
|
|
90
|
+
* shell): the host delivers it via `ui/notifications/tool-result`,
|
|
91
|
+
* caught either by the buffer script (pre-parse arrivals) or by the
|
|
92
|
+
* runtime's own autostart listener. Live-channel / codeUrl fetches are
|
|
93
|
+
* unavailable under the CSP this shell targets; delivered meta is
|
|
94
|
+
* expected to carry the fetch-free channels (inline `codeB64`, inline
|
|
95
|
+
* `propsJson`).
|
|
96
|
+
*
|
|
97
|
+
* Served per-mount via `installMcpAppsOutbound({ shellHtml })` — the
|
|
98
|
+
* module-level thin-shell constants (and their pinned CSP hash) are
|
|
99
|
+
* deliberately untouched.
|
|
100
|
+
*/
|
|
101
|
+
export declare function buildInlineRenderShellHtml(runtimeSource: string): string;
|
|
102
|
+
export declare function registerGguiRenderResource(server: McpServer, shellHtml?: string, publicBaseUrl?: string,
|
|
103
|
+
/**
|
|
104
|
+
* Absolute runtime-bundle URL used as the CSP-declaration fallback
|
|
105
|
+
* when `publicBaseUrl` is absent — same posture as the per-render
|
|
106
|
+
* template registration ({@link buildCspMeta}'s second parameter).
|
|
107
|
+
* Deployments that publish an absolute `runtime.url` but
|
|
108
|
+
* deliberately do NOT set `publicBaseUrl` (it also feeds
|
|
109
|
+
* Origin/Host enforcement and OAuth) still get
|
|
110
|
+
* `_meta.ui.csp.{connectDomains,resourceDomains}` on the static
|
|
111
|
+
* resource read; before this fallback those reads carried no
|
|
112
|
+
* declaration at all and spec-compliant hosts applied the
|
|
113
|
+
* restrictive default (`connect-src 'none'`).
|
|
114
|
+
*/
|
|
115
|
+
runtimeUrl?: string,
|
|
116
|
+
/**
|
|
117
|
+
* Additional URLs whose origins the mounted iframe must be able to
|
|
118
|
+
* `connect-src` — unioned into `connectDomains` by
|
|
119
|
+
* {@link buildCspMeta}. The load-bearing entries are the live-channel
|
|
120
|
+
* origins (`wsUrl` + its ws→http origin flip): the STATIC shell is
|
|
121
|
+
* the resource cross-origin hosts (claude.ai) mount and derive the
|
|
122
|
+
* frame CSP from, so origins declared only on per-render resources
|
|
123
|
+
* never reach the frame. Without these, deployments that set no
|
|
124
|
+
* `publicBaseUrl` (the cloud pod — it feeds Origin/Host enforcement)
|
|
125
|
+
* declare only the runtime-CDN origin and every SSE / HTTP-polling /
|
|
126
|
+
* WS rung of the failover ladder is CSP-blocked in the mounted
|
|
127
|
+
* iframe — observed live on claude.ai (#471 round 11: frame booted
|
|
128
|
+
* with `connect-src assets.mcp.ggui.ai` only).
|
|
129
|
+
*/
|
|
130
|
+
extraConnectUrls?: readonly (string | undefined)[]): string;
|
|
82
131
|
/**
|
|
83
132
|
* Advertise the `io.modelcontextprotocol/ui` extension capability on
|
|
84
133
|
* an `McpServer`'s underlying `Server`. Idempotent - calling twice on
|
|
@@ -116,6 +165,16 @@ export interface SelfContainedShellInputs {
|
|
|
116
165
|
* renders without re-parsing.
|
|
117
166
|
*/
|
|
118
167
|
readonly codeHash?: string;
|
|
168
|
+
/**
|
|
169
|
+
* Base64-encoded compiled component source inlined on the bootstrap
|
|
170
|
+
* — the fetch-free twin of {@link codeUrl}, decoded by the
|
|
171
|
+
* iframe-runtime instead of fetched. May coexist with codeUrl
|
|
172
|
+
* (consumers prefer the inline bytes); mutually exclusive with
|
|
173
|
+
* {@link systemKind}. For hosts whose iframe CSP blocks the codeUrl
|
|
174
|
+
* fetch, and for deployments whose code store is unwired or down —
|
|
175
|
+
* the inline bytes make the shell mountable independently of both.
|
|
176
|
+
*/
|
|
177
|
+
readonly codeB64?: string;
|
|
119
178
|
/**
|
|
120
179
|
* System-card kind identifier, mapped at runtime against the
|
|
121
180
|
* built-in `SYSTEM_CARD_REGISTRY`. Mutually exclusive with
|
|
@@ -246,6 +305,15 @@ export interface SelfContainedShellInputs {
|
|
|
246
305
|
* present.
|
|
247
306
|
*/
|
|
248
307
|
readonly lastSequence?: McpAppAiGguiRenderMeta["lastSequence"];
|
|
308
|
+
/**
|
|
309
|
+
* Freeze-latch self-epoch (#483), mirrored from
|
|
310
|
+
* {@link McpAppAiGguiRenderMeta.epoch}: the history epoch of the
|
|
311
|
+
* record this shell mounts (pinned `#N` read ⇒ N; bare/head read ⇒
|
|
312
|
+
* the row's epoch). Absent ⇒ the runtime treats the mount as epoch
|
|
313
|
+
* 0 — correct only for a fresh render, so emitters serving epoch-
|
|
314
|
+
* bearing sessions MUST thread it.
|
|
315
|
+
*/
|
|
316
|
+
readonly epoch?: McpAppAiGguiRenderMeta["epoch"];
|
|
249
317
|
/**
|
|
250
318
|
* Wire-stamped polling fallback URL — `${base}/api/sessions/<id>/events?wsToken=<...>`.
|
|
251
319
|
* When the iframe-runtime's WS transport reaches `'failed'` (CSP
|
|
@@ -258,6 +326,17 @@ export interface SelfContainedShellInputs {
|
|
|
258
326
|
* shell builders do; callers composing their own shells SHOULD).
|
|
259
327
|
*/
|
|
260
328
|
readonly pollingUrl?: McpAppAiGguiRenderMeta["pollingUrl"];
|
|
329
|
+
/**
|
|
330
|
+
* Wire-stamped SSE middle rung between WS and polling —
|
|
331
|
+
* `${base}/api/sessions/<id>/stream?wsToken=<...>`. Serves the same
|
|
332
|
+
* ChannelFrame stream the WS pushes (each SSE `data:` line is one
|
|
333
|
+
* `{type, payload}` JSON; `id:` = the event-ledger seq on
|
|
334
|
+
* ledger-backed replay frames). Composed alongside
|
|
335
|
+
* {@link pollingUrl} via the protocol's `composeSessionApiUrls` so
|
|
336
|
+
* the two rungs cannot drift. Absent ⇒ the failover ladder skips
|
|
337
|
+
* straight to polling (WS → polling).
|
|
338
|
+
*/
|
|
339
|
+
readonly sseUrl?: McpAppAiGguiRenderMeta["sseUrl"];
|
|
261
340
|
}
|
|
262
341
|
/**
|
|
263
342
|
* Build the self-contained shell HTML for a given render.
|
|
@@ -619,5 +698,15 @@ export declare function installMcpAppsOutbound(server: McpServer, opts?: {
|
|
|
619
698
|
* there via `<McpAppIframe>`.
|
|
620
699
|
*/
|
|
621
700
|
readonly publicBaseUrl?: string;
|
|
622
|
-
|
|
701
|
+
/**
|
|
702
|
+
* Live-channel origins for the static shell's CSP declaration —
|
|
703
|
+
* forwarded to `registerGguiRenderResource` (see its
|
|
704
|
+
* `extraConnectUrls` docstring). Callers pass the deployment's
|
|
705
|
+
* `wsUrl` and its http-origin flip so the mounted iframe's
|
|
706
|
+
* `connect-src` covers the SSE/polling session API and the WS.
|
|
707
|
+
*/
|
|
708
|
+
readonly extraConnectUrls?: readonly (string | undefined)[];
|
|
709
|
+
}): {
|
|
710
|
+
readonly shellResourceUri: string;
|
|
711
|
+
};
|
|
623
712
|
//# sourceMappingURL=mcp-apps-outbound.d.ts.map
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"mcp-apps-outbound.d.ts","sourceRoot":"","sources":["../src/mcp-apps-outbound.ts"],"names":[],"mappings":"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"}
|