# 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:

```typescript
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:
    
    ```shell
    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:
    
    ```typescript
    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:

```html
<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.
