Skip to main content
usewebmcp is the strict-core React package. It registers tools with navigator.modelContext on mount and unregisters them on unmount without adding MCP-B-only hooks. navigator.modelContext must already exist at runtime through native browser support, @mcp-b/webmcp-polyfill, or @mcp-b/global.

Installation

pnpm add usewebmcp react

Minimal example

Hook

useWebMCP(config, deps?)

import { useWebMCP } from 'usewebmcp';
ParameterTypeDescription
configWebMCPConfigTool configuration object
depsDependencyListOptional dependency array that triggers tool re-registration when values change
Returns: WebMCPReturn
FieldTypeDescription
stateToolExecutionStateCurrent execution state
execute(input)(input) => PromiseManually invoke the tool from your UI or tests
reset()() => voidReset state to initial values

Config fields

FieldTypeRequiredDescription
namestringYesUnique tool identifier (lowercase with underscores)
descriptionstringYesHuman-readable description for AI assistants
inputSchemaJSON Schema or Standard Schema v1NoDefines input parameters. Use as const for inference.
outputSchemaJsonSchemaObjectNoDefines output structure and enables structuredContent.
annotationsToolAnnotationsNoMetadata hints such as readOnlyHint and idempotentHint
execute(input)(input) => T | Promise<T>Yes*Preferred tool implementation function
handler(input)(input) => T | Promise<T>Yes*Backward-compatible alias for execute
formatOutput(output)(output) => stringNoDeprecated. Prefer outputSchema.
onSuccess(result, input)(result, input) => voidNoCallback after successful execution
onError(error, input)(error, input) => voidNoCallback after failed execution
One of execute or handler is required. If both are present, execute wins.

ToolExecutionState

FieldTypeDescription
isExecutingbooleanWhether the tool is currently running
lastResultTOutput | nullResult from the most recent successful execution
errorError | nullError from the most recent failed execution
executionCountnumberTotal successful executions

Type inference

Input inference works with two schema formats:
  • JSON Schema literals with as const
  • Standard Schema v1 implementations such as Zod v4, Valibot, and ArkType
Output inference comes from outputSchema when you pass a JSON Schema literal:
  • the execute or handler return type is inferred from the schema
  • state.lastResult is typed accordingly
  • the MCP response includes structuredContent
const OUTPUT_SCHEMA = {
  type: 'object',
  properties: {
    total: { type: 'integer' },
  },
  required: ['total'],
  additionalProperties: false,
} as const;

const tool = useWebMCP({
  name: 'count_items',
  description: 'Count items',
  outputSchema: OUTPUT_SCHEMA,
  execute: () => ({ total: 3 }),
});

Re-registration triggers

The hook unregisters and re-registers when any of these values change:
  • name
  • description
  • inputSchema reference
  • outputSchema reference
  • annotations reference
  • values in deps
These callbacks are stored in refs and do not trigger re-registration:
  • execute
  • handler
  • onSuccess
  • onError
  • formatOutput
Define inputSchema, outputSchema, and annotations outside the component or memoize them. Fresh object references on every render force unnecessary re-registration.

Output schema contract

When outputSchema is defined, the implementation must return a JSON-serializable object. Returning a non-object value causes an error response from the registered MCP tool.

Exported types

TypeDescription
WebMCPConfigConfiguration object type
WebMCPReturnReturn value type
ToolExecutionStateExecution state shape
ToolExecuteFunctionTool implementation function signature
InferToolInputInfer input type from schema
InferOutputInfer output type from schema