Skip to main content
Engineering 2026-07-07

Expose Your WebMCP Tools as an MCP Server

MCP Trail

MCP Trail Team

Developer Relations

Expose Your WebMCP Tools as an MCP Server

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:

MethodWhat the bridge does
initializeReturns server capabilities and protocol version so the client can handshake
tools/listEnumerates the page’s registered WebMCP tools as MCP tool definitions
tools/callInvokes 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

Share this article