@mcp-b/react-webmcp 0.0.0-beta-20260109203913
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/LICENSE +21 -0
- package/README.md +670 -0
- package/dist/index.d.ts +1113 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +92 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1113 @@
|
|
|
1
|
+
import { ElicitationFormParams, ElicitationParams, ElicitationParams as ElicitationParams$1, ElicitationResult, ElicitationResult as ElicitationResult$1, ElicitationUrlParams, ModelContext as ModelContextProtocol, PromptDescriptor, ResourceDescriptor, SamplingRequestParams, SamplingRequestParams as SamplingRequestParams$1, SamplingResult, SamplingResult as SamplingResult$1, ToolDescriptor } from "@mcp-b/global";
|
|
2
|
+
import { DependencyList, ReactElement, ReactNode } from "react";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { CallToolResult, Resource, Resource as Resource$1, ServerCapabilities, ServerCapabilities as ServerCapabilities$1, Tool, Tool as Tool$1 } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import { PromptMessage, ResourceContents, ToolAnnotations } from "@mcp-b/webmcp-ts-sdk";
|
|
6
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
7
|
+
import { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
8
|
+
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
9
|
+
|
|
10
|
+
//#region src/types.d.ts
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Utility type to infer the output type from a Zod schema object.
|
|
14
|
+
*
|
|
15
|
+
* When `TOutputSchema` is a non-empty Zod schema object, this resolves to
|
|
16
|
+
* `z.infer<z.ZodObject<TOutputSchema>>`. When it's empty (`Record<string, never>`),
|
|
17
|
+
* it falls back to the provided `TFallback` type.
|
|
18
|
+
*
|
|
19
|
+
* @template TOutputSchema - Zod schema object for output validation
|
|
20
|
+
* @template TFallback - Fallback type when no schema is provided
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
type InferOutput<TOutputSchema extends Record<string, z.ZodTypeAny>, TFallback = unknown> = TOutputSchema extends Record<string, never> ? TFallback : z.infer<z.ZodObject<TOutputSchema>>;
|
|
24
|
+
/**
|
|
25
|
+
* Represents the current execution state of a tool, including loading status,
|
|
26
|
+
* results, errors, and execution history.
|
|
27
|
+
*
|
|
28
|
+
* @template TOutput - The type of data returned by the tool handler
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
interface ToolExecutionState<TOutput = unknown> {
|
|
32
|
+
/**
|
|
33
|
+
* Indicates whether the tool is currently executing.
|
|
34
|
+
* Use this to show loading states in your UI.
|
|
35
|
+
*/
|
|
36
|
+
isExecuting: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The result from the most recent successful execution.
|
|
39
|
+
* Will be `null` if the tool hasn't been executed or last execution failed.
|
|
40
|
+
*/
|
|
41
|
+
lastResult: TOutput | null;
|
|
42
|
+
/**
|
|
43
|
+
* The error from the most recent failed execution.
|
|
44
|
+
* Will be `null` if the tool hasn't been executed or last execution succeeded.
|
|
45
|
+
*/
|
|
46
|
+
error: Error | null;
|
|
47
|
+
/**
|
|
48
|
+
* Total number of times this tool has been executed.
|
|
49
|
+
* Increments on both successful and failed executions.
|
|
50
|
+
*/
|
|
51
|
+
executionCount: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Configuration options for the `useWebMCP` hook.
|
|
55
|
+
*
|
|
56
|
+
* Defines a tool's metadata, schema, handler, and lifecycle callbacks.
|
|
57
|
+
* Supports full Zod type inference for both input and output schemas.
|
|
58
|
+
*
|
|
59
|
+
* @template TInputSchema - Zod schema object defining input parameters
|
|
60
|
+
* @template TOutputSchema - Zod schema object defining output structure (enables structuredContent)
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*
|
|
64
|
+
* @example Basic tool without output schema:
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const config: WebMCPConfig = {
|
|
67
|
+
* name: 'posts_like',
|
|
68
|
+
* description: 'Like a post by its ID',
|
|
69
|
+
* inputSchema: {
|
|
70
|
+
* postId: z.string().uuid(),
|
|
71
|
+
* },
|
|
72
|
+
* handler: async ({ postId }) => {
|
|
73
|
+
* await api.likePost(postId);
|
|
74
|
+
* return { success: true };
|
|
75
|
+
* },
|
|
76
|
+
* };
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @example Tool with output schema (enables MCP structuredContent):
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const config: WebMCPConfig<
|
|
82
|
+
* { postId: z.ZodString },
|
|
83
|
+
* { likes: z.ZodNumber; likedAt: z.ZodString }
|
|
84
|
+
* > = {
|
|
85
|
+
* name: 'posts_like',
|
|
86
|
+
* description: 'Like a post and return updated like count',
|
|
87
|
+
* inputSchema: {
|
|
88
|
+
* postId: z.string().uuid(),
|
|
89
|
+
* },
|
|
90
|
+
* outputSchema: {
|
|
91
|
+
* likes: z.number().describe('Updated like count'),
|
|
92
|
+
* likedAt: z.string().describe('ISO timestamp of the like'),
|
|
93
|
+
* },
|
|
94
|
+
* // Handler return type is inferred from outputSchema
|
|
95
|
+
* handler: async ({ postId }) => {
|
|
96
|
+
* const result = await api.likePost(postId);
|
|
97
|
+
* return { likes: result.likes, likedAt: new Date().toISOString() };
|
|
98
|
+
* },
|
|
99
|
+
* };
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
interface WebMCPConfig<TInputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>, TOutputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>> {
|
|
103
|
+
/**
|
|
104
|
+
* Unique identifier for the tool (e.g., 'posts_like', 'graph_navigate').
|
|
105
|
+
* Must follow naming conventions: lowercase with underscores.
|
|
106
|
+
*/
|
|
107
|
+
name: string;
|
|
108
|
+
/**
|
|
109
|
+
* Human-readable description explaining what the tool does.
|
|
110
|
+
* This description is used by AI assistants to understand when to use the tool.
|
|
111
|
+
*/
|
|
112
|
+
description: string;
|
|
113
|
+
/**
|
|
114
|
+
* Zod schema object defining the input parameters for the tool.
|
|
115
|
+
* Each key is a parameter name, and the value is a Zod type definition.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* inputSchema: {
|
|
120
|
+
* postId: z.string().uuid().describe('The ID of the post to like'),
|
|
121
|
+
* userId: z.string().optional(),
|
|
122
|
+
* }
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
inputSchema?: TInputSchema;
|
|
126
|
+
/**
|
|
127
|
+
* **Recommended:** Zod schema object defining the expected output structure.
|
|
128
|
+
*
|
|
129
|
+
* When provided, this enables three key features:
|
|
130
|
+
* 1. **Type Safety**: The handler's return type is inferred from this schema
|
|
131
|
+
* 2. **MCP structuredContent**: The MCP response includes `structuredContent`
|
|
132
|
+
* containing the typed output per the MCP specification
|
|
133
|
+
* 3. **AI Understanding**: AI models can better understand and use the tool's output
|
|
134
|
+
*
|
|
135
|
+
* This is the recommended way to define tool outputs. The schema provides
|
|
136
|
+
* both compile-time type checking and runtime structure for MCP clients.
|
|
137
|
+
*
|
|
138
|
+
* @see {@link https://spec.modelcontextprotocol.io/specification/server/tools/#output-schemas}
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* outputSchema: {
|
|
143
|
+
* counter: z.number().describe('The current counter value'),
|
|
144
|
+
* timestamp: z.string().describe('ISO timestamp'),
|
|
145
|
+
* metadata: z.object({
|
|
146
|
+
* updatedBy: z.string(),
|
|
147
|
+
* }).describe('Additional metadata'),
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
outputSchema?: TOutputSchema;
|
|
152
|
+
/**
|
|
153
|
+
* Optional metadata annotations providing hints about tool behavior.
|
|
154
|
+
* See {@link ToolAnnotations} for available options.
|
|
155
|
+
*/
|
|
156
|
+
annotations?: ToolAnnotations;
|
|
157
|
+
/**
|
|
158
|
+
* The function that executes when the tool is called.
|
|
159
|
+
* Can be synchronous or asynchronous.
|
|
160
|
+
*
|
|
161
|
+
* When `outputSchema` is provided, the return type is inferred from the schema.
|
|
162
|
+
* Otherwise, any return type is allowed.
|
|
163
|
+
*
|
|
164
|
+
* @param input - Validated input parameters matching the inputSchema
|
|
165
|
+
* @returns The result data or a Promise resolving to the result
|
|
166
|
+
*/
|
|
167
|
+
handler: (input: z.infer<z.ZodObject<TInputSchema>>) => Promise<InferOutput<TOutputSchema>> | InferOutput<TOutputSchema>;
|
|
168
|
+
/**
|
|
169
|
+
* Custom formatter for the MCP text response.
|
|
170
|
+
*
|
|
171
|
+
* @deprecated Use `outputSchema` instead. The `outputSchema` provides type-safe
|
|
172
|
+
* structured output via MCP's `structuredContent`, which is the recommended
|
|
173
|
+
* approach for tool outputs. This property will be removed in a future version.
|
|
174
|
+
*
|
|
175
|
+
* @param output - The raw output from the handler
|
|
176
|
+
* @returns Formatted string for the MCP response content
|
|
177
|
+
*/
|
|
178
|
+
formatOutput?: (output: InferOutput<TOutputSchema>) => string;
|
|
179
|
+
/**
|
|
180
|
+
* Optional callback invoked when the tool execution succeeds.
|
|
181
|
+
* Useful for triggering side effects like navigation or analytics.
|
|
182
|
+
*
|
|
183
|
+
* @param result - The successful result from the handler
|
|
184
|
+
* @param input - The input that was passed to the handler
|
|
185
|
+
*/
|
|
186
|
+
onSuccess?: (result: InferOutput<TOutputSchema>, input: unknown) => void;
|
|
187
|
+
/**
|
|
188
|
+
* Optional callback invoked when the tool execution fails.
|
|
189
|
+
* Useful for error handling, logging, or showing user notifications.
|
|
190
|
+
*
|
|
191
|
+
* @param error - The error that occurred during execution
|
|
192
|
+
* @param input - The input that was passed to the handler
|
|
193
|
+
*/
|
|
194
|
+
onError?: (error: Error, input: unknown) => void;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Return value from the `useWebMCP` hook.
|
|
198
|
+
* Provides access to execution state and methods for manual tool control.
|
|
199
|
+
*
|
|
200
|
+
* @template TOutputSchema - Zod schema object defining output structure
|
|
201
|
+
* @public
|
|
202
|
+
*/
|
|
203
|
+
interface WebMCPReturn<TOutputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>> {
|
|
204
|
+
/**
|
|
205
|
+
* Current execution state including loading status, results, and errors.
|
|
206
|
+
* See {@link ToolExecutionState} for details.
|
|
207
|
+
*/
|
|
208
|
+
state: ToolExecutionState<InferOutput<TOutputSchema>>;
|
|
209
|
+
/**
|
|
210
|
+
* Manually execute the tool with the provided input.
|
|
211
|
+
* Useful for testing, debugging, or triggering execution from your UI.
|
|
212
|
+
*
|
|
213
|
+
* @param input - The input parameters to pass to the tool
|
|
214
|
+
* @returns Promise resolving to the tool's output
|
|
215
|
+
* @throws Error if validation fails or handler throws
|
|
216
|
+
*/
|
|
217
|
+
execute: (input: unknown) => Promise<InferOutput<TOutputSchema>>;
|
|
218
|
+
/**
|
|
219
|
+
* Reset the execution state to its initial values.
|
|
220
|
+
* Clears results, errors, and resets the execution count.
|
|
221
|
+
*/
|
|
222
|
+
reset: () => void;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Configuration options for the `useWebMCPPrompt` hook.
|
|
226
|
+
* Defines a prompt's metadata, argument schema, and message generator.
|
|
227
|
+
*
|
|
228
|
+
* @template TArgsSchema - Zod schema object defining prompt arguments
|
|
229
|
+
* @public
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* const config: WebMCPPromptConfig = {
|
|
234
|
+
* name: 'review_code',
|
|
235
|
+
* description: 'Review code for best practices',
|
|
236
|
+
* argsSchema: {
|
|
237
|
+
* code: z.string().describe('The code to review'),
|
|
238
|
+
* language: z.string().optional().describe('Programming language'),
|
|
239
|
+
* },
|
|
240
|
+
* get: async ({ code, language }) => ({
|
|
241
|
+
* messages: [{
|
|
242
|
+
* role: 'user',
|
|
243
|
+
* content: { type: 'text', text: `Review this ${language ?? ''} code:\n${code}` }
|
|
244
|
+
* }]
|
|
245
|
+
* }),
|
|
246
|
+
* };
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
interface WebMCPPromptConfig<TArgsSchema extends Record<string, z.ZodTypeAny> = Record<string, never>> {
|
|
250
|
+
/**
|
|
251
|
+
* Unique identifier for the prompt (e.g., 'review_code', 'summarize_text').
|
|
252
|
+
*/
|
|
253
|
+
name: string;
|
|
254
|
+
/**
|
|
255
|
+
* Optional description explaining what the prompt does.
|
|
256
|
+
* This helps AI assistants understand when to use the prompt.
|
|
257
|
+
*/
|
|
258
|
+
description?: string;
|
|
259
|
+
/**
|
|
260
|
+
* Optional Zod schema object defining the arguments for the prompt.
|
|
261
|
+
* Each key is an argument name, and the value is a Zod type definition.
|
|
262
|
+
*/
|
|
263
|
+
argsSchema?: TArgsSchema;
|
|
264
|
+
/**
|
|
265
|
+
* Function that generates the prompt messages.
|
|
266
|
+
* Can be synchronous or asynchronous.
|
|
267
|
+
*
|
|
268
|
+
* @param args - Validated arguments matching the argsSchema
|
|
269
|
+
* @returns Object containing the prompt messages
|
|
270
|
+
*/
|
|
271
|
+
get: (args: z.infer<z.ZodObject<TArgsSchema>>) => Promise<{
|
|
272
|
+
messages: PromptMessage[];
|
|
273
|
+
}> | {
|
|
274
|
+
messages: PromptMessage[];
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Return value from the `useWebMCPPrompt` hook.
|
|
279
|
+
* Indicates whether the prompt is registered.
|
|
280
|
+
*
|
|
281
|
+
* @public
|
|
282
|
+
*/
|
|
283
|
+
interface WebMCPPromptReturn {
|
|
284
|
+
/**
|
|
285
|
+
* Whether the prompt is currently registered with the Model Context API.
|
|
286
|
+
*/
|
|
287
|
+
isRegistered: boolean;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Configuration options for the `useWebMCPResource` hook.
|
|
291
|
+
* Defines a resource's metadata and read handler.
|
|
292
|
+
*
|
|
293
|
+
* @public
|
|
294
|
+
*
|
|
295
|
+
* @example Static resource
|
|
296
|
+
* ```typescript
|
|
297
|
+
* const config: WebMCPResourceConfig = {
|
|
298
|
+
* uri: 'config://app-settings',
|
|
299
|
+
* name: 'App Settings',
|
|
300
|
+
* description: 'Application configuration',
|
|
301
|
+
* mimeType: 'application/json',
|
|
302
|
+
* read: async (uri) => ({
|
|
303
|
+
* contents: [{ uri: uri.href, text: JSON.stringify(settings) }]
|
|
304
|
+
* }),
|
|
305
|
+
* };
|
|
306
|
+
* ```
|
|
307
|
+
*
|
|
308
|
+
* @example Dynamic resource with URI template
|
|
309
|
+
* ```typescript
|
|
310
|
+
* const config: WebMCPResourceConfig = {
|
|
311
|
+
* uri: 'user://{userId}/profile',
|
|
312
|
+
* name: 'User Profile',
|
|
313
|
+
* description: 'User profile data',
|
|
314
|
+
* read: async (uri, params) => ({
|
|
315
|
+
* contents: [{
|
|
316
|
+
* uri: uri.href,
|
|
317
|
+
* text: JSON.stringify(await fetchUser(params?.userId ?? ''))
|
|
318
|
+
* }]
|
|
319
|
+
* }),
|
|
320
|
+
* };
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
interface WebMCPResourceConfig {
|
|
324
|
+
/**
|
|
325
|
+
* The resource URI or URI template.
|
|
326
|
+
* - Static: "config://app-settings"
|
|
327
|
+
* - Template: "user://{userId}/profile" where {userId} becomes a parameter
|
|
328
|
+
*/
|
|
329
|
+
uri: string;
|
|
330
|
+
/**
|
|
331
|
+
* Human-readable name for the resource.
|
|
332
|
+
*/
|
|
333
|
+
name: string;
|
|
334
|
+
/**
|
|
335
|
+
* Optional description of what the resource provides.
|
|
336
|
+
*/
|
|
337
|
+
description?: string;
|
|
338
|
+
/**
|
|
339
|
+
* Optional MIME type of the resource content.
|
|
340
|
+
*/
|
|
341
|
+
mimeType?: string;
|
|
342
|
+
/**
|
|
343
|
+
* Function that reads and returns the resource content.
|
|
344
|
+
*
|
|
345
|
+
* @param uri - The resolved URI being requested
|
|
346
|
+
* @param params - Parameters extracted from URI template (if applicable)
|
|
347
|
+
* @returns Resource contents with the data
|
|
348
|
+
*/
|
|
349
|
+
read: (uri: URL, params?: Record<string, string>) => Promise<{
|
|
350
|
+
contents: ResourceContents[];
|
|
351
|
+
}>;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Return value from the `useWebMCPResource` hook.
|
|
355
|
+
* Indicates whether the resource is registered.
|
|
356
|
+
*
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
interface WebMCPResourceReturn {
|
|
360
|
+
/**
|
|
361
|
+
* Whether the resource is currently registered with the Model Context API.
|
|
362
|
+
*/
|
|
363
|
+
isRegistered: boolean;
|
|
364
|
+
}
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/useWebMCP.d.ts
|
|
367
|
+
/**
|
|
368
|
+
* React hook for registering and managing Model Context Protocol (MCP) tools.
|
|
369
|
+
*
|
|
370
|
+
* This hook handles the complete lifecycle of an MCP tool:
|
|
371
|
+
* - Registers the tool with `window.navigator.modelContext`
|
|
372
|
+
* - Manages execution state (loading, results, errors)
|
|
373
|
+
* - Validates input using Zod schemas
|
|
374
|
+
* - Handles tool execution and lifecycle callbacks
|
|
375
|
+
* - Automatically unregisters on component unmount
|
|
376
|
+
* - Returns `structuredContent` when `outputSchema` is defined
|
|
377
|
+
*
|
|
378
|
+
* ## Output Schema (Recommended)
|
|
379
|
+
*
|
|
380
|
+
* Always define an `outputSchema` for your tools. This provides:
|
|
381
|
+
* - **Type Safety**: Handler return type is inferred from the schema
|
|
382
|
+
* - **MCP structuredContent**: AI models receive structured, typed data
|
|
383
|
+
* - **Better AI Understanding**: Models can reason about your tool's output format
|
|
384
|
+
*
|
|
385
|
+
* ```tsx
|
|
386
|
+
* useWebMCP({
|
|
387
|
+
* name: 'get_user',
|
|
388
|
+
* description: 'Get user by ID',
|
|
389
|
+
* inputSchema: { userId: z.string() },
|
|
390
|
+
* outputSchema: {
|
|
391
|
+
* id: z.string(),
|
|
392
|
+
* name: z.string(),
|
|
393
|
+
* email: z.string().email(),
|
|
394
|
+
* },
|
|
395
|
+
* handler: async ({ userId }) => {
|
|
396
|
+
* const user = await fetchUser(userId);
|
|
397
|
+
* return { id: user.id, name: user.name, email: user.email };
|
|
398
|
+
* },
|
|
399
|
+
* });
|
|
400
|
+
* ```
|
|
401
|
+
*
|
|
402
|
+
* ## Re-render Optimization
|
|
403
|
+
*
|
|
404
|
+
* This hook is optimized to minimize unnecessary tool re-registrations:
|
|
405
|
+
*
|
|
406
|
+
* - **Memoized JSON conversion**: Zod-to-JSON schema conversions are memoized to
|
|
407
|
+
* avoid recomputation on every render.
|
|
408
|
+
*
|
|
409
|
+
* - **Ref-based callbacks**: `handler`, `onSuccess`, `onError`, and `formatOutput`
|
|
410
|
+
* are stored in refs, so changing these functions won't trigger re-registration.
|
|
411
|
+
*
|
|
412
|
+
* **IMPORTANT**: If `inputSchema`, `outputSchema`, or `annotations` are defined inline
|
|
413
|
+
* or change on every render, the tool will re-register unnecessarily. To avoid this,
|
|
414
|
+
* memoize these values using `useMemo` or define them outside your component:
|
|
415
|
+
*
|
|
416
|
+
* ```tsx
|
|
417
|
+
* // Good: Memoized schema (won't change unless deps change)
|
|
418
|
+
* const outputSchema = useMemo(() => ({
|
|
419
|
+
* count: z.number(),
|
|
420
|
+
* items: z.array(z.string()),
|
|
421
|
+
* }), []);
|
|
422
|
+
*
|
|
423
|
+
* // Good: Static schema defined outside component
|
|
424
|
+
* const OUTPUT_SCHEMA = {
|
|
425
|
+
* count: z.number(),
|
|
426
|
+
* items: z.array(z.string()),
|
|
427
|
+
* };
|
|
428
|
+
*
|
|
429
|
+
* // Bad: Inline schema (creates new object every render)
|
|
430
|
+
* useWebMCP({
|
|
431
|
+
* outputSchema: { count: z.number() }, // Re-registers every render!
|
|
432
|
+
* });
|
|
433
|
+
* ```
|
|
434
|
+
*
|
|
435
|
+
* **What triggers re-registration:**
|
|
436
|
+
* - Changes to `name` or `description`
|
|
437
|
+
* - Changes to `inputSchema`, `outputSchema`, or `annotations` (reference comparison)
|
|
438
|
+
* - Changes to any value in the `deps` argument (reference comparison)
|
|
439
|
+
*
|
|
440
|
+
* **What does NOT trigger re-registration:**
|
|
441
|
+
* - Changes to `handler`, `onSuccess`, `onError`, or `formatOutput` functions
|
|
442
|
+
*
|
|
443
|
+
* @template TInputSchema - Zod schema object defining input parameter types
|
|
444
|
+
* @template TOutputSchema - Zod schema object defining output structure (enables structuredContent)
|
|
445
|
+
*
|
|
446
|
+
* @param config - Configuration object for the tool
|
|
447
|
+
* @param deps - Optional dependency array that triggers tool re-registration when values change.
|
|
448
|
+
* Similar to React's `useEffect` dependencies. When any value changes (by reference),
|
|
449
|
+
* the tool will be unregistered and re-registered. Prefer primitive values over
|
|
450
|
+
* objects/arrays to minimize re-registrations.
|
|
451
|
+
*
|
|
452
|
+
* @returns Object containing execution state and control methods
|
|
453
|
+
*
|
|
454
|
+
* @remarks
|
|
455
|
+
* The hook uses React refs to store callbacks (`handler`, `onSuccess`, `onError`, `formatOutput`)
|
|
456
|
+
* which prevents re-registration when these functions change. This is a performance optimization
|
|
457
|
+
* that follows the "latest ref" pattern.
|
|
458
|
+
*
|
|
459
|
+
* When `outputSchema` is provided, the MCP response includes both text content and
|
|
460
|
+
* `structuredContent` per the MCP specification. The type system ensures that the handler's
|
|
461
|
+
* return type matches the output schema through Zod's type inference.
|
|
462
|
+
*
|
|
463
|
+
* @public
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* Basic tool with outputSchema (recommended):
|
|
467
|
+
* ```tsx
|
|
468
|
+
* function PostActions() {
|
|
469
|
+
* const likeTool = useWebMCP({
|
|
470
|
+
* name: 'posts_like',
|
|
471
|
+
* description: 'Like a post by ID',
|
|
472
|
+
* inputSchema: {
|
|
473
|
+
* postId: z.string().uuid().describe('The ID of the post to like'),
|
|
474
|
+
* },
|
|
475
|
+
* outputSchema: {
|
|
476
|
+
* success: z.boolean().describe('Whether the like was successful'),
|
|
477
|
+
* likeCount: z.number().describe('Updated like count'),
|
|
478
|
+
* },
|
|
479
|
+
* handler: async ({ postId }) => {
|
|
480
|
+
* const result = await api.posts.like(postId);
|
|
481
|
+
* return { success: true, likeCount: result.likes };
|
|
482
|
+
* },
|
|
483
|
+
* });
|
|
484
|
+
*
|
|
485
|
+
* // likeTool.state.lastResult is typed as { success: boolean; likeCount: number } | null
|
|
486
|
+
* if (likeTool.state.isExecuting) {
|
|
487
|
+
* return <Spinner />;
|
|
488
|
+
* }
|
|
489
|
+
*
|
|
490
|
+
* return <div>Likes: {likeTool.state.lastResult?.likeCount ?? 0}</div>;
|
|
491
|
+
* }
|
|
492
|
+
* ```
|
|
493
|
+
*
|
|
494
|
+
* @example
|
|
495
|
+
* Tool with annotations and callbacks:
|
|
496
|
+
* ```tsx
|
|
497
|
+
* const deleteTool = useWebMCP({
|
|
498
|
+
* name: 'posts_delete',
|
|
499
|
+
* description: 'Delete a post permanently',
|
|
500
|
+
* inputSchema: {
|
|
501
|
+
* postId: z.string().uuid(),
|
|
502
|
+
* },
|
|
503
|
+
* outputSchema: {
|
|
504
|
+
* deleted: z.boolean(),
|
|
505
|
+
* deletedAt: z.string().describe('ISO timestamp of deletion'),
|
|
506
|
+
* },
|
|
507
|
+
* annotations: {
|
|
508
|
+
* destructiveHint: true,
|
|
509
|
+
* idempotentHint: false,
|
|
510
|
+
* },
|
|
511
|
+
* handler: async ({ postId }) => {
|
|
512
|
+
* await api.posts.delete(postId);
|
|
513
|
+
* return { deleted: true, deletedAt: new Date().toISOString() };
|
|
514
|
+
* },
|
|
515
|
+
* onSuccess: () => {
|
|
516
|
+
* navigate('/posts');
|
|
517
|
+
* toast.success('Post deleted');
|
|
518
|
+
* },
|
|
519
|
+
* onError: (error) => {
|
|
520
|
+
* toast.error(`Failed to delete: ${error.message}`);
|
|
521
|
+
* },
|
|
522
|
+
* });
|
|
523
|
+
* ```
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* Tool with deps for automatic re-registration:
|
|
527
|
+
* ```tsx
|
|
528
|
+
* function SitesManager({ sites }: { sites: Site[] }) {
|
|
529
|
+
* // Without deps, you'd need getter functions like: getSiteCount: () => sites.length
|
|
530
|
+
* // With deps, values can be used directly in description and handler
|
|
531
|
+
* const sitesTool = useWebMCP(
|
|
532
|
+
* {
|
|
533
|
+
* name: 'sites_query',
|
|
534
|
+
* description: `Query available sites. Current count: ${sites.length}`,
|
|
535
|
+
* outputSchema: {
|
|
536
|
+
* count: z.number(),
|
|
537
|
+
* sites: z.array(z.object({ id: z.string(), name: z.string() })),
|
|
538
|
+
* },
|
|
539
|
+
* handler: async () => ({
|
|
540
|
+
* count: sites.length,
|
|
541
|
+
* sites: sites.map(s => ({ id: s.id, name: s.name })),
|
|
542
|
+
* }),
|
|
543
|
+
* },
|
|
544
|
+
* [sites] // Re-register tool when sites array changes (by reference)
|
|
545
|
+
* );
|
|
546
|
+
*
|
|
547
|
+
* return <SitesList sites={sites} />;
|
|
548
|
+
* }
|
|
549
|
+
* ```
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* Optimizing with memoization and deps:
|
|
553
|
+
* ```tsx
|
|
554
|
+
* function OptimizedSites({ sites }: { sites: Site[] }) {
|
|
555
|
+
* // Memoize schema to prevent re-registration on every render
|
|
556
|
+
* const outputSchema = useMemo(() => ({
|
|
557
|
+
* sites: z.array(z.object({ id: z.string(), name: z.string() })),
|
|
558
|
+
* }), []);
|
|
559
|
+
*
|
|
560
|
+
* // Use primitive values in deps for better control
|
|
561
|
+
* const siteIds = sites.map(s => s.id).join(',');
|
|
562
|
+
* const siteCount = sites.length;
|
|
563
|
+
*
|
|
564
|
+
* const sitesTool = useWebMCP(
|
|
565
|
+
* {
|
|
566
|
+
* name: 'sites_query',
|
|
567
|
+
* description: `Query ${siteCount} available sites`,
|
|
568
|
+
* outputSchema,
|
|
569
|
+
* handler: async () => ({
|
|
570
|
+
* sites: sites.map(s => ({ id: s.id, name: s.name })),
|
|
571
|
+
* }),
|
|
572
|
+
* },
|
|
573
|
+
* [siteIds, siteCount] // Only re-register when IDs or count actually change
|
|
574
|
+
* );
|
|
575
|
+
*
|
|
576
|
+
* return <SitesList sites={sites} />;
|
|
577
|
+
* }
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
declare function useWebMCP<TInputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>, TOutputSchema extends Record<string, z.ZodTypeAny> = Record<string, never>>(config: WebMCPConfig<TInputSchema, TOutputSchema>, deps?: DependencyList): WebMCPReturn<TOutputSchema>;
|
|
581
|
+
//#endregion
|
|
582
|
+
//#region src/useWebMCPContext.d.ts
|
|
583
|
+
/**
|
|
584
|
+
* Convenience hook for exposing read-only context data to AI assistants.
|
|
585
|
+
*
|
|
586
|
+
* This is a simplified wrapper around {@link useWebMCP} specifically designed for
|
|
587
|
+
* context tools that expose data without performing actions. The hook automatically
|
|
588
|
+
* configures appropriate annotations (read-only, idempotent) and handles value
|
|
589
|
+
* serialization.
|
|
590
|
+
*
|
|
591
|
+
* Note: This hook does not use an output schema, so the result will not include
|
|
592
|
+
* `structuredContent` in the MCP response. Use {@link useWebMCP} directly with
|
|
593
|
+
* `outputSchema` if you need structured output for MCP compliance.
|
|
594
|
+
*
|
|
595
|
+
* @template T - The type of context data to expose
|
|
596
|
+
*
|
|
597
|
+
* @param name - Unique identifier for the context tool (e.g., 'context_current_post')
|
|
598
|
+
* @param description - Human-readable description of the context for AI assistants
|
|
599
|
+
* @param getValue - Function that returns the current context value
|
|
600
|
+
* @returns Tool execution state and control methods
|
|
601
|
+
*
|
|
602
|
+
* @public
|
|
603
|
+
*
|
|
604
|
+
* @example
|
|
605
|
+
* Expose current post context:
|
|
606
|
+
* ```tsx
|
|
607
|
+
* function PostDetailPage() {
|
|
608
|
+
* const { postId } = useParams();
|
|
609
|
+
* const { data: post } = useQuery(['post', postId], () => fetchPost(postId));
|
|
610
|
+
*
|
|
611
|
+
* useWebMCPContext(
|
|
612
|
+
* 'context_current_post',
|
|
613
|
+
* 'Get the currently viewed post ID and metadata',
|
|
614
|
+
* () => ({
|
|
615
|
+
* postId,
|
|
616
|
+
* title: post?.title,
|
|
617
|
+
* author: post?.author,
|
|
618
|
+
* tags: post?.tags,
|
|
619
|
+
* createdAt: post?.createdAt,
|
|
620
|
+
* })
|
|
621
|
+
* );
|
|
622
|
+
*
|
|
623
|
+
* return <PostContent post={post} />;
|
|
624
|
+
* }
|
|
625
|
+
* ```
|
|
626
|
+
*
|
|
627
|
+
* @example
|
|
628
|
+
* Expose user session context:
|
|
629
|
+
* ```tsx
|
|
630
|
+
* function AppRoot() {
|
|
631
|
+
* const { user, isAuthenticated } = useAuth();
|
|
632
|
+
*
|
|
633
|
+
* useWebMCPContext(
|
|
634
|
+
* 'context_user_session',
|
|
635
|
+
* 'Get the current user session information',
|
|
636
|
+
* () => ({
|
|
637
|
+
* isAuthenticated,
|
|
638
|
+
* userId: user?.id,
|
|
639
|
+
* email: user?.email,
|
|
640
|
+
* permissions: user?.permissions,
|
|
641
|
+
* })
|
|
642
|
+
* );
|
|
643
|
+
*
|
|
644
|
+
* return <App />;
|
|
645
|
+
* }
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
declare function useWebMCPContext<T>(name: string, description: string, getValue: () => T): WebMCPReturn;
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region src/useWebMCPPrompt.d.ts
|
|
651
|
+
/**
|
|
652
|
+
* React hook for registering Model Context Protocol (MCP) prompts.
|
|
653
|
+
*
|
|
654
|
+
* This hook handles the complete lifecycle of an MCP prompt:
|
|
655
|
+
* - Registers the prompt with `window.navigator.modelContext`
|
|
656
|
+
* - Converts Zod schemas to JSON Schema for argument validation
|
|
657
|
+
* - Automatically unregisters on component unmount
|
|
658
|
+
*
|
|
659
|
+
* @template TArgsSchema - Zod schema object defining argument types
|
|
660
|
+
*
|
|
661
|
+
* @param config - Configuration object for the prompt
|
|
662
|
+
* @returns Object indicating registration status
|
|
663
|
+
*
|
|
664
|
+
* @public
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* Simple prompt without arguments:
|
|
668
|
+
* ```tsx
|
|
669
|
+
* function HelpPrompt() {
|
|
670
|
+
* const { isRegistered } = useWebMCPPrompt({
|
|
671
|
+
* name: 'help',
|
|
672
|
+
* description: 'Get help with using the application',
|
|
673
|
+
* get: async () => ({
|
|
674
|
+
* messages: [{
|
|
675
|
+
* role: 'user',
|
|
676
|
+
* content: { type: 'text', text: 'How do I use this application?' }
|
|
677
|
+
* }]
|
|
678
|
+
* }),
|
|
679
|
+
* });
|
|
680
|
+
*
|
|
681
|
+
* return <div>Help prompt {isRegistered ? 'ready' : 'loading'}</div>;
|
|
682
|
+
* }
|
|
683
|
+
* ```
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* Prompt with typed arguments:
|
|
687
|
+
* ```tsx
|
|
688
|
+
* function CodeReviewPrompt() {
|
|
689
|
+
* const { isRegistered } = useWebMCPPrompt({
|
|
690
|
+
* name: 'review_code',
|
|
691
|
+
* description: 'Review code for best practices',
|
|
692
|
+
* argsSchema: {
|
|
693
|
+
* code: z.string().describe('The code to review'),
|
|
694
|
+
* language: z.string().optional().describe('Programming language'),
|
|
695
|
+
* },
|
|
696
|
+
* get: async ({ code, language }) => ({
|
|
697
|
+
* messages: [{
|
|
698
|
+
* role: 'user',
|
|
699
|
+
* content: {
|
|
700
|
+
* type: 'text',
|
|
701
|
+
* text: `Please review this ${language ?? ''} code:\n\n${code}`
|
|
702
|
+
* }
|
|
703
|
+
* }]
|
|
704
|
+
* }),
|
|
705
|
+
* });
|
|
706
|
+
*
|
|
707
|
+
* return <div>Code review prompt {isRegistered ? 'ready' : 'loading'}</div>;
|
|
708
|
+
* }
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
declare function useWebMCPPrompt<TArgsSchema extends Record<string, z.ZodTypeAny> = Record<string, never>>(config: WebMCPPromptConfig<TArgsSchema>): WebMCPPromptReturn;
|
|
712
|
+
//#endregion
|
|
713
|
+
//#region src/useWebMCPResource.d.ts
|
|
714
|
+
/**
|
|
715
|
+
* React hook for registering Model Context Protocol (MCP) resources.
|
|
716
|
+
*
|
|
717
|
+
* This hook handles the complete lifecycle of an MCP resource:
|
|
718
|
+
* - Registers the resource with `window.navigator.modelContext`
|
|
719
|
+
* - Supports both static URIs and URI templates with parameters
|
|
720
|
+
* - Automatically unregisters on component unmount
|
|
721
|
+
*
|
|
722
|
+
* @param config - Configuration object for the resource
|
|
723
|
+
* @returns Object indicating registration status
|
|
724
|
+
*
|
|
725
|
+
* @public
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* Static resource:
|
|
729
|
+
* ```tsx
|
|
730
|
+
* function AppSettingsResource() {
|
|
731
|
+
* const { isRegistered } = useWebMCPResource({
|
|
732
|
+
* uri: 'config://app-settings',
|
|
733
|
+
* name: 'App Settings',
|
|
734
|
+
* description: 'Application configuration',
|
|
735
|
+
* mimeType: 'application/json',
|
|
736
|
+
* read: async (uri) => ({
|
|
737
|
+
* contents: [{
|
|
738
|
+
* uri: uri.href,
|
|
739
|
+
* text: JSON.stringify({ theme: 'dark', language: 'en' })
|
|
740
|
+
* }]
|
|
741
|
+
* }),
|
|
742
|
+
* });
|
|
743
|
+
*
|
|
744
|
+
* return <div>Settings resource {isRegistered ? 'ready' : 'loading'}</div>;
|
|
745
|
+
* }
|
|
746
|
+
* ```
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* Dynamic resource with URI template:
|
|
750
|
+
* ```tsx
|
|
751
|
+
* function UserProfileResource() {
|
|
752
|
+
* const { isRegistered } = useWebMCPResource({
|
|
753
|
+
* uri: 'user://{userId}/profile',
|
|
754
|
+
* name: 'User Profile',
|
|
755
|
+
* description: 'User profile data by ID',
|
|
756
|
+
* mimeType: 'application/json',
|
|
757
|
+
* read: async (uri, params) => {
|
|
758
|
+
* const userId = params?.userId ?? '';
|
|
759
|
+
* const profile = await fetchUserProfile(userId);
|
|
760
|
+
* return {
|
|
761
|
+
* contents: [{
|
|
762
|
+
* uri: uri.href,
|
|
763
|
+
* text: JSON.stringify(profile)
|
|
764
|
+
* }]
|
|
765
|
+
* };
|
|
766
|
+
* },
|
|
767
|
+
* });
|
|
768
|
+
*
|
|
769
|
+
* return <div>User profile resource {isRegistered ? 'ready' : 'loading'}</div>;
|
|
770
|
+
* }
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
declare function useWebMCPResource(config: WebMCPResourceConfig): WebMCPResourceReturn;
|
|
774
|
+
//#endregion
|
|
775
|
+
//#region src/useElicitationHandler.d.ts
|
|
776
|
+
/**
|
|
777
|
+
* State for elicitation requests, tracking the current request and results.
|
|
778
|
+
*/
|
|
779
|
+
interface ElicitationState {
|
|
780
|
+
/** Whether an elicitation request is currently in progress */
|
|
781
|
+
isLoading: boolean;
|
|
782
|
+
/** The last elicitation result received */
|
|
783
|
+
result: ElicitationResult$1 | null;
|
|
784
|
+
/** Any error that occurred during the last request */
|
|
785
|
+
error: Error | null;
|
|
786
|
+
/** Total number of requests made */
|
|
787
|
+
requestCount: number;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Configuration options for the useElicitation hook.
|
|
791
|
+
*/
|
|
792
|
+
interface UseElicitationConfig {
|
|
793
|
+
/**
|
|
794
|
+
* Optional callback invoked when an elicitation request completes successfully.
|
|
795
|
+
*/
|
|
796
|
+
onSuccess?: (result: ElicitationResult$1) => void;
|
|
797
|
+
/**
|
|
798
|
+
* Optional callback invoked when an elicitation request fails.
|
|
799
|
+
*/
|
|
800
|
+
onError?: (error: Error) => void;
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Return value from the useElicitation hook.
|
|
804
|
+
*/
|
|
805
|
+
interface UseElicitationReturn {
|
|
806
|
+
/** Current state of elicitation */
|
|
807
|
+
state: ElicitationState;
|
|
808
|
+
/** Function to request user input from the connected client */
|
|
809
|
+
elicitInput: (params: ElicitationParams$1) => Promise<ElicitationResult$1>;
|
|
810
|
+
/** Reset the state */
|
|
811
|
+
reset: () => void;
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* React hook for requesting user input from the connected MCP client.
|
|
815
|
+
*
|
|
816
|
+
* Elicitation allows the server (webpage) to request user input from the
|
|
817
|
+
* connected client. This is useful when the page needs additional information
|
|
818
|
+
* from the user, such as API keys, configuration options, or confirmations.
|
|
819
|
+
*
|
|
820
|
+
* There are two modes:
|
|
821
|
+
* 1. **Form mode**: For non-sensitive data collection using a schema-driven form.
|
|
822
|
+
* 2. **URL mode**: For sensitive data collection via a web URL (API keys, OAuth, etc.).
|
|
823
|
+
*
|
|
824
|
+
* @param config - Optional configuration including callbacks
|
|
825
|
+
* @returns Object containing state and the elicitInput function
|
|
826
|
+
*
|
|
827
|
+
* @example Form elicitation:
|
|
828
|
+
* ```tsx
|
|
829
|
+
* function ConfigForm() {
|
|
830
|
+
* const { state, elicitInput } = useElicitation({
|
|
831
|
+
* onSuccess: (result) => console.log('Got input:', result),
|
|
832
|
+
* onError: (error) => console.error('Elicitation failed:', error),
|
|
833
|
+
* });
|
|
834
|
+
*
|
|
835
|
+
* const handleConfigure = async () => {
|
|
836
|
+
* const result = await elicitInput({
|
|
837
|
+
* message: 'Please provide your configuration',
|
|
838
|
+
* requestedSchema: {
|
|
839
|
+
* type: 'object',
|
|
840
|
+
* properties: {
|
|
841
|
+
* apiKey: { type: 'string', title: 'API Key', description: 'Your API key' },
|
|
842
|
+
* model: { type: 'string', enum: ['gpt-4', 'gpt-3.5'], title: 'Model' }
|
|
843
|
+
* },
|
|
844
|
+
* required: ['apiKey']
|
|
845
|
+
* }
|
|
846
|
+
* });
|
|
847
|
+
*
|
|
848
|
+
* if (result.action === 'accept') {
|
|
849
|
+
* console.log('Config:', result.content);
|
|
850
|
+
* }
|
|
851
|
+
* };
|
|
852
|
+
*
|
|
853
|
+
* return (
|
|
854
|
+
* <button onClick={handleConfigure} disabled={state.isLoading}>
|
|
855
|
+
* Configure
|
|
856
|
+
* </button>
|
|
857
|
+
* );
|
|
858
|
+
* }
|
|
859
|
+
* ```
|
|
860
|
+
*
|
|
861
|
+
* @example URL elicitation (for sensitive data):
|
|
862
|
+
* ```tsx
|
|
863
|
+
* const { elicitInput } = useElicitation();
|
|
864
|
+
*
|
|
865
|
+
* const handleOAuth = async () => {
|
|
866
|
+
* const result = await elicitInput({
|
|
867
|
+
* mode: 'url',
|
|
868
|
+
* message: 'Please authenticate with GitHub',
|
|
869
|
+
* elicitationId: 'github-oauth-123',
|
|
870
|
+
* url: 'https://github.com/login/oauth/authorize?client_id=...'
|
|
871
|
+
* });
|
|
872
|
+
*
|
|
873
|
+
* if (result.action === 'accept') {
|
|
874
|
+
* console.log('OAuth completed');
|
|
875
|
+
* }
|
|
876
|
+
* };
|
|
877
|
+
* ```
|
|
878
|
+
*/
|
|
879
|
+
declare function useElicitation(config?: UseElicitationConfig): UseElicitationReturn;
|
|
880
|
+
//#endregion
|
|
881
|
+
//#region src/useSamplingHandler.d.ts
|
|
882
|
+
/**
|
|
883
|
+
* State for sampling requests, tracking the current request and results.
|
|
884
|
+
*/
|
|
885
|
+
interface SamplingState {
|
|
886
|
+
/** Whether a sampling request is currently in progress */
|
|
887
|
+
isLoading: boolean;
|
|
888
|
+
/** The last sampling result received */
|
|
889
|
+
result: SamplingResult$1 | null;
|
|
890
|
+
/** Any error that occurred during the last request */
|
|
891
|
+
error: Error | null;
|
|
892
|
+
/** Total number of requests made */
|
|
893
|
+
requestCount: number;
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Configuration options for the useSampling hook.
|
|
897
|
+
*/
|
|
898
|
+
interface UseSamplingConfig {
|
|
899
|
+
/**
|
|
900
|
+
* Optional callback invoked when a sampling request completes successfully.
|
|
901
|
+
*/
|
|
902
|
+
onSuccess?: (result: SamplingResult$1) => void;
|
|
903
|
+
/**
|
|
904
|
+
* Optional callback invoked when a sampling request fails.
|
|
905
|
+
*/
|
|
906
|
+
onError?: (error: Error) => void;
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Return value from the useSampling hook.
|
|
910
|
+
*/
|
|
911
|
+
interface UseSamplingReturn {
|
|
912
|
+
/** Current state of sampling */
|
|
913
|
+
state: SamplingState;
|
|
914
|
+
/** Function to request LLM completion from the connected client */
|
|
915
|
+
createMessage: (params: SamplingRequestParams$1) => Promise<SamplingResult$1>;
|
|
916
|
+
/** Reset the state */
|
|
917
|
+
reset: () => void;
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* React hook for requesting LLM completions from the connected MCP client.
|
|
921
|
+
*
|
|
922
|
+
* Sampling allows the server (webpage) to request LLM completions from the
|
|
923
|
+
* connected client. This is useful when the page needs AI capabilities like
|
|
924
|
+
* summarization, generation, or analysis.
|
|
925
|
+
*
|
|
926
|
+
* @param config - Optional configuration including callbacks
|
|
927
|
+
* @returns Object containing state and the createMessage function
|
|
928
|
+
*
|
|
929
|
+
* @example Basic usage:
|
|
930
|
+
* ```tsx
|
|
931
|
+
* function AIAssistant() {
|
|
932
|
+
* const { state, createMessage } = useSampling({
|
|
933
|
+
* onSuccess: (result) => console.log('Got response:', result),
|
|
934
|
+
* onError: (error) => console.error('Sampling failed:', error),
|
|
935
|
+
* });
|
|
936
|
+
*
|
|
937
|
+
* const handleAsk = async () => {
|
|
938
|
+
* const result = await createMessage({
|
|
939
|
+
* messages: [
|
|
940
|
+
* { role: 'user', content: { type: 'text', text: 'What is 2+2?' } }
|
|
941
|
+
* ],
|
|
942
|
+
* maxTokens: 100,
|
|
943
|
+
* });
|
|
944
|
+
* console.log(result.content);
|
|
945
|
+
* };
|
|
946
|
+
*
|
|
947
|
+
* return (
|
|
948
|
+
* <div>
|
|
949
|
+
* <button onClick={handleAsk} disabled={state.isLoading}>
|
|
950
|
+
* Ask AI
|
|
951
|
+
* </button>
|
|
952
|
+
* {state.result && <p>{JSON.stringify(state.result.content)}</p>}
|
|
953
|
+
* </div>
|
|
954
|
+
* );
|
|
955
|
+
* }
|
|
956
|
+
* ```
|
|
957
|
+
*/
|
|
958
|
+
declare function useSampling(config?: UseSamplingConfig): UseSamplingReturn;
|
|
959
|
+
//#endregion
|
|
960
|
+
//#region src/client/McpClientProvider.d.ts
|
|
961
|
+
/**
|
|
962
|
+
* Context value provided by McpClientProvider.
|
|
963
|
+
*
|
|
964
|
+
* @internal
|
|
965
|
+
*/
|
|
966
|
+
interface McpClientContextValue {
|
|
967
|
+
client: Client;
|
|
968
|
+
tools: Tool$1[];
|
|
969
|
+
resources: Resource$1[];
|
|
970
|
+
isConnected: boolean;
|
|
971
|
+
isLoading: boolean;
|
|
972
|
+
error: Error | null;
|
|
973
|
+
capabilities: ServerCapabilities$1 | null;
|
|
974
|
+
reconnect: () => Promise<void>;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Props for the McpClientProvider component.
|
|
978
|
+
*
|
|
979
|
+
* @public
|
|
980
|
+
*/
|
|
981
|
+
interface McpClientProviderProps {
|
|
982
|
+
/**
|
|
983
|
+
* React children to render within the provider.
|
|
984
|
+
*/
|
|
985
|
+
children: ReactNode;
|
|
986
|
+
/**
|
|
987
|
+
* MCP Client instance to use for communication.
|
|
988
|
+
*/
|
|
989
|
+
client: Client;
|
|
990
|
+
/**
|
|
991
|
+
* Transport instance for the client to connect through.
|
|
992
|
+
*/
|
|
993
|
+
transport: Transport;
|
|
994
|
+
/**
|
|
995
|
+
* Optional request options for the connection.
|
|
996
|
+
*/
|
|
997
|
+
opts?: RequestOptions;
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Provider component that manages an MCP client connection and exposes
|
|
1001
|
+
* tools, resources, and connection state to child components.
|
|
1002
|
+
*
|
|
1003
|
+
* This provider handles:
|
|
1004
|
+
* - Establishing and maintaining the MCP client connection
|
|
1005
|
+
* - Fetching available tools and resources from the server
|
|
1006
|
+
* - Listening for server notifications about tool/resource changes
|
|
1007
|
+
* - Managing connection state and errors
|
|
1008
|
+
* - Automatic cleanup on unmount
|
|
1009
|
+
*
|
|
1010
|
+
* @param props - Component props
|
|
1011
|
+
* @returns Provider component wrapping children
|
|
1012
|
+
*
|
|
1013
|
+
* @public
|
|
1014
|
+
*
|
|
1015
|
+
* @example
|
|
1016
|
+
* Connect to an MCP server via tab transport:
|
|
1017
|
+
* ```tsx
|
|
1018
|
+
* import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
1019
|
+
* import { TabClientTransport } from '@mcp-b/transports';
|
|
1020
|
+
* import { McpClientProvider } from '@mcp-b/react-webmcp';
|
|
1021
|
+
*
|
|
1022
|
+
* const client = new Client(
|
|
1023
|
+
* { name: 'my-app', version: '1.0.0' },
|
|
1024
|
+
* { capabilities: {} }
|
|
1025
|
+
* );
|
|
1026
|
+
*
|
|
1027
|
+
* const transport = new TabClientTransport('mcp', {
|
|
1028
|
+
* clientInstanceId: 'my-app-instance',
|
|
1029
|
+
* });
|
|
1030
|
+
*
|
|
1031
|
+
* function App() {
|
|
1032
|
+
* return (
|
|
1033
|
+
* <McpClientProvider client={client} transport={transport}>
|
|
1034
|
+
* <MyAppContent />
|
|
1035
|
+
* </McpClientProvider>
|
|
1036
|
+
* );
|
|
1037
|
+
* }
|
|
1038
|
+
* ```
|
|
1039
|
+
*
|
|
1040
|
+
* @example
|
|
1041
|
+
* Access tools from child components:
|
|
1042
|
+
* ```tsx
|
|
1043
|
+
* function MyAppContent() {
|
|
1044
|
+
* const { tools, isConnected, isLoading } = useMcpClient();
|
|
1045
|
+
*
|
|
1046
|
+
* if (isLoading) {
|
|
1047
|
+
* return <div>Connecting to MCP server...</div>;
|
|
1048
|
+
* }
|
|
1049
|
+
*
|
|
1050
|
+
* if (!isConnected) {
|
|
1051
|
+
* return <div>Failed to connect to MCP server</div>;
|
|
1052
|
+
* }
|
|
1053
|
+
*
|
|
1054
|
+
* return (
|
|
1055
|
+
* <div>
|
|
1056
|
+
* <h2>Available Tools:</h2>
|
|
1057
|
+
* <ul>
|
|
1058
|
+
* {tools.map(tool => (
|
|
1059
|
+
* <li key={tool.name}>{tool.description}</li>
|
|
1060
|
+
* ))}
|
|
1061
|
+
* </ul>
|
|
1062
|
+
* </div>
|
|
1063
|
+
* );
|
|
1064
|
+
* }
|
|
1065
|
+
* ```
|
|
1066
|
+
*/
|
|
1067
|
+
declare function McpClientProvider({
|
|
1068
|
+
children,
|
|
1069
|
+
client,
|
|
1070
|
+
transport,
|
|
1071
|
+
opts
|
|
1072
|
+
}: McpClientProviderProps): ReactElement;
|
|
1073
|
+
/**
|
|
1074
|
+
* Hook to access the MCP client context.
|
|
1075
|
+
* Must be used within an {@link McpClientProvider}.
|
|
1076
|
+
*
|
|
1077
|
+
* @returns The MCP client context including client instance, tools, resources, and connection state
|
|
1078
|
+
* @throws Error if used outside of McpClientProvider
|
|
1079
|
+
*
|
|
1080
|
+
* @public
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* ```tsx
|
|
1084
|
+
* function ToolsList() {
|
|
1085
|
+
* const { tools, isConnected, error, reconnect } = useMcpClient();
|
|
1086
|
+
*
|
|
1087
|
+
* if (error) {
|
|
1088
|
+
* return (
|
|
1089
|
+
* <div>
|
|
1090
|
+
* Error: {error.message}
|
|
1091
|
+
* <button onClick={reconnect}>Retry</button>
|
|
1092
|
+
* </div>
|
|
1093
|
+
* );
|
|
1094
|
+
* }
|
|
1095
|
+
*
|
|
1096
|
+
* if (!isConnected) {
|
|
1097
|
+
* return <div>Not connected</div>;
|
|
1098
|
+
* }
|
|
1099
|
+
*
|
|
1100
|
+
* return (
|
|
1101
|
+
* <ul>
|
|
1102
|
+
* {tools.map(tool => (
|
|
1103
|
+
* <li key={tool.name}>{tool.description}</li>
|
|
1104
|
+
* ))}
|
|
1105
|
+
* </ul>
|
|
1106
|
+
* );
|
|
1107
|
+
* }
|
|
1108
|
+
* ```
|
|
1109
|
+
*/
|
|
1110
|
+
declare function useMcpClient(): McpClientContextValue;
|
|
1111
|
+
//#endregion
|
|
1112
|
+
export { type CallToolResult, type ElicitationFormParams, type ElicitationState as ElicitationHandlerState, type ElicitationState, type ElicitationParams, type ElicitationResult, type ElicitationUrlParams, type InferOutput, McpClientProvider, type McpClientProviderProps, type ModelContextProtocol, type PromptDescriptor, type PromptMessage, type Resource, type ResourceContents, type ResourceDescriptor, type SamplingState as SamplingHandlerState, type SamplingState, type SamplingRequestParams, type SamplingResult, type ServerCapabilities, type Tool, type ToolAnnotations, type ToolDescriptor, type ToolExecutionState, type UseElicitationConfig, type UseElicitationConfig as UseElicitationHandlerConfig, type UseElicitationReturn as UseElicitationHandlerReturn, type UseElicitationReturn, type UseSamplingConfig, type UseSamplingConfig as UseSamplingHandlerConfig, type UseSamplingReturn as UseSamplingHandlerReturn, type UseSamplingReturn, type WebMCPConfig, type WebMCPPromptConfig, type WebMCPPromptReturn, type WebMCPResourceConfig, type WebMCPResourceReturn, type WebMCPReturn, useElicitation, useElicitation as useElicitationHandler, useMcpClient, useSampling, useSampling as useSamplingHandler, useWebMCP, useWebMCPContext, useWebMCPPrompt, useWebMCPResource };
|
|
1113
|
+
//# sourceMappingURL=index.d.ts.map
|