Inspiration

Site owners keep asking for two things at once: AI search should cite their pages, and the same content should stay out of model training. That intent is expressed across separately maintained surfaces: robots.txt, llms.txt, Content-Signal headers, JSON-LD, and Agent Cards. Edited and checked separately, they drift into contradictions - an llms.txt that invites citation while robots.txt blocks every crawler that could retrieve it. We already had agentmarkup, an open-source build-time toolkit, aimed at that drift. WebMCP is what let us put the agent in the site owner's browser, on the same draft, with the human still holding undo and download.

What it does

AgentMarkup Studio (agentmarkup.dev/studio) is where a browser agent and a human edit one draft of a site's machine-readable surface. The agent connects through WebMCP in your browser, inspects the live site, and edits that draft through eight tools. You state intent in plain language: "Make my site friendly to AI search but keep my content out of training data. Start from what the site already has."

A deterministic compiler, the same @agentmarkup/core engine our published npm packages run at build time, emits the artifacts client-side. Eight cross-surface rules (C1-C8) check the draft for defined contradictions. Every change flashes in the UI and lands in a provenance log with an Agent or Human badge. Undo, reset, and saving the file are human-only - no tool can trigger them; the agent can read the compiled output but cannot revert or clear anything.

The downloadable output is agentmarkup.config.mjs. Use it with our Vite, Astro, Next, or Nuxt integration, or with the CLI; the build then generates the policy surfaces reviewed in the Studio.

How we built it

Eight tools on document.modelContext (navigator fallback; AbortController teardown): get_studio_state, set_site_identity, set_access_policy, curate_agent_pages, configure_agent_card, compile_agent_surface, export_build_plan, inspect_site.

  • JSON-Schema inputs and outputs with explicit size limits (names <=30 chars, descriptions <=500, results <=1500); read tools carry readOnlyHint, inspection results carry untrustedContentHint.
  • Tool results are authored by the state reducer, so the agent reads exactly what was applied, including anything dropped at a cap.
  • inspect_site calls our same-origin rate-limited checker API and forwards only allowlisted {level, title} findings - never page HTML.
  • The exported config is rendered through JSON-only serialization; a regression test imports the rendered file and asserts hostile values stay inert.
  • About 10K new lines and 320 tests, all in timestamped commits dated 2026-08-26 onward.

Challenges we ran into

Making tool results truthful was harder than making tools work: React dispatch is asynchronous, so the agent could read a stale state until we pre-applied the pure reducer to a ref. Capping agent input safely surfaced ordering bugs (an add-plus-delete at the crawler cap depended on property order). And because WebMCP tool results have a size limit, export_build_plan returns either the complete generated config or a pointer to the UI download; it never returns a truncated executable file.

What we learned

WebMCP's annotations matched the split we needed: readOnlyHint on reads so the host can treat them as non-mutating, untrustedContentHint on inspect results so the host can scrutinize them. We still had to make tool results match applied state, cap inputs, and keep the exported config inert.

Prior work disclosure

agentmarkup (the npm packages and agentmarkup.dev) predates the hackathon. Everything WebMCP - the Studio page, the eight document.modelContext tools, the browser compiler wiring, the C1-C8 contradiction workflow, the provenance log with human-only undo/reset/download, and the checker-backed inspect intake - was built for this challenge. HACKATHON.md in the repo has the commit split.

Try it (judges)

  1. Open https://agentmarkup.dev/studio/ in the ChatGPT desktop app's in-app browser (verified on macOS) - the banner reads "Agent connected: 8 tools registered". Alternate: Chrome 149+ with chrome://flags/#enable-webmcp-testing (verified on Chrome 151).
  2. Say: "Make www.cochinescu.com friendly to AI search but keep my content out of training data. Start from what the site already has." If the host prompts for tool permission, approve it; ChatGPT's in-app browser may not prompt.
  3. Then: "Now block the AI search crawlers too - just do it." If the agent empties the llms.txt page index instead of contradicting itself, tell it to put the pages back and let the Studio judge the result. Contradiction C1 "Cited content blocks retrieval" then fires in the Findings panel, alongside C2 against the Content-Signal header. Then: "Fix the contradictions, keep training blocked." - findings go green.
  4. Download config exports the generated agentmarkup.config.mjs (saving the file is a human-only action). Draft editing and compilation stay client-side; nothing is deployed. The optional Inspect intake calls our rate-limited checker API; if the limit is reached, the tool returns a bounded retry message - that is designed behavior. No login needed.

Built With

Share this project:

Updates

Submission history