History

Keep MCP-Apps rendering across a cold session restore

The negotiated MCP-Apps capability lived only in the tool server instance, set from the client at initialize. A session whose Durable Object was evicted (deploy, idle) and cold-restored on the same mcp-session-id was rebuilt with no initialize to replay, so apps support read back as false and create-artifact/show-artifact answered with the deep-link fallback instead of the inline widget, mid-conversation. Persist the negotiated bit in SessionMeta and seed the rebuilt server from it. A real initialize still overrules the restored value in both directions, and init carries the stored bit through its re-resolve so restoring a session no longer erases it.

Rhys Sullivan committed 3 months ago

Commit ed7bf081 parent a7c46896 files · +325 −4Browse files

Showing the changes to apps (2 of 6 files). Show all

Unified · Split

2 files
  1. apps/cloud/src/mcp/session-durable-object.ts +4 −0
  2. apps/host-cloudflare/src/mcp/session-durable-object.ts +4 −0
apps/cloud/src/mcp/session-durable-object.ts+4−0
@@ -280,6 +280,10 @@ export class McpSessionDOSqlite extends McpAgentSessionDOBase<Env, CloudSessionD · 279 unmodified lines
280 // flag existed carry no value; absent now means off, same as a fresh280 // flag existed carry no value; absent now means off, same as a fresh
281 // connection that did not ask for `?artifacts=true`.281 // connection that did not ask for `?artifacts=true`.
282 artifactsEnabled: sessionMeta.artifactsEnabled ?? false,282 artifactsEnabled: sessionMeta.artifactsEnabled ?? false,
283 // Cold restores rebuild this server with no `initialize` to replay, so
284 // the negotiated apps support comes back from storage instead.
285 restoredAppsEnabled: sessionMeta.appsEnabled ?? false,
286 onAppsEnabledChange: (appsEnabled) => self.persistAppsEnabled(appsEnabled),
283 loadAppShellHtml,287 loadAppShellHtml,
284 smokeRenderArtifact,288 smokeRenderArtifact,
285 artifactUrl: artifactUrlFor(289 artifactUrl: artifactUrlFor(
apps/host-cloudflare/src/mcp/session-durable-object.ts+4−0
@@ -149,6 +149,10 @@ export class McpSessionDO extends McpAgentSessionDOBase<CloudflareEnv, CfSession · 148 unmodified lines
149 // flag existed carry no value; absent now means off, same as a fresh149 // flag existed carry no value; absent now means off, same as a fresh
150 // connection that did not ask for `?artifacts=true`.150 // connection that did not ask for `?artifacts=true`.
151 artifactsEnabled: sessionMeta.artifactsEnabled ?? false,151 artifactsEnabled: sessionMeta.artifactsEnabled ?? false,
152 // Cold restores rebuild this server with no `initialize` to replay, so
153 // the negotiated apps support comes back from storage instead.
154 restoredAppsEnabled: sessionMeta.appsEnabled ?? false,
155 onAppsEnabledChange: (appsEnabled) => self.persistAppsEnabled(appsEnabled),
152 loadAppShellHtml: self.loadAppShellHtml,156 loadAppShellHtml: self.loadAppShellHtml,
153 smokeRenderArtifact,157 smokeRenderArtifact,
154 ...(artifactOrigin158 ...(artifactOrigin

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t