orca-webmcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@orca-webmcpBuild me a pizza using the tools in the page open in Orca"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
orca-webmcp
An MCP server that exposes the WebMCP tools of pages open in Orca's embedded browser to any MCP client — Claude Code, Codex, Cursor, or an agent running inside an Orca terminal.
No Chrome extension, no browser flag, no WebSocket bridge, no external browser.
Why
The existing way to hand WebMCP tools to a desktop agent is the WebMCP Bridge Chrome extension, which needs:
a real Chrome install with
chrome://flags/#enable-webmcp-testingenabled,the extension installed and manually activated per tab,
navigator.modelContextTesting, which only exists behind that flag,a WebSocket server holding
127.0.0.1:12315.
Orca already ships a Chromium browser and an orca eval command that runs JavaScript in a tab.
That is everything the job needs: document.modelContext exposes getTools() and executeTool()
directly, so tools can be read and invoked without any of the machinery above.
Related MCP server: @teatak/mcp-server-browser
How it works
Orca tab (page registers tools on document.modelContext)
↑ orca eval --page <id> --expression "...getTools() / executeTool()..."
orca-webmcp (this MCP server)
↑ stdio / MCP
Any MCP clientOn every tools/list the server runs orca tab list, evaluates document.modelContext.getTools()
in each tab, and republishes the results as MCP tools named tab{index}_{toolName}. A tools/call
resolves that name back to a page id and runs executeTool there.
Tabs without WebMCP contribute nothing and never fail the listing.
Requirements
Node.js 18+
The Orca app running, with its CLI on
PATH(or setORCA_BIN)A page that exposes
document.modelContext— natively, or via@mcp-b/webmcp-polyfill
Install
npm installRegister with a client
# Claude Code
claude mcp add --scope user --transport stdio orca-webmcp -- node /absolute/path/to/src/index.js// Cursor — .cursor/mcp.json
{ "mcpServers": { "orca-webmcp": { "command": "node", "args": ["/absolute/path/to/src/index.js"] } } }Configuration
Variable | Default | Purpose |
|
| Path to the Orca CLI |
| (all tabs) | Scope tools to one worktree's tabs, e.g. |
|
| Per-command timeout in ms |
Try it
orca tab create --url https://googlechromelabs.github.io/webmcp-tools/demos/pizza-maker/Then ask your agent to build a pizza. The tools appear as tab0_add_topping,
tab0_set_pizza_style, and so on.
In-page agent (no model API key)
The same repo ships a floating chat panel that runs inside the page, so a user can drive a WebMCP site without a terminal, an extension, or a model API key. The brain is a live Claude Code session held open by the bridge, authenticated by the operator's existing login.
Widget in the page ──HTTP──▶ agent-server ──▶ live Claude Code session
▲ │
└──────── orca eval ◀── orca-webmcp ◀────── MCP ──────┘The session stays open per tab. Spawning a process per prompt put ~10-12s of startup in front of ~3s of work; an open session pays that once. Measured end to end through the panel: 41s per prompt before, ~10s after the first.
The turn Claude Code runs already has this project's MCP server registered, so it can call the very tools the page exposes — the request goes out through HTTP and comes back in through the browser.
npm run agent # bridge on 127.0.0.1:8765
orca tab create --url https://googlechromelabs.github.io/webmcp-tools/demos/pizza-maker/
npm run inject -- --url pizza-maker # or --page <id>, or --allThe panel lists the page's tools and refreshes on toolchange. Each browser tab keeps its own
conversation, so follow-up prompts have context.
Orca's toolbar cannot be extended by third parties, so there is no button to click. Instead, run the watcher and the panel mounts itself on every http(s) tab, surviving navigation:
npm run watchVariable | Default | Purpose |
|
| Bridge port |
|
| Close a tab's session after this much silence |
Why the bridge is not simply open
The bridge is a listening port on the operator's machine, and every page loaded in the browser can
reach 127.0.0.1. Two things keep a hostile page from using it:
A per-run token. The server mints a secret at startup and writes it to
$TMPDIR/orca-webmcp-token with mode 0600. inject.js and watch.js read it and bake it into the
panel they mount, so a page the operator injected can call /chat and a drive-by page gets a 403.
A tool allowlist. The session is restricted to mcp__orca-webmcp__*. Even a request that
somehow carried a valid token can only call WebMCP tools in tabs the operator already opened — not
read files, not run commands.
The trailing
__*is load-bearing.mcp__orca-webmcpon its own matches no tool, and a turn that can call nothing answers as though the page had never registered any.
Nothing about the operator's Claude subscription is stored or transmitted by this project: the Agent SDK reads Claude Code's own credentials, and the bridge only ever sees prompt text and the session's reply.
Making your own page reachable
Orca's Chromium does not ship WebMCP, so document.modelContext only exists on a page that brings
it. Load the polyfill and your tools register everywhere — Orca, Chrome with the flag, Chrome
without it:
npm i @mcp-b/webmcp-polyfillimport { initializeWebMCPPolyfill } from '@mcp-b/webmcp-polyfill';
initializeWebMCPPolyfill(); // no-op where the browser already provides the API
document.modelContext.registerTool({
name: 'make_offer',
description: 'Offer a price for the listing. The seller accepts or counters.',
inputSchema: {
type: 'object',
properties: { amount: { type: 'number', description: 'Offer in US dollars.' } },
required: ['amount'],
},
async execute({ amount }) {
const verdict = evaluateOffer(amount); // your logic, your rules, your secrets
return { content: [{ type: 'text', text: verdict }] };
},
});The polyfill costs nothing where it is not needed — it returns early when document.modelContext
already exists — and without it a page that guards its registration is silently invisible to every
agent:
if (document.modelContext) { // undefined in Orca
document.modelContext.registerTool(...); // never runs, no tools, no error
}That guard is why most of the Chrome Labs demos expose nothing here. They are showcases for the native API written for developers running the flag, not sites built to work on a stranger's machine — a distinction worth keeping when borrowing their structure.
Keep the polyfill until native support is the common case. The API moved from
navigator.modelContext to document.modelContext during 2026, and the npm package tracks changes
like that; a vendored copy does not.
Registration and consumption are separate
document.modelContext is where a page registers tools. Reading and invoking them is a different
surface, and which one is available depends on the browser:
Surface | Purpose | Where it exists |
| a page publishes a tool | native, or via the polyfill |
| an agent reads and calls tools | alongside the above — this is what this project uses |
| the testing consumer API | only behind |
Extensions built against navigator.modelContextTesting need that flag and a Chrome new enough to
have it. Reading getTools() off document.modelContext needs neither, which is why this project
works in a browser that has no WebMCP support of its own.
Known limits
Tool names are keyed by tab index, which shifts when tabs are opened or closed. The mapping is rebuilt on every
tools/listand refreshed on a miss, but a call issued against a stale listing can land on a different tab.Tool changes are not pushed. The server has no
tools/list_changednotification yet, so a client sees new tools on its next listing.Orca's Chromium (Chrome 150 as of app 1.4.190) does not ship WebMCP natively; pages must load the polyfill themselves. All Chrome Labs demos do.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Access Kernel's cloud-based browsers and app actions via MCP (remote HTTP + OAuth).
MCP server to assist with JxBrowser development.
Search, inspect and invoke every public tool on Invokera through one MCP connection.
Stealth web browser for agents: search, fetch, click, download and type in persistent MCP sessions.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP bridge server that allows AI tools to call functions and execute code directly within a web browser tab. It enables developers to register custom browser-side tools with full access to the DOM, web APIs, and local application state.16Apache 2.0
- AlicenseNot gradedqualityDmaintenanceAn MCP server that runs in the browser, letting web pages register custom tools and prompts and expose them to an MCP client over WebSocket. Enables agents to drive UI, call page-scoped APIs, and get human-in-the-loop confirmation.15MIT
- FlicenseNot gradedqualityDmaintenanceEnables websites to expose JavaScript functions as MCP tools, allowing AI agents to interact with the browser environment via a protocol and Chrome extension.1,093
- AlicenseNot gradedqualityAmaintenanceBridges OpenCode to Chromium's WebMCP API, exposing WebMCP tools from a webpage as standard MCP tools for any MCP client.181MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/FrancoDuran23/orca_webMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server