Conversation
Adds ui/sandbox-list-tools, ui/sandbox-call-tool and ui/notifications/sandbox-tools-changed to the draft specification: the Sandbox proxy, which is the only party same-origin with the View, reads the tools the View registers with WebMCP (document.modelContext) and answers the Host itself. The standard tools/list and tools/call are untouched and keep reaching Views that answer them. The `tools` app capability and the View-handled tools/list, tools/call and notifications/tools/list_changed are marked deprecated in favor of WebMCP. Includes the matching spec types and regenerated schemas. Illustrates one of the options discussed in modelcontextprotocol#797.
App.registerTool() becomes a deprecated wrapper over
document.modelContext.registerTool(): the App no longer serves the tool
over tools/list / tools/call and no longer declares the `tools`
capability on its behalf. A callback's structuredContent (or its
content) becomes the WebMCP result; isError rejects. App.oncalltool,
App.onlisttools and App.sendToolListChanged are deprecated too, and the
first two warn once per App.
Host side, AppBridge.sendSandboxResourceReady() injects a small
document.modelContext polyfill into the View HTML by default
(`modelContextPolyfill: false` opts out; a native implementation wins).
createModelContextRelay() is the helper a Sandbox proxy uses to read the
View's tools and answer the new reserved messages, and AppBridge gains
listWebMcpTools(), callWebMcpTool() and onwebmcptoolschange. listTools()
and callTool() are deprecated.
A tool result is {content: [], structuredContent: value}; a tool that
throws is an isError result.
This is a breaking change in behavior: a View on this SDK that uses
registerTool exposes no tools on a Host that has not adopted the
polyfill injection and the relay.
The sandbox proxy uses createModelContextRelay() to answer the Host's reserved tool messages from the View's document.modelContext, and the Host lists and calls the tools with listWebMcpTools() / callWebMcpTool() in a new "App tools (WebMCP)" panel. The sandbox iframe delegates the `tools` Permissions Policy feature so native WebMCP works too.
Migrates the budget-allocator, map, pdf and debug examples from app.registerTool() to document.modelContext.registerTool(), typed with webmcp-types (0.1.10, MIT, no dependencies, pinned). Tools return plain data, which reaches the Host as structuredContent, and throw to report errors. debug-server logs its WebMCP calls instead of the raw oncalltool / onlisttools handlers; three.js no longer declares a `tools` capability it has no handlers for.
Describes the move to WebMCP for Views, and what Hosts and Sandbox proxies have to adopt, including the behavior change for Views that keep using app.registerTool() on a Host without the polyfill injection and the relay.
Loads the budget-allocator, debug and shadertoy examples in basic-host and lists and calls their tools end to end: a View registering with document.modelContext, a throwing tool, and the deprecated App.registerTool() wrapper (with its single warning).
The docker targets bind-mounted the repo and ran `npm ci` in it, which left the host with Linux binaries in node_modules, and passed `-it`, which fails without a terminal. They now share scripts/e2e-docker.sh: the repo is still mounted (so snapshots are written back) but every node_modules directory is shadowed by an anonymous volume, and `-it` is only used when stdin and stdout are terminals.
@modelcontextprotocol/ext-apps
@modelcontextprotocol/server-basic-preact
@modelcontextprotocol/server-basic-react
@modelcontextprotocol/server-basic-solid
@modelcontextprotocol/server-basic-svelte
@modelcontextprotocol/server-basic-vanillajs
@modelcontextprotocol/server-basic-vue
@modelcontextprotocol/server-budget-allocator
@modelcontextprotocol/server-cohort-heatmap
@modelcontextprotocol/server-customer-segmentation
@modelcontextprotocol/server-debug
@modelcontextprotocol/server-lazy-auth
@modelcontextprotocol/server-map
@modelcontextprotocol/server-pdf
@modelcontextprotocol/server-scenario-modeler
@modelcontextprotocol/server-shadertoy
@modelcontextprotocol/server-sheet-music
@modelcontextprotocol/server-system-monitor
@modelcontextprotocol/server-threejs
@modelcontextprotocol/server-transcript
@modelcontextprotocol/server-video-resource
@modelcontextprotocol/server-wiki-explorer
commit: |
This branch has not been deployed
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.
Summary
Prototype of one option discussed in #797: make WebMCP (
document.modelContext) how a View exposes tools, deprecatingapp.registerTooland View-handledtools/list. The issue is undecided, so this is meant to make that option concrete for discussion, not to merge as-is. Related: #796, #691.AppBridgeinjects a small polyfill into the View HTML (a native implementation wins). The sandbox proxy, the only party same-origin with the View, reads the tools with a newcreateModelContextRelayand answers reserved messages; Hosts call newlistWebMcpTools()/callWebMcpTool(). Results are{content: [], structuredContent: value}. Spec, basic-host, four examples and a v3 migration guide follow. The last commit (docker e2e script) is independent and can be dropped.Breaking: a View using
registerToolexposes no tools on a Host without the injection and relay. It needs a major release; no version bump here.Test plan
bun test src examplespasses (558); tsc and typedoc are clean.npm run test:e2e:dockershows the same 24 failures as a cleanorigin/mainrun (font rendering on arm64 Docker, PDF servers not starting) plus 3 new passing WebMCP tests, which also pass in Chrome 154 with native WebMCP. Not verified: other browsers, real third-party Hosts.Known limits: no image results, no size caps in the relay, native quirks handled for current Chrome only.
cc/ @liady @idosal @domfarolino