This Page Exposes a Real WebMCP Tool

WebMCP is an emerging browser API that lets a web page register callable tools that an AI agent — Gemini in Chrome, a browser extension bridged to Claude, anything sharing the tab — can discover and invoke, the same way an MCP server exposes tools to a model. No separate server, no API keys: the tool lives in this page’s own JavaScript.

The tool below is real, not a simulation: it checks the /health endpoint of every app hosted on this lab and reports which are up. Run it yourself first, then wire up an AI agent to call it — every step is spelled out below.

1. Is It Working In Your Browser?

Registering the tool…

What can and cannot call this page’s tools in your current browser
Native document.modelContext checking…
Polyfill fallback checking…
Gemini in Chrome can call these tools checking…
Claude / other MCP client (via a bridge extension) checking…

WebMCP has two kinds of consumer. Gemini in Chrome is built into the browser and only reads the native document.modelContext — currently a Chrome 149 origin trial, so it’s off unless you turn it on (§6). A bridge extension (for Claude, Cursor, etc.) injects a script into the page and can read the vendored @mcp-b/webmcp-polyfill (pinned v5.1.0) that this page loads as a fallback. Either way, the same registerTool() call below is what runs.

2. The Code That Registers It

This is the literal call this page makes on load — nothing hidden:

document.modelContext.registerTool({
  name: 'check_lab_app_health',
  description:
    'Checks the /health endpoint of apps hosted on the Kudithipudi ' +
    'AI Lab (lab.kudithipudi.org) and reports which are up or down.',
  inputSchema: {
    type: 'object',
    properties: {
      app: {
        type: 'string',
        enum: [/* one of 24 known app slugs */],
        description: 'Check one app by its URL slug. Omit to check every app.'
      }
    }
  },
  execute: async ({ app } = {}) => checkLabAppHealth({ app })
});

3. Run It Yourself (No AI)

This button calls the exact same execute function registered above. No model is involved — it’s plain JavaScript making fetch() calls. An agent invoking check_lab_app_health gets back precisely this.

4. Bonus: The Declarative Style

WebMCP also has a second, no-JavaScript way to expose a tool: annotate a plain HTML form with toolname / tooldescription attributes. An agent can fill it in and submit it exactly like a person would. Try it — this one pings a single app by its URL slug:

<form toolname="ping_lab_app"
      tooldescription="Ping a single lab app by its URL slug and report whether it is up."
      toolautosubmit>
  <input name="app" toolparamdescription="URL slug of the app, e.g. 'goals'.">
  <button type="submit">Ping App</button>
</form>

5. Where’s the AI — and Where Isn’t It?

A common misread of WebMCP is that it puts a language model inside your page. It doesn’t. Here is exactly what is and isn’t a model:

Registering the toolPlain JavaScript. No model.
Running execute()Plain JavaScript — fetch(), returns JSON. No model. (The button in §3 did exactly this.)
Deciding to call the toolThe model. It reads the name, description & schema and picks the tool.
Filling in the argumentsThe model. It generates JSON matching inputSchema.
Explaining the resultThe model. It reads the JSON your tool returned and phrases an answer.

So WebMCP doesn’t add an LLM to your site. It gives whatever LLM is already driving the browser a clean, typed way to act — instead of guessing at screenshots and DOM nodes.

6. Call It From an AI Agent

Gemini in Chrome

Gemini reads the native API, which ships off by default. Turn it on for your own browser:

  1. Use Chrome 149 or newer (check chrome://version).
  2. Open chrome://flags/#enable-webmcp-testing, set it to Enabled, and click Relaunch. A tab refresh alone won’t apply it.
  3. Reload this page. The Native document.modelContext row in §1 should flip to a green ✓.
  4. Open the Gemini side panel and ask: “Use the check_lab_app_health tool” or “Which apps in this lab are down?”
  5. Optional: install the Model Context Tool Inspector to watch the tools register and invoke them by hand.

To make this work for every visitor with no flags, the site owner registers the origin for the WebMCP origin trial and drops the token into a <meta http-equiv="origin-trial"> tag (there’s a placeholder in this page’s <head>).

Claude, Claude Code, Cursor & other MCP clients

These can’t reach a browser tab on their own. A bridge extension reads the page’s tools (native or polyfill) and relays them over a local MCP server:

# 1. Load a WebMCP bridge extension in Chrome (unpacked):
#    github.com/WebMCP-org  ·  github.com/agentcathq/webmcp-react/releases

# 2. Register the relay with Claude Code:
claude mcp add --transport stdio webmcp-server -- npx webmcp-server

# 3. Open this page, click the extension icon, activate it for this tab.

# 4. Ask Claude:  "check the health of all the lab apps"
#    The tool shows up namespaced, e.g. tab-1:check_lab_app_health

For Claude Desktop, add the same webmcp-server command to claude_desktop_config.json under mcpServers. The plain claude.ai web UI can’t do this — it has no path to a browser tab.

7. Verify It Yourself

Net ToolsWebMCP Check card scans any URL for these same signals server-side. Scan it with the field blank and it defaults to this page — it should come back “WebMCP Signals Detected”, picking up both the imperative registerTool() call and the declarative form attributes.

Open Net Tools →