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

# @mcp-b/react-webmcp

> React hooks for Model Context Protocol with automatic lifecycle management and Zod validation. Register AI-accessible tools with useWebMCP() hook for React 18+ applications.

This package provides two sets of hooks: **provider hooks** for registering your tools with automatic lifecycle management and Zod validation, and **client hooks** for connecting to MCP servers and calling tools. The hooks handle the boilerplate of tool registration/cleanup, leaving you to focus on tool logic.

## Prerequisites

* **React 18+** or **React 19** (supports both versions)
* **@mcp-b/global** package installed
* **Zod** for schema validation
* **[MCP-B Extension](https://chromewebstore.google.com/detail/mcp-b-extension/daohopfhkdelnpemnhlekblhnikhdhfa)** for testing tools
* Basic understanding of React hooks and async/await

## Installation

```bash theme={null}
pnpm add @mcp-b/react-webmcp @mcp-b/global zod
```

For client functionality:

```bash theme={null}
pnpm add @mcp-b/transports @modelcontextprotocol/sdk
```

## Features

**Provider Hooks (Registering Tools)**

* Type-safe with Zod validation
* Automatic lifecycle management (StrictMode compatible)
* Execution state tracking for UI feedback

**Client Hooks (Consuming Tools)**

* MCP server connection management
* Real-time tool list updates
* Automatic reconnection handling

***

# Provider API (Registering Tools)

## Basic Usage

```tsx theme={null}
import '@mcp-b/global';
import { useWebMCP } from '@mcp-b/react-webmcp';
import { z } from 'zod';

function PostsPage() {
  const [posts, setPosts] = useState([]);

  const likeTool = useWebMCP({
    name: 'posts_like',
    description: 'Like a post by ID',
    inputSchema: {
      postId: z.string().uuid()
    },
    handler: async ({ postId }) => {
      await api.posts.like(postId);
      return { success: true };
    }
  });

  return (
    <div>
      {likeTool.state.isExecuting && <Spinner />}
      {likeTool.state.error && <Error />}
    </div>
  );
}
```

## Read-Only Context

```tsx theme={null}
import { useWebMCPContext } from '@mcp-b/react-webmcp';

function PostDetail() {
  const { postId } = useParams();
  const { data: post } = useQuery(['post', postId], fetchPost);

  useWebMCPContext(
    'context_current_post',
    'Get current post metadata',
    () => ({ postId, title: post?.title, author: post?.author })
  );

  return <div>{/* UI */}</div>;
}
```

## API Reference

### `useWebMCP(config)`

| Option         | Type                          | Required | Description                                         |
| -------------- | ----------------------------- | -------- | --------------------------------------------------- |
| `name`         | `string`                      | ✓        | Unique tool identifier                              |
| `description`  | `string`                      | ✓        | Human-readable description                          |
| `inputSchema`  | `Record<string, ZodType>`     | -        | Zod validation schema                               |
| `handler`      | `(input) => Promise<TOutput>` | ✓        | Tool execution function                             |
| `annotations`  | `ToolAnnotations`             | -        | Metadata hints (readOnlyHint, idempotentHint, etc.) |
| `formatOutput` | `(output) => string`          | -        | Custom output formatter                             |
| `onError`      | `(error, input) => void`      | -        | Error handler                                       |

**Returns:**

```tsx theme={null}
{
  state: {
    isExecuting: boolean;
    lastResult: TOutput | null;
    error: Error | null;
  };
  execute: (input) => Promise<TOutput>;
  reset: () => void;
}
```

### `useWebMCPContext(name, description, getValue)`

Simplified hook for read-only context. Auto-registers and returns current state.

***

# Client API (Consuming Tools)

## Basic Usage

```tsx theme={null}
import { McpClientProvider, useMcpClient } from '@mcp-b/react-webmcp';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { TabClientTransport } from '@mcp-b/transports';

const client = new Client({ name: 'MyApp', version: '1.0.0' });
const transport = new TabClientTransport('mcp');

function App() {
  return (
    <McpClientProvider client={client} transport={transport}>
      <ToolConsumer />
    </McpClientProvider>
  );
}

function ToolConsumer() {
  const { client, tools, isConnected } = useMcpClient();

  const callTool = async () => {
    const result = await client.callTool({
      name: 'posts_like',
      arguments: { postId: '123' }
    });
    console.log(result.content[0].text);
  };

  return (
    <div>
      <p>Connected: {isConnected}</p>
      <p>Tools: {tools.map(t => t.name).join(', ')}</p>
      <button onClick={callTool} disabled={!isConnected}>
        Call Tool
      </button>
    </div>
  );
}
```

## API Reference

### `McpClientProvider`

```tsx theme={null}
<McpClientProvider client={client} transport={transport} opts={opts}>
  {children}
</McpClientProvider>
```

**Available Transports:**

* `TabClientTransport` - Same-page MCP server
* `ExtensionClientTransport` - Chrome extension server
* `InMemoryTransport` - Testing

### `useMcpClient()`

**Returns:**

```tsx theme={null}
{
  client: Client;              // MCP SDK client
  tools: Tool[];               // Available tools
  resources: Resource[];       // Available resources
  isConnected: boolean;        // Connection status
  isLoading: boolean;          // Connecting
  error: Error | null;         // Connection error
  capabilities: ServerCapabilities | null;
  reconnect: () => Promise<void>;
}
```

***

# Complete Example

```tsx theme={null}
import '@mcp-b/global';
import { McpClientProvider, useWebMCP, useMcpClient } from '@mcp-b/react-webmcp';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { TabClientTransport } from '@mcp-b/transports';
import { z } from 'zod';

const client = new Client({ name: 'MyApp', version: '1.0.0' });
const transport = new TabClientTransport('mcp');

function App() {
  return (
    <McpClientProvider client={client} transport={transport}>
      <Counter />
    </McpClientProvider>
  );
}

function Counter() {
  const [count, setCount] = useState(0);
  const { client, tools, isConnected } = useMcpClient();

  // Register tool
  useWebMCP({
    name: 'increment',
    description: 'Increment counter',
    inputSchema: { amount: z.number().default(1) },
    handler: async ({ amount }) => {
      setCount(prev => prev + amount);
      return { newValue: count + amount };
    }
  });

  // Call tool
  const callTool = async () => {
    const res = await client.callTool({
      name: 'increment',
      arguments: { amount: 5 }
    });
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={callTool} disabled={!isConnected}>
        Increment
      </button>
    </div>
  );
}
```

***

# Best Practices

**Tool Naming**: Use verb-noun format with domain prefix: `posts_like`, `graph_navigate`, `table_filter`

**Annotations**: Set `readOnlyHint` (true for queries), `idempotentHint` (true if safe to retry), `destructiveHint` (for deletions)

**Error Handling**: Throw descriptive errors. Use `onError` for logging/toasts. Handle connection errors in client components.

**Performance**: Tools auto-dedupe in StrictMode. Use `useWebMCPContext` for lightweight read-only data.

***

# Migration from Legacy Package

If you're migrating from an older version of this package (previously named `@mcp-b/mcp-react-hooks`):

**Before:**

```tsx theme={null}
const { registerTool } = useMcpServer();
useEffect(() => {
  const tool = registerTool('my_tool', { description: '...' }, handler);
  return () => tool.remove();
}, []);
```

**After:**

```tsx theme={null}
useWebMCP({
  name: 'my_tool',
  description: '...',
  handler
});
// Auto-registers and cleans up
```

Client hooks (`McpClientProvider`, `useMcpClient`) remain unchanged.

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="@mcp-b/global" icon="globe" href="/packages/global">
    Web Model Context API polyfill
  </Card>

  <Card title="@mcp-b/transports" icon="arrows-left-right" href="/packages/transports">
    Transport implementations
  </Card>

  <Card title="Core Concepts" icon="diagram-project" href="/concepts/overview">
    Architecture and tool lifecycle
  </Card>

  <Card title="Security Guide" icon="shield-halved" href="/security">
    Best practices for tool security
  </Card>

  <Card title="Quick Start" icon="rocket" href="/quickstart">
    Get started with WebMCP
  </Card>

  <Card title="Examples" icon="code" href="/examples">
    Real-world React implementations
  </Card>
</CardGroup>
