Give your agent something useful to do

Trying WebMCP on homelab.codes and henrysowell.com: useful cases for homelab tools and exploring my photography, plus what the work taught me.

OpenAI’s WebMCP contest caught my attention. I wanted to see whether it could be useful on any of my sites, so I chose homelab.codes and henrysowell.com to try it.

homelab.codes is where I share what I’m building and learning about homelabs and self-hosting, through guides, posts, and tools for other homelabbers. henrysowell.com is my personal site, bringing together my writing, projects, and photography.

I worked with a coding agent on each site to find useful ways to add WebMCP. A few were worth building: helping an agent check a Compose file or compare networks, and letting a visitor use an agent to find photographs and put together an exhibit.

What WebMCP is

WebMCP is a proposal for a small browser API. A page registers tools, each with a name, a plain-language description, a schema for its inputs, and a function that runs when the tool is called. A browser that supports it can show those tools to the visitor’s agent, and the agent can call them by name and get structured results back.

The page decides what to offer. The browser sits in the middle. The visitor’s agent asks. That is the whole shape of it.

It is early. The specification is a W3C Community Group draft. Chrome and Edge offer origin trials; ChatGPT’s desktop app supports it; Brave has experimental support. The upstream status page tracks the rest. These two sites are enrolled in Chrome’s trial, which covers Chrome 149 through 156 and ends no later than November 16, 2026. The recorded demonstrations and the live tool calls below were checked in Chrome 152 on September 6, 2026. Current draft, implementation status.

Whether or not your browser has an agent, the ordinary controls keep working.

Tools on homelab.codes

Start with Compose Doctor. Paste a Compose file and it checks for missing dependencies, port collisions, undeclared volumes, and risky host access. It lists services with mounts and the names of environment variables it saw, without their values.

With a supporting browser, an agent can hand it a configuration through the tool inspect_compose. The YAML and the findings land on the same page you would use by hand; the agent and the button run the same code. The agent gets something specific to work with, a list of findings with service names, and you get to read the same list before you act on any of it.

Here is the whole loop: inspect the sample, read the findings, revise it, and check again.

Compose inspection: findings, revision and recheck · 1:34. Recorded in Chrome 152 on September 6, 2026. The tool calls and pages are real; the diagrams are explanatory; the narration is generated from my voice clone.
Read the video transcript

Imagine asking your agent to check a Compose file before you run it. Here is what the website can give back, and how that changes the next step.

Compose Doctor exposes a named tool, inspect compose, with a required text input. The agent can discover what the tool does and the shape of the input it accepts.

The agent submits the sample YAML to that tool. The recorded browser shows the same configuration and report that a person can inspect by hand.

The response identifies two public port bindings, a missing health check, and a possible port collision. Service names and specific findings give the agent something concrete to work with.

In this demonstration, we bind the web port to loopback, remove the published database port, and add a health check. Those changes address the returned findings.

The revised file goes through the same tool, and its bounded checks return no findings. That is a recheck of this sample, not proof that a deployment is safe.

The YAML and report stay visible on the page. You can review the changes before using them. The site checks locally, but an agent provider may receive the inputs and results.

For the agent: a clear contract and structured feedback. For you: a visible result you can review. The website contributes its existing logic to the conversation. Validate the final configuration on your host.

The boundary matters. Compose Doctor does not start containers, resolve your external files, or certify anything. Zero findings means zero findings from those checks. You still need Docker’s own validation and a run on your host.

Subnet Planner works the same way. Give it two networks to compare and a parent block to divide:

{
  "networks": "192.168.10.0/24\n192.168.10.128/25",
  "parent": "10.10.0.0/22",
  "childPrefix": 24
}

The first pair overlaps. The parent block divides into four /24 networks with their host ranges, on the page and in the agent’s structured result. Nothing scans your network or reserves an address. You are planning, not changing.

Making the tools callable did not remove the need to make them good. The same work added a Storage & Restore Planner and a Certificate Inspector, replaced a lossy YAML formatter with one that keeps comments and anchors, and wrote down what each tool cannot check.

Exploring henrysowell.com

The photography collection on henrysowell.com contains 278 numbered plates, a small set from about fifty thousand frames over twenty years. The site also has an illustrated bird catalog from my inky-bird-frame project, with field marks, measurements, habitat, and sources for 168 species. Those records existed before WebMCP and give the tools something useful to work with.

The site registers nine tools, all read-only: search the photographs, fetch a plate, list and fetch birds, find notes and projects, identify a bird from a description, and build an exhibit. They read from three small data files the build writes from the same records the pages are rendered from, so the tools and the pages share one source. The tool code loads only when the browser offers an agent context; everyone else gets the same static pages as before.

Ask for photographs of fog. The search matches the text in captions, image descriptions, tags, and categories, and returns the matching plates with their metadata. In the recorded example it asks for up to five. Three of those five became an exhibit called “Fog and silence”: a tower disappearing into fog, a bare tree above a valley, and low cloud over a bay.

The agent passes the title and the plate numbers, in the order they should hang, to curate_exhibit. The tool returns a link. Opening that link is a separate step, and the page it opens shows the photographs in that order.

Photograph search and a Fog and silence exhibit · 1:43. Recorded in Chrome 152 on September 6, 2026. The tool calls and pages are real; the diagrams are explanatory; the narration is generated from my voice clone.
Read the video transcript

In this example, I’m hosting my photography on my own website. Let’s give visitors a new way to explore it. Ask an agent to find photographs of fog and build a small exhibit. My site gives it the tools. You get a link you can open.

The site exposes tools to search its photographs and curate an exhibit. Search returns plate numbers. The next tool accepts those numbers in the order you want them to hang.

The actual search asks for fog and up to five results. The search matches text in captions, image descriptions, tags and categories. It returns metadata to the agent while the collection page stays unchanged.

Three of the five returned plates show a tower, a tree above a valley, and a bay beneath low cloud. Their stable plate numbers become the input for an exhibit called Fog and silence.

The agent passes the title and ordered plate numbers to curate exhibit. The tool returns a link that encodes that selection. It does not upload photographs or write a database record.

Opening that returned link is a separate browser action. Here is the real page: Fog and silence, with the selected photographs in the requested order.

The photographs remain part of the original site, with links back to their individual pages. The title and plate selection live in the URL, so the same link can reopen the exhibit.

For the agent: composable tools with concrete outputs. For the visitor: a personal route into the collection. Web M C P lets this website participate in the task, while the photographs remain the experience.

There is no account and no upload. The tool constructs the link without creating a database record. The title and the plate numbers travel in the link itself, which is why the link works and also why it should be treated as something meant to share.

The bird tools use the same records the other way around. Give identify_bird a description in your own words, “a bright red bird with a pointed crest and a black mask and a thick orange bill,” and it ranks the catalog by how many of your words match each plate’s field marks, colors, and habitat, and hands back the candidates with the words that matched. In a live check on September 6, the first answer was the Northern Cardinal. It is a weighted text matcher, not an image model, and the score is a ranking, not a probability. Open the plate and judge it yourself. That is what the field marks are for.

What building it taught me

The useful bugs were embarrassingly specific.

The bird matcher’s first version gave the robin credit when someone wrote “bigger than a robin.” Being bigger than a robin is a qualification shared by a fairly wide selection of things. Comparison words are now set aside before scoring, so the words you spend describing another bird do not describe this one.

On homelab.codes, two tests had names that did more work than their assertions. One claimed to cover a rejected registration but only exercised a browser without WebMCP. Another claimed to check recovery after a failure but only ran a successful call. Both passed. The follow-up added the real rejection, cancellation, and recovery cases, and the production code passed them without a change, which is still a fix: the tests now support what is being claimed about the code.

A unit test also cannot speak for a hosting platform. A live test on Cloudflare Pages showed that disconnecting the client did not reliably stop a request already in flight upstream; a six-second operation ran to completion after the client left at two seconds. The URL expander’s ten-second deadline did stop a longer one. So the deadline stays, and the site does not promise an instant cancellation the platform never demonstrated.

Every one of those came from checking a claim against something real: a session in an actual browser, a deployed request, a test that finally tested what its name said.

Two agents, one mailbox

I was also testing how two models approached the implementation. I used Claude Code with Fable 5.1 for henrysowell.com, and Codex with GPT-6 Astral for homelab.codes. I wanted to see where their choices differed. Partway through, I asked them to compare notes and improve each other’s work.

The existing solutions I looked at felt like too much for that job, so I quickly built notedrop, a shared folder that works as a mailbox. One folder per job, one file per message, no server. Each agent reads its inbox, replies, and marks what it has handled.

One exchange shows what it was for. The homelab.codes agent reviewed a henrysowell.com pull request and found a cancellation listener that stayed attached after a tool call finished, along with a text limit the schema never advertised. The other agent fixed both, added tests for finished and failed calls, and sent the results back. That follow-up also changed text-length checks to count code points rather than UTF-16 units, as JSON Schema requires. Comparing the two implementations exposed the same bug on homelab.codes: its validator could reject input its own schema allowed. It became a separate pull request with ten boundary tests.

notedrop worked beautifully. The agents sent findings and replies with evidence attached: the change, the tests, and what had reached production. Each agent had a separate monitor watching its inbox; notedrop itself just carried messages. This article went through the same exchange before it came back to me.

What stays private, and what does not

homelab.codes runs these tools in your browser, so the site does not need to receive your configuration. That is a statement about my server, not about your agent. If you hand an agent your input or let it read the page, the agent’s provider may see both. The DNS, RDAP, and URL expansion tools do make network requests, with their own disclosures and limits. Password, private key, htpasswd, and WireGuard generation stay manual, which keeps them out of the callable tool set, and an agent or extension with access to the page can still read what the page displays.

On henrysowell.com, an exhibit link carries its title and plate numbers. Anyone you send it to gets them; so can your browser history and my host’s request logs. “No database” is not a privacy policy. It is a description of where the data went.

WebMCP lets a tool annotate itself as read-only, or its output as untrusted. Those are hints for the agent, not controls. henrysowell.com marks all of its tools read-only and marks the two that return your own words back, the bird matcher and the exhibit builder, as untrusted content. Neither annotation stops an agent from seeing a result. Chrome’s annotation documentation.

Try it

If you have a supporting browser and agent, give Compose Doctor a small configuration with nothing sensitive in it, compare two networks, or ask for an exhibit from my photography. Watch what the page shows next to what the agent tells you. If you do not have that support yet, the tools and the collections are there to use by hand, and they will stay that way.

There is more to do. IPv6 planning and mixed-disk storage estimates are still ahead. henrysowell.com does not yet introduce these tools to visitors. The bird matcher will not replace a field guide. And the trial token expires in November, which is the kind of date that belongs in the same sentence as the feature.

If there is a home lab chore you keep doing the hard way, tell me about it. That is where the next tool should come from.