Open-source MCP server that exposes a deterministic web control loop for coding agents: create -> step -> snapshot -> stop with hybrid DOM + frame perception.
- CDP-first perception via
Page.startScreencast - DOM and accessibility summaries
- Frame metadata + optional frame files
- Bounded ring buffers and backpressure tracking
- Deterministic action execution with selector-first + coordinate fallback
- Replay manifest per session (
web_agent_replay) - stdio transport (default) + optional REST bridge
web_agent_session_createweb_agent_stepweb_agent_snapshotweb_agent_session_stopweb_agent_replay
npm install
npx playwright install --with-deps chromium
npm run build
npm run startnpm run smoke
npm run benchmarkSmoke and benchmark scripts use the REST transport on port 3400 by default and validate the create/step/snapshot/stop flow.
npm run smoke:youtube
npm run benchmark:youtubesmoke:youtube runs the smoke flow against a real YouTube video URL.
benchmark:youtube runs YouTube plus W3 animation media suites with DOM + frame fallbacks.
MCP_TRANSPORT=rest WEB_AGENT_REST_PORT=3400 node dist/index.jsExample:
curl -s http://localhost:3400/tools/web_agent_session_create \
-H "Content-Type: application/json" \
-d '{"target_url":"https://example.com"}'{
"name": "web_agent_session_create",
"arguments": {
"target_url": "https://example.com",
"capture_profile": "adaptive",
"max_steps": 200
}
}{
"name": "web_agent_step",
"arguments": {
"session_id": "<session-id>",
"action": "click",
"selector": "button[type=submit]",
"capture": {
"include_dom": true,
"include_frame": true
}
}
}{
"name": "web_agent_snapshot",
"arguments": {
"session_id": "<session-id>",
"include_dom": true,
"include_network": true,
"include_frame": true
}
}{
"name": "web_agent_session_stop",
"arguments": {
"session_id": "<session-id>",
"preserve_artifacts": true
}
}{
"name": "web_agent_replay",
"arguments": {
"trace_id": "trace_1700000000000_...",
"step_range": { "start": 1, "end": 20 }
}
}MCP_TRANSPORT=stdio|restMCP_MAX_SESSIONSMCP_HEADLESSWEB_AGENT_ALLOWLISTWEB_AGENT_DENYLISTWEB_AGENT_REST_PORTWEB_AGENT_REST_HOSTWEB_AGENT_POLICY=model_owns_action|deterministic
Recommended checks:
npm run lintnpm run typechecknpm run buildnpm run testnpm run benchmark