Skip to main content
Start with the browser standard. Add MCP-B packages only when you need behavior beyond that standard.

Decision flowchart

Ask these questions in order:
  1. Does the target browser ship navigator.modelContext natively? If yes, and that covers your use case, you may not need any package at all.
  2. Do you need compile-time types without any runtime? Install @mcp-b/webmcp-types as a dev dependency.
  3. Do you need the WebMCP standard in browsers that lack native support, and nothing else? Install @mcp-b/webmcp-polyfill.
  4. Do you need MCP bridge transport, callTool, listTools, prompts, resources, elicitation, or sampling? Install @mcp-b/global.
  5. Do you need React hooks? Choose usewebmcp for strict core, or @mcp-b/react-webmcp for the full MCP-B surface.

Package comparison

PackageRuntimeCore APIMCP extensionsTransportReact
@mcp-b/webmcp-typesNoTypes onlyTypes onlyNoNo
@mcp-b/webmcp-polyfillYesregisterTool, unregisterToolNoNoNo
@mcp-b/globalYesAll core methodscallTool, listTools, prompts, resources, elicitation, samplingTab + iframeNo
usewebmcpYesVia hookNoNoYes
@mcp-b/react-webmcpYesVia hookFull MCP-B surfaceVia @mcp-b/globalYes

If you want the WebMCP standard only

Install the polyfill. It adds navigator.modelContext and stays on the strict WebMCP path. It does not add MCP-B extension methods.
npm install @mcp-b/webmcp-polyfill
main.ts
import { initializeWebMCPPolyfill } from '@mcp-b/webmcp-polyfill';

initializeWebMCPPolyfill();

navigator.modelContext.registerTool({
  name: 'get-page-title',
  description: 'Get the current page title',
  inputSchema: { type: 'object', properties: {} },
  async execute() {
    return {
      content: [{ type: 'text', text: document.title }],
    };
  },
});
The polyfill is non-destructive. If navigator.modelContext already exists natively, initialization is a no-op. For type inference on tool arguments, pair the polyfill with @mcp-b/webmcp-types:
npm install --save-dev @mcp-b/webmcp-types
See Use Schemas and Structured Output for details.

If you want the full MCP-B runtime

Install @mcp-b/global. It layers the MCP-B runtime on top of the WebMCP surface.
npm install @mcp-b/global
main.ts
import '@mcp-b/global';

navigator.modelContext.registerTool({
  name: 'search-products',
  description: 'Search the product catalog by query',
  inputSchema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'Search query' },
      limit: { type: 'integer', description: 'Max results' },
    },
    required: ['query'],
  },
  async execute(args) {
    const results = await searchProducts(args.query, args.limit ?? 10);
    return {
      content: [{ type: 'text', text: JSON.stringify(results) }],
    };
  },
});
@mcp-b/global auto-initializes on import. It installs the polyfill first, then replaces navigator.modelContext with a BrowserMcpServer that keeps the core behavior and adds MCP-B-only methods such as callTool, listTools, prompts, resources, and transport support. If you need to customize before initialization (for example, to restrict allowed origins), set options on window.__webModelContextOptions before loading the script:
<script>
  window.__webModelContextOptions = {
    transport: {
      tabServer: { allowedOrigins: ['https://myapp.com'] },
    },
  };
</script>
<script src="https://unpkg.com/@mcp-b/global@latest/dist/index.iife.js"></script>

If you want React hooks

npm install usewebmcp react
CounterTool.tsx
import { useWebMCP } from 'usewebmcp';

export function CounterTool() {
  const counterTool = useWebMCP({
    name: 'counter_get',
    description: 'Get current count',
    inputSchema: { type: 'object', properties: {} } as const,
    execute: async () => ({ count: 42 }),
  });

  return (
    <div>
      <p>Executions: {counterTool.state.executionCount}</p>
    </div>
  );
}
usewebmcp expects navigator.modelContext to exist. Provide it with @mcp-b/webmcp-polyfill or @mcp-b/global.

If you only need types

Install @mcp-b/webmcp-types as a dev dependency. It has no runtime code and no side effects.
npm install --save-dev @mcp-b/webmcp-types
Add it to your tsconfig.json to get navigator.modelContext typing:
tsconfig.json
{
  "compilerOptions": {
    "types": ["@mcp-b/webmcp-types"]
  }
}
This is useful when you are writing against a native browser implementation or a third-party polyfill and want type-safe tool descriptors without adding any runtime dependency.

How the layers relate

For a deeper look at the layering rationale, see Runtime Layering. The Native vs Polyfill vs Global page explains why the three runtime strategies exist. The Strict Core vs MCP-B Extensions page covers the boundary between the specification surface and MCP-B additions.