
If your product runs on Next.js or React, WebMCP fits neatly: a tool is a small function, and your API routes already do the real work. This guide shows a clean pattern. New to the topic? Start with what WebMCP is.
Register tools in a client component
document.modelContext exists only in the browser, so registration belongs in useEffect. Render nothing, and pass an AbortSignal so that tools disappear when the visitor leaves the page:
'use client';
import { useEffect } from 'react';
export default function SearchTool() {
useEffect(() => {
const mc = document.modelContext || navigator.modelContext;
if (!mc?.registerTool) return undefined; // browsers without WebMCP skip this
const controller = new AbortController();
mc.registerTool({
name: 'search_products',
description: 'Search the catalog. Returns up to 5 products with price and link.',
inputSchema: {
type: 'object',
properties: { query: { type: 'string' } },
required: ['query'],
},
annotations: { readOnlyHint: true },
execute: async ({ query }, { signal }) => {
const res = await fetch('/api/search?q=' + encodeURIComponent(query), { signal });
return JSON.stringify(await res.json());
},
}, { signal: controller.signal });
return () => controller.abort();
}, []);
return null;
}Add <SearchTool /> to the layout or page where the tool makes sense. React Strict Mode runs effects twice in development, and the clean-up above handles that.
Keep the logic in an API route
The tool is only a thin wrapper. Validation, limits and permissions belong on the server, where a visitor cannot change them:
// app/api/search/route.js
import { NextResponse } from 'next/server';
export async function GET(request) {
const q = (request.nextUrl.searchParams.get('q') || '').slice(0, 80);
if (!q) return NextResponse.json({ error: 'missing_query' }, { status: 400 });
const items = await searchCatalog(q, { limit: 5 }); // your own function
return NextResponse.json(items.map(({ name, price, url }) => ({ name, price, url })));
}Forms as tools
For a simple form, add toolname and tooldescription to the <form> element. React passes these unknown lowercase attributes through to the page. The browser fills in the form and, by default, the visitor still presses the button.
Safety rules
- Start read-only. Search and details first; mark them with
readOnlyHint. - Ask before acting. Mark cart, booking and form actions with
consequentialHint, so the visitor confirms. - Check on the server. The browser is not a security boundary, so validate every input and permission in your backend.
- Return little. Send only what a customer may see, never admin data or other customers’ records.
Test it
- Use a recent Chrome with WebMCP turned on, through the origin trial or the testing flag.
- Call each tool with good and bad inputs.
- Check that normal visitors see no change.
- Run the free WebMCP checker on the exact page where your tools live.
Want it done for you?
We add WebMCP to Next.js and React products, from a free readiness audit to tested tools. See our WebMCP integration services and Next.js development.
Frequently asked questions
Can I register WebMCP tools in a React Server Component?
No. WebMCP runs in the browser, so tools must be registered in a client component. A server component can pass data to that client component as props.
Do WebMCP tools work with server-side rendering?
Yes. The page renders on the server as usual, and tools are registered after hydration. Check that document.modelContext exists before using it.
Why do my tools register twice in development?
React Strict Mode runs effects twice in development. Passing an AbortSignal and aborting it in the effect’s clean-up removes the first registration.
Is there a TypeScript type for WebMCP?
Yes. Chrome’s documentation points to the webmcp-types npm package for typings of the imperative API.
How we can help
- WebMCP Integration ServicesWebMCP development for any stack, from WordPress and Shopify to Next.js, Laravel and Django: search, FAQs and forms offered as secure tools for AI browser agents, with a free audit.
- Next.js DevelopmentProduction Next.js 14 / 15 applications with App Router, Server Components, edge deployment, and TypeScript-first delivery on Vercel or AWS.
- Custom Web Application DevelopmentFull-stack custom web application development for SaaS, internal tools, dashboards, and enterprise portals across React, Next.js, Node, Laravel, and Django.
Talk to an engineer about your project
Tell us what you are building. We reply within one business day with a candid view on scope, approach and effort.
Book a free strategy callWritten by the UnlockLive IT engineering team. UnlockLive IT Limited works with clients through its Los Angeles headquarters and Toronto office and delivers engineering from its Dhaka delivery centre. About us