Inspiration
If you want to track a competitor today, you don't search for an app; you ask your AI agent to do that. That works OK at the beginning, but then it misses important things after a few weeks. We built an app that tracks competitors better, and it's AI agent-friendly. But agents couldn't sign up and set up everything for you without your action. Until we added WebMCP :)
What it does
Every page of competitortracker.io now registers 11 WebMCP tools - in production, in four languages, for any agent riding along in the visitor's browser. Three groups:
- Q&A over the site's own words.
search_site,get_page,get_pricing,compare_with_rival,about_competitor_tracker. An agent can answer any question about the product from what the pages actually say — the agent and the human are never told different things. - Public competitor data.
search_companies,get_company,list_industries,get_industry,get_recent_changesover our open CC BY 4.0 data: 300+ tracked companies, 50 industries, and the dated, classified change feed. This is the product doing its actual job in the agent's hands, not a description of it. - Agent signup.
start_tracking_competitors: the agent names the companies you care about, we create an unclaimed organization (no email, nothing charged, self-deletes in four days), and hand back a claim link plus a short-lived read token. The tool then tells the agent the follow-up move: wait ~15 seconds, callGET /v1/changeswith the token, and lead with what changed at your competitors — then hand over the claim link so the human takes ownership.
So the full arc works with zero forms: ask a question, see real competitor changes, get tracking set up, claim it - all before you have an account.
How we built it
The site is Hugo on Cloudflare Workers, and most of the machinery already existed for AI crawlers: every page has a markdown twin, llms.txt is a curated per-page index, and our competitor data ships as an open JSON tree. So the WebMCP layer needed no search backend and no new data - the tools are framework-free ES modules that read what the site already publishes, plus one POST to our live agent-signup API.
Details we care about:
- A 411-byte loader rides every page; the ~13 KB tool bundle is injected only when a
modelContextruntime actually exists. Ordinary visitors pay nothing. - The two required headers (
Permissions-Policy: tools=(self),Origin-Agent-Cluster: ?1) ship from our edge worker, the single chokepoint for all responses. - Every
execute()is wrapped so no failure ever throws - a browser agent runtime has no defined behavior for an uncaught rejection, so every path returns a result the agent can read. - Telemetry counts calls, never contents: tool name, page, language, outcome.
- The module is open source (MIT) - the loader, registration helper and validation utils are generic enough to point at your own tools.
Challenges we ran into
- The spec moved under us. The getter lives on
document.modelContextbut half the browsers on the origin trial still carrynavigator.modelContext; we probe both. AndunregisterTool()/provideContext()are gone from the spec - teardown is aborting the signal you registered with. Generated code confidently suggests the removed API. - Testing without a runtime. No browser in our CI has WebMCP, so we built a Node harness that runs the real tool modules with stubbed browser globals against the live site and API — every tool, every error path.
- Honest copy is a design constraint here. A
503from the signup API must never be spoken as "we don't track that company," and the 15-second wait is a write-settle margin, not "we're fetching your data now" - the change history is already published. Agents repeat what tools tell them, so the tool result text is a product surface. - How do I test this? It took some time to figure out how to test WebMCP in Chrome.
Accomplishments that we're proud of
- It's live on our real production site, not a hackathon sandbox - every page, every language, behind a one-line kill switch.
- The signup flow keeps the human in charge without a single confirmation dialog: the org holds no money, sends no email, expires unclaimed, and the claim page is the confirmation step.
- The whole thing reuses surfaces we'd already built for fetching agents (markdown twins,
llms.txt, open data) - the pre-account story just needed the last mile into the tab. - Fifteen seconds after asking, an agent shows you what your competitors changed. That's the demo, and it's real.
What we learned
- A tool declaration is a hint to a cooperative agent, never a security boundary — validation lives server-side, and the published-catalog-only rule (the tool never fetches a URL you supply) is the guarantee the whole feature stands on.
- The right scope for in-page tools isn't feature parity with our MCP server (50 tools behind OAuth). The web page is the before-the-account surface; the MCP server is after. Drawing that line made every other decision easy.
- Sites that already publish machine-readable views get WebMCP almost for free. The work we'd done for crawlers became the engine for in-tab agents.
- WebMCP is fun!
What's next for Competitor Tracker & Co. WebMCP
- Teach people how to use this.
- Join the WebMCP origin trial (Chrome 149+) so the tools work for real visitors without flags.
- Declarative form annotations for the few forms the site has, and page-scoped context - a company page pre-scoping its own tools.
- Localized tool descriptions for our FR/DE/JA pages.
- Watching our telemetry to learn which tools agents actually call, and feeding that back into both the WebMCP surface and the full MCP server.
Log in or sign up for Devpost to join the conversation.