Action–State Interactivity Spec (Issue #38, Feb 2026)
The hypothesis
Can an LLM solve a Sudoku puzzle with zero knowledge of the DOM — no screenshots, no HTML parsing, no element selectors — using only state observation and action invocation?
That's the core question. If the answer is yes, it validates something significant: that a sufficiently rich action–state contract is a complete interface for an agent. The DOM becomes irrelevant. The LLM reads the board state, reasons about the puzzle, issues placeNumber(row, col, digit) actions, observes the updated state, and repeats — solving the puzzle the same way a human would, just through a declared API instead of a visual UI.
The problem it's solving
Today agents interacting with web apps resort to visual scraping (screenshots) or DOM parsing (raw HTML). Both are slow, brittle, and disconnected from the app's actual intent — the agent is reverse-engineering the UI rather than talking to the app directly.
The proposed pattern
Each app declares a manifest: available actions with parameter schemas, and the state shape the agent needs to observe. An MCP server exposes an invoke_action tool. The server fires an SSE event into the app's event bus. The app's reactive system handles it exactly as it would a user interaction — visually indistinguishable, but fully headless-capable.
Agent interaction loop:
- Read the app manifest (available actions + state schema)
- Read current board state
- Reason about next move
- Call
invoke_action(app, "placeNumber", { row, col, digit }) - Observe updated state
- Repeat until solved
Manifest structure
name: sudoku
actions:
placeNumber:
description: Place a number into the selected cell (1-9)
params:
row: { type: integer, minimum: 0, maximum: 8 }
col: { type: integer, minimum: 0, maximum: 8 }
digit: { type: integer, minimum: 1, maximum: 9 }
state:
currentPuzzle:
type: number[][]
dimensions: [9, 9]
description: Live board state; 0 = empty cell
Authored in YAML, served as JSON. The manifest is the contract the agent reads once at session start.
Relationship to WebMCP (W3C)
WebMCP proposes the same model at the browser API layer. Key difference: WebMCP explicitly excludes headless, autonomous agent workflows. This pattern operates precisely in that space — no browser required, agent-only workflows fully supported.
Status, September 2026. The framing above was written in February 2026 against Chrome 146 Canary and navigator.modelContext; every specific in that sentence has since moved, and the shape of the idea has not. Chrome shipped the API in 146. The spec then relocated it from navigator.modelContext to document.modelContext in the 21 July draft, with Chrome 150 deprecating the old location — so a live registration has to feature-detect both. A public origin trial runs Chrome 149 through 156. Edge is experimental behind a flag; Firefox and Safari are in the discussion without commitments. It remains a W3C Community Group draft co-edited by Google and Microsoft, not standards-track, with close to zero deployment on real sites and no mainstream agent calling the tools yet — Gemini in Chrome is announced as the first consumer but unshipped.
The relocation is the part worth keeping, not the version numbers. In six months the transport changed namespace once and deprecated its old one; the action metadata schema changed not at all.
Key insight
The transport (SSE) is mechanical. The interesting design work is the action metadata schema: name, params, constraints, effects, domain knowledge. That schema is durable — when WebMCP lands, you swap the transport, not the schema.
That held. WebMCP landed in Chrome and then moved, and a manifest written to this shape would have survived the move untouched.
WebMCP status re-checked 2026-09-04 against The State of WebMCP: July 2026 and navigator.modelContext: Chrome's WebMCP API. The original section was written February 2026 and is preserved above rather than rewritten, since the whole point is which parts aged.