WebMCP tool registry

Install the tools a site never shipped.

Agents guess at the DOM because almost no site publishes real tools. Install a package here and the extension registers its tools on the page, so your agent calls reddit_comment instead of hunting for the reply box.

Requires Chrome 149+ with the WebMCP testing flag enabled

packages published
6
tools available
18
domains covered
6

Tools on this page

reddit.com

  • reddit_subreddit_hot

    List hot posts in a subreddit.

    read
  • reddit_search

    Search posts using the site's own GraphQL API.

    read
  • reddit_comment

    Post a comment or reply. Confirms before it writes.

    write

injected by webmcp.cafe · community package · pinned v1

01

Sites won't do this for you

WebMCP is a live W3C proposal and adoption is roughly zero. The sites you use every day won't be first. They'd never ship the tools you actually want anyway.

02

Scraping rots quietly

A selector breaks the day a class name changes and nothing tells you. A package that declares the site's own HTTP API fails loudly instead. A 4xx you can see beats a div you can't find.

03

Agents can write packages

A package is data. URL patterns, tool descriptions, and an API block declaring the site's own HTTP endpoints. Publishing is one API call. The agent that needed the tool can be the one that contributes it.

How it runs

Two ways in.

Same registry, same packages, same execution engine. The difference is where the agent sits. It can run outside the browser and talk to the registry over MCP, or run inside the page on tools the extension already injected. Step through each one.

Mode 01

From your terminal

An agent outside the browser, like Claude Code or any other MCP client, searches the registry, publishes what's missing, and pins an install. The extension delivers that exact version into the page.

Step 1 / 6

You ask for something on a site your agent can't operate

It can load the page, but it has no tools for it. Only markup to guess at, one rename away from breaking.

  1. You ask for something on a site your agent can't operate. It can load the page, but it has no tools for it. Only markup to guess at, one rename away from breaking.
  2. The agent checks the registry before improvising. @robertn702/webmcp-cafe-mcp runs over stdio beside the agent and exposes lookup_package, list_packages, publish_package and install_package.
  3. Which is a thin client over the public REST API. GET /api/packages/lookup?url=… is the same endpoint the extension calls. Writes carry an Authorization: Bearer API key you create in settings.
  4. Newest version, most specific pattern first. Postgres serves each package's latest version, ranked by URL-pattern specificity. Nothing there yet? The agent writes one and calls publish_package. It gets zod-validated and stored as version 1.
  5. Installing pins you to one exact version. install_package writes an installs row on your webmcp.cafe account and returns a handoff link. Opening that link drives the install bridge into the extension: the body is fetched, apiContentHash is re-verified, and it lands atomically in chrome.storage.local. A new upstream version never arrives on its own — moving the pin is a fresh click.
  6. And the tools appear on the page. The extension registers each pinned tool with document.modelContext.registerTool(). Your agent now calls reddit_comment instead of hunting for a textarea.

Mode 02

In the browser

No terminal, no API key. Packages you've installed live in the extension's local storage; on each page load the extension matches them against the URL and registers their tools, and the browser's own agent picks them up as if the site had shipped them.

Step 1 / 7

You open a page

At document_idle the extension's content script wakes up on whatever site you're on. You're signed in, cookies and all.

  1. You open a page. At document_idle the extension's content script wakes up on whatever site you're on. You're signed in, cookies and all.
  2. The content script hands the URL off. The background worker holds the install index and the revocation check, so browser.runtime.sendMessage passes the URL to the worker rather than each frame reading storage directly.
  3. Match against your installed packages. The worker reads the install index from local storage and matches the URL with domainLookupKeys + rankPackagesByUrl. Only packages you've explicitly installed register — nothing auto-discovers — and revoked versions are dropped at registration time.
  4. Matching tools get registered. A package whose minEngine outranks the extension is skipped whole, never half-registered. The rest go in tool by tool via registerTool(). Any name the site already claimed is left alone.
  5. You ask the browser's agent. No terminal, no API key, no MCP config. Installing the extension is the entire setup.
  6. It sees injected tools as ordinary page tools. WebMCP tools carry no provenance today, so a community package is indistinguishable from one the site shipped itself.
  7. The executor does the work. A same-origin API call riding the cookies you already have — no DOM selectors, no scraping. Anything flagged destructiveHint stops for a confirm dialog.

Trust model

Read it before you run it.

A package registers tools on pages you're signed into. So nothing here asks you to take our word for it.

The source is public

The extension, this registry, the schema and the MCP server all live in one GitHub repo. What the extension does with a package is code you can read.

Packages are data, not code

A package is a JSON document. URL patterns, tool descriptions, and an API block declaring the site's own HTTP endpoints. Nothing in it can run arbitrary code in your page.

You see every tool first

The package page lists each tool it registers and what that tool takes. Nothing shows up on a page you didn't already read.

Updates can’t ambush you

Your install is pinned to one version, and a published version is never edited. A bad update reaches you when you move the pin and not before. Rolling back means moving it back.

A call can’t leave the site

API mode is locked to the package's own origin, checked when it's published and again when it runs. Your session on one site stays there.

Nothing runs without the extension.

Install it once, add a package, and the tools are there next time you open the site.