Expose Your WebMCP Tools as an MCP Server
Short answer: @mcptrail/webmcp-bridge implements the MCP JSON-RPC methods — initialize, tools/list, and tools/call — backed by the tools your page has registered with WebMCP, over a transport you plug in. That turns browser-only tools into a real MCP endpoint, so any MCP client can list and call them instead of only a browser agent that happens to be in the tab.
WebMCP tools are declared in the page and callable in the browser session. That’s their strength and their cage: a desktop MCP client like Claude Desktop or Cursor has no endpoint to reach them. The bridge speaks MCP on one side and your registered WebMCP tools on the other. (For the protocol basics, see What is WebMCP?)
Install and create a bridge
The package is MIT open source on GitHub at github.com/ElBartoTn/webmcp-bridge. Install it in the page (or worker) that has your WebMCP tools registered:
npm install @mcptrail/webmcp-bridge
Create a bridge with a transport, then hand it JSON-RPC requests. It answers them from the page’s live toolset:
import { createMcpBridge } from "@mcptrail/webmcp-bridge";
const bridge = createMcpBridge({ transport });
const res = await bridge.handle({
jsonrpc: "2.0",
id: 1,
method: "tools/list",
});
// res.result.tools === the page's registered WebMCP tools, in MCP shape
bridge.handle takes any MCP request and returns a proper JSON-RPC response. You wire it to whatever carries messages to your client — that’s the transport.
The three methods it implements
An MCP server is, at minimum, three request handlers. The bridge maps each onto the page’s WebMCP tools:
| Method | What the bridge does |
|---|---|
initialize | Returns server capabilities and protocol version so the client can handshake |
tools/list | Enumerates the page’s registered WebMCP tools as MCP tool definitions |
tools/call | Invokes the named WebMCP tool with the client’s arguments and returns the result |
Because it answers from the live registration, a tool the page registers later shows up in the next tools/list — you don’t re-declare anything in the bridge. It’s a thin, faithful adapter, not a second copy of your tool definitions.
Pluggable transport
handle is transport-agnostic on purpose. It takes a request object and returns a response object; how those bytes travel is up to you. That means the same bridge works over a WebSocket to a relay, a postMessage channel to an extension, or an in-memory pipe in a test.
// Example: drive the bridge from incoming transport messages
transport.onMessage(async (raw) => {
const request = JSON.parse(raw);
const response = await bridge.handle(request);
transport.send(JSON.stringify(response));
});
Swap the transport and the tool logic never changes. This is what lets a browser tab present itself to a desktop MCP client: the transport carries JSON-RPC out of the page, and the bridge answers every request from the tools registered in that tab.
What the bridge does and doesn’t do
The bridge solves reachability — it makes browser tools speak MCP. It does not add auth, logging, policy, or approvals. Anyone who can reach the transport can call tools/call, and there’s no record of what ran. For a personal tool over a trusted transport that’s fine. For anything shared, you want a governed layer in front.
That governed layer is the hosted version. Turn a WebMCP site into a guarded MCP server explains how MCP Trail’s Chrome extension bridges a tab’s WebMCP tools through a proxy that adds a per-server bearer token, an audit log of every call, per-tool allow/deny policy, drift attestation, and human approvals — no code. Under the hood it’s the same bridge idea (the proxy treats the tab as a webmcp_bridge upstream), wrapped in the enforcement a team can rely on. Use the library to make the endpoint; use MCP Trail when that endpoint needs to be safe to hand out.
FAQ
Why can’t Claude or Cursor call WebMCP tools directly?
WebMCP tools live in a browser tab and are only exposed to an agent running in that tab — there’s no network endpoint an external MCP client can connect to. @mcptrail/webmcp-bridge gives them one by implementing initialize, tools/list, and tools/call over a transport, so a desktop client can reach the tab’s tools like any other MCP server.
Does the bridge add authentication?
No. The library is a faithful protocol adapter — it makes browser tools reachable, but it adds no auth, logging, or approvals. For anything beyond a personal, trusted setup, put a governed layer in front. MCP Trail’s hosted bridge adds a bearer token, audit logs, policy, and human approvals around the same pattern.
Do tools registered later show up automatically?
Yes. The bridge answers tools/list and tools/call from the page’s live WebMCP registration, so a tool the page registers after the bridge is created appears in the next tools/list with no extra work. You never re-declare tool definitions inside the bridge.
Explore features · Open MCP Trail
Related articles
- What is WebMCP? — the plain-English introduction to browser-native tools and how MCP relates.
- Turn a WebMCP site into a guarded MCP server — the hosted, governed version: MCP Trail’s extension bridges a tab’s tools through a proxy with auth, audit, and approvals.
- Client-side approvals for WebMCP tool calls — add a confirmation step before a bridged write tool runs.
- Detect WebMCP toolset drift on the client — catch when the toolset behind the bridge silently changes.