> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcp-b.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect WebMCP to Claude Desktop and Cursor

> Bridge browser-hosted WebMCP tools to Claude Desktop, Cursor, Windsurf, and other MCP clients through @mcp-b/webmcp-local-relay.

This guide shows you how to bridge WebMCP tools from browser tabs to desktop AI agents using `@mcp-b/webmcp-local-relay`.

```text theme={null}
 Browser Tab                          Local Machine
┌──────────────────────┐             ┌──────────────────────┐
│                      │  WebSocket  │                      │
│   Website with       ├────────────▶  webmcp-local-relay   │
│   WebMCP tools       │  localhost  │   (MCP server)       │
│                      │             │                      │
└──────────────────────┘             └──────────┬───────────┘
                                               │
                                         stdio │ JSON-RPC
                                               │
                                    ┌──────────▼───────────┐
                                    │                      │
                                    │   Claude / Cursor /  │
                                    │   any MCP client     │
                                    │                      │
                                    └──────────────────────┘
```

## Configure your MCP client

Add the relay server to your MCP client configuration. This works with Claude Desktop, Cursor, Windsurf, Claude Code, or any client that speaks MCP over stdio.

<CodeGroup>
  ```json "claude_desktop_config.json" theme={null}
  {
    "mcpServers": {
      "webmcp-local-relay": {
        "command": "npx",
        "args": ["-y", "@mcp-b/webmcp-local-relay@latest"]
      }
    }
  }
  ```

  ```bash "Claude Code" theme={null}
  claude mcp add webmcp-local-relay -- npx -y @mcp-b/webmcp-local-relay@latest
  ```
</CodeGroup>

<Note>
  For Claude Desktop, you can also download the `.mcpb` bundle from [GitHub
  Releases](https://github.com/WebMCP-org/npm-packages/releases) and double-click to install. No
  terminal required.
</Note>

## Add the embed script to your page

The relay discovers tools through a hidden iframe injected by `embed.js`. Add a single script tag to your page:

```html theme={null}
<script src="https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay@6/dist/browser/embed.js"></script>
```

Load the embed from the same major version as the page's MCP-B runtime (`@mcp-b/global` or
`@mcp-b/webmcp-polyfill`). A page that still runs a 5.x runtime must load
`@mcp-b/webmcp-local-relay@5`.

If your page already registers tools on `document.modelContext`, they are picked up automatically.
Tools registered after `embed.js` loads are also discovered through `toolchange` events and a polling
fallback; script order does not control discovery.

If you are new to WebMCP, this complete example loads `@mcp-b/global`, registers a tool, and adds the
embed:

```html theme={null}
<script src="https://cdn.jsdelivr.net/npm/@mcp-b/global@6/dist/index.iife.js"></script>
<script>
  if (!document.modelContext) throw new Error('WebMCP is unavailable');
  void document.modelContext
    .registerTool({
      name: 'get_page_title',
      description: 'Get the current page title',
      inputSchema: { type: 'object', properties: {} },
      execute: async () => ({ content: [{ type: 'text', text: document.title }] }),
    })
    .catch(console.error);
</script>
<script src="https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay@6/dist/browser/embed.js"></script>
```

Serve local pages from an HTTP origin such as `http://localhost:3000`. Do not open them as `file:`
URLs, whose opaque origin cannot be used for descriptor-based tool execution.

## Verify the connection

Once the relay is running and your page has loaded `embed.js`, your AI agent has access to three management tools:

| Tool | What it does |
| - | - |
| `webmcp_list_sources` | Lists connected browser tabs with metadata (tab ID, origin, URL, title, tool count) |
| `webmcp_list_tools` | Lists all relayed tools with source info |
| `webmcp_open_page` | Opens a URL in the default browser or refreshes a connected source page by matching origin |

Tools also register as first-class MCP tools using their original name. When multiple tabs register a tool with the same name, the relay appends a short tab-ID suffix for disambiguation (e.g. `search_ed93`, `search_a1b2`).

Ask your agent to list sources or tools to confirm the connection is working. Try [webmcp.sh](https://webmcp.sh) as a test target; it registers tools for SQL queries, entity management, navigation, and more.

<Frame caption="webmcp.sh: a live demo app with WebMCP tools you can relay to any desktop agent">
  <img src="https://mintcdn.com/mcp-b/TkOh_I05YhX4--64/images/webmcp-sh-homepage.png?fit=max&auto=format&n=TkOh_I05YhX4--64&q=85&s=61970ba83d0bb81bd78ae94b22e140f7" alt="webmcp.sh landing page showing registered WebMCP tools" width="3024" height="1488" data-path="images/webmcp-sh-homepage.png" />
</Frame>

## Use a custom port

The relay prefers WebSocket port `9333` on `127.0.0.1`. If you need a fixed port, configure both sides:

**Relay CLI:**

```bash theme={null}
npx @mcp-b/webmcp-local-relay --port 9444
```

**Embed script:**

```html theme={null}
<script
  src="https://cdn.jsdelivr.net/npm/@mcp-b/webmcp-local-relay@6/dist/browser/embed.js"
  data-relay-port="9444"
></script>
```

An explicit `--port` selects that exact root port. A compatible relay already using it is shared in
client mode; an unrelated process using it causes startup to fail.

## Restrict allowed origins

By default, the relay accepts connections from any browser page (`*`). For production or shared machines, restrict which origins can register tools:

```bash theme={null}
# Single origin
npx @mcp-b/webmcp-local-relay --widget-origin https://myapp.com

# Multiple origins
npx @mcp-b/webmcp-local-relay --widget-origin https://app1.com,https://app2.com
```

The `--widget-origin` flag validates the browser's WebSocket `Origin` header. The injected widget
inherits the host page origin, so browser code cannot replace it with a different value in the
handshake. This flag is not local-process authentication; keep the relay bound to loopback unless
you provide another trusted boundary.

## Handle multiple MCP clients

No configuration is needed. A relay started by a second MCP client joins the running relay in client
mode, so both clients share the same browser connections. See [Reconnection and client
mode](/packages/webmcp-local-relay/reference#reconnection-and-client-mode) for port discovery and
failover.

## Troubleshoot common issues

| Problem | Fix |
| - | - |
| `No sources connected` | Confirm the page loaded `embed.js` and the relay process is running |
| `No tools listed` | Confirm tools are registered on the page. The embed detects changes and polls every two seconds, regardless of script order. |
| `Tool not found` | The tab reloaded or disconnected. Call `webmcp_list_tools` to refresh |
| Connection blocked | Verify `--widget-origin` matches the WebSocket origin and the relay port matches `data-relay-port` |
| `Host response timeout:` | The page exceeded its per-request timeout (default 60 seconds). Raise `data-request-timeout` and set a slightly higher relay `--invoke-timeout` |

After a disconnect, the widget retries on its own and rediscovers the relay when you return to the
tab. See the [relay reference](/packages/webmcp-local-relay/reference#reconnection-and-client-mode)
for the retry schedule.

## Related pages

* [Local Relay Reference](/packages/webmcp-local-relay/reference) for the full CLI options and architecture details
* [Transports and Bridges](/explanation/architecture/transports-and-bridges) for how the relay fits into the WebMCP transport layer
* [Desktop Agent Relay Tutorial](/tutorials/desktop-agent-relay) for a step-by-step walkthrough from scratch


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.