@ggui-ai/mcp-server 0.1.0-rc.3 → 0.2.0-alpha.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.
Files changed (59) hide show
  1. package/README.md +1 -1
  2. package/dist/build-mcp.d.ts +8 -8
  3. package/dist/build-mcp.d.ts.map +1 -1
  4. package/dist/build-mcp.js +53 -12
  5. package/dist/console-auth.d.ts +7 -7
  6. package/dist/console-auth.d.ts.map +1 -1
  7. package/dist/console-auth.js +4 -4
  8. package/dist/console-cache.d.ts +2 -2
  9. package/dist/console-cache.d.ts.map +1 -1
  10. package/dist/console-cache.js +10 -10
  11. package/dist/console-headers.d.ts +2 -2
  12. package/dist/console-headers.js +2 -2
  13. package/dist/console-payloads.d.ts +3 -3
  14. package/dist/console-payloads.d.ts.map +1 -1
  15. package/dist/console-payloads.js +10 -10
  16. package/dist/console-timeline.d.ts +12 -30
  17. package/dist/console-timeline.d.ts.map +1 -1
  18. package/dist/console-timeline.js +44 -45
  19. package/dist/index.d.ts +7 -7
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +5 -5
  22. package/dist/instructions-presets.d.ts +1 -1
  23. package/dist/instructions-presets.d.ts.map +1 -1
  24. package/dist/instructions-presets.js +40 -22
  25. package/dist/llm-backed-negotiator.d.ts +6 -6
  26. package/dist/llm-backed-negotiator.d.ts.map +1 -1
  27. package/dist/llm-backed-negotiator.js +92 -91
  28. package/dist/mcp-apps-inbound.d.ts +3 -3
  29. package/dist/mcp-apps-inbound.d.ts.map +1 -1
  30. package/dist/mcp-apps-inbound.js +28 -23
  31. package/dist/mcp-apps-outbound.d.ts +136 -121
  32. package/dist/mcp-apps-outbound.d.ts.map +1 -1
  33. package/dist/mcp-apps-outbound.js +384 -414
  34. package/dist/mcp-mounts.d.ts +21 -20
  35. package/dist/mcp-mounts.d.ts.map +1 -1
  36. package/dist/mcp-mounts.js +25 -29
  37. package/dist/{session-channel.d.ts → render-channel.d.ts} +145 -102
  38. package/dist/render-channel.d.ts.map +1 -0
  39. package/dist/{session-channel.js → render-channel.js} +481 -462
  40. package/dist/schema-compat.d.ts +11 -11
  41. package/dist/schema-compat.d.ts.map +1 -1
  42. package/dist/schema-compat.js +6 -6
  43. package/dist/server.d.ts +224 -219
  44. package/dist/server.d.ts.map +1 -1
  45. package/dist/server.js +1498 -1963
  46. package/dist/storage.d.ts +7 -7
  47. package/dist/storage.d.ts.map +1 -1
  48. package/dist/storage.js +12 -12
  49. package/package.json +12 -11
  50. package/dist/render-gate.d.ts +0 -87
  51. package/dist/render-gate.d.ts.map +0 -1
  52. package/dist/render-gate.js +0 -77
  53. package/dist/render-rate-limit.d.ts +0 -59
  54. package/dist/render-rate-limit.d.ts.map +0 -1
  55. package/dist/render-rate-limit.js +0 -73
  56. package/dist/render-signing.d.ts +0 -98
  57. package/dist/render-signing.d.ts.map +0 -1
  58. package/dist/render-signing.js +0 -113
  59. package/dist/session-channel.d.ts.map +0 -1
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * MCP Apps outbound wiring — the server-side half of the
3
- * `ggui_push -> ui://ggui/session -> iframe -> live channel` delivery path.
3
+ * `ggui_render -> ui://ggui/render -> iframe -> live channel` delivery path.
4
4
  *
5
5
  * Responsibilities of this module (and nothing else):
6
6
  *
7
7
  * 1. Advertise the `io.modelcontextprotocol/ui` capability on every
8
8
  * fresh `McpServer` instance so MCP Apps hosts know the server
9
9
  * speaks the UI extension.
10
- * 2. Register `ui://ggui/session` as a static resource servable via
10
+ * 2. Register `ui://ggui/render` as a static resource servable via
11
11
  * MCP `resources/read`. The resource body is the thin-shell HTML
12
12
  * hosts sandbox-render when they see `_meta.ui.resourceUri` on a
13
- * `ggui_push` result.
13
+ * `ggui_render` result.
14
14
  *
15
15
  * Boundary discipline:
16
16
  *
@@ -31,13 +31,13 @@
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
  */
34
- import { type McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
35
- import type { SessionStore, VectorStore } from '@ggui-ai/mcp-server-core';
36
- import { type GguiBootstrapMeta } from '@ggui-ai/protocol/integrations/mcp-apps';
37
- export declare const GGUI_SESSION_SHELL_HTML = "<!doctype html>\n<html lang=\"en\" style=\"height:100%\"><head><meta charset=\"utf-8\"><title>ggui session</title></head>\n<body style=\"margin:0;height:100%;min-height:480px\"><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, derive base URL + shortCode from structuredContent,\n// fetch JSON bootstrap (componentCode + ids + runtimeUrl), set\n// window.__GGUI_BOOTSTRAP__, 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.\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 readToolResult(p){\n if(!p)return null;\n var sc=p.structuredContent;\n if(sc&&typeof sc.url==='string'&&typeof sc.shortCode==='string'){\n return {url:sc.url,shortCode:sc.shortCode};\n }\n if(Array.isArray(p.content)){\n for(var i=0;i<p.content.length;i++){\n var c=p.content[i];\n if(c&&c.type==='text'&&typeof c.text==='string'){\n try{var j=JSON.parse(c.text);\n if(j&&typeof j.url==='string'&&typeof j.shortCode==='string'){\n return {url:j.url,shortCode:j.shortCode};\n }\n }catch(e){}\n }\n }\n }\n return null;\n}\nfunction deriveBase(url){\n try{var u=new URL(url);return u.origin;}catch(e){return null;}\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 mountFromBootstrap(bootstrap){\n if(mounted)return;\n // runtimeUrl is the only load-bearing field at the shell layer \u2014\n // it tells us which iframe-runtime bundle to fetch. componentCode\n // is OPTIONAL: present in self-contained-mode bootstraps (the\n // runtime renders the inlined code without WS), absent in\n // GguiBootstrapMeta-shaped bootstraps (the runtime opens the WS\n // subscription via wsUrl+token to receive the stack). Either is\n // valid; the runtime decides at boot time. Rejecting on missing\n // componentCode silently breaks every Path B GguiBootstrapMeta\n // delivery, which is the whole point of the inline-bootstrap path.\n if(!bootstrap||typeof bootstrap.runtimeUrl!=='string'){\n setOverlay('Bootstrap payload malformed.');\n postBootstrapFailed('BOOTSTRAP_MALFORMED','Bootstrap payload malformed.');\n return;\n }\n setOverlay('Loading UI\u2026');\n window.__GGUI_BOOTSTRAP__=bootstrap;\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=bootstrap.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}\nasync function mount(toolResult){\n if(mounted)return;\n var base=deriveBase(toolResult.url);\n if(!base){setOverlay('Invalid URL in tool result.');return;}\n setOverlay('Loading UI\u2026');\n var bootstrap;\n try{\n var bRes=await fetch(base+'/api/bootstrap/'+encodeURIComponent(toolResult.shortCode),{\n cache:'no-store',\n headers:{accept:'application/json'},\n });\n if(!bRes.ok){setOverlay('Bootstrap fetch failed: HTTP '+bRes.status);return;}\n bootstrap=await bRes.json();\n }catch(e){setOverlay('Bootstrap fetch error: '+(e&&e.message||e));return;}\n return mountFromBootstrap(bootstrap);\n}\nfunction readBootstrapFromInitResult(result){\n if(!result||typeof result!=='object')return null;\n var toolOutput=result.toolOutput;\n if(!toolOutput||typeof toolOutput!=='object')return null;\n var meta=toolOutput._meta;\n if(!meta||typeof meta!=='object')return null;\n var ggui=meta.ggui;\n if(!ggui||typeof ggui!=='object')return null;\n var b=ggui.bootstrap;\n if(!b||typeof b!=='object')return null;\n // Same loosening as mountFromBootstrap: only runtimeUrl is required\n // here. GguiBootstrapMeta forwarded by first-party McpAppIframe\n // hosts omits componentCode by design (the runtime fetches the\n // stack via\n // wsUrl+token). Requiring componentCode at the shell layer turned\n // every Path B inline-bootstrap delivery into a silent reject.\n if(typeof b.runtimeUrl!=='string')return null;\n return b;\n}\nfunction hasGguiMetaPlaceholder(result){\n // Detect the protocol-violation case where the host signaled\n // \"I tried to deliver bootstrap\" (toolOutput._meta.ggui exists)\n // but the bootstrap field itself is absent or malformed. In that\n // shape, we fail-fast with BOOTSTRAP_META_MISSING rather than\n // sitting in the Path-A waiting state forever.\n if(!result||typeof result!=='object')return false;\n var toolOutput=result.toolOutput;\n if(!toolOutput||typeof toolOutput!=='object')return false;\n var meta=toolOutput._meta;\n if(!meta||typeof meta!=='object')return false;\n var ggui=meta.ggui;\n return !!ggui&&typeof ggui==='object';\n}\nfunction readBootstrapFromCallToolResult(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 (NOT under params.toolOutput, which is where the\n // first-party McpAppIframe convention wraps it). Spec-compliant\n // hosts (Claude Desktop, claude.ai Connector, Claude Code) deliver\n // bootstrap material here.\n if(!params||typeof params!=='object')return null;\n var meta=params._meta;\n if(!meta||typeof meta!=='object')return null;\n var ggui=meta.ggui;\n if(!ggui||typeof ggui!=='object')return null;\n var b=ggui.bootstrap;\n if(!b||typeof b!=='object')return null;\n // Same loosening as readBootstrapFromInitResult / mountFromBootstrap:\n // only runtimeUrl is required at the shell layer. componentCode is\n // optional (absent for GguiBootstrapMeta-shaped bootstraps that\n // open WS via wsUrl+token).\n if(typeof b.runtimeUrl!=='string')return null;\n return b;\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. Try this FIRST so Claude Desktop / claude.ai\n // Connector / Claude Code land here.\n var specB=readBootstrapFromCallToolResult(m.params);\n if(specB){mountFromBootstrap(specB);return;}\n // First-party McpAppIframe convention: bootstrap nested under\n // params.toolOutput._meta. First-party hosts (Studio, Portal,\n // console) use this shape for both init-response and post-init\n // notification.\n var bb=readBootstrapFromInitResult(m.params);\n if(bb){mountFromBootstrap(bb);return;}\n // Path A (last-resort fallback): host posts structuredContent.\n // {url, shortCode}; shell fetches /api/bootstrap/<shortCode>\n // over HTTP. The OSS server doesn't mount that endpoint, so this\n // path is effectively dead unless a hosted operator wires it.\n var tr=readToolResult(m.params);\n if(tr)mount(tr);\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-session',version:'1.0.0'},\n protocolVersion:'2026-01-26'\n}).then(function(result){\n clearTimeout(initTimer);\n postNotification('ui/notifications/initialized',{});\n // Path B: bootstrap inline in ui/initialize result. Hosts using\n // <McpAppIframe>'s first-party dispatch deliver bootstrap meta here\n // and never send a separate ui/notifications/tool-result.\n var b=readBootstrapFromInitResult(result);\n if(b){mountFromBootstrap(b);return;}\n // Protocol-violation surface: host signalled an attempt\n // (toolOutput._meta.ggui exists) but bootstrap is missing or\n // malformed. Fail fast so hosts pinning a typed error envelope\n // don't sit on the Path-A waiting overlay forever. Only fires\n // when the meta placeholder is present \u2014 a fully absent _meta.ggui\n // still falls through to Path A waiting.\n if(hasGguiMetaPlaceholder(result)){\n var msg='ui/initialize result missing _meta.ggui.bootstrap or runtimeUrl';\n setOverlay(msg);\n postBootstrapFailed('BOOTSTRAP_META_MISSING',msg);\n return;\n }\n // Path A: wait for the host to send ui/notifications/tool-result\n // with structuredContent.{url, shortCode}. MCP Apps hosts that don't\n // implement the reading-B inline-bootstrap convention land here.\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>";
34
+ import type { RenderStore, VectorStore } from "@ggui-ai/mcp-server-core";
35
+ import { type McpAppAiGguiRenderMeta } from "@ggui-ai/protocol/integrations/mcp-apps";
36
+ import { type McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
37
+ export declare const GGUI_RENDER_SHELL_HTML = "<!doctype html>\n<html lang=\"en\" style=\"height:100%\"><head><meta charset=\"utf-8\"><title>ggui render</title></head>\n<body style=\"margin:0;height:100%;min-height:480px\"><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, or the first-party\n// params.toolOutput._meta shape), set window.__GGUI_META__ to the\n// 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; renderId 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\": { renderId,\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('BOOTSTRAP_MALFORMED','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 readMetaFromInitResult(result){\n if(!result||typeof result!=='object')return null;\n var toolOutput=result.toolOutput;\n if(!toolOutput||typeof toolOutput!=='object')return null;\n var meta=toolOutput._meta;\n if(!meta||typeof meta!=='object')return null;\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 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}\nfunction hasAiGguiMetaPlaceholder(result){\n // Detect the protocol-violation case where the host signaled\n // \"I tried to deliver meta\" (toolOutput._meta carries an\n // ai.ggui/render key) but it's malformed. Fail-fast with\n // BOOTSTRAP_META_MISSING rather than waiting forever.\n if(!result||typeof result!=='object')return false;\n var toolOutput=result.toolOutput;\n if(!toolOutput||typeof toolOutput!=='object')return false;\n var meta=toolOutput._meta;\n if(!meta||typeof meta!=='object')return false;\n return 'ai.ggui/render' in meta;\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 (NOT under params.toolOutput, which is where the\n // first-party McpAppIframe convention wraps it). Spec-compliant\n // hosts (Claude Desktop, claude.ai Connector, Claude Code) deliver\n // slice-envelope material here.\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. Try this FIRST so Claude Desktop / claude.ai\n // Connector / Claude Code land here.\n var specB=readMetaFromCallToolResult(m.params);\n if(specB){mountFromMeta(specB);return;}\n // First-party McpAppIframe convention: slice envelope nested under\n // params.toolOutput._meta. First-party hosts (Studio, Portal,\n // console) use this shape for both init-response and post-init\n // notification.\n var bb=readMetaFromInitResult(m.params);\n if(bb){mountFromMeta(bb);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 two\n // branches 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-session',version:'1.0.0'},\n protocolVersion:'2026-01-26'\n}).then(function(result){\n clearTimeout(initTimer);\n postNotification('ui/notifications/initialized',{});\n // Path B: slice envelope inline in ui/initialize result. Hosts\n // using <McpAppIframe>'s first-party dispatch deliver meta here\n // and never send a separate ui/notifications/tool-result.\n var b=readMetaFromInitResult(result);\n if(b){mountFromMeta(b);return;}\n // Protocol-violation surface: host signalled an attempt\n // (toolOutput._meta carries ai.ggui/render) but it's malformed.\n // Fail fast so hosts pinning a typed error envelope don't sit on\n // the Path-A waiting overlay forever.\n if(hasAiGguiMetaPlaceholder(result)){\n var msg='ui/initialize result missing valid ai.ggui/render.runtimeUrl';\n setOverlay(msg);\n postBootstrapFailed('BOOTSTRAP_META_MISSING',msg);\n return;\n }\n // Path A: wait for the host to send ui/notifications/tool-result\n // with structuredContent.{url, shortCode}. MCP Apps hosts that don't\n // implement the reading-B inline-meta convention land here.\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>";
38
38
  /**
39
39
  * CSP `script-src` source expression that authorises the inline
40
- * `<script>` block of {@link GGUI_SESSION_SHELL_HTML} when it executes
40
+ * `<script>` block of {@link GGUI_RENDER_SHELL_HTML} when it executes
41
41
  * inside an iframe whose CSP is inherited from a parent host.
42
42
  *
43
43
  * # Why this exists
@@ -74,8 +74,8 @@ export declare const GGUI_SESSION_SHELL_HTML = "<!doctype html>\n<html lang=\"en
74
74
  * path where the host is `<McpAppIframe>` and the parent SPA owns
75
75
  * the CSP it inherits.
76
76
  */
77
- export declare const GGUI_SESSION_SHELL_SCRIPT_HASH: string;
78
- export declare function registerGguiSessionResource(server: McpServer, shellHtml?: string, publicBaseUrl?: string): void;
77
+ export declare const GGUI_RENDER_SHELL_SCRIPT_HASH: string;
78
+ export declare function registerGguiRenderResource(server: McpServer, shellHtml?: string, publicBaseUrl?: string): void;
79
79
  /**
80
80
  * Advertise the `io.modelcontextprotocol/ui` extension capability on
81
81
  * an `McpServer`'s underlying `Server`. Idempotent - calling twice on
@@ -94,9 +94,9 @@ export declare function advertiseMcpAppsUiCapability(server: McpServer): void;
94
94
  * @public
95
95
  */
96
96
  export interface SelfContainedShellInputs {
97
- /** Session id whose top-of-stack render is being inlined. */
98
- readonly sessionId: string;
99
- /** App / tenant id the session is scoped to. */
97
+ /** Render id whose visible-bits surface is being inlined. */
98
+ readonly renderId: string;
99
+ /** App / tenant id the render is scoped to. */
100
100
  readonly appId: string;
101
101
  /**
102
102
  * Content-addressable URL the iframe fetches the compiled ES module
@@ -124,22 +124,11 @@ export interface SelfContainedShellInputs {
124
124
  * `<script type="module" src=...>`. MUST be absolute (or root-
125
125
  * relative resolvable from the host's iframe origin) — `srcdoc`
126
126
  * iframes have `about:srcdoc` as their URL so a bare relative path
127
- * cannot resolve. Also inlined on the `__GGUI_BOOTSTRAP__` global so
127
+ * cannot resolve. Also inlined on the `__GGUI_META__` global so
128
128
  * the iframe-runtime's bootstrap validator (which requires
129
129
  * `runtimeUrl` across all modes) accepts the envelope.
130
130
  */
131
131
  readonly runtimeUrl: string;
132
- /** Optional stack-item id forwarded to the renderer for parity
133
- * with single-item-mode bootstrap selectors. */
134
- readonly stackItemId?: string;
135
- /**
136
- * Canvas-mode flag. When `true`, the
137
- * bootstrap is built as session-scoped (no stackItemId, no
138
- * codeUrl/systemKind — live-mode trio MUST be supplied) and the
139
- * iframe-runtime mounts {@link CanvasShell} instead of a single
140
- * stack item. Mutually exclusive with {@link stackItemId}.
141
- */
142
- readonly canvasMode?: boolean;
143
132
  /** Optional theme id forwarded to the renderer. */
144
133
  readonly themeId?: string;
145
134
  /**
@@ -150,7 +139,7 @@ export interface SelfContainedShellInputs {
150
139
  * `LoadedTheme.mode` for preset/file forms; default-source themes
151
140
  * omit this field entirely.
152
141
  */
153
- readonly themeMode?: 'light' | 'dark';
142
+ readonly themeMode?: "light" | "dark";
154
143
  /**
155
144
  * Optional pre-serialized props (must be a JSON string) forwarded
156
145
  * to the renderer. Server inlines the string verbatim — the
@@ -159,7 +148,7 @@ export interface SelfContainedShellInputs {
159
148
  readonly propsJson?: string;
160
149
  /**
161
150
  * Names of same-server tools whose `_meta.ui.visibility` includes
162
- * `"app"`, mirrored from {@link GguiBootstrapMeta.appCallableTools}.
151
+ * `"app"`, mirrored from {@link McpAppAiGguiRenderMeta.appCallableTools}.
163
152
  * Forwarded to the iframe-runtime so its dispatch closure can choose
164
153
  * Pattern α (direct `tools/call`) over Pattern β (3-message bridge)
165
154
  * per wired action — even on the self-contained `/r/<shortCode>`
@@ -169,23 +158,23 @@ export interface SelfContainedShellInputs {
169
158
  * Empty / absent → no fallout: the runtime's dispatch routes every
170
159
  * action through Pattern β.
171
160
  */
172
- readonly appCallableTools?: GguiBootstrapMeta['appCallableTools'];
161
+ readonly appCallableTools?: McpAppAiGguiRenderMeta["appCallableTools"];
173
162
  /**
174
- * Per-action wired-tool mapping for the active stack item, mirrored
175
- * from {@link GguiBootstrapMeta.actionNextSteps}.
163
+ * Per-action wired-tool mapping for the active render, mirrored
164
+ * from {@link McpAppAiGguiRenderMeta.actionNextSteps}.
176
165
  */
177
- readonly actionNextSteps?: GguiBootstrapMeta['actionNextSteps'];
166
+ readonly actionNextSteps?: McpAppAiGguiRenderMeta["actionNextSteps"];
178
167
  /**
179
- * Per-slot data for the active stack item's `contextSpec`, mirrored
180
- * from {@link GguiBootstrapMeta.contextSlots}. The runtime
168
+ * Per-slot data for the active render's `contextSpec`, mirrored
169
+ * from {@link McpAppAiGguiRenderMeta.contextSlots}. The runtime
181
170
  * synthesizes one `React.createContext(default)` per entry at boot.
182
171
  * Without this field, contextSpec UIs render with un-seeded
183
172
  * Providers.
184
173
  */
185
- readonly contextSlots?: GguiBootstrapMeta['contextSlots'];
174
+ readonly contextSlots?: McpAppAiGguiRenderMeta["contextSlots"];
186
175
  /**
187
- * Permissions-Policy directive list derived from the active stack
188
- * item's `clientCapabilities.gadgets[*].permission`.
176
+ * Permissions-Policy directive list derived from the active render's
177
+ * `clientCapabilities.gadgets[*].permission`.
189
178
  * When present (non-empty), inlined onto the bootstrap as
190
179
  * `permissionsPolicy` so the iframe-runtime can surface the gate set
191
180
  * to in-iframe consumers (debug overlay, permission-aware UI). The
@@ -199,33 +188,38 @@ export interface SelfContainedShellInputs {
199
188
  /**
200
189
  * Resolved gadget catalog the iframe runtime dynamically imports at
201
190
  * boot. Each entry is `{hook,
202
- * package?, bundleUrl?}`. The MCP-Apps `_meta.ggui.bootstrap`
203
- * channel already forwards this via `push.ts`; this field is the
191
+ * package?, bundleUrl?}`. The MCP-Apps `_meta` slice channel already
192
+ * forwards this via the render-mutation handler; this field is the
204
193
  * symmetric forward for the self-contained shell so `/r/<shortCode>`
205
- * and `resources/read` iframes don't render as STDLIB-only when
206
- * the contract declares wrappers.
194
+ * and `resources/read` iframes don't render as STDLIB-only when the
195
+ * contract declares wrappers.
196
+ */
197
+ readonly gadgets?: McpAppAiGguiRenderMeta["gadgets"];
198
+ /**
199
+ * Content-addressable hash for the active render's compiled
200
+ * contract validators, mirrored from
201
+ * {@link McpAppAiGguiRenderMeta.contractHash}. The iframe-runtime
202
+ * resolves validators via `fetch({@link validatorsUrl})` + dynamic
203
+ * import. Paired with {@link validatorsUrl} — present together or
204
+ * absent together.
207
205
  */
208
- readonly gadgets?: GguiBootstrapMeta['gadgets'];
206
+ readonly contractHash?: McpAppAiGguiRenderMeta["contractHash"];
209
207
  /**
210
- * Precompiled, eval-free contract validators (one ESM validator-
211
- * module source per `propsSpec` / `actionSpec` / `streamSpec` /
212
- * `contextSpec`), mirrored from
213
- * {@link GguiBootstrapMeta.compiledValidators}. The renderer iframe's
214
- * strict CSP (no `'unsafe-eval'`) blocks runtime `ajv.compile()`, so
215
- * the iframe loads these precompiled modules via `blob:` import
216
- * instead. Symmetric forward for the self-contained shell so
217
- * `/r/<shortCode>` and `resources/read` iframes validate wire
218
- * traffic exactly as the MCP-Apps postMessage path does.
208
+ * URL serving the content-addressable contract-validator bundle,
209
+ * mirrored from {@link McpAppAiGguiRenderMeta.validatorsUrl}.
210
+ * Symmetric forward for the self-contained shell so `/r/<shortCode>`
211
+ * and `resources/read` iframes resolve validators exactly as the
212
+ * MCP-Apps postMessage path does.
219
213
  */
220
- readonly compiledValidators?: GguiBootstrapMeta['compiledValidators'];
214
+ readonly validatorsUrl?: McpAppAiGguiRenderMeta["validatorsUrl"];
221
215
  /**
222
216
  * Server-filtered public env values that declared wrappers'
223
217
  * `requires` cover (minimum-disclosure subset of `App.publicEnv`).
224
- * Symmetric with the `_meta.ggui.bootstrap` channel — every
225
- * transport that produces a `GguiBootstrapMeta` envelope MUST
226
- * forward this field so wrappers' `getPublicEnv()` reads land.
218
+ * Symmetric with the `ai.ggui/render` slice channel — every
219
+ * transport that produces the meta MUST forward this field so
220
+ * wrappers' `getPublicEnv()` reads land.
227
221
  */
228
- readonly publicEnv?: GguiBootstrapMeta['publicEnv'];
222
+ readonly publicEnv?: McpAppAiGguiRenderMeta["publicEnv"];
229
223
  /**
230
224
  * Live-mode WebSocket URL the iframe-runtime opens to receive
231
225
  * `props_update` / `stack_*` frames. When set alongside `token` +
@@ -238,7 +232,9 @@ export interface SelfContainedShellInputs {
238
232
  /**
239
233
  * Single-use bootstrap token authorising the WS subscribe. Paired
240
234
  * with {@link wsUrl} — half-live envelopes (one without the other)
241
- * are rejected as MALFORMED by `parseBootstrap`. Server-minted via
235
+ * are rejected as MALFORMED by the iframe-runtime slice-meta
236
+ * extractors (`parseMetaFromGlobal`, `parseMetaFromToolResult`).
237
+ * Server-minted via
242
238
  * the same `mintBootstrap` minter the JSON `/api/bootstrap/<shortCode>`
243
239
  * route uses, so both transports share replay-cache state.
244
240
  */
@@ -249,12 +245,32 @@ export interface SelfContainedShellInputs {
249
245
  * live updates silently no-op until a fresh push refreshes creds.
250
246
  */
251
247
  readonly expiresAt?: string;
248
+ /**
249
+ * Monotonic RenderEvent ledger cursor at emit time, mirrored from
250
+ * {@link McpAppAiGguiRenderMeta.lastSequence}. Polling clients
251
+ * initialize the R7 `/events?sinceSequence=N` cursor from this.
252
+ * Absent in pre-R7 envelopes (back-compat); post-R7 it MUST be
253
+ * present.
254
+ */
255
+ readonly lastSequence?: McpAppAiGguiRenderMeta["lastSequence"];
256
+ /**
257
+ * Wire-stamped polling fallback URL — `${base}/api/renders/<id>/events?wsToken=<...>`.
258
+ * When the iframe-runtime's WS transport reaches `'failed'` (CSP
259
+ * blocks `ws://`, corporate firewall, etc.), `@ggui-ai/live-channel`
260
+ * fails over to cursor-based event polling against this URL using
261
+ * `{@link lastSequence}` as the initial cursor.
262
+ *
263
+ * Absent ⇒ runtime stays in WS-only mode. Operators that want the
264
+ * fallback path lit up MUST thread this through (the canvas/inline
265
+ * shell builders do; callers composing their own shells SHOULD).
266
+ */
267
+ readonly pollingUrl?: McpAppAiGguiRenderMeta["pollingUrl"];
252
268
  }
253
269
  /**
254
270
  * Build the self-contained shell HTML for a given session.
255
271
  *
256
272
  * The returned HTML is a complete, standalone document: it inlines the
257
- * compiled component (base64) + session ids in a `window.__GGUI_BOOTSTRAP__`
273
+ * compiled component (base64) + session ids in a `window.__GGUI_META__`
258
274
  * global, then loads the iframe-runtime bundle via `<script type="module"
259
275
  * src={runtimeUrl}>`. The runtime takes over synchronously on import,
260
276
  * mounts the component, and the iframe paints WITHOUT any further server
@@ -276,40 +292,40 @@ export interface SelfContainedShellInputs {
276
292
  */
277
293
  export declare function buildSelfContainedShell(opts: SelfContainedShellInputs): string;
278
294
  /**
279
- * Minimal "loading" HTML served when a per-session resource is fetched
280
- * for a session whose top stack item has no componentCode yet
295
+ * Minimal "loading" HTML served when a per-render resource is fetched
296
+ * for a render whose visible-bits surface has no componentCode yet
281
297
  * (placeholder, generation in flight). Renders a tiny status surface
282
298
  * so hosts that pin lifecycle selectors don't see a blank document.
283
299
  *
284
- * Hosts SHOULD re-fetch when they observe additional `ggui_push`
285
- * results on the same session — the per-call `_meta.ui.resourceUri`
286
- * value stays stable across pushes for a session, so re-fetching the
300
+ * Hosts SHOULD re-fetch when they observe additional `ggui_render`
301
+ * results on the same render — the per-call `_meta.ui.resourceUri`
302
+ * value stays stable across commits for a render, so re-fetching the
287
303
  * same URI returns fresher HTML on the second try.
288
304
  *
289
305
  * @public
290
306
  */
291
- export declare function buildSelfContainedLoadingShell(sessionId: string): string;
307
+ export declare function buildSelfContainedLoadingShell(renderId: string): string;
292
308
  /**
293
- * Options for {@link registerGguiSessionResourceTemplate}.
309
+ * Options for {@link registerGguiRenderResourceTemplate}.
294
310
  *
295
311
  * @public
296
312
  */
297
- export interface GguiSessionResourceTemplateOptions {
298
- /** SessionStore the template handler reads to find the topmost
299
- * stack item's componentCode. */
300
- readonly sessionStore: SessionStore;
313
+ export interface GguiRenderResourceTemplateOptions {
314
+ /** RenderStore the template handler reads to find the render's
315
+ * componentCode. */
316
+ readonly renderStore: RenderStore;
301
317
  /** Absolute URL of the iframe-runtime bundle inlined in the shell. */
302
318
  readonly runtimeUrl: string;
303
319
  /**
304
320
  * Content-addressable code-blob store. When wired alongside
305
- * {@link codeBaseUrl}, the resource template hashes the top stack
306
- * item's componentCode, writes it to the store, and inlines the
307
- * resulting `codeUrl` into the shell bootstrap. Without these deps
308
- * the resource path emits the loading shell when the top item is a
321
+ * {@link codeBaseUrl}, the resource template hashes the render's
322
+ * componentCode, writes it to the store, and inlines the resulting
323
+ * `codeUrl` into the shell bootstrap. Without these deps the
324
+ * resource path emits the loading shell when the render is a
309
325
  * compiled component (the static-component channel cannot deliver
310
326
  * without a URL).
311
327
  */
312
- readonly codeStore?: import('@ggui-ai/mcp-server-core').CodeStore;
328
+ readonly codeStore?: import("@ggui-ai/mcp-server-core").CodeStore;
313
329
  /**
314
330
  * Base URL the code-blob route resolves to. Paired with {@link codeStore}.
315
331
  */
@@ -323,7 +339,7 @@ export interface GguiSessionResourceTemplateOptions {
323
339
  */
324
340
  readonly themeId?: string;
325
341
  /** Theme color mode resolved from `ggui.json#theme.mode`. */
326
- readonly themeMode?: 'light' | 'dark';
342
+ readonly themeMode?: "light" | "dark";
327
343
  /**
328
344
  * Per-app metadata store the resource handler reads to resolve
329
345
  * `App.publicEnv` for the bootstrap projection.
@@ -332,17 +348,17 @@ export interface GguiSessionResourceTemplateOptions {
332
348
  * resource-served bootstrap (wrappers calling `getPublicEnv` throw
333
349
  * at hook-mount with a clear "not provided" message).
334
350
  */
335
- readonly appMetadataStore?: import('@ggui-ai/mcp-server-core').AppMetadataStore;
351
+ readonly appMetadataStore?: import("@ggui-ai/mcp-server-core").AppMetadataStore;
336
352
  /**
337
353
  * Vector store backing the blueprint registry. When wired alongside
338
354
  * `defaultAppIdFallback`, the resource handler runs a registry-only
339
355
  * rehydrate fallback for the two-segment URI shape
340
- * (`ui://ggui/session/{sessionId}/{blueprintKey}`): if the session is
356
+ * (`ui://ggui/render/{renderId}/{blueprintKey}`): if the render is
341
357
  * gone but the blueprint registry still holds the entry, return the
342
358
  * static initial render (default props + default context) instead of
343
359
  * the dead "Generating UI…" loading shell. Single-tenant OSS sees
344
360
  * meaningful improvement; multi-tenant deployments leave both options
345
- * undefined to keep the loading-shell behavior on session miss.
361
+ * undefined to keep the loading-shell behavior on render miss.
346
362
  */
347
363
  readonly vectorStore?: VectorStore;
348
364
  /**
@@ -354,72 +370,72 @@ export interface GguiSessionResourceTemplateOptions {
354
370
  * and rehydrate works across session expiry / process restart.
355
371
  */
356
372
  readonly defaultAppIdFallback?: string;
357
- /**
358
- * Bootstrap minter for canvas-mode
359
- * sessions. Supplied by the deployment (cloud wires it to the
360
- * AppSync-bound minter; OSS wires it to the in-process minter
361
- * already used by /api/bootstrap/<shortCode>).
362
- *
363
- * When the resource handler observes `session.mcpAppsMode ===
364
- * 'canvas'`, it calls this to obtain `wsUrl` + `token` + `expiresAt`
365
- * and inlines them on the canvas shell's bootstrap. Without this
366
- * dep wired, the handler falls back to the legacy single-item path
367
- * (no canvas).
368
- *
369
- * Returning `null` / throwing here degrades to the legacy path
370
- * silently — the caller has no way to deliver a working canvas
371
- * without WS credentials, but pinning a stackItem render is
372
- * strictly better than serving a dead-loading shell.
373
- */
374
- readonly mintBootstrap?: (sessionId: string, appId: string) => Promise<{
375
- readonly wsUrl: string;
376
- readonly token: string;
377
- readonly expiresAt: string;
378
- } | null>;
379
373
  /**
380
374
  * Operator-supplied public origin. When present, every
381
375
  * `resources/read` response from this template carries
382
376
  * `_meta.ui.csp.{connectDomains,resourceDomains}` so claude.ai's
383
377
  * cross-origin iframe CSP allows the runtime bundle, codeUrl
384
378
  * fetches, and the live-channel WebSocket. Symmetric with the
385
- * declaration on the static `ui://ggui/session` resource. Absent ⇒
379
+ * declaration on the static `ui://ggui/render` resource. Absent ⇒
386
380
  * `_meta.ui.csp` omitted and the host's default CSP applies
387
381
  * (`connect-src 'none'` in claude.ai — runtime bundle fails to
388
382
  * load with a generic "script error").
389
383
  */
390
384
  readonly publicBaseUrl?: string;
385
+ /**
386
+ * Live-channel WebSocket bootstrap minter. When wired, every
387
+ * `resources/read` response embeds `{wsUrl, wsToken}` in the shell
388
+ * so the iframe-runtime opens a WebSocket immediately on mount and
389
+ * receives `props_update` frames for in-place re-renders.
390
+ *
391
+ * Without this, the per-render resource shell mounts in
392
+ * static-component mode (codeUrl only) — initial render works but
393
+ * server-side state mutations (`ggui_update`) never visibly update
394
+ * the iframe. Spec-compliant MCP-Apps hosts can still re-fetch
395
+ * `resources/read` per-tool-result to get fresh HTML, but in-place
396
+ * live updates require the WS pipe.
397
+ *
398
+ * Mirrors the `mintWsToken` plumbed into the handler-side render
399
+ * machinery in `server.ts`; the resource template owns its own
400
+ * call here because it runs OUTSIDE the per-tool-call context.
401
+ */
402
+ readonly mintWsToken?: (renderId: string, appId: string) => {
403
+ readonly wsUrl: string;
404
+ readonly token: string;
405
+ readonly expiresAt: string;
406
+ };
391
407
  }
392
408
  /**
393
- * Register a `ui://ggui/session/{sessionId}` resource template. Each
394
- * `resources/read` request is resolved by looking up the session in the
395
- * store, picking the topmost component stack item, and returning the
396
- * self-contained shell with that componentCode inlined.
409
+ * Register a `ui://ggui/render/{renderId}` resource template. Each
410
+ * `resources/read` request is resolved by looking up the render in the
411
+ * store and returning the self-contained shell with that
412
+ * componentCode inlined.
397
413
  *
398
- * Per-call `_meta.ui.resourceUri` (stamped by `ggui_push.resultMeta`)
399
- * pins the URI to a specific sessionId; hosts fetch THAT URI rather
400
- * than the static `ui://ggui/session` one. Both registrations co-exist:
414
+ * Per-call `_meta.ui.resourceUri` (stamped by `ggui_render.resultMeta`)
415
+ * pins the URI to a specific renderId; hosts fetch THAT URI rather
416
+ * than the static `ui://ggui/render` one. Both registrations co-exist:
401
417
  * legacy postMessage shell at the static URI, self-contained shell at
402
418
  * the templated URI.
403
419
  *
404
420
  * Failure modes:
405
- * - Session not found → loading shell (host re-fetches; absent
406
- * session is a transient state immediately after `ggui_push`).
407
- * - Session found, no componentCode yet → loading shell.
408
- * - Session found, componentCode present → self-contained shell.
421
+ * - Render not found → loading shell (host re-fetches; absent
422
+ * render is a transient state immediately after `ggui_render`).
423
+ * - Render found, no componentCode yet → loading shell.
424
+ * - Render found, componentCode present → self-contained shell.
409
425
  *
410
426
  * Returns nothing; mutates the server in place.
411
427
  *
412
428
  * @public
413
429
  */
414
- export declare function registerGguiSessionResourceTemplate(server: McpServer, opts: GguiSessionResourceTemplateOptions): void;
430
+ export declare function registerGguiRenderResourceTemplate(server: McpServer, opts: GguiRenderResourceTemplateOptions): void;
415
431
  /**
416
432
  * Apply the full MCP Apps outbound wiring to a fresh `McpServer` - both
417
- * the capability advertisement and the `ui://ggui/session` resource. The
433
+ * the capability advertisement and the `ui://ggui/render` resource. The
418
434
  * single entry-point `build-mcp.ts` calls so request-path wiring stays
419
435
  * one line.
420
436
  *
421
- * When `selfContained` is supplied, ALSO registers the per-session
422
- * `ui://ggui/session/{sessionId}` resource template that serves the
437
+ * When `selfContained` is supplied, ALSO registers the per-render
438
+ * `ui://ggui/render/{renderId}` resource template that serves the
423
439
  * self-contained shell (the path third-party MCP Apps hosts use). The
424
440
  * legacy static URI registration is unconditional — first-party hosts
425
441
  * (Studio, Portal, console) still rely on the postMessage path.
@@ -427,16 +443,15 @@ export declare function registerGguiSessionResourceTemplate(server: McpServer, o
427
443
  export declare function installMcpAppsOutbound(server: McpServer, opts?: {
428
444
  readonly shellHtml?: string;
429
445
  /**
430
- * Per-session self-contained shell registration. When supplied,
431
- * `ui://ggui/session/{sessionId}` becomes a readable resource
446
+ * Per-render self-contained shell registration. When supplied,
447
+ * `ui://ggui/render/{renderId}` becomes a readable resource
432
448
  * template whose body inlines the compiled componentCode from the
433
- * session's topmost stack item. Absent → only the legacy
434
- * postMessage shell is registered.
449
+ * render. Absent → only the legacy postMessage shell is registered.
435
450
  */
436
- readonly selfContained?: GguiSessionResourceTemplateOptions;
451
+ readonly selfContained?: GguiRenderResourceTemplateOptions;
437
452
  /**
438
453
  * Public origin the server is reachable at — forwarded to
439
- * `registerGguiSessionResource` so the static `ui://ggui/session`
454
+ * `registerGguiRenderResource` so the static `ui://ggui/render`
440
455
  * resource carries `_meta.ui.csp.{connectDomains,resourceDomains}`
441
456
  * authorising the iframe to fetch the runtime bundle and open a
442
457
  * WebSocket. Omit when running same-origin behind a first-party
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-apps-outbound.d.ts","sourceRoot":"","sources":["../src/mcp-apps-outbound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp-apps-outbound.d.ts","sourceRoot":"","sources":["../src/mcp-apps-outbound.ts"],"names":[],"mappings":"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"}