AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Bridge WebMCP tools from your browser tabs to Claude Code, Codex, or any other MCP client. A web page registers tools with document.modelContext.registerTool(); you click Connect this tab in the extension popup; those tools show up in your agent, running inside your logged-in browser session. The only server involved is a small Cloudflare Workers relay: the extension comes pointed at the hosted instance (relay.webmcp-cloud-relay.workers.dev) so it works out of the box with no account, and self-hosting the same code is one command plus a settings field.查看完整 README ↗Bridge WebMCP tools from your browser tabs to Claude Code, Codex, or any other MCP client. A web page registers tools with document.modelContext.registerTool(); you click Connect this tab in the extension popup; those tools show up in your agent, running inside your logged-in browser session. The only server involved is a small Cloudflare Workers relay: the extension comes pointed at the hosted instance (relay.webmcp-cloud-relay.workers.dev) so it works out of the box with no account, and self-hosting the same code is one command plus a settings field.
flowchart TB
A["MCP client<br/>Claude Code · Codex · …"]
subgraph relay["Relay — hosted default, or self-hosted (Cloudflare Workers)"]
W["Worker router<br/>/t/:token/mcp · /t/:token/ws"]
DO["Bridge Durable Object<br/>one per pairing token"]
W --> DO
end
SW["Extension service worker<br/>grants · namespacing · reconnect"]
CS["Content script (isolated)<br/>+ reader (MAIN, consumer only)"]
P["Web page with WebMCP<br/>native (origin trial) or site-shipped polyfill"]
A -->|"streamable HTTP (MCP)"| W
DO <-->|"WebSocket"| SW
SW <-->|"chrome.runtime port"| CS
CS <-->|"getTools / executeTool<br/>+ toolchange"| P
The extension holds an outbound WebSocket to the relay, so nothing in your browser needs to be reachable from the internet. The relay's Durable Object — one per pairing token — keeps the current tool snapshot and forwards tools/call to the extension, which routes it to the granted tab.
The interesting part is the last hop. The extension is a pure consumer: it never defines a web API on pages. A page opts into WebMCP itself — either the browser ships document.modelContext natively (Chrome 149 has one behind an origin trial), or the page ships any spec-shaped polyfill, such as GoogleChromeLabs' webmcp-polyfill.
To consume it, the extension injects a MAIN-world reader: a subscriber that watches for document.modelContext (a page-shipped polyfill is MAIN-world JavaScript, invisible to the isolated world), listens to toolchange, lists tools with getTools(), and runs them with executeTool() — the spec's own caller side, so the tool always executes in the page's context. The reader relays to the isolated-world content script over window.postMessage; that protocol is internal to the extension, both ends being extension code. On pages without WebMCP the reader finds nothing, announces nothing, and modifies nothing.
activeTab).search on github.com is exposed as github_com_search, so several connected tabs never collide.notifications/tools/list_changed; MCP clients on the SSE stream re-list automatically.1. Build and load the extension (or grab the zip from the latest release):
cd packages/extension
pnpm build
Open chrome://extensions, enable Developer mode, click Load unpacked, and select packages/extension/dist.
2. Copy your MCP URL. Open the popup: it already points at the hosted relay and shows your MCP URL — https://…/t/<token>/mcp — masked, with a copy button and a Reveal toggle. (Prefer your own relay? See Self-hosting the relay.)
3. Register the server with your agent.
Claude Code:
claude mcp add --transport http webmcp <mcpUrl>
Codex:
codex mcp add webmcp --url <mcpUrl>
4. Connect a tab. Open a page that registers WebMCP tools, click the extension icon, and press Connect this tab. The badge turns green, and the tools appear in your agent (existing sessions pick them up via tools/list_changed).
No such page at hand? Open your relay's base URL, e.g. relay.webmcp-cloud-relay.workers.dev — it serves examples/demo/index.html, which registers three note-taking tools when document.modelContext exists in your browser (and tells you when it doesn't). The official demos also make good test targets.
The hosted relay is the default for convenience, but the relay is designed to be yours: tool arguments and results pass through it in plaintext (see Security model), and self-hosting removes that trust entirely. You need a Cloudflare account (the free plan is plenty — see Costs) and wrangler login:
cd packages/relay
pnpm install
pnpm run deploy
Wrangler prints the deployed URL, e.g. https://relay.<your-subdomain>.workers.dev. Paste it into the popup's Settings → Relay base URL; your MCP URL changes accordingly, so re-register it with your agent.
Write standard WebMCP code — feature-detect and register:
if (document.modelContext) {
document.modelContext.registerTool({
name: "add_todo",
description: "Adds a todo item",
inputSchema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"],
},
execute: ({ text }) => addTodo(text),
});
}
Until browsers ship the API by default, make document.modelContext exist on your page the way the official demos do: register for the origin trial for native support, and/or include a spec-shaped polyfill such as GoogleChromeLabs' webmcp-polyfill (Apache-2.0). The bridge consumes whichever implementation is present — it needs the caller side (getTools / executeTool / toolchange) in addition to registerTool.
Read this before pointing an agent at a page you do not trust. The privacy policy (PRIVACY.md) covers the same ground in policy form.
untrustedContentHint, and the MCP server's instructions tell the client to treat results as data, never as instructions. Prompt injection through a hostile page is a real risk — only connect tabs you trust.chrome.storage.session, so they are gone after a browser restart. Closing a tab or navigating it to another origin drops its grant.For personal use the relay fits in Cloudflare's free plan; the Workers Paid plan ($5/month) buys headroom. The dominant charge is Durable Object duration: the DO is billed at 128 MB for as long as it is active, and it is active the whole time an MCP client holds the SSE notification stream open — about 450 GB-s per hour, against a free-plan limit of 13,000 GB-s/day (so even one client connected 24/7 just fits, and clients like Claude Code only connect during a session). The relay also caps this surface: at most 4 concurrent SSE streams per bridge, each living at most 2 hours (clients reconnect transparently), and streams are closed after 5 minutes without the extension connected. Everything else — MCP requests, the extension's hibernated WebSocket with its auto-response pings, the one-row tool snapshot, the static demo page, egress — is negligible or free.
pnpm install # at the repo root
pnpm -r typecheck
pnpm -r test
For the relay, cd packages/relay && pnpm dev runs wrangler dev with a local Durable Object; point the extension at the printed http://localhost:8787 to exercise the whole path. For the extension, pnpm build in packages/extension re-bundles into dist/; hit Reload on chrome://extensions afterwards.
| Path | What it is |
|---|---|
packages/protocol | Shared wire types between the extension and the relay (tool descriptors, WebSocket message union). |
packages/relay | Cloudflare Worker: MCP streamable-HTTP endpoint, Bridge Durable Object, extension WebSocket. |
packages/extension | Chrome MV3 extension: MAIN-world reader (consumer only), content script, service worker, popup UI. |
examples/demo | A tiny WebMCP page (three note-taking tools) to try the bridge against. |
MIT — see LICENSE.