WebMCP document.modelContext: Stop Registering on navigator
Chrome moved the getter, deprecated navigator.modelContext in Chromium 150, and left an alias so your old paste still runs. Here is how I register real tools on a live SPA configurator.
WebMCP document.modelContext: When navigator Still Works and You Still Lose
I pasted navigator.modelContext from a March tutorial, registered three tools, called getTools(), and got an empty array back on a page that "supported WebMCP."
Blood pressure spike. The alias hid the move. Chrome put the getter on document.modelContext in the W3C draft (May 27 2026). Chromium 150 marked navigator.modelContext deprecated and kept the alias so nothing hard-fails.
That is the trap. WebMCP document.modelContext is the name you should ship on. Feature-detect both globals, register on document, unregister with AbortSignal, pass signal through execute, and prove the registry with getTools() before an agent wastes a session screenshot-clicking your configurator.
>
The trap: navigator.modelContext still resolves in Chrome 150. document.modelContext is where
registerTool lives now. Copy old snippets and you look integrated while agents get zero callable
tools.
Why WebMCP document.modelContext matters on product pages
I am wiring this on another site - a live SPA with a real-time 3D configurator shell, not on bernhardrieder.com. The business case is blunt.
If the page exposes no tools, the agent guesses from pixels. If the page exposes get_config and set_option, the agent finishes the configuration task. That is career leverage for frontend builders who own revenue surfaces.
Server MCP - Cursor config, Unreal editor plugins - runs outside the tab. WebMCP runs inside the page on document.modelContext. Different layer. Different playbook.
Chrome Imperative API baseline //
Google's Imperative API docs (published May 18 2026, updated August 20 2026) document registerTool on
document.modelContext with name, description, inputSchema, and execute. HTTPS is required. Origin
trial is the Chrome shipping path today.
1
document, not navigator
Chromium 150 deprecated navigator.modelContext. The alias is a bridge, not a strategy.
2
AbortSignal unregister
provideContext and unregisterTool() are gone. Pass controller.signal into registerTool, then
controller.abort() on teardown.
3
getTools() proof
Do not trust registration logs. Same-origin getTools() is the receipt agents need.
4
In-flight safety
Chrome 153: unregistering does not break in-flight executions. Still pass signal into fetch
inside execute.
navigator.modelContext deprecated: the silent alias problem
Google's modern-web guidance is explicit. navigator.modelContext is deprecated in Chromium 150. provideContext, clearContext, and unregisterTool() are no longer supported.
The alias means your staging build keeps working while your mental model rots. I hit this on a configurator branch where registration ran on navigator and document.modelContext.getTools() returned nothing useful.
navigator.modelContext deprecated in Chrome 150: the alias hides the move to document.modelContext.
Ship registration on document before the bridge disappears.
If modelContext is undefined, stop. Check HTTPS, origin trial token, and Chrome build. Do not throw on public traffic.
document.modelContext registerTool on a 3D configurator SPA
My configurator exposes three tools. That is enough for an agent to read state, change an option, and discover valid keys.
get_config returns JSON state. set_option applies one key/value. list_options returns the catalog the UI already knows about.
Each registration shares one AbortController so route changes tear down the whole bundle.
javascript
1const controller =newAbortController();2const{ signal }= controller;34modelContext.registerTool({5name:'get_config',6description:'Return current configurator state as JSON',7inputSchema:{8type:'object',9properties:{},10additionalProperties:false,11},12 signal,13execute:async(_input,{signal: execSignal })=>{14if(execSignal?.aborted)thrownewDOMException('Aborted','AbortError');15return{16content:[{type:'text',text:JSON.stringify(getConfigState())}],17};18},19});
Mirror that pattern for set_option and list_options. Keep schemas strict. Agents send JSON - loose schemas create silent rejects.
WebMCP 3D configurator tools share one AbortController. controller.abort() unregisters every tool
bound to that signal - your kill-switch for modal close or route leave.
>
Key Insight: registerTool without getTools() verification is theater. I log names after every boot:
modelContext.getTools().map((t) => t.name). Same-origin only unless you opt into fromOrigins.
AbortSignal unregister WebMCP and Chrome 153 in-flight behavior
Unregister means pass signal from AbortController into registerTool, then call controller.abort() when the shell unmounts or an operator hits kill-switch.
As of Chrome 153, unregistering a tool does not cancel in-flight executions. That is good for production - a teardown mid-request should not corrupt partial config state.
Still pass execSignal into fetch inside execute. Cancellation becomes your policy, not the browser's accident.
javascript
1exportfunctionteardownWebMcpTools(controller){2 controller.abort();3const remaining = modelContext.getTools();4console.info('[WebMCP] tools after abort', remaining.map((t)=> t.name));5}
Listen for toolchange on document.modelContext if you run multiple registration waves. Registration and abort both emit events worth logging in staging.
Chrome WebMCP origin trial //
WebMCP ships through Chrome origin trial today. Apply the token on domains you control. Microsoft
co-authored the W3C work - that is not the same as Edge shipping the same build behavior. Do not
invent cross-browser dates.
WebMCP vs MCP vs llms.txt
Three layers. I keep them separate in architecture reviews.
Server MCP - processes, editors, CLIs. Cursor talks to GitHub. Unreal exposes editor tools on loopback. Install and auth live in config files.
WebMCP - tools inside the tab on document.modelContext. The agent that already has the page open can call executeTool without a sidecar server.
llms.txt - static discovery file. Great for crawl agents. It does not execute set_option on a live GLB material.
You need the right layer per surface. A configurator needs WebMCP registerTool on the page that owns the state.
WebMCP vs MCP vs llms.txt: in-page imperative tools, out-of-page servers, and static agent
discovery solve different problems. Mixing labels confuses buyers and breaks integrations.
executeTool smoke tests before you trust any agent
After registration, run imperative smoke tests in the console:
If smoke tests pass and the UI moves, you have callable tools. If the agent still screenshots, the runtime is not wired to WebMCP yet - that is a different integration ticket.
Cross-origin iframe tools need allow="tools" Permissions Policy on the iframe and exposedTo origins on registerTool. Parent pages call getTools({ fromOrigins: ['https://child.example'] }) only when policy allows it.
What I ship next on the configurator branch
I keep server MCP for build pipelines and editor automation. I keep WebMCP on the product surface where money changes hands.
My checklist before merge: feature detect, three tools, getTools() log, executeTool smoke, abort teardown, no registration on bernhardrieder.com or any domain I do not own.
Download the directive in the Toolbox tab. It is the agent-runnable version of this playbook - phases, validation gates, and kill-switch abort in one paste.
>
Bottom line: document.modelContext registerTool is the API name search will chase in late 2026.
navigator.modelContext deprecated is the trap that wastes a sprint. Prove tools with getTools(),
not hope.
Latest Blog Posts
Guide2026-08-29
Unreal Engine MCP Cursor Setup: Wire the Agent to UE 5.8
Unreal Engine MCP Cursor setup fails when All Toolsets is off, Auto Start is skipped, or Cursor opens before the editor. Here is the exact UE 5.8 plugin order, the ModelContextProtocol.GenerateClientConfig Cursor command, and a kill-switch so Spatial AI gets hands without nuking the project.
Manifesto2026-05-02
The Rise of the Agentic Internet
The era of building website content is dead. The digital world just hasn't seen the body yet. I am moving to Full Agentic AI — and the implications will dismantle the current server-based software industry.
2026-02-12
LM Studio vs. Ollama
LM Studio runs Llama 4 Scout on local GPUs - but even 96GB VRAM has limits. Context length matters. Kilo Code bridges your IDE to local models. Here is what I learned.
Best Practices2026-02-08
Why You Must Run ESLint Before You Touch the "Cloud"
Running ESLint locally isn't optional - it's your first defense against broken Vercel deployments. I learned this the hard way when my code pushed to Git, triggered Vercel, and failed after 5 minutes of waiting. The fix? A 0.5-second local ESLint check that catches errors before they reach production. Here's why ESLint prevents deployment failures, code rot, and invisible performance bugs.
A
B
C
This article is part of a Semantic Cluster. All links are managed by the Digital Architect AI.