You are in retro mode.

Agent tools · Experiment

WebMCP

The typed tools this site hands to an AI agent, what they return, and where the standard honestly stands.

WebMCP is a browser API that lets a page hand an AI agent a set of typed tools — real functions with names, inputs, and return values — instead of leaving it to guess its way through the interface. It is a W3C Community Group draft, available in Chrome behind an origin trial, and the 4 tools below are the ones this site registers.

Run any of them here. The buttons call the same handler an agent calls, in this page — not a live protocol round-trip.

Where does WebMCP actually stand today?

Spec status
A Draft Community Group Report of the W3C Web Machine Learning Community Group.
Browser support
An origin trial in Chrome, available from Chrome 149. No other engine implements it currently.
This site's token
The origin-trial token embedded in these pages expires . After that Chrome ignores it and the tools simply stop registering.
Discovery
Registration is purely the JavaScript API, so this page and /webmcp/tools.json are this site's own implementation. Discovery paths and standards are evolving.

What is WebMCP, and why would a site bother?

An agent driving an ordinary web page has to infer everything: which element is the search box, what a button does, whether a click worked. WebMCP replaces the inference with a contract. A page calls registerTool with a name, a description, and a JSON Schema for the inputs, and the agent gets a function it can call and a return value it can parse — the same shape the Model Context Protocol gives a server-side tool, but running in the page, with the page's own data and the visitor's own session.

The interesting part for a site like this one is that it costs nothing to be wrong about. Registration is feature-detected and additive: on every browser that has nomodelContext — which is currently every browser except Chrome behind a flag or the origin trial — the code returns immediately, writes no DOM, and reads no layout. Remove the tools and the site is byte-for-byte what it was.

Which tools does this site register?

4 tools: 3 that read published content, 1 that writes — and what it writes is a preference in your own browser. Definitions below are read from the live tool objects at build time, so they stay in sync with what an agent receives.

Tool 01 / 04

describe_site

read

Describe mattpyle.com: who the author is, what the site is, and which sections it has. Call this first for context about the site you're on.

Inputs

None. Takes no arguments.

Returns

An object with person, site, and sections.

Try it

No inputs — call it as-is.

Disabled — needs JavaScript.

Output · JSONUnavailable
// JavaScript is off, so nothing here can run.
// The definitions, inputs and snippets on this page
// are static text and still read fine without it.
How an agent calls it
const tool = (await document.modelContext.getTools()).find(t => t.name === 'describe_site');
await document.modelContext.executeTool(tool, '{}');

Tool 02 / 04

get_recent_writing

read

List the most recent published articles on mattpyle.com, newest first, optionally filtered to a single tag.

Inputs

NameTypeRequiredConstraints
limitintegerNo1–20, default 5
tagstringNo

Returns

An object with posts: title, url, date, tags, description.

Try it

How many articles to return (1-20).

Only return articles carrying this tag (case-insensitive).

Disabled — needs JavaScript.

Output · JSONUnavailable
// JavaScript is off, so nothing here can run.
// The definitions, inputs and snippets on this page
// are static text and still read fine without it.
How an agent calls it
const tool = (await document.modelContext.getTools()).find(t => t.name === 'get_recent_writing');
await document.modelContext.executeTool(tool, '{"limit":5}');

Tool 03 / 04

search_content

read

Search the titles, descriptions, and tags of every published article, build, and changelog entry on mattpyle.com.

Inputs

NameTypeRequiredConstraints
querystringYesmin length 1

Returns

An object with results: type, title, url, snippet.

Try it

Text to search for (case-insensitive).

Disabled — needs JavaScript.

Output · JSONUnavailable
// JavaScript is off, so nothing here can run.
// The definitions, inputs and snippets on this page
// are static text and still read fine without it.
How an agent calls it
const tool = (await document.modelContext.getTools()).find(t => t.name === 'search_content');
await document.modelContext.executeTool(tool, '{"query":"webmcp"}');

Tool 04 / 04

set_appearance

write

Switch mattpyle.com between its modern appearance and a retro, GeoCities-era skin. This changes only the calling browser's own view (stored in that browser's localStorage) — it never affects the site for other visitors. Pass mode: 'retro' or 'modern'.

Inputs

NameTypeRequiredConstraints
modestringYesmodern | retro

Returns

An object with mode and message: the mode actually applied.

Try it

Mode

The appearance to switch to: 'modern' or 'retro'.

Disabled — needs JavaScript.

Output · JSONUnavailable
// JavaScript is off, so nothing here can run.
// The definitions, inputs and snippets on this page
// are static text and still read fine without it.
How an agent calls it
const tool = (await document.modelContext.getTools()).find(t => t.name === 'set_appearance');
await document.modelContext.executeTool(tool, '{"mode":"modern"}');

How does an agent use these tools?

Every page on this site registers the tools on document.modelContext when the page loads, including after a client-side navigation. An agent running inside the browser discovers them from that object and invokes one by name. Nothing is exposed over the network, there is no endpoint to hit, and there is no authentication — the tools live entirely in the page you already have open.

Arguments go over as a JSON string, not an object — passing an object throwsFailed to parse input arguments. Results come back as a JSON string too. The snippet in each card above is the exact call.

Because Chrome does not enforce the declared inputSchema, every handler validates its own inputs — clamping limit, rejecting a blank query, falling back to modern for an unknown mode.

How can I test them myself?

The buttons on this page work everywhere, in any browser, with no setup — they call the handler directly. What they do not exercise is the protocol.

For that you need Chrome from version 149 with the WebMCP origin trial, pluschrome://flags/#enable-webmcp-testing, and something on the agent side to make the calls — the Model Context Tool Inspector extension is the straightforward option. Chrome's WebMCP documentation is the current reference for both.

Where are the machine-readable resources?

If you are reading this as text rather than executing JavaScript on the live page, you cannot call the tools — but you can read the same things they read.

  • /webmcp/tools.json — the tool manifest: names, descriptions, input schemas, and an example call for each. Generated from the real tool objects at build time.
  • /webmcp/index.json — the content index the tools themselves read: the author entity, the section map, and every published article, build, and changelog entry.
  • /llms.txt and/llms-full.txt — the site index and the full content export.
  • /agents.md — how to read and cite this site.