Skip to main content

Command Palette

Search for a command to run...

Getting Started with WebMCP: Exposing Structured Web Tools to AI Agents

Published
9 min read
Getting Started with WebMCP: Exposing Structured Web Tools to AI Agents

WebMCP (Web Model Context Protocol) is a new browser feature (currently in Chrome 146+ Canary/Beta) that lets websites publish structured “tools” (functions) directly to in-browser AI agents. Instead of an agent taking screenshots or scraping the DOM, your page can explicitly tell the agent what actions are possible and how to use them. In Chrome’s words, WebMCP “exposes structured tools, ensuring AI agents can perform actions on your site with increased speed, reliability, and precision”. In practice, a WebMCP tool has a name, description, JSON schema for inputs, and an async execute function that returns structured output. For example, an e-commerce site might register a searchProducts tool (with parameters like query and filters) so an AI can call it directly, instead of clicking through filters manually.

WebMCP defines two complementary APIs on top of your web page: a declarative API using HTML attributes, and an imperative API using JavaScript. With the declarative API, you simply annotate an existing HTML <form> with attributes like toolname="myTool" and tooldescription="..." (plus optional parameters). The browser then treats submitting that form as invoking a structured tool. With the imperative API, you use JavaScript to call navigator.modelContext.registerTool({...}) (after loading the WebMCP library). This lets you register custom functions as tools on the fly. Both approaches end up registering tools that AI agents (and tools like the Model Context Inspector) can discover and call. Once registered, agents see a “tool contract” (name, schema, description), so they can call something like await myWebMCPClient.callTool("add_to_cart", { productId, quantity }) with confidence.

How WebMCP Works

WebMCP runs entirely in the browser (no special server needed). Internally, Chrome 146+ exposes a new object navigator.modelContext once you load a helper library (or use the declarative form flags). Through this, your page provides context to the browsing AI agent. For example, using the imperative API you might write:

import '@mcp-b/global';  // WebMCP helper to create navigator.modelContext

useEffect(() => {
  navigator.modelContext.registerTool({
    name: "set_counter",
    description: "Set the page counter to the given number",
    inputSchema: {
      type: "object",
      properties: {
        newCount: { type: "number", description: "The number to set" }
      },
      required: ["newCount"]
    },
    async execute({ newCount }) {
      setCount(newCount);  // update React state or DOM
      return { content: [{ type: "text", text: `Counter set to ${newCount}` }] };
    }
  });
  navigator.modelContext.registerTool({
    name: "get_counter",
    description: "Get the current counter value",
    inputSchema: { type: "object", properties: {} },
    async execute() {
      return { content: [{ type: "text", text: `Counter is ${count}` }] };
    }
  });
}, [count]);

In this React example (adapted from WebMCP docs), we register two tools on page load: set_counter and get_counter. Each tool has a name, a natural-language description, and a JSON Schema for its inputs. When an agent invokes one of these tools, the execute function runs on the client. In our case, set_counter updates a state variable (setCount) and returns a text message, while get_counter returns the current count. The WebMCP library (@mcp-b/global) makes navigator.modelContext available and handles communicating with any AI agent. (This pattern follows the official WebMCP example of registerTool usage.)

Unlike screenshots or raw DOM, this approach is type-safe and fast. The AI sees exactly what tools exist and what parameters they accept. According to VentureBeat, a single structured tool call “can replace what might have been dozens of browser interactions,” greatly reducing cost and errors. The standard also ensures human-in-the-loop safety – the agent uses the browser context of a real user, not a headless bot. As one developer wrote, WebMCP is like “MCP (Anthropic’s Model Context Protocol) but built into the browser tab”, giving agents a clear “handshake” with the site.

Getting Started: Setup & Downloads

To try WebMCP today, you need a compatible browser and some tools:

  • Chrome 146+ Canary/Dev (or equivalent flag support). As of early 2026, WebMCP is only in Chrome behind the experimental flag “WebMCP for testing” (go to chrome://flags and enable it). After enabling, relaunch Chrome.

  • Model Context Tool Inspector extension. This Chrome extension (from Google) lets you browse and invoke WebMCP tools on any page. It shows the tools and schemas your site exposes, and can test them manually or via an AI model (Gemini or Claude) integration.

  • Gemini/Claude API key (optional). The Inspector can use a chatbot model (like Google Gemini) to test natural-language calls to your tools. You can get a free Gemini API key from AI Studio to try this feature. (However, a key isn’t needed just to see the tools or test manually.)

  • Node.js and NPM/Yarn. To build and run our example app. We’ll install the official WebMCP helper library @mcp-b/global from NPM, which auto-initializes navigator.modelContext for us.

  • Code editor of your choice (e.g. VSCode).

With the flag on and the Inspector installed, you can open any WebMCP-enabled page and see its tools. For example, the WebMCP travel demo site (linked in the docs) publishes a searchFlights tool. You can manually invoke it in the Inspector or have an agent invoke it via Chat.

Example: Imperative WebMCP in React (Counter App)

Below is a simple React example showing how to use WebMCP tools. It’s a local app (no server needed) that displays a counter. We register two tools so an AI agent (or the Inspector) can get or set the counter.

  1. Create a React project (using Vite or Create React App). For example, using Vite:

    npm create vite@latest webmcp-demo -- --template react
    cd webmcp-demo
    npm install # install dependencies
    npm install @mcp-b/global
    
  2. Enable WebMCP flag in Chrome (as above), then npm run dev and open the app in Chrome.

  3. Code (App.jsx): Import @mcp-b/global at the top. Use useEffect to register tools when the component mounts. Here’s sample code:

    import React, { useEffect, useState } from 'react';
    import '@mcp-b/global';  // Initialize WebMCP (navigator.modelContext)
    
    function App() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        // Register a tool to set the counter
        const reg1 = navigator.modelContext.registerTool({
          name: "set_counter",
          description: "Set the counter to a specific value",
          inputSchema: {
            type: "object",
            properties: {
              newCount: { type: "number", description: "New count value" }
            },
            required: ["newCount"]
          },
          async execute({ newCount }) {
            setCount(newCount);
            return { content: [{ type: "text", text: `Counter set to ${newCount}` }] };
          }
        });
    
        // Register a tool to get the current counter
        const reg2 = navigator.modelContext.registerTool({
          name: "get_counter",
          description: "Get the current counter value",
          inputSchema: { type: "object", properties: {} },
          async execute() {
            return { content: [{ type: "text", text: `Counter is ${count}` }] };
          }
        });
    
        // Cleanup if component unmounts
        return () => {
          reg1.unregister();
          reg2.unregister();
        };
      }, [count]);
    
      return (
        <div style={{ padding: "2rem", fontFamily: "sans-serif" }}>
          <h1>WebMCP Counter Demo</h1>
          <p>Current count: <b>{count}</b></p>
          <button onClick={() => setCount(count+1)}>Increment</button>
          <p>Open the WebMCP inspector (🔧) to invoke <code>get_counter</code> or <code>set_counter</code>.</p>
        </div>
      );
    }
    
    export default App;
    

    This app registers two WebMCP tools on startup. The Inspector extension (or any MCP-compatible agent) will list get_counter and set_counter with their schemas. For example, get_counter has no inputs (an empty object schema) and returns text, while set_counter requires a numeric newCount and updates the state. The execute functions return a result using the { content: [{type: "text", text: "..."}]} format to send a response back to the agent. This follows the pattern shown in official WebMCP docs.

  4. Run and Test: With the app running in Chrome (flag enabled), open the Model Context Tool Inspector. You should see the two tools listed. You can click one to invoke it. For get_counter, it will immediately respond with the current count. For set_counter, you can enter a number (e.g. 42) and the page’s state will update. Alternatively, you can test via the built-in AI assistant: ask it “list WebMCP tools” and “set counter to 7” and see it call your tools automatically (as shown in demos). Because these tools run on the client, no special backend or hosting is needed – everything happens in the browser window.

Declarative WebMCP Example (HTML Form)

In addition to imperative tools, WebMCP lets you convert HTML forms into tools with minimal changes. For instance, suppose you have a simple form for user login. You can annotate it like this:

<form toolname="login" tooldescription="Log in with email and password" toolautosubmit="true">
  <label>Email: <input name="email" type="email" required toolparamtitle="email" toolparamdescription="User email"></label><br>
  <label>Password: <input name="password" type="password" required toolparamtitle="password" toolparamdescription="User password"></label><br>
  <button type="submit">Log In</button>
</form>
<script>
  // Traditional form handling (for human users)
  document.querySelector('form').addEventListener('submit', async (e) => {
    e.preventDefault();
    // Perform login...
    alert("Logged in!");
  });
</script>

By adding the toolname, tooldescription, and toolparam* attributes, the browser automatically exposes this form as a tool called "login", with parameters email and password defined by the form fields. An agent can call it like a function. If toolautosubmit is true, the form submits automatically when invoked by the agent. (WebMCP also fires an agentInvoked flag and lets you return a response via event.respondWith() for AI use – see details if needed.) The point is: no extra JavaScript needed for basic forms – just annotate your HTML. The Codely blog confirms that adding those attributes is “all you need”.

What’s Next and Further Reading

WebMCP is still experimental but evolving quickly. Chrome’s official announcement and docs encourage developers to “make your site agent-ready” by defining tools. The specification is being refined under W3C’s Web Machine Learning community, and more browsers will likely add support in future.

For more examples and details, check out:

  • Google’s WebMCP blog post, which explains the vision of structured tools and the two APIs.

  • The WebMCP GitHub quickstart (with code examples).

  • The MCP-B documentation (webmachinelearning docs) shows API usage and React examples.

By following these guides and running the sample code above, you can begin experimenting with WebMCP today. The core idea is: give AI agents a clear contract for what your site can do, and they’ll interact much more reliably than by “guessing buttons”. As Google puts it, this is a foundational step toward an agentic web where the site actively helps the AI help the user.