@mcp-b/react-webmcp 1.1.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -565
- package/dist/index.d.ts +120 -243
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +18 -9
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](https://reactjs.org/)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**[Full Documentation](https://docs.mcp-b.ai/packages/react-webmcp)** | **[Quick Start](https://docs.mcp-b.ai/quickstart)** | **[AI Framework Integration](https://docs.mcp-b.ai/ai-frameworks)**
|
|
12
12
|
|
|
13
13
|
**@mcp-b/react-webmcp** provides React hooks that expose your components as AI-callable tools via the Model Context Protocol. Build AI-powered React applications where Claude, ChatGPT, Gemini, Cursor, and Copilot can interact with your app's functionality.
|
|
14
14
|
|
|
@@ -22,73 +22,22 @@
|
|
|
22
22
|
| **Execution State Tracking** | Built-in loading, success, and error states for UI feedback |
|
|
23
23
|
| **Works with Any AI** | Compatible with Claude, ChatGPT, Gemini, Cursor, Copilot, and any MCP client |
|
|
24
24
|
|
|
25
|
-
## Use Cases
|
|
26
|
-
|
|
27
|
-
- **AI-Controllable Dashboards**: Let AI agents filter data, generate reports, and navigate views
|
|
28
|
-
- **Form Automation**: Expose form submission as tools for AI-powered data entry
|
|
29
|
-
- **E-commerce Integration**: AI agents can search products, add to cart, and checkout
|
|
30
|
-
- **Content Management**: Let AI edit, publish, and organize content in your CMS
|
|
31
|
-
- **Data Visualization**: AI can adjust chart parameters, zoom, and export visualizations
|
|
32
|
-
|
|
33
|
-
## Features
|
|
34
|
-
|
|
35
|
-
### Provider Hooks (Registering Tools)
|
|
36
|
-
- **Type-Safe**: Full TypeScript support with Zod schema validation
|
|
37
|
-
- **State-Aware**: Track execution state (loading, success, error) for UI feedback
|
|
38
|
-
- **React-Native**: Designed for React's lifecycle, including StrictMode compatibility
|
|
39
|
-
- **Developer-Friendly**: Intuitive API with comprehensive examples
|
|
40
|
-
|
|
41
|
-
### Client Hooks (Consuming Tools)
|
|
42
|
-
- **MCP Client Provider**: Connect to MCP servers and consume their tools
|
|
43
|
-
- **Real-time Updates**: Listen for tool list changes via MCP notifications
|
|
44
|
-
- **Connection Management**: Automatic connection handling with reconnect support
|
|
45
|
-
- **Type-Safe Tool Calls**: Full TypeScript support for client operations
|
|
46
|
-
|
|
47
25
|
## Installation
|
|
48
26
|
|
|
49
27
|
```bash
|
|
50
28
|
pnpm add @mcp-b/react-webmcp zod
|
|
51
29
|
```
|
|
52
30
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
This package supports **Zod 3.25+** and **Zod 4.x**. Simply use the standard import:
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { z } from 'zod';
|
|
59
|
-
|
|
60
|
-
function MyComponent() {
|
|
61
|
-
useWebMCP({
|
|
62
|
-
name: 'my_tool',
|
|
63
|
-
description: 'My tool',
|
|
64
|
-
inputSchema: {
|
|
65
|
-
name: z.string().describe('User name'),
|
|
66
|
-
},
|
|
67
|
-
handler: async ({ name }) => ({ message: `Hello, ${name}!` }),
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
```
|
|
31
|
+
If you only want strict core WebMCP hooks (without MCP-B extension APIs like prompts/resources/sampling/elicitation), use `usewebmcp` instead.
|
|
71
32
|
|
|
72
33
|
For client functionality, you'll also need:
|
|
73
34
|
```bash
|
|
74
35
|
pnpm add @mcp-b/transports @modelcontextprotocol/sdk
|
|
75
36
|
```
|
|
76
37
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
**For Provider Hooks:** Requires the global `navigator.modelContext` API. Install `@mcp-b/global` or use a browser that implements the Web Model Context API.
|
|
80
|
-
|
|
81
|
-
**For Client Hooks:** Requires an MCP server to connect to (e.g., one created with `@mcp-b/global` or the Model Context Protocol SDK).
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
# Part 1: Provider API (Registering Tools)
|
|
86
|
-
|
|
87
|
-
Use these hooks to expose tools from your React app that AI agents can discover and call.
|
|
88
|
-
|
|
89
|
-
## Quick Start - Provider
|
|
38
|
+
**Prerequisites:** Provider hooks require the `navigator.modelContext` API. Install `@mcp-b/global` or use a browser that implements the Web Model Context API.
|
|
90
39
|
|
|
91
|
-
|
|
40
|
+
## Quick Start - Provider (Registering Tools)
|
|
92
41
|
|
|
93
42
|
```tsx
|
|
94
43
|
import { useWebMCP } from '@mcp-b/react-webmcp';
|
|
@@ -117,206 +66,18 @@ function PostsPage() {
|
|
|
117
66
|
<div>
|
|
118
67
|
{likeTool.state.isExecuting && <Spinner />}
|
|
119
68
|
{likeTool.state.error && <ErrorAlert error={likeTool.state.error} />}
|
|
120
|
-
{/* Your UI */}
|
|
121
|
-
</div>
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Tool with Output Schema (Recommended)
|
|
127
|
-
|
|
128
|
-
**Output schemas are essential for modern AI integrations** - they enable AI agents to return structured, type-safe responses:
|
|
129
|
-
|
|
130
|
-
```tsx
|
|
131
|
-
import { useWebMCP } from '@mcp-b/react-webmcp';
|
|
132
|
-
import { z } from 'zod';
|
|
133
|
-
|
|
134
|
-
function ProductSearch() {
|
|
135
|
-
const searchTool = useWebMCP({
|
|
136
|
-
name: 'products_search',
|
|
137
|
-
description: 'Search for products in the catalog',
|
|
138
|
-
inputSchema: {
|
|
139
|
-
query: z.string().describe('Search query'),
|
|
140
|
-
maxResults: z.number().min(1).max(50).default(10),
|
|
141
|
-
category: z.enum(['electronics', 'clothing', 'books']).optional(),
|
|
142
|
-
},
|
|
143
|
-
// Output schema enables structured responses
|
|
144
|
-
outputSchema: {
|
|
145
|
-
products: z.array(z.object({
|
|
146
|
-
id: z.string(),
|
|
147
|
-
name: z.string(),
|
|
148
|
-
price: z.number(),
|
|
149
|
-
inStock: z.boolean(),
|
|
150
|
-
})),
|
|
151
|
-
total: z.number().describe('Total matching products'),
|
|
152
|
-
hasMore: z.boolean(),
|
|
153
|
-
},
|
|
154
|
-
handler: async ({ query, maxResults, category }) => {
|
|
155
|
-
const results = await api.products.search({ query, maxResults, category });
|
|
156
|
-
return {
|
|
157
|
-
products: results.items,
|
|
158
|
-
total: results.totalCount,
|
|
159
|
-
hasMore: results.totalCount > maxResults,
|
|
160
|
-
};
|
|
161
|
-
},
|
|
162
|
-
// Format for text display (structuredContent is auto-generated from return value)
|
|
163
|
-
formatOutput: (result) => `Found ${result.total} products`,
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
return (
|
|
167
|
-
<div>
|
|
168
|
-
{searchTool.state.isExecuting && <Spinner />}
|
|
169
|
-
{searchTool.state.lastResult && (
|
|
170
|
-
<p>Found {searchTool.state.lastResult.total} products</p>
|
|
171
|
-
)}
|
|
172
69
|
</div>
|
|
173
70
|
);
|
|
174
71
|
}
|
|
175
72
|
```
|
|
176
73
|
|
|
177
|
-
|
|
178
|
-
- AI providers compile schemas to TypeScript, enabling type-safe code generation
|
|
179
|
-
- Responses are validated against the schema
|
|
180
|
-
- Better AI reasoning about expected output format
|
|
181
|
-
|
|
182
|
-
### Context Tool
|
|
183
|
-
|
|
184
|
-
Expose read-only context to AI:
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
import { useWebMCPContext } from '@mcp-b/react-webmcp';
|
|
188
|
-
|
|
189
|
-
function PostDetailPage() {
|
|
190
|
-
const { postId } = useParams();
|
|
191
|
-
const { data: post } = useQuery(['post', postId], () => fetchPost(postId));
|
|
192
|
-
|
|
193
|
-
useWebMCPContext(
|
|
194
|
-
'context_current_post',
|
|
195
|
-
'Get the currently viewed post ID and metadata',
|
|
196
|
-
() => ({
|
|
197
|
-
postId,
|
|
198
|
-
title: post?.title,
|
|
199
|
-
author: post?.author,
|
|
200
|
-
tags: post?.tags,
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
return <div>{/* Post UI */}</div>;
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Provider API Reference
|
|
209
|
-
|
|
210
|
-
### `useWebMCP`
|
|
211
|
-
|
|
212
|
-
Main hook for registering MCP tools with full control over behavior and state.
|
|
213
|
-
|
|
214
|
-
```tsx
|
|
215
|
-
function useWebMCP<
|
|
216
|
-
TInputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>,
|
|
217
|
-
TOutputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>
|
|
218
|
-
>(
|
|
219
|
-
config: WebMCPConfig<TInputSchema, TOutputSchema>,
|
|
220
|
-
deps?: DependencyList
|
|
221
|
-
): WebMCPReturn<TOutputSchema>
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
`InferOutput<TOutputSchema>` is the output type inferred from `outputSchema`.
|
|
225
|
-
|
|
226
|
-
#### Configuration Options
|
|
227
|
-
|
|
228
|
-
| Option | Type | Required | Description |
|
|
229
|
-
|--------|------|----------|-------------|
|
|
230
|
-
| `name` | `string` | ✓ | Unique tool identifier (e.g., 'posts_like') |
|
|
231
|
-
| `description` | `string` | ✓ | Human-readable description for AI |
|
|
232
|
-
| `inputSchema` | `Record<string, ZodType>` | - | Input validation using Zod schemas |
|
|
233
|
-
| `outputSchema` | `Record<string, ZodType>` | - | Output schema for structured responses (recommended) |
|
|
234
|
-
| `annotations` | `ToolAnnotations` | - | Metadata hints for the AI |
|
|
235
|
-
| `handler` | `(input) => Promise<TOutput>` | ✓ | Function that executes the tool |
|
|
236
|
-
| `formatOutput` | `(output) => string` | - | Custom output formatter |
|
|
237
|
-
| `onSuccess` | `(result, input) => void` | - | Success callback |
|
|
238
|
-
| `onError` | `(error, input) => void` | - | Error handler callback |
|
|
239
|
-
|
|
240
|
-
#### Memoization and `deps` (important)
|
|
241
|
-
|
|
242
|
-
`useWebMCP` uses reference equality to decide when to re-register a tool. Inline
|
|
243
|
-
objects/arrays/functions can cause constant re-registration.
|
|
244
|
-
|
|
245
|
-
Bad:
|
|
246
|
-
```tsx
|
|
247
|
-
useWebMCP({
|
|
248
|
-
name: 'counter',
|
|
249
|
-
description: `Count: ${count}`,
|
|
250
|
-
outputSchema: { count: z.number() },
|
|
251
|
-
handler: async () => ({ count }),
|
|
252
|
-
});
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Good:
|
|
256
|
-
```tsx
|
|
257
|
-
const OUTPUT_SCHEMA = { count: z.number() };
|
|
258
|
-
const description = useMemo(() => `Count: ${count}`, [count]);
|
|
259
|
-
|
|
260
|
-
useWebMCP(
|
|
261
|
-
{
|
|
262
|
-
name: 'counter',
|
|
263
|
-
description,
|
|
264
|
-
outputSchema: OUTPUT_SCHEMA,
|
|
265
|
-
handler: async () => ({ count }),
|
|
266
|
-
},
|
|
267
|
-
[count]
|
|
268
|
-
);
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
`deps` behaves like `useEffect` dependencies (reference comparison). Prefer
|
|
272
|
-
primitive values or memoized objects to avoid unnecessary re-registrations.
|
|
273
|
-
|
|
274
|
-
`handler` is stored in a ref to avoid re-registration when it changes. If you
|
|
275
|
-
memoize `handler` with stale dependencies, you'll still capture stale values.
|
|
276
|
-
|
|
277
|
-
#### Return Value
|
|
278
|
-
|
|
279
|
-
```tsx
|
|
280
|
-
interface WebMCPReturn<TOutputSchema> {
|
|
281
|
-
state: {
|
|
282
|
-
isExecuting: boolean; // Currently running
|
|
283
|
-
lastResult: InferOutput<TOutputSchema> | null; // Last successful result
|
|
284
|
-
error: Error | null; // Last error
|
|
285
|
-
executionCount: number; // Total executions
|
|
286
|
-
};
|
|
287
|
-
execute: (input: unknown) => Promise<InferOutput<TOutputSchema>>; // Manual execution
|
|
288
|
-
reset: () => void; // Reset state
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### `useWebMCPContext`
|
|
293
|
-
|
|
294
|
-
Simplified hook for read-only context exposure:
|
|
295
|
-
|
|
296
|
-
```tsx
|
|
297
|
-
function useWebMCPContext<T>(
|
|
298
|
-
name: string,
|
|
299
|
-
description: string,
|
|
300
|
-
getValue: () => T
|
|
301
|
-
): WebMCPReturn
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
---
|
|
305
|
-
|
|
306
|
-
# Part 2: Client API (Consuming Tools)
|
|
307
|
-
|
|
308
|
-
Use these hooks to connect to MCP servers and call their tools from your React app.
|
|
309
|
-
|
|
310
|
-
## Quick Start - Client
|
|
311
|
-
|
|
312
|
-
### Connecting to an MCP Server
|
|
74
|
+
## Quick Start - Client (Consuming Tools)
|
|
313
75
|
|
|
314
76
|
```tsx
|
|
315
77
|
import { McpClientProvider, useMcpClient } from '@mcp-b/react-webmcp';
|
|
316
78
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
317
79
|
import { TabClientTransport } from '@mcp-b/transports';
|
|
318
80
|
|
|
319
|
-
// Create client and transport
|
|
320
81
|
const client = new Client({ name: 'MyApp', version: '1.0.0' });
|
|
321
82
|
const transport = new TabClientTransport('mcp', { clientInstanceId: 'my-app' });
|
|
322
83
|
|
|
@@ -329,13 +90,10 @@ function App() {
|
|
|
329
90
|
}
|
|
330
91
|
|
|
331
92
|
function ToolConsumer() {
|
|
332
|
-
const { client, tools, isConnected
|
|
93
|
+
const { client, tools, isConnected } = useMcpClient();
|
|
333
94
|
|
|
334
95
|
const handleCallTool = async () => {
|
|
335
|
-
const result = await client.callTool({
|
|
336
|
-
name: 'posts_like',
|
|
337
|
-
arguments: { postId: '123' }
|
|
338
|
-
});
|
|
96
|
+
const result = await client.callTool({ name: 'posts_like', arguments: { postId: '123' } });
|
|
339
97
|
console.log('Result:', result.content[0].text);
|
|
340
98
|
};
|
|
341
99
|
|
|
@@ -343,347 +101,48 @@ function ToolConsumer() {
|
|
|
343
101
|
<div>
|
|
344
102
|
<p>Connected: {isConnected ? 'Yes' : 'No'}</p>
|
|
345
103
|
<p>Available Tools: {tools.length}</p>
|
|
346
|
-
<
|
|
347
|
-
{tools.map(tool => (
|
|
348
|
-
<li key={tool.name}>{tool.name} - {tool.description}</li>
|
|
349
|
-
))}
|
|
350
|
-
</ul>
|
|
351
|
-
<button onClick={handleCallTool} disabled={!isConnected}>
|
|
352
|
-
Call Tool
|
|
353
|
-
</button>
|
|
104
|
+
<button onClick={handleCallTool} disabled={!isConnected}>Call Tool</button>
|
|
354
105
|
</div>
|
|
355
106
|
);
|
|
356
107
|
}
|
|
357
108
|
```
|
|
358
109
|
|
|
359
|
-
|
|
110
|
+
## API Overview
|
|
360
111
|
|
|
361
|
-
|
|
362
|
-
function ToolList() {
|
|
363
|
-
const { tools, isConnected, capabilities } = useMcpClient();
|
|
112
|
+
### Provider Hooks
|
|
364
113
|
|
|
365
|
-
|
|
366
|
-
|
|
114
|
+
| Hook | Description |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| `useWebMCP(config, deps?)` | Register a tool with full control over behavior and state |
|
|
117
|
+
| `useWebMCPContext(name, description, getValue)` | Simplified hook for read-only context exposure |
|
|
367
118
|
|
|
368
|
-
|
|
369
|
-
<div>
|
|
370
|
-
<h3>Tools ({tools.length})</h3>
|
|
371
|
-
{capabilities?.tools?.listChanged && (
|
|
372
|
-
<p>✓ Server supports real-time tool updates</p>
|
|
373
|
-
)}
|
|
374
|
-
{tools.map(tool => (
|
|
375
|
-
<div key={tool.name}>
|
|
376
|
-
<h4>{tool.name}</h4>
|
|
377
|
-
<p>{tool.description}</p>
|
|
378
|
-
</div>
|
|
379
|
-
))}
|
|
380
|
-
</div>
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
|
-
```
|
|
119
|
+
### Client Hooks
|
|
384
120
|
|
|
385
|
-
|
|
121
|
+
| Hook / Component | Description |
|
|
122
|
+
|-------------------|-------------|
|
|
123
|
+
| `McpClientProvider` | Provider component managing an MCP client connection |
|
|
124
|
+
| `useMcpClient()` | Access client, tools, connection status, and capabilities |
|
|
386
125
|
|
|
387
|
-
|
|
126
|
+
## Zod Version Compatibility
|
|
388
127
|
|
|
389
|
-
|
|
128
|
+
This package supports **Zod 3.25.76+** (3.x only).
|
|
390
129
|
|
|
391
|
-
|
|
392
|
-
interface McpClientProviderProps {
|
|
393
|
-
children: ReactNode;
|
|
394
|
-
client: Client; // MCP client instance
|
|
395
|
-
transport: Transport; // Transport for connection
|
|
396
|
-
opts?: RequestOptions; // Optional connection options
|
|
397
|
-
}
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
#### Example Transports
|
|
401
|
-
|
|
402
|
-
```tsx
|
|
403
|
-
// Connect to same-page MCP server (via @mcp-b/global)
|
|
404
|
-
import { TabClientTransport } from '@mcp-b/transports';
|
|
405
|
-
const transport = new TabClientTransport('mcp', { clientInstanceId: 'my-app' });
|
|
406
|
-
|
|
407
|
-
// Connect to Chrome extension MCP server
|
|
408
|
-
import { ExtensionClientTransport } from '@mcp-b/transports';
|
|
409
|
-
const transport = new ExtensionClientTransport({ portName: 'mcp' });
|
|
410
|
-
|
|
411
|
-
// In-memory connection (for testing)
|
|
412
|
-
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
413
|
-
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### `useMcpClient`
|
|
130
|
+
## Documentation
|
|
417
131
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
```tsx
|
|
421
|
-
interface McpClientContextValue {
|
|
422
|
-
client: Client; // MCP client instance
|
|
423
|
-
tools: Tool[]; // Available tools from server
|
|
424
|
-
resources: Resource[]; // Available resources
|
|
425
|
-
isConnected: boolean; // Connection status
|
|
426
|
-
isLoading: boolean; // Currently connecting
|
|
427
|
-
error: Error | null; // Connection error
|
|
428
|
-
capabilities: ServerCapabilities | null; // Server capabilities
|
|
429
|
-
reconnect: () => Promise<void>; // Manual reconnection
|
|
430
|
-
}
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
#### Calling Tools
|
|
434
|
-
|
|
435
|
-
```tsx
|
|
436
|
-
function MyComponent() {
|
|
437
|
-
const { client, isConnected } = useMcpClient();
|
|
438
|
-
|
|
439
|
-
const callTool = async () => {
|
|
440
|
-
if (!isConnected) return;
|
|
441
|
-
|
|
442
|
-
try {
|
|
443
|
-
const result = await client.callTool({
|
|
444
|
-
name: 'my_tool',
|
|
445
|
-
arguments: { foo: 'bar' }
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
// Extract text from result
|
|
449
|
-
const text = result.content
|
|
450
|
-
.filter(c => c.type === 'text')
|
|
451
|
-
.map(c => c.text)
|
|
452
|
-
.join('\n');
|
|
453
|
-
|
|
454
|
-
console.log(text);
|
|
455
|
-
} catch (error) {
|
|
456
|
-
console.error('Tool call failed:', error);
|
|
457
|
-
}
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
return <button onClick={callTool}>Call Tool</button>;
|
|
461
|
-
}
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
|
|
466
|
-
# Complete Example: Both Provider and Client
|
|
467
|
-
|
|
468
|
-
This example shows a React app that both exposes tools AND consumes tools from an MCP server.
|
|
469
|
-
|
|
470
|
-
```tsx
|
|
471
|
-
import '@mcp-b/global'; // Provides navigator.modelContext
|
|
472
|
-
import { McpClientProvider, useWebMCP, useMcpClient } from '@mcp-b/react-webmcp';
|
|
473
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
474
|
-
import { TabClientTransport } from '@mcp-b/transports';
|
|
475
|
-
import { z } from 'zod';
|
|
476
|
-
|
|
477
|
-
// Create client to consume tools
|
|
478
|
-
const client = new Client({ name: 'MyApp', version: '1.0.0' });
|
|
479
|
-
const transport = new TabClientTransport('mcp', { clientInstanceId: 'my-app' });
|
|
480
|
-
|
|
481
|
-
function App() {
|
|
482
|
-
return (
|
|
483
|
-
<McpClientProvider client={client} transport={transport}>
|
|
484
|
-
<ToolProvider />
|
|
485
|
-
<ToolConsumer />
|
|
486
|
-
</McpClientProvider>
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Component that REGISTERS tools
|
|
491
|
-
function ToolProvider() {
|
|
492
|
-
const [count, setCount] = useState(0);
|
|
493
|
-
|
|
494
|
-
// Expose a tool that increments the counter
|
|
495
|
-
useWebMCP({
|
|
496
|
-
name: 'increment_counter',
|
|
497
|
-
description: 'Increment the counter',
|
|
498
|
-
inputSchema: {
|
|
499
|
-
amount: z.number().default(1)
|
|
500
|
-
},
|
|
501
|
-
handler: async ({ amount }) => {
|
|
502
|
-
setCount(prev => prev + amount);
|
|
503
|
-
return { newValue: count + amount };
|
|
504
|
-
}
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
return <div>Counter: {count}</div>;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// Component that CONSUMES tools
|
|
511
|
-
function ToolConsumer() {
|
|
512
|
-
const { client, tools, isConnected } = useMcpClient();
|
|
513
|
-
const [result, setResult] = useState('');
|
|
514
|
-
|
|
515
|
-
const callIncrementTool = async () => {
|
|
516
|
-
const res = await client.callTool({
|
|
517
|
-
name: 'increment_counter',
|
|
518
|
-
arguments: { amount: 5 }
|
|
519
|
-
});
|
|
520
|
-
setResult(res.content[0].text);
|
|
521
|
-
};
|
|
522
|
-
|
|
523
|
-
return (
|
|
524
|
-
<div>
|
|
525
|
-
<p>Available Tools: {tools.map(t => t.name).join(', ')}</p>
|
|
526
|
-
<button onClick={callIncrementTool} disabled={!isConnected}>
|
|
527
|
-
Call increment_counter Tool
|
|
528
|
-
</button>
|
|
529
|
-
{result && <p>Result: {result}</p>}
|
|
530
|
-
</div>
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
---
|
|
536
|
-
|
|
537
|
-
# Migration from @mcp-b/mcp-react-hooks
|
|
538
|
-
|
|
539
|
-
If you're migrating from the deprecated `@mcp-b/mcp-react-hooks` package:
|
|
540
|
-
|
|
541
|
-
## What Changed
|
|
542
|
-
|
|
543
|
-
- **Server providers removed**: `McpServerProvider` and `McpMemoryProvider` are gone
|
|
544
|
-
- **Everything in one package**: Both client and provider hooks are now in `@mcp-b/react-webmcp`
|
|
545
|
-
- **Tool registration**: Use `useWebMCP` instead of server providers
|
|
546
|
-
- **Client unchanged**: `McpClientProvider` and `useMcpClient` work the same way
|
|
547
|
-
|
|
548
|
-
## Migration Guide
|
|
549
|
-
|
|
550
|
-
### Before (mcp-react-hooks)
|
|
551
|
-
|
|
552
|
-
```tsx
|
|
553
|
-
import { McpClientProvider, useMcpClient } from '@mcp-b/mcp-react-hooks';
|
|
554
|
-
import { McpServerProvider, useMcpServer } from '@mcp-b/mcp-react-hooks';
|
|
555
|
-
```
|
|
556
|
-
|
|
557
|
-
### After (react-webmcp)
|
|
558
|
-
|
|
559
|
-
```tsx
|
|
560
|
-
// Client hooks - same API
|
|
561
|
-
import { McpClientProvider, useMcpClient } from '@mcp-b/react-webmcp';
|
|
562
|
-
|
|
563
|
-
// For registering tools, use useWebMCP instead of server providers
|
|
564
|
-
import { useWebMCP } from '@mcp-b/react-webmcp';
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
### Converting Server to Provider
|
|
568
|
-
|
|
569
|
-
**Before:**
|
|
570
|
-
```tsx
|
|
571
|
-
function MyApp() {
|
|
572
|
-
const { registerTool } = useMcpServer();
|
|
573
|
-
|
|
574
|
-
useEffect(() => {
|
|
575
|
-
const tool = registerTool('my_tool', { description: '...' }, handler);
|
|
576
|
-
return () => tool.remove();
|
|
577
|
-
}, []);
|
|
578
|
-
}
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
**After:**
|
|
582
|
-
```tsx
|
|
583
|
-
function MyApp() {
|
|
584
|
-
useWebMCP({
|
|
585
|
-
name: 'my_tool',
|
|
586
|
-
description: '...',
|
|
587
|
-
handler: handler
|
|
588
|
-
});
|
|
589
|
-
// Auto-registers and cleans up on unmount
|
|
590
|
-
}
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
---
|
|
594
|
-
|
|
595
|
-
# Best Practices
|
|
596
|
-
|
|
597
|
-
### Tool Naming
|
|
598
|
-
- Use verb-noun format: `posts_like`, `graph_navigate`, `table_filter`
|
|
599
|
-
- Prefix with domain: `posts_`, `comments_`, `graph_`
|
|
600
|
-
- Be specific and descriptive
|
|
601
|
-
|
|
602
|
-
### Annotations
|
|
603
|
-
- Always set `readOnlyHint` (true for queries, false for mutations)
|
|
604
|
-
- Set `idempotentHint` (true if repeated calls are safe)
|
|
605
|
-
- Set `destructiveHint` for delete/permanent operations
|
|
606
|
-
|
|
607
|
-
### Error Handling
|
|
608
|
-
- Throw descriptive errors from tool handlers
|
|
609
|
-
- Use `onError` callback for side effects (logging, toasts)
|
|
610
|
-
- Handle connection errors in client components
|
|
611
|
-
|
|
612
|
-
### Performance
|
|
613
|
-
- Tools automatically prevent duplicate registration in React StrictMode
|
|
614
|
-
- Use `useWebMCPContext` for lightweight read-only data exposure
|
|
615
|
-
- Client automatically manages reconnection and tool list updates
|
|
616
|
-
|
|
617
|
-
## Frequently Asked Questions
|
|
618
|
-
|
|
619
|
-
### What AI agents can use my React tools?
|
|
620
|
-
|
|
621
|
-
Any MCP-compatible client can discover and call your tools, including:
|
|
622
|
-
- **Claude Desktop** and Claude.ai
|
|
623
|
-
- **ChatGPT** (via plugins/GPTs)
|
|
624
|
-
- **Cursor** IDE
|
|
625
|
-
- **VS Code Copilot**
|
|
626
|
-
- **Gemini** applications
|
|
627
|
-
- **Windsurf**, **Cline**, and other MCP clients
|
|
628
|
-
|
|
629
|
-
### How do AI agents connect to my React app?
|
|
630
|
-
|
|
631
|
-
AI agents connect via browser extensions or the `@mcp-b/chrome-devtools-mcp` server, which bridges desktop AI clients to browser-based MCP tools.
|
|
632
|
-
|
|
633
|
-
### Is this production-ready?
|
|
634
|
-
|
|
635
|
-
Yes! The hooks handle React StrictMode, automatic cleanup, and proper lifecycle management. Tools are automatically unregistered when components unmount.
|
|
636
|
-
|
|
637
|
-
### Can I use this with Next.js / Remix / Gatsby?
|
|
638
|
-
|
|
639
|
-
Yes! These hooks work with any React framework. Just ensure `@mcp-b/global` is loaded on the client side.
|
|
640
|
-
|
|
641
|
-
### How do I validate tool inputs?
|
|
642
|
-
|
|
643
|
-
Use Zod schemas in `inputSchema`. Invalid inputs are automatically rejected with descriptive error messages.
|
|
644
|
-
|
|
645
|
-
```tsx
|
|
646
|
-
inputSchema: {
|
|
647
|
-
email: z.string().email().describe('User email address'),
|
|
648
|
-
age: z.number().min(0).max(120).describe('User age')
|
|
649
|
-
}
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
### Can tools access React state?
|
|
653
|
-
|
|
654
|
-
Yes! Tool handlers have access to component state via closures. State updates trigger re-renders as expected.
|
|
655
|
-
|
|
656
|
-
## Comparison with Alternatives
|
|
657
|
-
|
|
658
|
-
| Feature | @mcp-b/react-webmcp | Raw MCP SDK | Custom Implementation |
|
|
659
|
-
|---------|---------------------|-------------|----------------------|
|
|
660
|
-
| React Lifecycle Integration | Automatic | Manual | Manual |
|
|
661
|
-
| StrictMode Support | Yes | N/A | Manual |
|
|
662
|
-
| Zod Schema Validation | Built-in | Manual | Manual |
|
|
663
|
-
| Execution State Tracking | Built-in | Manual | Manual |
|
|
664
|
-
| TypeScript Support | Full | Partial | Varies |
|
|
132
|
+
For full API reference, output schemas, memoization patterns, migration guide, best practices, and complete examples, see the [React WebMCP Guide](../../docs/react-webmcp-guide.md).
|
|
665
133
|
|
|
666
134
|
## Related Packages
|
|
667
135
|
|
|
668
136
|
- [`@mcp-b/global`](https://docs.mcp-b.ai/packages/global) - W3C Web Model Context API polyfill (required for provider hooks)
|
|
669
137
|
- [`@mcp-b/transports`](https://docs.mcp-b.ai/packages/transports) - Browser-specific MCP transports
|
|
670
138
|
- [`@mcp-b/chrome-devtools-mcp`](https://docs.mcp-b.ai/packages/chrome-devtools-mcp) - Connect desktop AI agents to browser tools
|
|
671
|
-
- [
|
|
139
|
+
- [`usewebmcp`](../usewebmcp) - React hooks for strict core WebMCP API only
|
|
672
140
|
|
|
673
141
|
## Resources
|
|
674
142
|
|
|
675
143
|
- [WebMCP Documentation](https://docs.mcp-b.ai)
|
|
676
|
-
- [AI Framework Integration](https://docs.mcp-b.ai/ai-frameworks)
|
|
677
|
-
- [Best Practices](https://docs.mcp-b.ai/best-practices)
|
|
678
144
|
- [Model Context Protocol Spec](https://modelcontextprotocol.io)
|
|
679
|
-
- [MCP GitHub Repository](https://github.com/modelcontextprotocol)
|
|
680
145
|
|
|
681
146
|
## License
|
|
682
147
|
|
|
683
148
|
MIT - see [LICENSE](../../LICENSE) for details
|
|
684
|
-
|
|
685
|
-
## Support
|
|
686
|
-
|
|
687
|
-
- [GitHub Issues](https://github.com/WebMCP-org/npm-packages/issues)
|
|
688
|
-
- [Documentation](https://docs.mcp-b.ai)
|
|
689
|
-
- [Discord Community](https://discord.gg/a9fBR6Bw)
|