react-webmcp 0.2.0 → 0.2.1
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 +135 -16
- package/dist/index.d.mts +292 -12
- package/dist/index.d.ts +292 -12
- package/dist/index.js +351 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +331 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,17 +4,33 @@ React hooks and components for the [WebMCP](https://github.com/webmachinelearnin
|
|
|
4
4
|
|
|
5
5
|
WebMCP is a W3C-proposed web standard (Chrome 146+) that allows websites to register tools that AI agents can discover and invoke directly, replacing unreliable screen-scraping with robust, schema-driven interaction.
|
|
6
6
|
|
|
7
|
-
**react-webmcp** provides idiomatic React primitives for
|
|
7
|
+
**react-webmcp** provides idiomatic React primitives for three API styles: **Imperative** (hooks), **Declarative** (HTML-attributed components), and **Adapter** (framework-agnostic wrappers for Material UI, Ant Design, and custom components).
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
+
### Imperative API
|
|
12
|
+
|
|
11
13
|
- **`useWebMCPTool`** — Register a single tool with automatic lifecycle management (mount/unmount)
|
|
12
14
|
- **`useWebMCPContext`** — Register multiple tools at once via `provideContext()`
|
|
13
15
|
- **`useToolEvent`** — Listen for `toolactivated` and `toolcancel` browser events
|
|
16
|
+
|
|
17
|
+
### Declarative API
|
|
18
|
+
|
|
14
19
|
- **`<WebMCPForm>`** — Declarative form component with `toolname` / `tooldescription` attributes
|
|
15
20
|
- **`<WebMCPInput>`, `<WebMCPSelect>`, `<WebMCPTextarea>`** — Form controls with `toolparam*` attributes
|
|
21
|
+
|
|
22
|
+
### Adapter API (third-party UI libraries)
|
|
23
|
+
|
|
24
|
+
- **`<WebMCP.Tool>`** — Wrapper that auto-detects fields from children, merges with `fields` prop, and registers via context
|
|
25
|
+
- **`<WebMCP.Field>`** — Zero-UI wrapper for custom components that can't be auto-detected
|
|
26
|
+
- **`useRegisterField`** — Hook to register field metadata from inside any component
|
|
27
|
+
- **`extractFields`**, **`buildInputSchema`**, **`validateSchema`** — Utilities for schema generation and dev-mode validation
|
|
28
|
+
|
|
29
|
+
### General
|
|
30
|
+
|
|
16
31
|
- **`<WebMCPProvider>`** — Context provider for availability detection
|
|
17
32
|
- Full TypeScript support with `navigator.modelContext` type augmentation
|
|
33
|
+
- SSR-safe tool registration and schema collection
|
|
18
34
|
- Works with the [Model Context Tool Inspector](https://chromewebstore.google.com/detail/model-context-tool-inspec/gbpdfapgefenggkahomfgkhfehlcenpd) extension
|
|
19
35
|
|
|
20
36
|
## Requirements
|
|
@@ -115,6 +131,49 @@ function ReservationForm() {
|
|
|
115
131
|
}
|
|
116
132
|
```
|
|
117
133
|
|
|
134
|
+
### Adapter API (WebMCP.Tool + useRegisterField)
|
|
135
|
+
|
|
136
|
+
Integrate with third-party UI libraries (Material UI, Ant Design) or custom components. The Adapter API auto-detects fields from children, or lets you declare them explicitly:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { WebMCP, WebMCPProvider } from "react-webmcp";
|
|
140
|
+
|
|
141
|
+
// Auto-detection: fields inferred from input/select props
|
|
142
|
+
<WebMCP.Tool
|
|
143
|
+
name="submit_contact"
|
|
144
|
+
description="Submit a contact form"
|
|
145
|
+
onExecute={(input) => console.log(input)}
|
|
146
|
+
>
|
|
147
|
+
<input name="email" type="email" required />
|
|
148
|
+
<select name="subject">
|
|
149
|
+
<option value="general">General</option>
|
|
150
|
+
<option value="support">Support</option>
|
|
151
|
+
</select>
|
|
152
|
+
</WebMCP.Tool>
|
|
153
|
+
|
|
154
|
+
// Explicit registration: for custom components without standard props
|
|
155
|
+
<WebMCP.Tool name="rate_feedback" description="Rate our product" onExecute={handler}>
|
|
156
|
+
<WebMCP.Field name="rating" type="number" required min={1} max={5}>
|
|
157
|
+
<StarRating value={rating} onChange={setRating} />
|
|
158
|
+
</WebMCP.Field>
|
|
159
|
+
</WebMCP.Tool>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
For components you control, use `useRegisterField` inside a wrapper:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
function RatingField({ value, onChange }) {
|
|
166
|
+
useRegisterField({
|
|
167
|
+
name: "rating",
|
|
168
|
+
type: "number",
|
|
169
|
+
required: true,
|
|
170
|
+
min: 1,
|
|
171
|
+
max: 5,
|
|
172
|
+
});
|
|
173
|
+
return <StarRating value={value} onChange={onChange} />;
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
118
177
|
## API Reference
|
|
119
178
|
|
|
120
179
|
### Hooks
|
|
@@ -193,6 +252,66 @@ All standard HTML attributes are also supported.
|
|
|
193
252
|
|
|
194
253
|
Context provider that makes WebMCP availability info accessible via `useWebMCPStatus()`.
|
|
195
254
|
|
|
255
|
+
### Adapter API
|
|
256
|
+
|
|
257
|
+
#### `<WebMCP.Tool>` / `<WebMCPTool>`
|
|
258
|
+
|
|
259
|
+
Wrapper component that collects field definitions from children (auto-detection), the `fields` prop, and context-registered fields via `useRegisterField`, then registers the tool with the generated JSON Schema.
|
|
260
|
+
|
|
261
|
+
| Prop | Type | Description |
|
|
262
|
+
|------|------|-------------|
|
|
263
|
+
| `name` | `string` | Unique tool identifier |
|
|
264
|
+
| `description` | `string` | Human-readable description for agents |
|
|
265
|
+
| `onExecute` | `(input) => any` | Handler called on invocation |
|
|
266
|
+
| `fields` | `Record<string, Partial<FieldDefinition>>` | *(optional)* Override or enrich field metadata |
|
|
267
|
+
| `strict` | `boolean` | *(optional)* Throw on schema validation errors in dev (default: `false`) |
|
|
268
|
+
| `autoSubmit` | `boolean` | *(optional)* Submit when invoked by agent |
|
|
269
|
+
| `annotations` | `ToolAnnotations` | *(optional)* Tool hints |
|
|
270
|
+
| `onToolActivated` | `(name) => void` | *(optional)* Activation callback |
|
|
271
|
+
| `onToolCancel` | `(name) => void` | *(optional)* Cancel callback |
|
|
272
|
+
|
|
273
|
+
#### `<WebMCP.Field>` / `<WebMCPField>`
|
|
274
|
+
|
|
275
|
+
Zero-UI wrapper that registers a field via context. Renders a Fragment. Use when child components don't expose `name` or other form props.
|
|
276
|
+
|
|
277
|
+
| Prop | Type | Description |
|
|
278
|
+
|------|------|-------------|
|
|
279
|
+
| `name` | `string` | Field name |
|
|
280
|
+
| `type` | `string` | *(optional)* HTML input type, default `"string"` |
|
|
281
|
+
| `required` | `boolean` | *(optional)* Whether required |
|
|
282
|
+
| `description` | `string` | *(optional)* Description for agents |
|
|
283
|
+
| `min`, `max` | `number` | *(optional)* Numeric constraints |
|
|
284
|
+
| `minLength`, `maxLength` | `number` | *(optional)* String length constraints |
|
|
285
|
+
| `pattern` | `string` | *(optional)* Regex for string validation |
|
|
286
|
+
| `enumValues` | `Array` of string/number/boolean | *(optional)* Allowed values |
|
|
287
|
+
| `oneOf` | `{ value, label }[]` | *(optional)* Labelled options (auto-detected from `<option>` children if omitted) |
|
|
288
|
+
|
|
289
|
+
#### `useRegisterField(field)`
|
|
290
|
+
|
|
291
|
+
Registers field metadata with the nearest `WebMCP.Tool` context. Call from inside custom components that don't render standard form elements. SSR-safe.
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
useRegisterField({
|
|
295
|
+
name: "rating",
|
|
296
|
+
type: "number",
|
|
297
|
+
required: true,
|
|
298
|
+
min: 1,
|
|
299
|
+
max: 5,
|
|
300
|
+
description: "Star rating from 1 to 5",
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
#### `FieldDefinition`
|
|
305
|
+
|
|
306
|
+
Type for field metadata. See `src/adapters/types.ts` for the full interface.
|
|
307
|
+
|
|
308
|
+
#### Utilities (schema building)
|
|
309
|
+
|
|
310
|
+
- **`extractFields(children)`** — Traverse React children and extract `FieldDefinition[]` from `name`, `type`, `required`, etc.
|
|
311
|
+
- **`extractOptions(children)`** — Extract `{ value, label }[]` from `<option>` or `MenuItem`-like children.
|
|
312
|
+
- **`buildInputSchema(fields)`** — Convert `FieldDefinition[]` to JSON Schema.
|
|
313
|
+
- **`validateSchema(fields, { strict? })`** — Dev-mode validation; warns (or throws if `strict`) on conflicts.
|
|
314
|
+
|
|
196
315
|
### Utilities
|
|
197
316
|
|
|
198
317
|
#### `isWebMCPAvailable()`
|
|
@@ -231,22 +350,17 @@ useWebMCPTool({
|
|
|
231
350
|
|
|
232
351
|
## Demos
|
|
233
352
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Replicates Google's [react-flightsearch](https://googlechromelabs.github.io/webmcp-tools/demos/react-flightsearch/) demo using `useWebMCPTool` hooks. Exposes 4 tools: `searchFlights`, `listFlights`, `setFilters`, `resetFilters`.
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
cd demos/flight-search
|
|
240
|
-
npm install
|
|
241
|
-
npm run dev
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### French Bistro (Declarative API)
|
|
353
|
+
Four demo apps showcase the different API styles. See [demos/README.md](./demos/README.md) for a detailed comparison and quick-start guide.
|
|
245
354
|
|
|
246
|
-
|
|
355
|
+
| Demo | API | Description |
|
|
356
|
+
|------|-----|-------------|
|
|
357
|
+
| [french-bistro](./demos/french-bistro) | Declarative | Restaurant reservation form — `WebMCPForm`, `WebMCPInput`, `WebMCPSelect`, `WebMCPTextarea` |
|
|
358
|
+
| [flight-search](./demos/flight-search) | Imperative | Flight search with `useWebMCPTool` — `searchFlights`, `listFlights`, `setFilters`, `resetFilters` |
|
|
359
|
+
| [contact-form](./demos/contact-form) | All four | Same form implemented four ways side-by-side for comparison |
|
|
360
|
+
| [custom-components](./demos/custom-components) | Adapter | Custom UI (`StarRating`, `TagInput`, `ColorPicker`) with `useRegisterField` and `WebMCP.Field` |
|
|
247
361
|
|
|
248
362
|
```bash
|
|
249
|
-
cd demos
|
|
363
|
+
cd demos/<demo-name>
|
|
250
364
|
npm install
|
|
251
365
|
npm run dev
|
|
252
366
|
```
|
|
@@ -264,8 +378,10 @@ npm run dev
|
|
|
264
378
|
```
|
|
265
379
|
Your React App
|
|
266
380
|
│
|
|
267
|
-
├─ useWebMCPTool()
|
|
268
|
-
├─ <WebMCPForm>
|
|
381
|
+
├─ useWebMCPTool() ──► navigator.modelContext.registerTool()
|
|
382
|
+
├─ <WebMCPForm> ──► <form toolname="..." tooldescription="...">
|
|
383
|
+
├─ <WebMCP.Tool> ──► Collects fields (children + fields + useRegisterField)
|
|
384
|
+
│ → buildInputSchema() → registerTool()
|
|
269
385
|
│
|
|
270
386
|
└─ Browser (Chrome 146+)
|
|
271
387
|
│
|
|
@@ -285,6 +401,9 @@ import type {
|
|
|
285
401
|
JSONSchema,
|
|
286
402
|
ToolAnnotations,
|
|
287
403
|
WebMCPFormSubmitEvent,
|
|
404
|
+
WebMCPToolProps,
|
|
405
|
+
WebMCPFieldProps,
|
|
406
|
+
FieldDefinition,
|
|
288
407
|
ModelContext,
|
|
289
408
|
} from "react-webmcp";
|
|
290
409
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React$1 from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* WebMCP type definitions for the W3C navigator.modelContext API.
|
|
@@ -270,7 +270,7 @@ declare function useWebMCPContext(config: {
|
|
|
270
270
|
*/
|
|
271
271
|
declare function useToolEvent(event: "toolactivated" | "toolcancel", callback: (toolName: string) => void, toolNameFilter?: string): void;
|
|
272
272
|
|
|
273
|
-
interface WebMCPFormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>, "onSubmit"> {
|
|
273
|
+
interface WebMCPFormProps extends Omit<React$1.FormHTMLAttributes<HTMLFormElement>, "onSubmit"> {
|
|
274
274
|
/** The tool name exposed to AI agents. Maps to the `toolname` HTML attribute. */
|
|
275
275
|
toolName: string;
|
|
276
276
|
/** Description of what this tool does. Maps to `tooldescription`. */
|
|
@@ -286,7 +286,7 @@ interface WebMCPFormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>
|
|
|
286
286
|
onToolActivated?: (toolName: string) => void;
|
|
287
287
|
/** Called when a tool cancel event fires for this form's tool. */
|
|
288
288
|
onToolCancel?: (toolName: string) => void;
|
|
289
|
-
children: React.ReactNode;
|
|
289
|
+
children: React$1.ReactNode;
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
292
292
|
* A React wrapper for the WebMCP declarative API.
|
|
@@ -314,7 +314,7 @@ interface WebMCPFormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>
|
|
|
314
314
|
*/
|
|
315
315
|
declare function WebMCPForm({ toolName, toolDescription, toolAutoSubmit, onSubmit, onToolActivated, onToolCancel, children, ...rest }: WebMCPFormProps): react_jsx_runtime.JSX.Element;
|
|
316
316
|
|
|
317
|
-
interface WebMCPInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
317
|
+
interface WebMCPInputProps extends React$1.InputHTMLAttributes<HTMLInputElement> {
|
|
318
318
|
/** Maps to the `toolparamtitle` attribute (overrides the JSON Schema property key). */
|
|
319
319
|
toolParamTitle?: string;
|
|
320
320
|
/** Maps to the `toolparamdescription` attribute (describes this parameter to agents). */
|
|
@@ -337,14 +337,14 @@ interface WebMCPInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
|
337
337
|
* />
|
|
338
338
|
* ```
|
|
339
339
|
*/
|
|
340
|
-
declare const WebMCPInput: React.ForwardRefExoticComponent<WebMCPInputProps & React.RefAttributes<HTMLInputElement>>;
|
|
340
|
+
declare const WebMCPInput: React$1.ForwardRefExoticComponent<WebMCPInputProps & React$1.RefAttributes<HTMLInputElement>>;
|
|
341
341
|
|
|
342
|
-
interface WebMCPSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
|
342
|
+
interface WebMCPSelectProps extends React$1.SelectHTMLAttributes<HTMLSelectElement> {
|
|
343
343
|
/** Maps to the `toolparamtitle` attribute (overrides the JSON Schema property key). */
|
|
344
344
|
toolParamTitle?: string;
|
|
345
345
|
/** Maps to the `toolparamdescription` attribute (describes this parameter to agents). */
|
|
346
346
|
toolParamDescription?: string;
|
|
347
|
-
children: React.ReactNode;
|
|
347
|
+
children: React$1.ReactNode;
|
|
348
348
|
}
|
|
349
349
|
/**
|
|
350
350
|
* A `<select>` element enhanced with WebMCP declarative attributes.
|
|
@@ -364,9 +364,9 @@ interface WebMCPSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement
|
|
|
364
364
|
* </WebMCPSelect>
|
|
365
365
|
* ```
|
|
366
366
|
*/
|
|
367
|
-
declare const WebMCPSelect: React.ForwardRefExoticComponent<WebMCPSelectProps & React.RefAttributes<HTMLSelectElement>>;
|
|
367
|
+
declare const WebMCPSelect: React$1.ForwardRefExoticComponent<WebMCPSelectProps & React$1.RefAttributes<HTMLSelectElement>>;
|
|
368
368
|
|
|
369
|
-
interface WebMCPTextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
369
|
+
interface WebMCPTextareaProps extends React$1.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
370
370
|
/** Maps to the `toolparamtitle` attribute (overrides the JSON Schema property key). */
|
|
371
371
|
toolParamTitle?: string;
|
|
372
372
|
/** Maps to the `toolparamdescription` attribute (describes this parameter to agents). */
|
|
@@ -386,7 +386,7 @@ interface WebMCPTextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaE
|
|
|
386
386
|
* />
|
|
387
387
|
* ```
|
|
388
388
|
*/
|
|
389
|
-
declare const WebMCPTextarea: React.ForwardRefExoticComponent<WebMCPTextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
389
|
+
declare const WebMCPTextarea: React$1.ForwardRefExoticComponent<WebMCPTextareaProps & React$1.RefAttributes<HTMLTextAreaElement>>;
|
|
390
390
|
|
|
391
391
|
interface WebMCPContextValue {
|
|
392
392
|
/** Whether navigator.modelContext is available in this browser. */
|
|
@@ -412,7 +412,7 @@ interface WebMCPContextValue {
|
|
|
412
412
|
* ```
|
|
413
413
|
*/
|
|
414
414
|
declare function WebMCPProvider({ children }: {
|
|
415
|
-
children: React.ReactNode;
|
|
415
|
+
children: React$1.ReactNode;
|
|
416
416
|
}): react_jsx_runtime.JSX.Element;
|
|
417
417
|
/**
|
|
418
418
|
* Returns the current WebMCP availability status.
|
|
@@ -445,4 +445,284 @@ declare function isWebMCPAvailable(): boolean;
|
|
|
445
445
|
*/
|
|
446
446
|
declare function isWebMCPTestingAvailable(): boolean;
|
|
447
447
|
|
|
448
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Type definitions for the WebMCP adapter layer.
|
|
450
|
+
*
|
|
451
|
+
* These types support the runtime schema collector engine that enables
|
|
452
|
+
* third-party UI component libraries (e.g. Material UI) to work with
|
|
453
|
+
* the WebMCP tool registration API.
|
|
454
|
+
*/
|
|
455
|
+
/**
|
|
456
|
+
* Describes a single field (tool parameter) collected from React children,
|
|
457
|
+
* the `fields` prop, or via `useRegisterField`.
|
|
458
|
+
*
|
|
459
|
+
* @example
|
|
460
|
+
* ```ts
|
|
461
|
+
* const field: FieldDefinition = {
|
|
462
|
+
* name: "email",
|
|
463
|
+
* type: "email",
|
|
464
|
+
* required: true,
|
|
465
|
+
* description: "Recipient's email address",
|
|
466
|
+
* };
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
interface FieldDefinition {
|
|
470
|
+
/** Field name — must be unique within a tool. */
|
|
471
|
+
name: string;
|
|
472
|
+
/** HTML input type (e.g. "text", "email", "number"). Defaults to "string". */
|
|
473
|
+
type?: string;
|
|
474
|
+
/** Whether the field is required. */
|
|
475
|
+
required?: boolean;
|
|
476
|
+
/** Human-readable title for agents. */
|
|
477
|
+
title?: string;
|
|
478
|
+
/** Human-readable description for agents. */
|
|
479
|
+
description?: string;
|
|
480
|
+
/** Minimum numeric value (maps to JSON Schema `minimum`). */
|
|
481
|
+
min?: number;
|
|
482
|
+
/** Maximum numeric value (maps to JSON Schema `maximum`). */
|
|
483
|
+
max?: number;
|
|
484
|
+
/** Minimum string length (maps to JSON Schema `minLength`). */
|
|
485
|
+
minLength?: number;
|
|
486
|
+
/** Maximum string length (maps to JSON Schema `maxLength`). */
|
|
487
|
+
maxLength?: number;
|
|
488
|
+
/** Regex pattern for string validation (maps to JSON Schema `pattern`). */
|
|
489
|
+
pattern?: string;
|
|
490
|
+
/** Allowed values — mapped to JSON Schema `enum`. */
|
|
491
|
+
enumValues?: (string | number | boolean)[];
|
|
492
|
+
/** Labelled options — mapped to JSON Schema `oneOf`. */
|
|
493
|
+
oneOf?: {
|
|
494
|
+
value: string | number | boolean;
|
|
495
|
+
label: string;
|
|
496
|
+
}[];
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Props for the `WebMCP.Tool` component.
|
|
501
|
+
*/
|
|
502
|
+
interface WebMCPToolProps {
|
|
503
|
+
/** Unique tool name exposed to AI agents. */
|
|
504
|
+
name: string;
|
|
505
|
+
/** Human-readable description of what this tool does. */
|
|
506
|
+
description: string;
|
|
507
|
+
/** Handler called when an AI agent invokes this tool. */
|
|
508
|
+
onExecute: (input: Record<string, unknown>) => unknown | Promise<unknown>;
|
|
509
|
+
/** Optional field overrides / enrichment keyed by field name. */
|
|
510
|
+
fields?: Record<string, Partial<FieldDefinition>>;
|
|
511
|
+
/** When true, schema validation issues throw instead of warn. */
|
|
512
|
+
strict?: boolean;
|
|
513
|
+
/** If true, the tool auto-submits when filled by an agent. */
|
|
514
|
+
autoSubmit?: boolean;
|
|
515
|
+
/** Optional metadata hints for agents. */
|
|
516
|
+
annotations?: ToolAnnotations;
|
|
517
|
+
/** Called when a `toolactivated` event fires for this tool. */
|
|
518
|
+
onToolActivated?: (toolName: string) => void;
|
|
519
|
+
/** Called when a `toolcancel` event fires for this tool. */
|
|
520
|
+
onToolCancel?: (toolName: string) => void;
|
|
521
|
+
children: React$1.ReactNode;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Framework-agnostic tool wrapper that collects a JSON Schema from its
|
|
525
|
+
* React children and registers it as a WebMCP tool.
|
|
526
|
+
*
|
|
527
|
+
* Fields are auto-detected from child components (e.g. `<Input name="email" />`),
|
|
528
|
+
* enriched via the `fields` prop, and can be overridden by descendant
|
|
529
|
+
* components using `useRegisterField`.
|
|
530
|
+
*
|
|
531
|
+
* @example
|
|
532
|
+
* ```tsx
|
|
533
|
+
* <WebMCPTool
|
|
534
|
+
* name="send_email"
|
|
535
|
+
* description="Send an email to a user"
|
|
536
|
+
* onExecute={async ({ email, priority }) => {
|
|
537
|
+
* await sendEmail(email, priority);
|
|
538
|
+
* return { content: [{ type: "text", text: "Sent!" }] };
|
|
539
|
+
* }}
|
|
540
|
+
* fields={{ email: { description: "Recipient's email" } }}
|
|
541
|
+
* >
|
|
542
|
+
* <FormControl>
|
|
543
|
+
* <Input name="email" type="email" required />
|
|
544
|
+
* </FormControl>
|
|
545
|
+
* </WebMCPTool>
|
|
546
|
+
* ```
|
|
547
|
+
*/
|
|
548
|
+
declare function WebMCPTool({ name, description, onExecute, fields: fieldsProp, strict, autoSubmit, annotations, onToolActivated, onToolCancel, children, }: WebMCPToolProps): react_jsx_runtime.JSX.Element;
|
|
549
|
+
declare namespace WebMCPTool {
|
|
550
|
+
var displayName: string;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Props for the `WebMCP.Field` component.
|
|
555
|
+
*/
|
|
556
|
+
interface WebMCPFieldProps extends Omit<FieldDefinition, "name"> {
|
|
557
|
+
/** Field name — must be unique within the parent `WebMCP.Tool`. */
|
|
558
|
+
name: string;
|
|
559
|
+
children: React$1.ReactNode;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Zero-UI wrapper that registers a field with the nearest `WebMCP.Tool`.
|
|
563
|
+
*
|
|
564
|
+
* Use this as an escape hatch for custom components that cannot be
|
|
565
|
+
* auto-detected by the children traversal engine. Enum values are
|
|
566
|
+
* automatically detected from children that have a `value` prop
|
|
567
|
+
* (e.g. `<MenuItem value="low">Low</MenuItem>`).
|
|
568
|
+
*
|
|
569
|
+
* Renders a React Fragment — no extra DOM elements are introduced.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* ```tsx
|
|
573
|
+
* <WebMCP.Field name="priority" description="Email priority">
|
|
574
|
+
* <Select>
|
|
575
|
+
* <MenuItem value="low">Low</MenuItem>
|
|
576
|
+
* <MenuItem value="high">High</MenuItem>
|
|
577
|
+
* </Select>
|
|
578
|
+
* </WebMCP.Field>
|
|
579
|
+
* ```
|
|
580
|
+
*/
|
|
581
|
+
declare function WebMCPField({ children, name, ...rest }: WebMCPFieldProps): react_jsx_runtime.JSX.Element;
|
|
582
|
+
declare namespace WebMCPField {
|
|
583
|
+
var displayName: string;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Register a field definition with the nearest `WebMCP.Tool` ancestor.
|
|
588
|
+
*
|
|
589
|
+
* Uses `useEffect` (SSR-safe) so registration only happens on the client.
|
|
590
|
+
* The field is automatically unregistered on unmount. Re-registration
|
|
591
|
+
* only occurs when the field definition changes (compared by fingerprint).
|
|
592
|
+
*
|
|
593
|
+
* If no `WebMCP.Tool` ancestor exists, a dev-mode warning is logged.
|
|
594
|
+
*
|
|
595
|
+
* @example
|
|
596
|
+
* ```tsx
|
|
597
|
+
* function MyField() {
|
|
598
|
+
* useRegisterField({ name: "email", type: "email", required: true });
|
|
599
|
+
* return <input name="email" type="email" required />;
|
|
600
|
+
* }
|
|
601
|
+
* ```
|
|
602
|
+
*/
|
|
603
|
+
declare function useRegisterField(field: FieldDefinition): void;
|
|
604
|
+
|
|
605
|
+
interface UseSchemaCollectorOptions {
|
|
606
|
+
/** React children to traverse for auto-detected fields. */
|
|
607
|
+
children: React.ReactNode;
|
|
608
|
+
/** Optional field overrides keyed by field name. */
|
|
609
|
+
fields?: Record<string, Partial<FieldDefinition>>;
|
|
610
|
+
/** When true, validation issues throw instead of warn. */
|
|
611
|
+
strict?: boolean;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Core engine hook that collects field definitions from three sources,
|
|
615
|
+
* merges them, validates in dev, and builds a deterministic JSON Schema.
|
|
616
|
+
*
|
|
617
|
+
* **Sources** (lowest to highest priority):
|
|
618
|
+
* 1. Children traversal (auto-detected from React tree)
|
|
619
|
+
* 2. `fields` prop (enrichment / override)
|
|
620
|
+
* 3. Context-registered fields (via `useRegisterField`)
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```tsx
|
|
624
|
+
* const { schema, registerField, unregisterField } = useSchemaCollector({
|
|
625
|
+
* children,
|
|
626
|
+
* fields: { email: { description: "Recipient" } },
|
|
627
|
+
* });
|
|
628
|
+
* ```
|
|
629
|
+
*/
|
|
630
|
+
declare function useSchemaCollector({ children, fields: fieldsProp, strict, }: UseSchemaCollectorOptions): {
|
|
631
|
+
schema: JSONSchema;
|
|
632
|
+
registerField: (field: FieldDefinition) => void;
|
|
633
|
+
unregisterField: (name: string) => void;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Recursively extract option values from React children.
|
|
638
|
+
*
|
|
639
|
+
* Detects elements that have a `value` prop (e.g. `<MenuItem value="low">Low</MenuItem>`)
|
|
640
|
+
* and collects `{ value, label }` pairs. The label is derived from string children
|
|
641
|
+
* or falls back to `String(value)`.
|
|
642
|
+
*
|
|
643
|
+
* @example
|
|
644
|
+
* ```tsx
|
|
645
|
+
* const options = extractOptions(
|
|
646
|
+
* <>
|
|
647
|
+
* <MenuItem value="low">Low</MenuItem>
|
|
648
|
+
* <MenuItem value="high">High</MenuItem>
|
|
649
|
+
* </>
|
|
650
|
+
* );
|
|
651
|
+
* // [{ value: "low", label: "Low" }, { value: "high", label: "High" }]
|
|
652
|
+
* ```
|
|
653
|
+
*/
|
|
654
|
+
declare function extractOptions(children: React$1.ReactNode): {
|
|
655
|
+
value: string | number | boolean;
|
|
656
|
+
label: string;
|
|
657
|
+
}[];
|
|
658
|
+
/**
|
|
659
|
+
* Recursively extract field definitions from a React children tree.
|
|
660
|
+
*
|
|
661
|
+
* Walks the tree using `React.Children.toArray` (safe, pure traversal).
|
|
662
|
+
* Detects field names from `props.name`, `props.inputProps.name`, or
|
|
663
|
+
* `props.slotProps.input.name`. When a named element is found, it builds
|
|
664
|
+
* a `FieldDefinition` from its props and auto-detects enum values from
|
|
665
|
+
* its children. Elements without a name are recursed into.
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* ```tsx
|
|
669
|
+
* const fields = extractFields(
|
|
670
|
+
* <>
|
|
671
|
+
* <Input name="email" type="email" required />
|
|
672
|
+
* <Select name="priority">
|
|
673
|
+
* <MenuItem value="low">Low</MenuItem>
|
|
674
|
+
* <MenuItem value="high">High</MenuItem>
|
|
675
|
+
* </Select>
|
|
676
|
+
* </>
|
|
677
|
+
* );
|
|
678
|
+
* ```
|
|
679
|
+
*/
|
|
680
|
+
declare function extractFields(children: React$1.ReactNode): FieldDefinition[];
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Build a deterministic JSON Schema from an array of field definitions.
|
|
684
|
+
*
|
|
685
|
+
* Property names are sorted alphabetically and the `required` array is
|
|
686
|
+
* also sorted, ensuring identical output regardless of field insertion
|
|
687
|
+
* order.
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* ```ts
|
|
691
|
+
* const schema = buildInputSchema([
|
|
692
|
+
* { name: "email", type: "email", required: true },
|
|
693
|
+
* { name: "age", type: "number", min: 0, max: 120 },
|
|
694
|
+
* ]);
|
|
695
|
+
* ```
|
|
696
|
+
*/
|
|
697
|
+
declare function buildInputSchema(fields: FieldDefinition[]): JSONSchema;
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Validate an array of field definitions for common schema issues.
|
|
701
|
+
*
|
|
702
|
+
* In production this is a no-op. In development it checks for:
|
|
703
|
+
* - Duplicate field names
|
|
704
|
+
* - `pattern` used on non-string types
|
|
705
|
+
* - `min`/`max` used on non-number types
|
|
706
|
+
* - `minLength`/`maxLength` used on non-string types
|
|
707
|
+
* - Enum values whose types don't match the declared field type
|
|
708
|
+
*
|
|
709
|
+
* By default warnings are logged via `console.warn` with the
|
|
710
|
+
* `[react-webmcp]` prefix. When `strict` is `true`, an `Error` is
|
|
711
|
+
* thrown instead.
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```ts
|
|
715
|
+
* validateSchema(fields); // warns in dev
|
|
716
|
+
* validateSchema(fields, { strict: true }); // throws in dev
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
declare function validateSchema(fields: FieldDefinition[], options?: {
|
|
720
|
+
strict?: boolean;
|
|
721
|
+
}): void;
|
|
722
|
+
|
|
723
|
+
declare const WebMCP: {
|
|
724
|
+
readonly Tool: typeof WebMCPTool;
|
|
725
|
+
readonly Field: typeof WebMCPField;
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
export { type FieldDefinition, type JSONSchema, type JSONSchemaProperty, type ModelContext, type ModelContextTesting, type ToolActivatedEvent, type ToolAnnotations, type ToolCancelEvent, type ToolContent, type ToolContentJSON, type ToolContentText, type UseWebMCPToolConfig, WebMCP, type WebMCPContextConfig, WebMCPField, type WebMCPFieldProps, WebMCPForm, type WebMCPFormProps, type WebMCPFormSubmitEvent, WebMCPInput, type WebMCPInputProps, WebMCPProvider, WebMCPSelect, type WebMCPSelectProps, WebMCPTextarea, type WebMCPTextareaProps, WebMCPTool, type WebMCPToolDefinition, type WebMCPToolProps, buildInputSchema, extractFields, extractOptions, getModelContext, isWebMCPAvailable, isWebMCPTestingAvailable, useRegisterField, useSchemaCollector, useToolEvent, useWebMCPContext, useWebMCPStatus, useWebMCPTool, validateSchema };
|