@mcptrail/webmcp-bridge
v0.1.0
Published
Expose a page's WebMCP tools as a real MCP server: an in-page JSON-RPC handler (initialize/tools/list/tools/call/ping) over a pluggable transport.
Downloads
16
Maintainers
Readme
@mcptrail/webmcp-bridge
Expose a page's WebMCP tools as a real MCP server. createMcpBridge is an in-page JSON-RPC handler that speaks the Model Context Protocol methods — initialize, tools/list, tools/call, and ping — reading from the tools your page registered via navigator.modelContext.registerTool, over a pluggable transport you supply (WebSocket, postMessage, an extension port, anything).
Install
npm install @mcptrail/webmcp-bridgeUsage
import { createMcpBridge } from "@mcptrail/webmcp-bridge";
const bridge = createMcpBridge({
// Optionally seed tools directly; tools registered through
// navigator.modelContext.registerTool are picked up automatically.
tools: [
{
name: "search_hotels",
description: "Search hotels",
inputSchema: { type: "object", properties: { city: { type: "string" } }, required: ["city"] },
execute: (args) => JSON.stringify({ results: [] }),
},
],
serverInfo: { name: "my-page", version: "1.0.0" },
});
// Handle a JSON-RPC request directly…
const res = await bridge.handle({ jsonrpc: "2.0", id: 1, method: "tools/list" });
// …or wire a transport and let it round-trip for you.Transport
Pass a transport and the bridge listens for inbound requests and sends responses back. Requests without an id (notifications) are still handled but nothing is sent in reply.
const transport = {
send: (msg) => ws.send(JSON.stringify(msg)),
onMessage: (handler) => ws.addEventListener("message", (e) => handler(JSON.parse(e.data))),
};
createMcpBridge({ transport });API
const bridge = createMcpBridge(options);
bridge.handle(req); // Promise<JsonRpcResponse> — process one JSON-RPC request
bridge.tools(); // WebMcpTool[] — every registered tool
bridge.register(tool);// add a tool imperatively
bridge.close(); // restore the original modelContext.registerToolOptions
| Option | Default | Notes |
|--------|---------|-------|
| tools | [] | Tools to seed the registry with |
| target | navigator | Object whose .modelContext.registerTool is intercepted |
| serverInfo | { name: "webmcp-bridge", version: "0.1.0" } | Reported by initialize |
| transport | — | Pluggable transport; when set, the bridge auto-replies to requests |
| protocolVersion | "2025-06-18" | Reported by initialize |
Methods
| Method | Result |
|--------|--------|
| initialize | { protocolVersion, capabilities: { tools: {} }, serverInfo } |
| ping | {} |
| tools/list | { tools: [{ name, description, inputSchema }] } (schema defaults to { type: "object" }) |
| tools/call | runs execute(arguments); { content: [{ type: "text", text }], isError } |
Unknown tools return JSON-RPC error -32602; unknown methods return -32601. A thrown execute becomes isError: true with the error message as text.
Development
npm install
npm run typecheck
npm test # Vitest + jsdom
npm run build # tsup → dist (ESM + CJS + d.ts)License
MIT © Zied Guetari
