Why this use case is a strong fit for WebMCP

jsonloupe is local-first: the entire lossless JSON engine — worker-parsed, int64-exact, comfortable with five-million-element arrays — already runs inside the page. WebMCP tools execute in page context, so the bridge hands agents the real engine, not a proxy to a backend that doesn't exist. There is no server anywhere: the tools, the data, and the human's view live in the same tab.

The tool vocabulary was already proven — jsonloupe ships a stdio MCP server with the same bounded verbs (schema → query → refine, capped responses, the document itself never leaves). WebMCP is the transport that puts those verbs where the human is actually looking, and it enables three tools no headless server could ever offer: pushing a document into the human's open viewer, scrolling their tree to a row and flashing it, and filtering their view through the toolbar's own state.

How it creates a better user experience

It kills the loop every AI-and-JSON workflow lives in: agent produces JSON → human downloads it → opens a separate viewer → finds the problem → pastes back → repeat. With WebMCP, agent output lands directly in the viewer the human already has open (load_doc), questions are answered against the on-screen document with exact int64/decimal arithmetic (run_query, profile, sample, get_schema), and instead of describing where something is, the agent points — reveal_path scrolls the tree and flashes the row; highlight_matches filters the view to the evidence.

The agent's answers stay small and bounded (counts, groups, capped previews), so conversations stay fast and cheap — the document never round-trips through the model. And the human keeps authority over their own view: highlights use the toolbar's real filter state with the count visible in the chip, reversible by the human's own button at any moment.

What people and agents can do together that was difficult or impossible before

Look at the same document at the same time. Before, "human + agent + JSON" meant two disconnected copies — one in the chat context, one in a viewer — synced by hand. Now the agent's load_doc, reveal_path, and highlight_matches operate on the very pixels the human is watching: the agent investigates and points, the human sees and steers, and every agent action is visible, bounded, and reversible in the human's own UI. It turns "the agent said the problem is in tasks[1847]" into the row flashing on screen.

It also makes the collaboration safe to trust: every tool that returns document content is annotated untrustedContentHint, so the calling agent is told — at the protocol level — that a value like "IGNORE ALL PREVIOUS INSTRUCTIONS" inside the data is data. This carries forward jsonloupe's existing prompt-injection hardening work into the WebMCP era.

How WebMCP was implemented

A feature-detected, lazily-imported bridge (src/webmcp/, ~790 lines + 950 test lines) registers eight tools on document.modelContext: run_query, get_schema, profile, sample, load_doc, reveal_path, highlight_matches, clear_highlights. Tools dispatch over the same UI↔worker message protocol the human's own clicks use, so agent and human literally share one engine and one document. Responses are capped, staleness-checked against a document token (a doc swapped mid-tool aborts cleanly), and annotated with readOnlyHint/untrustedContentHint. Query errors return a caret under the fault plus the grammar, so agents self-correct.

Where the API is absent the bridge chunk is never fetched and the app is byte-for-byte unchanged (asserted by e2e). Verified by 70 unit tests plus a Playwright end-to-end suite that drives a real WebMCP-enabled Chromium through every tool, and live on jsonloupe.dev under the Chrome origin trial.

Prior work vs. new work

The viewer, engine, and stdio MCP server predate the submission window. Everything WebMCP — src/webmcp/, its tests, the wiring, the e2e suite — is new work within the window; see WEBMCP.md and the timestamped commit history (PRs #50, #51).

Built With

Share this project:

Updates

Submission history