Lets React developers expose typed app functionality as WebMCP tools that AI agents can discover and call.
Also known as agentcathq/webmcp-react
- Stars
- 92
- Tools
- —
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Oct 27, 2026
- License
- MIT
What is webmcp-react MCP?
webmcp-react lets React developers expose typed app functionality as WebMCP tools that AI agents can discover and call.
Summary generated from the project's README
About webmcp-react MCP server
Exposing parts of a React app as callable tools for AI agents is what webmcp-react handles, through hooks that register each tool on document.modelContext. React developers wrap their app in WebMCPProvider and declare tools with useMcpTool, giving each one a name, description, input and async handler. Inputs are defined with Zod for type inference in handlers, or with raw JSON Schema via inputSchema when Zod is not in use. React 18 or later is required, and Zod 3.25 or later or Zod 4 is a peer dependency when Zod is used.
The library installs a lightweight polyfill when the browser lacks native WebMCP support, and otherwise defers to the native API. It is SSR-safe and ships a "use client" banner, so Next.js and Remix need no extra setup, and it guards against duplicate registrations under StrictMode. Tools register on mount and unregister on unmount, so conditional rendering controls what agents can see. useMcpTool returns execution state (isExecuting, lastResult, error), each call receives its own AbortSignal, and onSuccess and onError callbacks run side effects. Four annotations (readOnlyHint, untrustedContentHint, consequentialHint, debugging) describe behavior to agents.
Agents with native WebMCP support such as Codex call tools directly from the page; Claude Code, Cursor and other MCP clients connect through a Bridge browser extension. A Wordle playground and agent skills installed with the skills CLI demonstrate and scaffold tools.
What you can do with it
- 1Catalog search tool for agentsRegister a search tool that takes a query string and returns matching catalog results for an AI client to call.
- 2Cancellable report fetchingLet an agent fetch a report by ID while wiring the provided AbortSignal into fetch so a cancelled call stops the request.
- 3Confirmation for ordersMark a checkout tool with a hint so agents know to check with the user before running something hard to undo.
- 4Admin tools behind conditional renderExpose admin-only tools only when the current user is an admin, letting mount and unmount handle registration.
- 5Tool execution state in UIDrive a button's disabled state and message from the execution state returned by a translation tool hook.
Written from the project's README. Every use case is checked against a quote from it.
How to install webmcp-react MCP
Formats verified 10 Nov 2026Add to CursorAdd to GooseInstall webmcp-react MCP in Claude Code
$ claude mcp add webmcp-react -- npx -y webmcp-reactInstall webmcp-react MCP in Cursor
~/.cursor/mcp.json
{
"mcpServers": {
"webmcp-react": {
"command": "npx",
"args": [
"-y",
"webmcp-react"
]
}
}
}Install webmcp-react MCP in VS Code
.vscode/mcp.json
{
"servers": {
"webmcp-react": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"webmcp-react"
]
}
}
}Install webmcp-react MCP in VS Code CLI
$ code --add-mcp '{"name":"webmcp-react","type":"stdio","command":"npx","args":["-y","webmcp-react"]}'Install webmcp-react MCP in Claude Desktop
claude_desktop_config.json
{
"mcpServers": {
"webmcp-react": {
"command": "npx",
"args": [
"-y",
"webmcp-react"
]
}
}
}Install webmcp-react MCP in Codex
$ codex mcp add webmcp-react -- npx -y webmcp-reactInstall webmcp-react MCP in Codex config.toml
~/.codex/config.toml
[mcp_servers.webmcp-react] command = "npx" args = ["-y", "webmcp-react"]
Install webmcp-react MCP in Gemini CLI
$ gemini mcp add -s user webmcp-react npx -- -y webmcp-reactInstall webmcp-react MCP in Gemini settings.json
~/.gemini/settings.json
{
"mcpServers": {
"webmcp-react": {
"command": "npx",
"args": [
"-y",
"webmcp-react"
]
}
}
}Automated checks
Ran Nov 13, 2026Full report →Passed our automated checks. That is not a security audit: read the code and give the server the narrowest access it needs. How checks work
- Source repository linked and reachablePass
- Open source license (OSI)Pass
- Commit or release in the last yearPass
- Package name not close to a popular packagePass
- Remote endpoint uses HTTPSNot checked
- Destructive tools are labelledNot checked
- No hidden instructions to the modelPass
- No critical advisory in the package or its dependenciesNot checked
README
View on GitHubwebmcp-react
React hooks for exposing typed tools on document.modelContext, aligned with the current WebMCP specification.
- Zod-first. Define inputs with Zod and get full type inference in handlers
- JSON Schema support. Pass raw JSON Schema when you do not use Zod
- Built-in polyfill. Installs a lightweight polyfill when native WebMCP is unavailable
- SSR-safe. Works with Next.js, Remix, and other server-rendering frameworks
- StrictMode-safe. Prevents duplicate registrations and orphaned tools
- Spec-aligned. Tracks the WebMCP specification and native Chrome behavior release by release
Requirements
- React 18 or later
- Zod 3.25 or later, or Zod 4, as a peer dependency. Tools can also be defined with JSON Schema.
Install
npm install webmcp-react zod
Quick start
Wrap your app in <WebMCPProvider> and register tools with useMcpTool:
import { WebMCPProvider, useMcpTool } from "webmcp-react";
import { z } from "zod";
function SearchTool() {
useMcpTool({
name: "search",
description: "Search the catalog",
input: z.object({ query: z.string() }),
handler: async ({ query }) => ({
content: [{ type: "text", text: `Results for: ${query}` }],
}),
});
return null;
}
export default function App() {
return (
<WebMCPProvider name="my-app" version="1.0">
<SearchTool />
</WebMCPProvider>
);
}
The tool is now registered on document.modelContext and any WebMCP-compatible agent can call it.
Agent skills
This repository ships agent skills that install webmcp-react and scaffold tools for you. Install them with the skills CLI:
npx skills add agentcathq/webmcp-react
The skills work with Cursor, Claude Code, GitHub Copilot, Cline, and 18+ other agents.
Playground
Try it live: WebMCP Wordle Demo
The playground is a fully playable Wordle clone built on webmcp-react hooks. Tools register and unregister as the game moves through its phases (idle, playing, won, lost). You can make guesses with the keyboard or through an AI agent. A DevPanel shows the current tool state, and an easy-mode toggle enables a hint tool.
To play with an AI agent:
- Codex. Open the demo in Codex and ask it to play. Codex discovers and calls the page's WebMCP tools directly.
- Claude, Cursor, and other MCP clients. Install the WebMCP Bridge extension, open the demo in Chrome, and activate the extension for the page.
How it works
WebMCP is a proposed web standard from the W3C Web Machine Learning Community Group. It adds document.modelContext to the browser, an API that lets any page expose typed, callable tools to AI agents. Chrome ships the API in Early Preview.
This library provides the React bindings for that API. <WebMCPProvider> installs a polyfill when native support is absent, and each useMcpTool call registers a tool that agents can discover and execute.
Connect to AI clients
Agents with built-in WebMCP browser support, such as Codex, discover and call tools directly from the page. Clients that cannot access document.modelContext directly, such as Claude Code and Cursor, connect through the WebMCP Bridge extension, which exposes your registered tools to any MCP client.
- Install the extension from the Chrome Web Store.
- Configure your MCP client. See the extension setup guide for details.
The extension will be deprecated when Chrome provides native bridging to desktop clients.
Testing in Chrome
Google's WebMCP extension lists a page's tools and runs an agent against them from a side panel, which is handy while building tools. It only sees tools registered through Chrome's native API, so on a page running the polyfill it finds nothing. Turn on chrome://flags/#enable-webmcp-testing (the extension needs Chrome 155 or newer) and <WebMCPProvider> will use the native API instead of the polyfill.
Usage
Execution state
useMcpTool returns reactive state you can use to build UI around tool execution:
function TranslateTool() {
const { state, execute } = useMcpTool({
name: "translate",
description: "Translate text to Spanish",
input: z.object({ text: z.string() }),
handler: async ({ text }) => {
const result = await translate(text, "es");
return { content: [{ type: "text", text: result }] };
},
});
return (
<div>
<button onClick={() => execute({ text: "Hello" })} disabled={state.isExecuting}>
{state.isExecuting ? "Translating..." : "Translate"}
</button>
{state.lastResult && <p>{state.lastResult.content[0].text}</p>}
{state.error && <p className="error">{state.error.message}</p>}
</div>
);
}
Cancellation
Each execution receives its own AbortSignal. Pass it to fetch and other cancellable work. Chrome 153+ aborts the signal when the agent cancels the call. On older browsers the library substitutes a never-aborting signal, so the second argument is always safe to use:
useMcpTool({
name: "fetch_report",
description: "Fetch a report by ID",
input: z.object({ id: z.string() }),
handler: async ({ id }, { signal }) => {
const res = await fetch(`/api/reports/${id}`, { signal });
return { content: [{ type: "text", text: await res.text() }] };
},
});
Title and annotations
Give a tool a human-friendly display title, and describe its behavior to agents with annotations. The current WebMCP specification defines four annotations: readOnlyHint, untrustedContentHint, consequentialHint and debugging. Set consequentialHint on tools that do something hard to undo, like placing an order, so agents know to check with the user first.
useMcpTool({
name: "search_users",
title: "Search users",
description: "Find users by name or email",
input: z.object({ query: z.string() }),
annotations: {
readOnlyHint: true,
},
handler: async ({ query }) => { /* ... */ },
});
Dynamic tools
Tools register on mount and unregister on unmount. Render them conditionally like any React component:
function App({ user }) {
return (
<WebMCPProvider name="app" version="1.0">
<PublicTools />
{user.isAdmin && <AdminTools />}
</WebMCPProvider>
);
}
Callbacks
Run side effects on success or failure:
useMcpTool({
name: "checkout",
description: "Complete a purchase",
input: z.object({ cartId: z.string() }),
handler: async ({ cartId }) => { /* ... */ },
onSuccess: (result) => analytics.track("checkout_complete"),
onError: (error) => toast.error(error.message),
});
onError fires when the handler throws. A handler that returns { isError: true } on its own still counts as a success, so onSuccess fires for it.
JSON Schema
Pass inputSchema directly to define a tool without Zod:
useMcpTool({
name: "calculate",
description: "Basic arithmetic",
inputSchema: {
type: "object",
properties: {
a: { type: "number" },
b: { type: "number" },
op: { type: "string", enum: ["add", "subtract", "multiply", "divide"] },
},
required: ["a", "b", "op"],
},
handler: async (args) => {
const { a, b, op } = args as { a: number; b: number; op: string };
const result = { add: a + b, subtract: a - b, multiply: a * b, divide: a / b }[op];
return { content: [{ type: "text", text: String(result) }] };
},
});
TypeScript
webmcp-react already types document.modelContext, so theres no need to add Google's webmcp-types as well. The two packages declare the same global differently and clash if you install both, see TypeScript and webmcp-types for details and a workaround.
SSR
The library works with Next.js, Remix, and any server-rendering framework. The build includes a "use client" banner, so no extra configuration is needed.
Browser support
| Environment | Behavior |
|---|---|
Chrome with native document.modelContext |
The library uses the native API. The polyfill is not installed. |
| All other browsers | The library installs its polyfill, which implements the registration and consumer APIs. |
The polyfill follows native Chrome behavior. See the polyfill section of the API reference for the exact Chrome versions each behavior tracks.
Versioning and stability
webmcp-react follows Semantic Versioning. Breaking changes to the public API bump the major version. Every release is documented in the changelog, including the WebMCP specification and Chrome changes it tracks.
outputSchema and structuredContent are documented library extensions to the WebMCP specification. They are part of the public API and follow the same versioning policy.
API
See the full API reference.
Contributing
Bug reports, feature requests, and pull requests are welcome. Read the contributing guide before you open a pull request. This project follows the Contributor Covenant Code of Conduct.
License
webmcp-react MCP questions
How do I add webmcp-react MCP to Claude Code?
Run claude mcp add webmcp-react -- npx -y webmcp-react in your terminal. Add --scope user to make it available in every project.
How do I add webmcp-react MCP to Cursor?
Open ~/.cursor/mcp.json and add the server under mcpServers, using the Cursor config shown in the install section above.
What is webmcp-react used for?
It provides React hooks for registering typed tools on document.modelContext, so AI agents can call your web app's functionality.
Does webmcp-react work without native WebMCP support in the browser?
Yes. It installs a lightweight polyfill when native WebMCP is unavailable, and uses the native API when present.
Can I define tools with JSON Schema instead of Zod?
Yes, pass inputSchema directly to define a tool without Zod.
Is webmcp-react SSR-safe?
Yes, it works with Next.js, Remix, and other server-rendering frameworks, and the build includes a "use client" banner.
How do tools get unregistered?
Tools register on mount and unregister on unmount, so you can render them conditionally like any React component.