About the project
Why WebMCP fits this use case
Incident response is a loop of health, logs, metrics, and deploys, plus a write when you know the cause. Those functions already live in the page. WebMCP exposes them as tools so an agent in the tab can call them instead of clicking the same six filters.
The reason it has to be WebMCP, not a server MCP: three checks only exist in the tab. The page diffs its own store before and after every execute. Every registered tool has a DOM control the test can querySelector. Undo and ask_operator wait on the person looking at the same incident. A remote server has no Zustand snapshot, no human control, and no operator in the chair.
WebKit opposed WebMCP because declared intent is unverifiable, because nothing keeps agent and human surfaces in parity, and because readOnlyHint is advisory. Ackboard treats those three sentences as tests.
How it creates a better experience
The agent does not scrape the DOM. It gets compact JSON, schemas, enums, structuredContent, and error objects. The UI still updates. Panels pulse. The header shows Ackboard's registered count next to the browser's own getTools() count. The Parity panel lists each tool beside the button a keyboard user would press.
Reads that used to dump pretty-printed log lines now return 5 slim rows inside Chrome's 1500-character budget. Over-budget payloads truncate with a pointer to analyze_error_patterns. Log tools set untrustedContentHint.
When the data cannot settle a question, ask_operator holds execute open until the person on the page replies. Create and update apply immediately and reverse from Undo last agent action. Only a runbook step still waits on Approve.
What people and agents can do together that was hard before
In one turn: "Why is payment-gateway red?" becomes health, signature-failure logs, the v1.8.3 chrony deploy, then a drafted incident. The operator can undo that ticket without asking the agent to delete it.
The part other incident consoles skip: the page itself catches a lying tool. Call contract_probe. It claims read-only and mutates a probe counter. The audit row goes red. No human had to click Deny first.
Remediation tools mount only while a P1 or P2 incident is open, then unmount. The count in the header changes. That is a shared live object, not a chat box next to a dashboard.
How WebMCP was implemented
Imperative document.modelContext.registerTool in src/webmcp/register-tools.ts. Nested annotations. execute(input, { signal }). Per-tier AbortControllers: core tools for the session, active-incident tools, remediation tools. Types from @mcp-b/webmcp-types. Reads return MCP structuredContent. The auditor is src/webmcp/contract-auditor.ts. Human selectors stay in a parallel map so Chrome does not see unknown fields. Undo is a page-owned journal, not a tool. HITL for runbook steps and operator questions use in-page dialogs; requestUserInteraction is still open (issue #165). See docs/adr/0002-human-in-the-loop.md, docs/adr/0004-contract-auditor.md, and docs/adr/0005-webkit-invariants.md.
Live URL
No login. Simulated fleet. Header badge says so. Seeded long-fuse incident is INC-001 on payment-gateway (NTP/chrony, Cloudflare 1.1.1.1 pattern).
Public repo
https://github.com/GunaPalanivel/ackboard
MIT license, visible in the About sidebar.
Which agent or client did you test with?
Chrome with the WebMCP flag, against https://ackboard.vercel.app. Wording must match .idea/AGENT-VERIFICATION.md after the next npm run verify pass. ChatGPT desktop in-app browser was not run. Do not claim Atlas or ChatGPT desktop.
What did you learn?
The shipping Chrome surface is smaller than blog posts about elicitation. execute's second argument today is { signal }, not requestUserInteraction. Tool count is a weak signal next to Duckboard's two tools. Nested annotations and structuredContent are a ten-second tell for a Chrome engineer. A tool's declared readOnlyHint is advisory until the page checks it. Human/agent parity is a selector, not a slogan. Vercel SSO on *.vercel.app will silently fail a judge who is not on your team. Atlas as a standalone browser was retired; the judge client is ChatGPT's in-app browser, which we did not run from this machine.
Built With
- react
- tailwind-css
- typescript
- vite
- webmcp
- zustand
Log in or sign up for Devpost to join the conversation.