# DevTool MCP [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/standardbeagle/devtool-mcp  
**GitHub Stars:** 22  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/devtool-mcp

## Description
Development tooling MCP server with process management, proxy, and frontend diagnostics

## Tools
Capabilities this server exposes over MCP:

- **api_audit** — Run an API-efficiency audit over the recorded fetch/XHR call buffer.

Analyzes the in-page fetch/XHR call buffer (window.__devtool_api) and flags:
  waterfall:      serial request chains that could run in parallel
  n-plus-one:     a parameterised endpoint hit many times (batch opportunity)
  duplicate-call: identical request repeated within a short window
  chatty-load:    too many calls during the initial page load

The audit reads a buffer populated by browsing — a fresh page load is required
to fill it. If the buffer is empty the audit returns score 100 with a summary
noting "no API calls recorded — reload page then re-run".

Examples:
  api_audit {proxy_id: "dev"}
  api_audit {id: "dev"}
  api_audit {proxy_id: "dev", raw: true}

Output:
  - Default: Compact text summary optimized for AI consumption
  - With raw: true: Full JSON with every finding and selector
- **automation** — Control browser automation sessions for programmatic testing and screenshots.

Actions:
  start: Start a chromedp automation session
  stop: Stop a running session
  status: Get session status
  list: List all active sessions
  screenshot: Take a screenshot (viewport, fullpage, element, or clip)
  navigate: Navigate to a URL
  evaluate: Execute JavaScript in the page

evaluate runs against THE APP by default, reaching through the proxy's content
frame for you — no document.getElementById('__devtool_content_frame').contentWindow
hop to write. If the app frame is still loading it waits (up to 5s) and then
fails loud rather than ever running your script in the wrong frame. Pass
frame:"top" to inspect the proxy chrome shell (overlay, indicator, panels)
instead. Async scripts are awaited, so you get the resolved value rather than a
pending promise; write one async script instead of chaining sequential calls.

Examples:
  automation {action: "start", url: "http://localhost:3000"}
  automation {action: "start", proxy_id: "dev"}
  automation {action: "screenshot", session_id: "auto-1234", type: "viewport"}
  automation {action: "screenshot", session_id: "auto-1234", type: "fullpage", viewport: "mobile"}
  automation {action: "screenshot", session_id: "auto-1234", type: "element", selector: "#main"}
  automation {action: "navigate", session_id: "auto-1234", url: "http://example.com"}
  automation {action: "evaluate", session_id: "auto-1234", script: "document.title"}
  automation {action: "evaluate", session_id: "auto-1234", script: "(async () => { const r = await fetch('/api/health'); return r.status })()"}
  automation {action: "evaluate", session_id: "auto-1234", script: "!!document.getElementById('__wt_panel')", frame: "top"}
  automation {action: "list"}
  automation {action: "stop", id: "auto-1234"}

Screenshot Types:
  viewport: Capture visible viewport only
  fullpage: Capture entire scrollable page
  element: Capture specific element by CSS selector
  clip: Capture specific region (requires x, y, width, height)

Viewport Presets:
  desktop: 1920x1080
  tablet: 768x1024
  mobile: 375x667

Requirements:
  - Chrome or Chromium must be installed
  - Proxy recommended for full devtool features
- **browser** — Launch and manage Chrome browser instances for automation.

Actions:
  start: Start a browser instance
  stop: Stop a running browser
  status: Get browser status
  list: List all active browsers

Features:
  - Chrome/Chromium only (auto-detected)
  - Headless mode by default
  - Auto-starts proxy if proxy_id specified but not found

Examples:
  browser {action: "start", url: "http://localhost:3000"}
  browser {action: "start", proxy_id: "dev"}
  browser {action: "start", url: "http://localhost:3000", proxy_id: "dev"}
  browser {action: "start", url: "http://localhost:3000", headless: false}
  browser {action: "status", id: "browser-1234"}
  browser {action: "list"}
  browser {action: "stop", id: "browser-1234"}

Proxy Auto-Start:
  When proxy_id is specified but the proxy doesn't exist, the browser tool
  will auto-start the proxy using the provided URL. The browser then opens
  through the proxy, enabling devtool features (screenshots, DOM inspection, etc.).

Requirements:
  - Chrome or Chromium must be installed
  - Chrome 109+ required for headless mode
- **currentpage** — Inspect the current page: framework diagnostics, layout issues, and session resources/metrics.

Actions:
  triage: (default) Classify React/Next/Vue/Svelte/Solid runtime problems (hydration, key,
          infinite-loop, reactivity) into category + fix + anti-pattern. Start here.
  layout: Diagnose containing-block traps, ineffective z-index, click interception, and
          clipped descendants — names the offending ancestor and the fix.
  list: List all active page sessions
  get: Get detailed information for a specific session (may be large)
  summary: Get a compact summary optimized for long/complex pages
  clear: Clear all page sessions

A page session groups together:
  - The initial HTML document request
  - All associated resource requests (JS, CSS, images, etc.)
  - Frontend JavaScript errors from that page
  - Performance metrics (page load time, paint timing, etc.)
  - User interactions (clicks, keyboard, scroll, etc.)
  - DOM mutations (added, removed, modified elements)

Examples:
  currentpage {proxy_id: "dev"}                       // triage (default)
  currentpage {proxy_id: "dev", action: "layout"}     // layout diagnosis
  currentpage {proxy_id: "dev", action: "summary", session_id: "page-1"}
  currentpage {proxy_id: "dev", action: "summary", session_id: "page-1", detail: ["interactions"], limit: 20}
  currentpage {proxy_id: "dev", action: "summary", session_id: "page-1", detail: ["interactions", "mutations"]}
  currentpage {proxy_id: "dev", action: "get", session_id: "page-1"}
  currentpage {proxy_id: "dev", action: "clear"}

The list action returns summary counts (interaction_count, mutation_count).
The summary action returns aggregated data (errors by type, interactions by type,
  last 5 interactions/mutations) - best for long pages to avoid context overflow.
  Use detail parameter to get full data for specific sections:
  - detail: ["interactions"] - include full interaction list
  - detail: ["mutations"] - include full mutation list
  - detail: ["errors"] - include compact error list (truncated stacks/messages)
  - detail: ["resources"] - include full resource URL list

Error format is automatically compacted to prevent token overflow:
  - Stack traces limited to first 3 lines
  - Messages truncated to 500 chars max
  - Source paths reduced to filename only
  - Individual stack lines capped at 120 chars
  - limit: N - max items per detailed section (default: 5, max: 100)
The get action returns full interaction and mutation history (may be large).

This provides a high-level view of active pages and their resources.
- **daemon** — Manage the devtool daemon service.

The daemon is a background process that maintains persistent state for
processes and proxies across MCP client connections.

Actions:
  status: Check if daemon is running
  info: Get daemon information (version, uptime, statistics)
  start: Start the daemon (auto-starts if needed)
  stop: Stop the daemon gracefully
  restart: Restart the daemon
  stop_all: Stop all processes and proxies (daemon keeps running)
  restart_all: Restart all processes and proxies (stop then start with same config)
  doctor: Run health checks and return diagnostic report

Examples:
  daemon {action: "status"}
  daemon {action: "info"}
  daemon {action: "start"}
  daemon {action: "stop"}
  daemon {action: "restart"}
  daemon {action: "stop_all"}
  daemon {action: "restart_all"}
  daemon {action: "doctor"}

The daemon auto-starts when needed, so manual start is rarely required.
Use stop_all/restart_all to manage running resources without stopping the daemon.
- **demo** — Author narrated demo videos with the in-repo demo engine.

This is a repo-checkout capability: it drives docs-site/screenshots/engine/demo.mjs,
which ships in the agnt repository, not the installed binary. Running it from a
project without that engine tree returns a loud error naming the requirement.

Actions:
  list:     Enumerate demos under docs-site/screenshots/demos with a per-demo
            segment and narration summary.
  record:   Start a recording as a daemon-managed process; returns a process_id
            immediately. Observe/stop it via the proc tool (output/status/stop).
            Pass only:"seg1,seg2" to record specific segments instead of the whole demo.
  assemble: Re-mux an already-recorded demo from its segment captures (engine
            --assemble-only) as a managed process; returns a process_id.
  inspect:  Cut-point authoring aid (not yet available — engine subcommand pending).
  publish:  Share via the demo-publish target (not yet available — engine subcommand pending).

Examples:
  demo {action: "list"}
  demo {action: "record", name: "incident-inbox"}
  demo {action: "record", name: "incident-inbox", only: "card-intro,fix"}
  demo {action: "assemble", name: "incident-inbox"}
  proc {action: "output", process_id: "demo-incident-inbox"}
  proc {action: "stop", process_id: "demo-incident-inbox"}
- **detect** — Detect project type and available scripts.
Returns ready-to-paste proc run / proc wait invocations and likely_signals
heuristics for each script, so agents can chain detect → proc run → proc wait
without hand-constructing commands.

Examples:
  detect {}
  detect {path: "."}
  detect {raw: true}   // skip compact text, return JSON only
- **devauth** — Sign in to the app under development as a dev-oidc persona.

Needs a dev-oidc block in .agnt.kdl (see docs/configuration.md § Dev OIDC).
agnt serves a dev OIDC issuer at <proxy>/__agnt/oidc; personas are the users
declared there.

Actions:
  personas: list the personas and the issuer URL
  as:       switch the browser behind proxy_id to a persona; the app is sent
            to its login-path and signs in again as that persona
  token:    mint an access token for persona + client, for API calls

Examples:
  devauth {action: "personas", proxy_id: "dev"}
  devauth {action: "as", proxy_id: "dev", persona: "admin"}
  devauth {action: "token", proxy_id: "dev", persona: "standard", client: "story-web"}
- **diagnose** — Diagnose a dead click (action=click) in one call.

Composes existing evidence — no new detection: the last recorded click from the
interaction ring buffer, the element and any obstruction at the click point,
the stacking root (__devtool.getStacking), the fixed/containing-block trap
(__devtool.getContainer), and browser_js incidents recorded since the click.

Verdicts:
  handler_missing       click reached its target; nothing intercepted it
  obstructed            another element is hit-testable at the click point
  container_trap        position:fixed/absolute captured by an ancestor
  no_click_recorded     interaction history empty — no cause fabricated
  insufficient_evidence helper absent (old bundle) or evidence incomplete

Examples:
  diagnose {action: "click", proxy_id: "dev"}
  diagnose {action: "click", proxy_id: "dev", selector: ".save-btn"}
  diagnose {action: "layout", proxy_id: "dev"}
  diagnose {action: "layout", proxy_id: "dev", selector: ".sidebar", viewport: {width: 375, height: 667}}

action=layout composes existing producers in one call: layout diagnose()
(containing-block traps, ineffective z-index, click interception, clipped
descendants), the responsive-risk scan for the CURRENT viewport only (no
multi-viewport sweep — that is responsive_audit), and for each
offscreen/overflow/clipped finding the stacking or container cause via
__devtool.getStacking/getContainer. Each finding carries a stable id and its
cause when one was found. A screenshot_recommended block (selector + exact
__devtool.screenshot call) is populated ONLY when at least one finding is
visual (overflow, clipped, offscreen, overlap). selector narrows the
diagnosis to one subtree; viewport resizes before diagnosing and the original
viewport is restored afterwards, including on failure.
- **error_queue** — Add an external CI/CD or infrastructure failure to agnt's unified error queue.

Use this when a failure came from GitHub Actions, Buildkite, deploy logs, a hosted service, or any source outside agnt's proxy/process monitors. The entry appears in get_incidents.

Examples:
  error_queue {message: "GitHub Actions build failed: go test ./...", source: "github-actions", category: "ci"}
  error_queue {message: "Deploy failed: migration timed out", source: "deploy", severity: "error"}
- **get_incidents** — [PREFERRED] Pull incidents from the session incident inbox.

The single error/incident surface. Provides cursor-based resumable pulls,
remediation hints, next-tool suggestions, and skill hints for each incident.

Sources: browser JS errors, HTTP 4xx/5xx, transport errors, proxy diagnostics,
process alerts, process crashes, build failures, port conflicts.

Examples:
  get_incidents {}
  get_incidents {severity: ["critical","error"]}
  get_incidents {since: "5m"}
  get_incidents {mark_read: true}
  get_incidents {detail: "full"}
  get_incidents {raw: true, limit: 50}
- **loading_audit** — Run a loading-UX audit over the recorded spinner/loader timeline.

Analyzes the in-page spinner timeline (window.__devtool_spinners) and flags:
  spinner-cascade:       loaders that fire serially (B appears after A finishes)
                         when they could have loaded in parallel
  spinner-fragmentation: 3+ concurrent sub-loaders under one ancestor that
                         should be consolidated into a single master loader

The audit reads a timeline populated during page load — a fresh page load is
required to capture the loading sequence. If the timeline is empty the audit
returns score 100 with a summary noting "No loading indicators recorded —
reload page then re-run".

Examples:
  loading_audit {proxy_id: "dev"}
  loading_audit {id: "dev"}
  loading_audit {proxy_id: "dev", raw: true}

Output:
  - Default: Compact text summary optimized for AI consumption
  - With raw: true: Full JSON with every finding and selector
- **proc** — Manage running processes.

Actions:
  list: List all running processes (use global: true for all directories)
  status: Get process status and info
  output: Get process output (tail/grep supported, falls back to script output history)
  stop: Gracefully stop a process (use force: true for immediate kill)
  restart: Restart a running process (stop then start with same config). For .agnt.kdl autostart scripts, process_id = script name.
  cleanup_port: Kill any process using a specific port
  autorestart: Enable/disable automatic restart when process exits
  scripts: List all registered scripts with state and start/fail counts
  script_output: Get script output history across restarts
  script_history: Get script state transition history
  snapshot: Unified dev-environment status (processes + proxies + recent errors + URLs + suggested next actions) in a single call. Use raw:true for structured JSON.
  find: Extract build warnings, compile errors, and test failures from a process's output buffer (framework-aware classification).
  run: Start a single admin-aware process; visible in proc list and SCRIPT LIST. Optionally gate on depends_on:[...] (default 30s timeout). Process state is "pending" while waiting; "starting" once deps clear; "failed" on dependency_timeout.
  run_group: Start a multi-process stack in one call. Cycle detection runs before any process launches; on cycle the call returns an error and no process is started. Each process may declare depends_on referencing other processes in the group; topo order is enforced via the readiness signaler.
  wait: Block until a named signal appears in a process's output. Polls (default 200ms, override with poll_ms) until match or timeout (default 30000ms). Returns {signal, matched_line, elapsed_ms} on hit, {timeout: true} on timeout — never errors. Pass signals:[...] to wait for whichever comes first.

Multi-stream output and signals:
  proc {action:"output", process_ids:["build","server","test"]}
  Pulls output from N processes in one call. Each line tagged "[id]" in compact output, NDJSON in raw mode.
  Add extract:["url","error","warning","ready","port"] to scan for structured signals — surfaced per-process under multi_stream[*].signals (or top-level signals when single process_id is used).
  Coordinates with proc snapshot: snapshot uses the unified-error classification pipeline (framework-aware), extract scans raw line buffers (regex, framework-agnostic).

Restarting dev servers:
  proc {action: "restart", process_id: "dev"}
Never use pkill or external commands - always use proc stop/restart for clean shutdown.

Auto-restart: Background processes automatically restart on crash by default (rate-limited
to max 5 restarts/minute to prevent loops). Use autorestart action to check or disable:
  proc {action: "autorestart", process_id: "dev"}  # Check status
  proc {action: "autorestart", process_id: "dev", auto_restart_enable: false}  # Disable

Examples:
  proc {action: "list"}
  proc {action: "status", process_id: "test"}
  proc {action: "output", process_id: "test", tail: 20}
  proc {action: "output", process_id: "test", grep: "FAIL"}
  proc {action: "stop", process_id: "test"}
  proc {action: "stop", process_id: "test", force: true}
  proc {action: "restart", process_id: "dev"}
  proc {action: "cleanup_port", port: 3000}
  proc {action: "autorestart", process_id: "dev", auto_restart_enable: false}
  proc {action: "scripts"}
  proc {action: "script_output", script_name: "dev", tail: 50}
  proc {action: "script_history", script_name: "dev"}
  proc {action: "snapshot"}                  # Compact dev environment summary
  proc {action: "snapshot", raw: true}       # Full JSON of processes, proxies, errors, urls, suggested_next
  proc {action: "output", process_ids: ["build","server"], extract: ["error","ready"]}  # Multi-stream + signals
  proc {action: "wait", process_id: "server", signal: "ready", timeout: 30000}          # Block until ready
  proc {action: "wait", process_id: "build", signals: ["ready", "error"], timeout: 60000}  # First wins
  proc {action: "run", id: "api", run: "go run ./cmd/api", depends_on: ["db"]}
  proc {action: "run_group", processes: [
    {id: "db",  run: "docker compose up db"},
    {id: "api", run: "go run ./cmd/api", depends_on: ["db"]},
    {id: "web", run: "npm run dev", depends_on: ["api"]}
  ]}
- **proxy** — Manage reverse proxy servers with traffic logging and frontend instrumentation.

Prefer a dedicated MCP audit when it answers the question: responsive_audit,
api_audit, loading_audit, snapshot. For broader page QA, run one compact
auditPageQuality pass; drill into failed areas only.

Discovery (before targeted exec):
  proxy {action: "exec", search: "X"}          -- find helpers by keyword
  proxy {action: "exec", describe: "name"}     -- get full signature + example
  proxy {action: "exec", code: "..."}          -- call one helper; raw JS last

Proxy lifecycle:
  proxy {action: "start", id: "dev", target_url: "http://localhost:3000"}
  proxy {action: "status", id: "dev"}
  proxy {action: "stop", id: "dev"}
  proxy {action: "list"}

Additional actions:
  restart:  Stop then start with same config
  navigate: Drive the page — proxy {action:"navigate", id:"dev", direction:"back|forward|reload"} or {direction:"goto", target_url:"..."}
  resize:   Resize the page viewport from outside (no reload) — proxy {action:"resize", id:"dev", width:375} (width:0 resets)
  toast:    Send notification to connected browsers
  chaos:    Inject controlled errors for resilience testing

Always-wrap frame model (the page runs inside a content iframe hosted by a chrome shell):
  - exec defaults to the INNER page content frame (the frame the developer is interacting with).
  - target:"outer" runs the REPL against the OUTER chrome shell (the proxy UI runtime / host) instead:
      proxy {action:"exec", id:"dev", target:"outer", code:"location.href"}
  - target:"inner" (default) scripts the page content frame.
  - resize/navigate observe and drive the page from the shell: resize the viewport, then run
    api_audit / loading_audit / responsive_audit (they target the inner frame) to measure the
    page at that size — all without a page reload.

Port selection:
  - Default: stable port derived from target URL hash (range 10000-60000)
  - Specify 'port' only when a fixed port is required
  - Assigned port returned in 'listen_addr' response field

Public URLs:
  - This tool serves a local listener; to expose it publicly use the 'tunnel' tool
    (cloudflare/ngrok), which mints a public URL and reports it back to the proxy
    (surfaced as 'public_url' in start/status).
  - The 'public_url' start field only sets URL-rewriting when you already front the
    proxy with your own tunnel; it does not create a tunnel.

Toast notifications:
  proxy {action: "toast", id: "dev", toast_message: "Task complete"}
  proxy {action: "toast", id: "dev", toast_type: "error", toast_title: "Build Failed", toast_message: "See console"}
  Toast types: success, error, warning, info (default)

The proxy automatically:
  - Logs all HTTP traffic (requests/responses)
  - Injects JavaScript to capture frontend errors
  - Captures performance metrics (page load, resources)
  - Provides WebSocket endpoint for metrics
  - Injects __devtool API with 50+ diagnostic functions

Each proxy has separate log storage and WebSocket connections.
- **proxylog** — Query and analyze proxy traffic logs.

Actions:
  query: Search logs with filters (default, may be large)
  summary: Get compact aggregated summary (recommended for large logs)
  clear: Clear all logs for a proxy
  stats: Get log statistics

Log Types:
  http: HTTP request/response pairs
  error: Frontend JavaScript errors with stack traces
  performance: Page load and resource timing metrics
  custom: Custom log messages from __devtool.log()
  screenshot: Screenshots captured via __devtool.screenshot()
  execution: Results of executed JavaScript code
  response: JavaScript execution responses
  interaction: User interactions (clicks, keyboard, scroll)
  mutation: DOM mutations (added, removed, modified elements)
  diagnostic: Framework/runtime diagnostics (severity: error, warning, info)
  panel_message: Messages sent from the floating indicator panel
  sketch: Sketches/wireframes from sketch mode (includes JSON data and PNG image path)

Summary Action (Recommended for Large Logs):
  The summary action aggregates logs by type and provides:
  - Counts by type (errors, http, performance, etc.)
  - Deduplicated error summaries (top 10 unique errors)
  - HTTP status/method breakdown
  - Average performance metrics
  - Recent entries for each type (last 5)

  Progressive reveal with detail parameter:
  - detail: ["errors"] - include compact error list (truncated stacks)
  - detail: ["http"] - include HTTP request list
  - detail: ["performance"] - include performance metrics
  - detail: ["interactions"] - include user interactions
  - detail: ["mutations"] - include DOM mutations
  - detail: ["other"] - include custom/panel/sketch logs
  - limit: N - max items per detailed section (default: 10, max: 100)

  All data is automatically compacted to prevent token overflow:
  - Error stack traces limited to first 3 lines
  - Messages truncated to 500 chars max
  - URLs truncated to 100 chars
  - Individual stack lines capped at 120 chars

Query Examples:
  proxylog {proxy_id: "dev", types: ["http"], methods: ["GET"]}
  proxylog {proxy_id: "dev", types: ["error"], limit: 5}
  proxylog {proxy_id: "dev", since: "5m", limit: 50}

Summary Examples (Recommended):
  proxylog {proxy_id: "dev", action: "summary"}
  proxylog {proxy_id: "dev", action: "summary", detail: ["errors"]}
  proxylog {proxy_id: "dev", action: "summary", detail: ["errors", "http"], limit: 20}
  proxylog {proxy_id: "dev", action: "summary", types: ["error"]}

Other Actions:
  proxylog {proxy_id: "dev", action: "stats"}
  proxylog {proxy_id: "dev", action: "clear"}

Each proxy maintains its own separate log storage.
- **publish** — Manage public walkthrough shares (trusted, session-scoped control plane).

Actions:
  create  — publish a walkthrough behind a fresh unguessable share token.
            Returns the token ONCE (never stored, never shown again — rotate if lost)
            plus a viewer-safe share id and the /s/{token} URL.
            Accepts a live origin to demo against — either walkthrough.upstream.url
            or the top-level "upstream" field (naming two different origins is
            rejected) — and variant ops including the raw-content ops setHTML,
            addStyle, and addScript. Publisher script runs only because its
            sha256 is pinned in the served revision's CSP script-src.
            The /s/{token} URL it returns is a PATH: prefix it with the origin
            serving the public plane, or use "agnt publish serve --dir" which
            prints whole URLs (and folds in a tunnel origin).
  status  — show a share's state (never the token; only a hash prefix).
  list    — list this project's shares.
  revoke  — kill a share immediately (token stops working at once).
  rotate  — mint a new token (old token dies immediately); returns the new token ONCE.
  feedback— read anonymous viewer feedback for a share you own (owner-scoped;
            paginated by cursor/limit). Returns rows + counts (total, dropped),
            never the token. Bodies are inert data — escape before rendering HTML.

Examples:
  publish {action: "create", walkthrough: {...}}
  publish {action: "create", walkthrough: {...}, upstream: "https://shop.example.com/cart"}
  publish {action: "list"}
  publish {action: "status", id: "<share-id>"}
  publish {action: "revoke", id: "<share-id>"}
  publish {action: "rotate", id: "<share-id>"}
  publish {action: "feedback", id: "<share-id>", limit: 50}
  publish {action: "feedback", id: "<share-id>", cursor: "<next_cursor>"}
- **release_qa** — Release gate: verify the changed flow, run exactly ONE broad audit, drill into failures only.

This is the ONE tool where a broad audit is the default — every other tool
stays targeted. Steps, in order:

1. verify: re-runs verify_change in-process over the session Investigation
   (the "changed flow" = the session's FailedAreas + Findings). Optional
   explicit flow steps run first through the existing proxy navigate/exec
   actions only — no new browser automation.
2. audit: exactly ONE broad audit per call — the full aggregate quality audit
   via __devtool.auditAll through proxy exec (default), or the named
   audit tool (responsive/api/loading) — with profile=release.
3. drill-down: ONLY for areas the broad audit failed. responsive findings
   -> diagnose action=layout on the failing selector; click-interception ->
   diagnose action=click with selector; api findings -> api_audit re-run.
   An area that passed is never drilled.

Header: release_qa: PASS|FAIL. PASS only when verify passed and the broad
audit returned no release-profile findings; any persist, finding or warning
fails the gate. FailedAreas and new finding ids merge into the session
Investigation.

Examples:
  release_qa {proxy_id: "dev"}
  release_qa {proxy_id: "dev", flow: [{action: "navigate", url: "http://localhost:3000/checkout"}, {action: "exec", selector: ".pay-btn"}]}
  release_qa {proxy_id: "dev", audit: "responsive", raw: true}
- **replaytest** — Record, refine, and replay deterministic browser replay-tests (Pro: advanced_testing).

Actions:
  list:    List saved scenarios (free)
  show:    Print a saved scenario's JSON (free)
  replay:  Run the baseline seed lane (and an optional fuzz preset) against a saved
           scenario, mocking the network in-page; persists and returns a report.
  explore: Compute the breadth-exploration seed partition for a scenario. Returns
           N seeds (explore_agents) for the calling agent to fan out to
           browser-debugger subagents.
  refine:  Use an LLM to mask volatile auto-captured assertions. Requires
           ANTHROPIC_API_KEY or CLAUDE_KEY in the daemon environment.
  record:  Open a recording window against a proxy (record + proxy_id). Captures
           traffic from this moment until stop.
  stop:    Close the recording window (stop + name): pulls the full-fidelity
           proxy log captured since record, assembles a scenario with response
           bodies preserved, and saves it. Requires daemon mode.

Examples:
  replaytest {action: "list"}
  replaytest {action: "show", name: "checkout"}
  replaytest {action: "replay", name: "checkout"}
  replaytest {action: "replay", name: "checkout", preset: "latency"}
  replaytest {action: "explore", name: "checkout", explore_agents: 4}
  replaytest {action: "refine", name: "checkout"}
- **responsive_audit** — Run responsive design audits across multiple viewport sizes.

Detects layout issues, content overflows, and viewport-specific accessibility problems
by loading the page in hidden iframes at target sizes.

Default viewports: mobile (375x667), tablet (768x1024), desktop (1440x900)

Checks available:
  layout:  Collapsed content, fixed element coverage, margin/padding squeeze
  overflow: Horizontal scroll, clipped content, truncated text, squeezed images
  a11y:     Touch target size, iOS zoom triggers, readability issues (mobile)

Examples:
  responsive_audit {proxy_id: "dev"}
  responsive_audit {proxy_id: "dev", checks: ["layout", "overflow"]}
  responsive_audit {proxy_id: "dev", viewports: [{name: "xs", width: 320, height: 568}]}
  responsive_audit {proxy_id: "dev", profile: "bug"}
  responsive_audit {proxy_id: "dev", raw: true}

Profiles (compact output projection):
  bug:     Top 5 findings by severity — triage view
  release: All findings — release gate
  full:    All findings (default)

Each compact finding carries an "id:" line (stable finding ID) and a "next:"
line (a concrete __devtool helper call for the offending selector).

Output:
  - Default: Compact text format optimized for AI consumption
  - With raw: true: Full JSON with all issues and details

The audit uses sequential viewport loading to avoid memory pressure.
Typical duration: 3-6 seconds for 3 viewports.
- **run** — Run a project script or raw command.

Modes:
  background (default): Returns process_id immediately for tracking via proc tool
  foreground: Waits for completion, returns exit_code/state/runtime (output via proc)
  foreground-raw: Waits for completion, returns exit_code/state/runtime + stdout/stderr

Auto-restart: Background processes automatically restart on crash (rate-limited to
prevent loops: max 5 restarts/minute). Use no_auto_restart: true to disable.
  run {script_name: "dev"}                    # Auto-restarts by default
  run {script_name: "test", no_auto_restart: true}  # Disable for one-time tasks

Restarting: Use proc restart (preferred) or stop then run again:
  proc {action: "restart", process_id: "dev"}
Never use pkill or external commands - always use proc stop/restart for clean shutdown.

Examples:
  run {script_name: "test"}
  run {script_name: "dev"}
  run {script_name: "test", mode: "foreground"}
  run {script_name: "test", mode: "foreground-raw"}
  run {raw: true, command: "go", args: ["mod", "tidy"], mode: "foreground-raw"}
- **session** — Manage agnt run sessions and schedule messages for AI agents.

Sessions are created automatically when 'agnt run' starts. You can send messages
directly to a session or schedule messages for future delivery.

Actions:
  list: List active sessions (filtered by current directory unless global: true)
  get: Get details for a specific session
  send: Send a message to a session immediately
  schedule: Schedule a message for future delivery
  tasks: List scheduled tasks
  cancel: Cancel a scheduled task

Examples:
  session {action: "list"}
  session {action: "list", global: true}
  session {action: "get", code: "claude-1"}
  session {action: "send", code: "claude-1", message: "Check the test results"}
  session {action: "schedule", code: "claude-1", duration: "5m", message: "Verify this completed"}
  session {action: "tasks"}
  session {action: "cancel", task_id: "task-abc123"}

Duration format:
  - "5m" = 5 minutes
  - "1h" = 1 hour
  - "1h30m" = 1 hour 30 minutes
  - "30s" = 30 seconds

Scheduled messages are delivered as synthetic stdin to the AI agent's PTY,
allowing you to remind the agent to check on tasks or verify completions.
- **snapshot** — Capture and compare visual snapshots for regression testing.

Actions:
- screenshot: Capture the current page of a running proxy (writes PNG to audit storage; path retrieved via proxylog)
- baseline: Create a new baseline from screenshots
- compare: Compare current screenshots to a baseline
- list: List all available baselines
- delete: Delete a baseline
- get: Get details of a specific baseline

End-to-end flow (screenshot → baseline/compare):
  1. snapshot {action: "screenshot", proxy_id: "dev", name: "home"}
  2. proxylog {proxy_id: "dev", types: ["screenshot"], limit: 1}   // read file_path
  3. snapshot {action: "baseline", name: "v1", pages: [{url: "/", screenshot_path: "<file_path>"}]}
Each page accepts either screenshot_path (the file from step 2) or inline screenshot_data (base64).

Example screenshot:
  snapshot {action: "screenshot", proxy_id: "dev"}
  snapshot {action: "screenshot", proxy_id: "dev", name: "homepage", full_page: true}
  snapshot {action: "screenshot", proxy_id: "dev", selector: ".header"}

Example baseline:
  snapshot {action: "baseline", name: "before-refactor", pages: [{url: "/", viewport: {width: 1920, height: 1080}, screenshot_path: "/…/screenshot-home.png"}]}

Example compare (diff_threshold overrides sensitivity, default 0.01):
  snapshot {action: "compare", baseline: "before-refactor", diff_threshold: 0.02, pages: [{url: "/", screenshot_path: "/…/screenshot-home.png"}]}
- **store** — Persistent key-value storage with scoped namespaces.

Actions:
  get: Retrieve a value by key
  set: Store a value by key
  delete: Remove a value by key
  list: List all keys in a scope
  clear: Clear all values in a scope
  get_all: Get all key-value pairs in a scope

Scopes:
  global: Shared across all contexts (scope_key: empty)
  folder: Per-directory storage (scope_key: directory path)
  page: Per-URL storage (scope_key: page URL)

Examples:
  store {action: "set", scope: "global", key: "api_key", value: "abc123"}
  store {action: "get", scope: "global", key: "api_key"}
  store {action: "set", scope: "page", scope_key: "http://localhost:3000", key: "user_id", value: 42}
  store {action: "list", scope: "folder", scope_key: "/home/user/project"}
  store {action: "get_all", scope: "global"}
  store {action: "delete", scope: "global", key: "api_key"}
  store {action: "clear", scope: "page", scope_key: "http://localhost:3000"}

Metadata:
  Optional metadata can be attached to values for additional context:
  store {action: "set", scope: "global", key: "config", value: {...}, metadata: {version: "1.0", author: "alice"}}

The store persists data across daemon restarts. Values are typed (string, number, boolean, object, array).
- **tunnel** — Manage tunnel connections for exposing a local port over the network.

Actions:
  start: Start a tunnel for a local port
  stop: Stop a running tunnel
  status: Get tunnel status and URL
  list: List all active tunnels

Providers:
  cloudflare: cloudflared Quick Tunnels — public internet (trycloudflare.com)
  ngrok: ngrok — public internet
  tailscale: 'tailscale serve' — tailnet-private HTTPS at this node's
             MagicDNS name (https://<machine>.<tailnet>.ts.net). Reachable
             only from other devices on your tailnet. One service per node
             at root '/' (multiple tailscale tunnels on the same machine
             will collide).

Examples:
  tunnel {action: "start", id: "dev", provider: "cloudflare", local_port: 8080}
  tunnel {action: "start", id: "dev", provider: "tailscale",  local_port: 8080}
  tunnel {action: "start", id: "dev", provider: "cloudflare", local_port: 12345, proxy_id: "dev"}
  tunnel {action: "status", id: "dev"}
  tunnel {action: "list"}
  tunnel {action: "stop", id: "dev"}

The tunnel automatically configures the proxy's public_url when proxy_id is
specified, enabling proper URL rewriting for cross-device testing through
the tunnel.

Requirements:
  - cloudflare: 'cloudflared' binary in PATH
  - ngrok: 'ngrok' binary in PATH
  - tailscale: 'tailscale' binary in PATH, node logged in, HTTPS + MagicDNS
    enabled in the tailnet admin console (serve requires HTTPS certs)
- **verify_change** — Recheck only the findings this session already recorded.

Reads the session Investigation, re-runs each target finding's producer
(get_incidents / responsive_audit / api_audit / loading_audit / diagnose)
IN-PROCESS with the exact recorded args — never a broad audit — and compares
by id: resolved (absent now), persists (still reported), new (reported by the
same producer but not a target). Screenshots via __devtool.screenshot are
captured ONLY for Visual=true findings that resolved or changed, recorded as
visual_baseline_ref. Unknown ids warn per-id (stale_finding_id) without
aborting. The outcome merges back into the Investigation.

Header: verify_change: PASS|FAIL (<n> resolved, <m> persist, <k> new);
FAIL whenever any target persists.

Examples:
  verify_change {}
  verify_change {finding_ids: ["a1b2c3d4"]}
  verify_change {proxy_id: "dev", raw: true}
- **walkthrough** — Run a live demo of work just completed in the browser overlay. Pops a floating, scrolling step list that narrates each step, highlights the matching app element, and advances by auto-timer, by the user clicking the highlighted element, or by waiting for an app-state condition. Next/Prev let the user step manually. Loaded scripts get a replay launcher in the overlay.

Actions:
- load:   register a script (shows a replay launcher; does not start)
- start:  begin playback (by inline script or script_id); mode auto|manual
- stop:   end the active walkthrough and hide the panel
- next/prev: step manually
- play/pause: control auto-advance
- status: current step / mode / running
- list:   registered scripts

Script shape:
  {id, title, steps:[{title, body, target?, gesture?, gesture_label?, advance:{type, ...}}]}
  advance.type:
    auto         {ms}        show ms then advance (default 5000)
    click-target            advance when the user clicks the highlighted target
    wait         {when,value} when: url-contains | element-present | element-visible
  gesture (optional, needs target): hover | click | scroll | drag
    Renders the matching animated affordance over the highlight; auto-dismisses
    when the step advances. The active step's narration reads through as it lands.
  gesture_label (optional, needs gesture, <=64 chars)
    Text under the affordance. Name the concrete action ("Click to open your
    cart", "Drag the handle to reorder") — omitted, it falls back to a generic
    verb phrase ("Click here").

Examples:
  walkthrough {action:"start", proxy_id:"dev", script:{id:"demo", title:"New checkout", steps:[
    {title:"Open cart", body:"Click the cart to begin.", target:"#cart-btn", gesture:"click", gesture_label:"Click to open your cart", advance:{type:"click-target"}},
    {title:"Totals", body:"Order total updates live.", target:".order-total", advance:{type:"auto", ms:4000}},
    {title:"Confirm", body:"You land on the confirm page.", advance:{type:"wait", when:"url-contains", value:"/confirm"}}
  ]}}
  walkthrough {action:"status", proxy_id:"dev"}
  walkthrough {action:"next", proxy_id:"dev"}
- **watch** — Get the shell command for streaming agnt events via Monitor.

Returns a command string that can be passed to Claude's Monitor tool.
Bridges the gap between the MCP client (which knows the daemon socket) and Monitor.

Targets:
  errors: Browser JS errors, HTTP errors, diagnostics
  interactions: Panel messages, clicks, keyboard, sketch events
  process: Process output for a specific process
  all: All agnt events (default)

Examples:
  watch {target: "errors", proxy_id: "dev"}
  watch {target: "interactions", proxy_id: "dev"}
  watch {target: "process", process_id: "app"}
  watch {target: "all"}
  watch {}

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "devtool-mcp": {
    "command": "uvx",
    "args": ["agnt"]
  }
}
```

## Documentation

## What DevTool MCP does

DevTool MCP MCP server gives an MCP client a control and diagnostics layer for local web development. It manages development processes and a background daemon, starts reverse proxies with frontend instrumentation, launches Chrome or Chromium, and exposes browser state to an AI coding agent.

The proxy records HTTP traffic, browser errors, performance measurements, interactions, DOM mutations, diagnostic events, screenshots, and JavaScript execution results. Page sessions group the document request, resources, errors, metrics, interactions, and mutations for later inspection. The server also supports persistent scoped key-value storage, public tunnels, visual snapshot comparisons, walkthrough overlays, and session messaging.

## How it works

A typical workflow starts a process or proxy for a local application, then opens that application through the proxy. The proxy injects the development instrumentation and keeps separate logs and WebSocket connections for each proxy. Browser automation can operate directly on a URL or use a proxy identifier; when a requested proxy is absent, the browser tool can start it from the supplied URL.

Inspection tools return compact summaries by default to limit context size. Detailed sections can be requested for errors, HTTP requests, performance data, interactions, mutations, resources, or other recorded events. Several audits depend on data collected during browsing: API and loading audits require a fresh page load, and responsive audits load hidden frames sequentially at selected viewport sizes.

The daemon preserves process and proxy state across MCP client connections. It starts automatically when needed, and its health-check action can report service problems. Processes can run in the background, be restarted cleanly, emit readiness signals, and be grouped with dependency ordering.

## Setup and configuration

Install the command-line package with npm, pip, or uv, or build it from source:

- `npm install -g @standardbeagle/agnt`
- `pip install agnt`
- `uv pip install agnt`

Register the MCP server with an MCP client using the `agnt mcp` command:

```json
{
  "mcpServers": {
    "agnt": {
      "command": "agnt",
      "args": ["mcp"]
    }
  }
}
```

The `agnt skills` command can install agent skills and register the MCP server. It requires Node.js and `npx`. Project setup can generate `.agnt.kdl` automatically for recognized application shapes, including Node, Go/Wails, .NET, Docker Compose, Django, Rails, Laravel, Phoenix, Hugo, Jekyll, MkDocs, and static sites. `agnt init` runs project setup without launching a coding session.

Chrome or Chromium is required for browser automation and browser management. Headless mode requires Chrome 109 or newer. Tunnel providers additionally require their corresponding `cloudflared`, `ngrok`, or `tailscale` binary and configuration.

## Tools and capabilities

- `proc`, `run`, `detect`, and `daemon` manage scripts, processes, dependencies, output, restart behavior, project detection, and service health.
- `proxy` and `proxylog` provide reverse-proxy lifecycle control, JavaScript execution, navigation, resizing, traffic logs, and aggregated diagnostics.
- `browser` and `automation` launch Chrome sessions, navigate pages, evaluate scripts, inspect session state, and capture viewport, full-page, element, or clipped screenshots.
- `currentpage`, `get_incidents`, `diagnose`, and `verify_change` support framework triage, layout diagnosis, incident retrieval, dead-click investigation, and targeted rechecks.
- `responsive_audit`, `api_audit`, `loading_audit`, `release_qa`, and `snapshot` cover responsive behavior, request patterns, loading sequences, release gates, and visual regressions.
- `tunnel`, `store`, `session`, `walkthrough`, `publish`, and `watch` handle public access, persistent values, agent sessions, browser demonstrations, share management, and event-monitoring commands.

## Limitations and notes

The API and loading audits analyze buffers populated by a page load; an empty buffer produces a clean score with a reload instruction rather than findings. `evaluate` targets the application frame by default and can target the outer proxy shell explicitly. Demo recording relies on the repository’s demo engine and therefore needs the relevant checkout tree, not only the installed binary. Tunnel behavior depends on the selected provider and its local binary. Channel mode is experimental and limited to Claude Code with additional development configuration.

_Full upstream README: https://allmcps.com/mcp/devtool-mcp/readme_

