A React todo app that exposes the same actions to people and browser-based AI agents with WebMCP, deployed as a Cloudflare Worker.
Important
WebMCP is experimental. The Chrome testing setup below is temporary and may change as browser support evolves.
- Four imperative tools to list, rename, complete or reopen, and delete todos
- One declarative tool generated from the visible add-todo form
- Shared React actions for UI controls and agent tools
- Runtime validation and JSON Schemas generated from Zod Mini
- Lifecycle-managed tool registration with cleanup on unmount
- A useful unsupported-browser state
- Browser-local persistence with
localStorage
This differs from examples/webmcp, which bridges remote McpAgent tools into WebMCP with registerWebMcp(). This example focuses on page-local React state and the browser's imperative and declarative WebMCP APIs.
| Tool | API | Purpose |
|---|---|---|
list_todos |
Imperative | List all, active, or completed todos and IDs |
add_todo |
Declarative | Create an active todo through the HTML form |
rename_todo |
Imperative | Replace a todo's text |
set_todo_completed |
Imperative | Complete or reopen a todo |
delete_todo |
Imperative | Permanently remove a todo |
Every tool invocation updates the same state as the human-facing controls. Tool output includes todo IDs for reliable follow-up calls.
From this directory:
pnpm install
pnpm run startOpen http://localhost:5173. Other useful commands:
pnpm run test # Run the jsdom test suite
pnpm run build # Create a production build
pnpm run types # Regenerate Worker binding types
pnpm run deploy # Build and deploy to CloudflareThe directory is self-contained so create-cloudflare-cli can copy it as a standalone starter. Its package metadata and .mcp.json should remain usable outside this monorepo.
The checked-in .mcp.json configures chrome-devtools-mcp with experimental WebMCP support.
-
Open
chrome://flags/#enable-webmcp-testingin Chrome, enable WebMCP for testing, and relaunch Chrome. -
Open
chrome://inspect/#remote-debuggingand enable Allow remote debugging for this browser instance. -
Open your MCP-compatible coding agent from this directory and enable the project-level chrome-devtools server. Restart an already-running agent so it discovers
.mcp.json. -
Start the app, open http://localhost:5173 in that Chrome instance, and ask your agent:
Add a todo to buy groceries on http://localhost:5173
Chrome may ask you to approve the debugging connection, and your coding agent may separately require approval before executing a tool. The MCP configuration exposes only navigation plus WebMCP discovery and execution as direct tools.
WebMCP is governed by the tools Permissions Policy. A cross-origin iframe embedding this app must include allow="tools".
A semantic form declares the add tool:
<form
toolname="add_todo"
tooldescription="Add one active todo to the current list."
toolautosubmit=""
onSubmit={submitTodo}
>
<input
name="text"
required
maxLength={200}
toolparamdescription="The todo text, between 1 and 200 characters."
/>
<button type="submit">Add todo</button>
</form>Imperative tools register for the component lifecycle:
useEffect(() => {
const controller = new AbortController();
void document.modelContext?.registerTool(tool, {
signal: controller.signal
});
return () => controller.abort();
}, [tool]);Use declarative tools for existing semantic forms. Use imperative tools for reads, complex inputs, or actions that do not naturally map to one form submission. Keep runtime validation in either path; a browser-visible schema is not a validation boundary.
The default uses localStorage so it runs without configuration. See Persist todos with Cloudflare D1 to make todos durable across browsers and devices.
.mcp.json Coding-agent connection for WebMCP tools
docs/d1.md Optional D1 persistence guide
src/App.tsx Todo UI and declarative WebMCP form
src/schemas.ts Zod Mini contracts and generated JSON Schemas
src/useTodos.ts Shared localStorage-backed todo actions
src/useWebMCPTools.ts Imperative WebMCP definitions and registration
src/webmcp.d.ts Experimental WebMCP type additions
src/server.ts Worker fallback for unmatched asset requests