Guided electronics diagnosis where an AI agent and a person split the work: the agent decides which test is worth running and interprets the result, the person holds the meter and does the repair.
Live: https://jackson-kuja.github.io/ProbeLoop/
The demo case is a small Bluetooth speaker that died after its USB-C cable got yanked. Five things could be wrong. The page exposes nine WebMCP tools so an agent in your browser can read the case, rank the remaining tests by expected information gain, highlight probe points on the board, record the reading you report back, and propose a repair once the evidence is strong enough. Approving that repair and confirming you actually did it are not tools. Those two steps only exist as buttons on the page.
Open the live URL in ChatGPT's in-app browser, or in Chrome 149+ with chrome://flags/#enable-webmcp-testing turned on. The status button in the header should read 9 tools registered. Then ask something like:
Diagnose this speaker. Pick the safest, most informative test, show me where to probe, and record only what I report back. Propose a repair when the evidence supports it, but leave approval to me.
When the agent asks for the reading, tell it you measured open / OL across F1 with USB unplugged. The open-fuse hypothesis jumps from 36% to about 90%, the agent proposes a like-for-like fuse swap, and then it has to stop and wait for you. Approve, tick the two confirmation boxes, tell the agent the device boots and charges, and the case closes at v7.
If your browser doesn't have WebMCP, the Console button calls the same handlers by hand.
| Tool | What it does |
|---|---|
get_case_state |
Current version, phase, ranked hypotheses, selected test, measurements, proposed repair |
list_safe_tests |
Remaining tests ranked by expected information gain |
recommend_next_test |
The single best next test and why |
focus_component |
Highlight a component on the board |
select_test |
Set up a test: shows probe points and the meter instruction |
record_measurement |
Save a reading the person reported; requires observed_by: "human" and power_disconnected: true |
stage_repair_plan |
Propose a predefined repair once its confidence threshold is met |
record_post_repair_check |
Save the startup/charging result the person observed after the repair |
get_case_report |
Short report with the evidence chain and who did what |
Every tool that changes state takes expected_version; a stale version fails with the current one so the agent can refresh and retry. Free-text fields are length-capped and flagged with untrustedContentHint. Read tools carry readOnlyHint. Registration happens on the top-level page through document.modelContext.registerTool, each with its own AbortSignal.
Plain ES modules, no build step, no dependencies, nothing leaves the browser.
src/data.js– the device, components, hypotheses with priors, tests with likelihood tables, and the one repair.src/domain.js– entropy and expected-information-gain ranking, Bayesian updates, the versioned state machine, and the report.src/tools.js– tool definitions (closed JSON Schemas) and handlers.src/webmcp.js– registration and cleanup.src/app.js– the page.
The page and the tools call the same domain functions, so whatever an agent does shows up immediately, and whatever you click is visible to the agent on its next read. Case state persists in localStorage; the reset button or ?reset=1 clears it.
More on the state machine and trust boundaries in docs/ARCHITECTURE.md.
python3 -m http.server 4173
# http://localhost:4173npm test # unit and contract tests
npm run verify # static checks + tests
python3 scripts/browser_verify.py # full v1→v7 run in headless Chromium (needs playwright)MIT. See LICENSE.

