How to Implement WebMCP in Your Web App: A Step-by-Step Guide
A step-by-step WebMCP implementation guide for web developers. Covers environment setup, feature detection, the @mcp-b/global polyfill, declarative and imperative tool registration, testing with the Inspector extension, and production deployment checklist.
How to Implement WebMCP in Your Web App: A Step-by-Step Guide
By Matheus Reis, Co-founder at Kn8 · Published April 10, 2026 · Updated April 21, 2026 · 12 min read
Tags: WebMCP · Implementation · Developer Guide · React · JavaScript
Prerequisites: Basic JavaScript knowledge. Familiarity with your frontend framework (React, Vue, or vanilla JS). An HTTPS-served web application (WebMCP requires a secure context). No backend changes required.
Step 0: Understand What You Are Setting Up
WebMCP exposes your application's capabilities to AI agents through a browser-native API — navigator.modelContext. You register named JavaScript functions (tools) with typed schemas. Agents discover these tools when they visit your page and call them with structured parameters.
This guide covers the complete implementation path:
- Set up your development environment
- Install the polyfill (required for non-Chrome browsers)
- Register your first tool using the Declarative API
- Register complex tools using the Imperative API
- Test with the Model Context Tool Inspector
- Add tools to your React or Vue components
- Deploy to production with the readiness checklist
Step 1: Set Up Your Development Environment
Option A — Chrome Early Preview (native WebMCP)
To test the native browser API without a polyfill:
- Install Chrome 146 Canary (version 146.0.7672.0 or higher)
- Navigate to
chrome://flags - Search for "WebMCP for testing" (flag name:
#enable-webmcp-testing) - Set it to Enabled
- Relaunch Chrome when prompted
Verify the flag is active by opening DevTools (F12) and running:
console.log("modelContext" in navigator); // true if flag is active
Option B — Polyfill (all browsers, recommended for production)
Install the @mcp-b/global package, which implements navigator.modelContext for all browsers:
npm install @mcp-b/global
Import it at the entry point of your application (before any tool registrations):
// main.js or index.js
import "@mcp-b/global";
The polyfill detects native API support and defers to it when available — so this pattern works on Chrome 146+ and all other browsers with a single codebase.
Step 2: Add Feature Detection
Always guard WebMCP calls with a feature check. This prevents errors on browsers where navigator.modelContext is not available — even with the polyfill, defensive checks improve clarity:
function registerWebMCPTools() {
if (!("modelContext" in navigator)) {
console.info("WebMCP not available in this environment.");
return;
}
// Register tools here
}
// Call after the page is fully initialized
document.addEventListener("DOMContentLoaded", registerWebMCPTools);
In React: call your registration function inside a useEffect with an empty dependency array so it runs once after mount.
Step 3: Register Your First Tool — The Declarative API
The Declarative API requires no JavaScript. If your application has HTML forms, you can expose them as agent-callable tools by adding two attributes.
Before (standard form):
<form id="search-form" action="/search" method="get">
<input name="query" type="text" placeholder="Search..." />
<select name="status">
<option value="active">Active</option>
<option value="archived">Archived</option>
</select>
<button type="submit">Search</button>
</form>
After (WebMCP-annotated form):
<form
id="search-form"
action="/search"
method="get"
toolname="searchCustomers"
tooldescription="Search the customer database by name or status. Returns matching customer records with account details. Leave query empty to list all customers."
>
<input name="query" type="text" placeholder="Search..." />
<select name="status">
<option value="active">Active</option>
<option value="archived">Archived</option>
</select>
<button type="submit">Search</button>
</form>
The browser reads these attributes and automatically generates a tool schema from the form's input fields. No JavaScript needed.
When to use the Declarative API:
- Simple search forms
- Filter panels
- Contact or request forms
- Any form where the existing HTML structure already communicates the tool's intent
Add toolautosubmit for read-only queries to skip the user click after the agent fills the form:
<form toolname="searchProducts" tooldescription="..." toolautosubmit>
Only use toolautosubmit on forms that do not modify state (searches, filters). For forms that submit orders, create records, or trigger actions, leave it off — the user should confirm before submission.
Step 4: Register Complex Tools — The Imperative API
The Imperative API gives you full control over tool schema, execution logic, and return values. Use it for tools that require JavaScript logic, access to application state, or multi-step operations.
Basic structure:
if ("modelContext" in navigator) {
navigator.modelContext.registerTool({
name: "createProject",
description: "Create a new project in the current workspace. Returns the project ID and URL.",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Project name. Must be unique within the workspace.",
maxLength: 80
},
template: {
type: "string",
enum: ["blank", "marketing", "engineering", "product"],
default: "blank",
description: "Starting template for the project."
}
},
required: ["name"],
additionalProperties: false
},
readOnlyHint: false, // This tool creates a record
execute: async ({ name, template = "blank" }) => {
try {
const project = await api.projects.create({ name, template });
return {
content: [{
type: "text",
text: `Project "${project.name}" created. ID: ${project.id}. Open at: ${project.url}`
}]
};
} catch (err) {
return {
content: [{
type: "text",
text: `Could not create project: ${err.message}`
}]
};
}
}
});
}
For the complete guide to designing tool names, descriptions, and schemas, see: WebMCP Tool Design Best Practices.
Step 5: Add WebMCP Tools to a React Application
In React, register tools inside a useEffect that runs after the component mounts. Unregister tools in the cleanup function if they are context-dependent (e.g., tied to a specific record that may change):
import { useEffect } from "react";
import "@mcp-b/global"; // Polyfill — import once at app root
function ProjectPage({ projectId, projectName }) {
useEffect(() => {
if (!("modelContext" in navigator)) return;
// Register tools relevant to this specific project
navigator.modelContext.registerTool({
name: "getProjectMembers",
description: `List all members of project "${projectName}" (ID: ${projectId}). ` +
"Returns name, email, role, and join date for each member.",
inputSchema: {
type: "object",
properties: {
role: {
type: "string",
enum: ["admin", "editor", "viewer", "all"],
default: "all",
description: "Filter members by role. Defaults to all roles."
}
},
additionalProperties: false
},
readOnlyHint: true,
execute: async ({ role = "all" }) => {
try {
const members = await api.projects.getMembers(projectId, { role });
const list = members.map(m =>
`${m.name} (${m.email}) — ${m.role}`
).join("\n");
return { content: [{ type: "text", text: list || "No members found." }] };
} catch (err) {
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
}
}
});
// Cleanup: unregister when component unmounts or projectId changes
return () => {
if ("modelContext" in navigator && navigator.modelContext.unregisterTool) {
navigator.modelContext.unregisterTool("getProjectMembers");
}
};
}, [projectId, projectName]);
return <div>{/* Project page content */}</div>;
}
Key React patterns:
- Import the polyfill once at your app root (
App.jsormain.js), not in individual components - Pass component props into the tool description to give agents context about the current record
- Include
projectIdin theuseEffectdependency array so tools re-register if the user navigates to a different project - Always return a cleanup function to unregister tools on unmount
Step 6: Test With the Model Context Tool Inspector
Google's official testing tool is the Model Context Tool Inspector, available as a Chrome extension. It lets you inspect registered tools, view their schemas, manually execute them, and test them against the Gemini API.
Installation:
- Open Chrome Web Store
- Search for "Model Context Tool Inspector"
- Install the extension
Using the Inspector:
- Navigate to your application in Chrome 146+ (with the WebMCP flag enabled)
- Open the Inspector panel (click the extension icon or open DevTools → Model Context Tools)
- You should see all tools registered by the current page
- Click any tool to expand its schema
- Fill in parameter values and click Execute to test the tool manually
If your tools do not appear in the Inspector:
- Confirm the WebMCP flag is enabled at
chrome://flags - Confirm
navigator.modelContextexists in console - Confirm your registration code runs after DOM ready (not before)
- Check for JavaScript errors in the console that may have interrupted registration
Step 7: Register Tools at the Right Time
Tools must be registered before an agent queries the page. The safest timing:
| Framework | When to register | |---|---| | Vanilla JS | DOMContentLoaded event | | React | useEffect(() => { ... }, []) (after mount) | | Vue | onMounted() hook | | Next.js | useEffect in page component (client-side only) | | SvelteKit | onMount() lifecycle function |
Important for Next.js / SSR frameworks: WebMCP is a browser-only API. Guard registrations with typeof window !== "undefined" checks, or use dynamic imports with { ssr: false }:
// Next.js — safe pattern
useEffect(() => {
if (typeof window === "undefined") return;
if (!("modelContext" in navigator)) return;
// Register tools
}, []);
Production Deployment Checklist
Before shipping WebMCP tools to production:
Security
- [ ] All tools with state mutation have
readOnlyHint: false(or omitted) - [ ] Irreversible operations use
requestUserInteraction()for step confirmation - [ ] All
execute()handlers are wrapped in try/catch - [ ] No sensitive data (credentials, tokens, PII) is returned in tool results
- [ ]
additionalProperties: falseis set on all input schemas
Reliability
- [ ] Feature detection guard (
"modelContext" in navigator) wraps all registrations - [ ] Tools are registered after page initialization, not before
- [ ] React/Vue components unregister tools on unmount
- [ ] Error messages are human-readable and suggest next steps
- [ ] All required parameters are explicitly listed in
required
Quality
- [ ] Every tool has a description of 2–4 sentences
- [ ] All enum values are explicitly listed
- [ ] All parameters have individual
descriptionfields - [ ] Tool names are camelCase verb + noun (no UI element names)
- [ ] Tools are page-specific, not a global catalog
Testing
- [ ] All tools visible in Model Context Tool Inspector
- [ ] All tools execute successfully with valid parameters
- [ ] All tools return readable error messages with invalid parameters
- [ ] Tools tested with the
@mcp-b/globalpolyfill on non-Chrome browser
Observability
- [ ] Server-side logging captures
agentInvokedflag fromSubmitEvent - [ ] Tool call rate, success rate, and error types are tracked
- [ ] Logs distinguish agent-driven from human-driven submissions
Frequently Asked Questions
Do I need to change my backend to support WebMCP?
No. WebMCP tools run in client-side JavaScript and call your existing frontend API clients. Your backend receives standard requests — it cannot tell the difference between a human clicking a button and an agent calling a WebMCP tool, unless you check the agentInvoked flag on SubmitEvent. No new API endpoints, no schema changes, no backend deployment.
How do I test WebMCP without Chrome Canary?
Use the @mcp-b/global polyfill, which implements navigator.modelContext for all browsers. Your tools will register and execute normally. The polyfill does not require any browser flags. You can also use the MCP-B Chrome extension for testing tool calls and responses without Chrome Canary's native implementation.
Can I use WebMCP with TypeScript?
Yes. The @mcp-b/react-webmcp package includes TypeScript type definitions. You can also import types directly from @mcp-b/global. Input schemas defined with Zod can be converted to JSON Schema format using zod-to-json-schema for type-safe tool definitions.
What happens if a user is on a browser that does not support WebMCP?
Without the polyfill, navigator.modelContext will be undefined and your feature detection guard will skip registration silently. Your application functions normally for human users. With the polyfill installed, navigator.modelContext is available in all modern browsers via the polyfill's transport layer, which communicates with agents through the MCP-B extension or other compatible clients.
How do I handle tools that depend on user authentication?
WebMCP tools execute within the user's existing authenticated browser session. Your execute handlers have access to the same cookies, session tokens, and local state that your human-facing UI uses. You do not need to handle authentication separately — the agent inherits the user's session automatically. If the user is not authenticated when the agent calls the tool, your API will return a 401 as normal, and your error handler should return a message directing the user to log in.
Key Takeaways
- Install
@mcp-b/globalfor cross-browser support; feature-detect before registering - Declarative API (HTML attributes) works for any existing form with minimal changes
- Imperative API (JavaScript) gives full control for complex, stateful operations
- In React: register in
useEffect, unregister in cleanup, re-register when context changes - Test with the Model Context Tool Inspector before deploying
- Use the production checklist to catch security and reliability issues before launch
References and Sources
- W3C Web Machine Learning Community Group. WebMCP Draft Specification. February 2026. https://webmachinelearning.github.io/webmcp/
- MCP-B. @mcp-b/global Polyfill Documentation. https://docs.mcp-b.ai/
- Google Chrome for Developers. WebMCP Early Preview Program. February 2026. https://developer.chrome.com/blog/webmcp-epp
- Datacamp. WebMCP Tutorial. March 2026. https://www.datacamp.com/tutorial/webmcp-tutorial
Further Reading
- What is WebMCP? — Kn8 Blog
- WebMCP Tool Design Best Practices — Kn8 Blog
- Kn8 Implementation Guide — Instrument your app with Kn8's SDK
- awesome-webmcp — Community SDKs, bridges, and examples
Request access to Kn8 to get WebMCP instrumented in your application with observability, permissions, and control built in.