Serve the MCP-Apps shell from static assets on Workers hosts - #1502
Merged
Conversation
The deployed cloud Worker has no filesystem, so loadMcpAppsShellHtml's fs.readFile always failed and the ui://executor/shell.html resource silently served a 'Shell not built' placeholder — an inert document that never starts the MCP-Apps handshake, so every artifact widget in every MCP client spun on its loading state forever with no error anywhere. - Workers hosts (cloud, host-cloudflare) now fetch the built shell through the ASSETS binding: mcpAppsShellAsset emits a stable-named copy alongside the content-hashed one, and makeAssetsShellHtmlLoader (new @executor-js/mcp-apps-shell/worker entry) reads and verifies it. Under vite dev the document travels inline via a dev-only virtual module, since no assets are emitted yet. - The shell document carries an identity marker the loaders verify, so an SPA not-found fallback (index.html with a 200) can never be served as the shell. - The self-host image reads the same emitted asset from its SPA dist; the runtime image has no packages/ tree for the old candidates. - The silent placeholder is gone: a host that cannot produce the shell fails the resource read with an actionable error. - App builds now fail when the shell asset is missing or wrong (apps/cloud scripts/build.mjs, assert-shell-asset.mjs on both hosts).
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
executor-cloud | 1e50ff3 | Jul 30 2026, 01:39 AM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 1e50ff3 | Commit Preview URL Branch Preview URL |
Jul 30 2026, 01:38 AM |
Contributor
Cloudflare previewTorn down — the PR is closed. |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
RhysSullivan
marked this pull request as ready for review
July 30, 2026 01:57
This was referenced Jul 30, 2026
RhysSullivan
added a commit
that referenced
this pull request
Jul 30, 2026
* Deliver MCP responses larger than the DO storage value cap The DO transport persisted every outbound message for reconnect replay BEFORE writing the live SSE frame, and storage.put of a value over the 128 KiB DO cap throws — so an oversize response (the ~5MB ui://executor/shell.html resource) was neither stored nor delivered and the client hung on keepalives forever. Found live in prod after #1502 made the shell resource actually serve its bytes. - storeEvent skips persistence for messages over a 120 KiB guard, logging mcp_event_store_skipped_oversize and returning undefined; the caller delivers the live frame without a replay id. - sendOnStream treats any storeEvent failure as best-effort: log, then still write the live SSE frame. - New e2e (cloud/mcp-oversize-response.test.ts) drives resources/read of the shell over real workerd and fails on a hang. - Event-store unit tests updated for the skip contract. * Fix e2e typecheck: Effect.die instead of the unavailable dieMessage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The cloud MCP host served a
Shell not builtplaceholder as theui://executor/shell.htmlresource:loadMcpAppsShellHtmlreads the built shell withfs.readFile, which can never succeed on a deployed Worker, and the loader silently fell back to an inert placeholder (and cached it for the isolate's lifetime). The placeholder never starts the MCP-Apps handshake, so every artifact widget in every remote MCP client hung on its loading state with no error anywhere in the chain. Confirmed against production with a directresources/read.The self-host image had the same failure by a different path: its runtime bundle carries no
packages/tree, so every read candidate missed there too.Fix
mcpAppsShellAssetnow emits a second, stable-named copy of the built shell (/assets/executor-mcp-apps-shell-stable.html) alongside the content-hashed one.@executor-js/mcp-apps-shell/workerentry:makeAssetsShellHtmlLoaderfetches that asset through theASSETSbinding (same pattern as the worker-bundler artifact, Serve the worker-bundler artifact from static assets #1378). cloud and host-cloudflare DOs use it; host-cloudflare gains theASSETSbinding in wrangler.jsonc. Undervite devthe document travels inline through a dev-only virtual module, built on first use.<meta>marker that loaders verify, so an SPA not-found fallback (index.html with a 200) can never be served as the shell.apps/cloud/scripts/build.mjsandassert-shell-asset.mjson both self-host targets fail the build if the stable asset is missing or is not the shell document; the shell build itself fails if the marker is lost.Verification
packages/hosts/mcp-apps-shellfull suite (82 tests, incl. the Chromium browser suite) green; new unit tests for the assets loader (404, SPA-fallback 200, dev thunk, caching).packages/hosts/mcpsuite green (167 tests).undefinedas intended.scenarios/artifacts.test.tsagainst the cloud target: 4/4 passed.