Repo of the Day
agentcathq/webmcp-react: React hooks for exposing your app's functionality as WebMCP tools - transport-agnostic, SSR-safe, Strict Mode safe, W3C spec-aligned
Published: Oct 6, 2026
Open repository ↗React hooks for exposing your app's functionality as WebMCP tools - transport-agnostic, SSR-safe, Strict Mode safe, W3C spec-aligned - agentcathq/webmcp-react
Summary
webmcp-react is a TypeScript library that exposes typed tools on document.modelContext, the API proposed by the W3C Web Machine Learning Community Group's WebMCP specification. It provides React hooks so an app's functionality can be discovered and called by AI agents such as Codex, Claude Code, or Cursor. The library is transport-agnostic, SSR-safe, and ships a polyfill for browsers that do not yet implement the native API.
What it is useful for
The library fits when you want agents to invoke real app functions rather than scrape the DOM. Typical use cases include exposing catalog search, report fetching, checkout flows, or game actions to an agent. Tools live alongside the React components that implement them, so a tool for an admin-only feature can be conditionally rendered with the rest of your UI, and it registers on mount and unregisters on unmount.
Inputs are defined with Zod for full type inference, and a JSON Schema option is available when you do not want Zod as a dependency. Handlers can be annotated with readOnlyHint or untrustedContentHint to describe their behavior to the calling agent. The package targets React 18 or later and is published under the MIT license. The README notes that the polyfill mirrors native Chrome behavior release by release, so behavior should be consistent across supported environments.
How engineers can use it
Install the package and Zod as a peer dependency:
npm install webmcp-react zod
Wrap your tree in WebMCPProvider and register a tool from any component 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 hook returns reactive state including isExecuting, lastResult, state.error, and an execute function. Handlers receive an AbortSignal so work can be cancelled; the README documents that Chrome 153+ aborts the signal on agent cancellation, while older browsers substitute a never-aborting signal. Side effects can be wired up with onSuccess and onError callbacks.
Limitations worth noting: the WebMCP Bridge Chrome extension is required for clients like Claude Code and Cursor until Chrome ships native bridging, and the README states the extension will be deprecated at that point. Full API and polyfill behavior are documented in the project's docs/ directory, which is the right place to look for details not covered here.