Skip to main content
Glama

h5-devtools-mcp

npm version npm downloads license

English | 简体中文

An MCP server that lets coding agents (Claude Code, Codex, Cursor…) debug H5 pages running inside Android WebViews on real devices — read console output and uncaught exceptions, and run JavaScript in the page, without opening chrome://inspect.

Status: v0.1, early. Android only.

How it works

Coding agent ──MCP (stdio)──▶ h5-devtools-mcp ──adb forward──▶ webview_devtools_remote_<pid> ──CDP──▶ WebView page

Every debuggable WebView exposes a Chrome DevTools Protocol endpoint on an abstract unix socket. The server discovers those sockets over adb (the same way chrome://inspect does), forwards them to local ports, and connects with CDP.

Related MCP server: Android DevTools MCP

Requirements

  • Node.js 18+

  • adb on your PATH (or set ADB_PATH)

  • An Android device with USB debugging enabled

  • The app must enable WebView debugging (debug builds usually do):

WebView.setWebContentsDebuggingEnabled(true);

Setup

# Claude Code
claude mcp add h5-devtools -- npx -y h5-devtools-mcp

Other MCP clients (Cursor, Codex…) take the same command: npx -y h5-devtools-mcp.

From source

git clone https://github.com/xianguoGou/h5-devtools-mcp.git
cd h5-devtools-mcp
npm install && npm run build
claude mcp add h5-devtools -- node /absolute/path/to/h5-devtools-mcp/dist/index.js

Tools

Tool

What it does

list_targets

List debuggable pages: app package, title, URL, visibility

attach

Connect to a page and start buffering console output

get_console

Read buffered entries, filtered by level / keyword / exclude_keywords, incrementally via since_seq

evaluate_js

Run a JavaScript expression in the page and return the result (promises are awaited)

detach

Disconnect from a page

Output is designed to be token-cheap: compact one-line entries, long messages truncated, and since_seq so an agent only reads what's new instead of re-reading the whole buffer on every turn.

Example

> list_targets
- id: R5CT1234/webview_devtools_remote_8812/3A1F…
  app: com.example.app (pid 8812) on SM-S9180
  title: "Order"
  url: https://m.example.com/order

> get_console { "levels": ["error"] }
#41 10:32:01.123 [error exception] TypeError: Cannot read properties of undefined (reading 'price')
    at https://m.example.com/assets/index-8f2a.js:1:48213
next since_seq: 57

Troubleshooting

  • "no debuggable WebView found" — the app hasn't enabled WebView debugging, or no WebView is alive yet. Open the H5 page first.

  • "debugger in use" — only one debugger can attach to a page. Close the chrome://inspect DevTools window.

  • "unauthorized" — accept the USB debugging prompt on the device.

Known limitations

  • Debugger-in-use detection is best-effort. It relies on /json/list omitting webSocketDebuggerUrl. Recent Chromium accepts several CDP clients per page, so attach may succeed alongside an open DevTools window; older WebViews may still refuse.

  • list_targets can take ~3s per unresponsive app. Sockets are queried one by one with a 3s timeout, and Android freezes background apps, so their WebView sockets stop answering. attach only re-checks the target's own socket and stays fast.

  • evaluate_js runs with the page's full privileges — it can read cookies, storage and tokens, and change page state. Keep it behind your agent's tool-permission prompt.

  • The e2e script expects port 9333 to be free. If a previous run left a headless Chromium behind, it attaches to that one; kill it first.

Development

The e2e test uses a fake adb and headless Chromium in place of a phone:

npm run build
CHROME=/path/to/chrome npm run test:e2e

Roadmap

  • Discover devices and WebView pages

  • Console messages, uncaught exceptions, browser log entries

  • Network requests and responses

  • JSBridge call logging (configurable bridge shapes)

  • evaluate_js

  • screenshot

  • JSBridge mocking

  • iOS (WKWebView via WebKit Inspector Protocol)

License

MIT

Available Tools

5 tools
attachAttach to a pageA

Connect to a WebView page and start buffering its console output and uncaught exceptions. Recent messages the engine still holds are replayed on attach, but attach before reproducing an issue to be sure nothing is missed.

ParametersJSON Schema
NameRequiredDescriptionDefault
target_idYesTarget id from list_targets

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are given, so the description carries the full behavioral burden. It discloses useful behavior—recent messages are replayed on attach, and attaching before reproduction avoids missing messages—but omits permissions, side effects, idempotency, and whether the operation is reversible. It provides some transparency but leaves key operational traits unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and followed by the key timing caveat. Every sentence earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple one-parameter schema, no annotations, and no output schema, the description covers purpose, behavior, and a critical usage caveat well. It could mention the relationship with detach or get_console for a fuller workflow picture, but it is largely complete for the attach action itself.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%; the sole parameter target_id is fully documented as 'Target id from list_targets'. The description adds no further parameter semantics, so the baseline of 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Connect') and resource ('WebView page'), and describes the exact effect: starting to buffer console output and uncaught exceptions. This distinguishes it from siblings like get_console (read buffered output), detach (stop), and list_targets (discover targets), even without naming them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a clear condition for use: 'attach before reproducing an issue to be sure nothing is missed.' This tells the agent when to invoke it. However, it does not name alternatives (e.g., get_console for reading without buffering) or state when not to use it, so it falls short of the explicit when/when-not/alternatives bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detachDetach from a pageA

Disconnect from a page and discard its buffered events.

ParametersJSON Schema
NameRequiredDescriptionDefault
target_idNoDefaults to the most recently attached page

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It adds valuable non-obvious context that buffered events are discarded, but it does not disclose permissions, reversibility, whether the page is closed, or the effect on other attached clients.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One tight sentence with zero waste. The core action and its most important side effect are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool with no output schema, this covers the basic action and one key side effect. It remains incomplete about whether detaching closes the page, whether it can be reattached, and what a caller should expect afterward.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single optional `target_id` is fully documented in the schema. The description adds no parameter-specific meaning beyond that baseline, which is appropriate here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: "Disconnect from a page." This is clearly the counterpart to the sibling `attach`, though it does not explicitly name that sibling or distinguish itself from `list_targets`/`get_console`.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: call this when you want to disconnect from a page, and the note about discarding buffered events hints at a consequence. However, there is no explicit when-to-use vs. when-not guidance, no mention of `attach`, and no prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evaluate_jsEvaluate JavaScript in a pageA
Destructive

Run a JavaScript expression in an attached page and return its result. Plain objects/arrays come back as JSON (so nested Map/Set/DOM values show as {}); other values (DOM nodes, Map, Set, Error, window) as a short description. Promises are awaited. For multiple statements or await, wrap them: (async () => { ... })(). Runs with the page's full privileges, so it can read cookies/storage and change page state.

ParametersJSON Schema
NameRequiredDescriptionDefault
target_idNoDefaults to the most recently attached page
expressionYesJavaScript expression to evaluate

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond annotations: it discloses that execution runs with the page's full privileges, can read cookies/storage and mutate page state (consistent with destructiveHint=true), awaits promises, and explains how different return types are serialized. This is exactly the behavioral detail annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tightly packed sentences with zero filler, front-loaded with the core action and return contract, then privileges. Every sentence carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full return-value burden and does so thoroughly (JSON for plain objects/arrays, short description for DOM/Map/Set/Error/window). Privilege and mutation scope are also covered, so nothing needed to call or interpret the tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes further by implying the expression parameter must be a single expression and must be wrapped in an async IIFE for statements/await. It adds no extra detail for target_id beyond the schema's own default note.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a JavaScript expression in an attached page and return its result') and is clearly distinct from the siblings (list_targets, attach, get_console, detach). An agent can identify the tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage guidance ('For multiple statements or await, wrap them: (async () => { ... })()') and notes target_id defaults to the most recently attached page. It stops short of naming when-not-to-use or pointing to a sibling such as get_console for log inspection, so no explicit alternatives are offered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_consoleRead console outputA
Read-only

Read buffered console messages, uncaught exceptions and browser log entries from an attached page. Returns the most recent matching entries. Pass since_seq from a previous call to get only new entries.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax entries to return (default 50)
levelsNoOnly these levels, e.g. ["warn", "error"]
keywordNoCase-insensitive substring match on message text and location
since_seqNoOnly entries with seq greater than this
target_idNoDefaults to the most recently attached page
exclude_keywordsNoDrop entries whose text or location contains any of these (case-insensitive), e.g. ["google-analytics", "doubleclick"]

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true already establishes the safety profile, so the description's job is additive context, which it delivers: it discloses that output is buffered, that the most recent matching entries are returned (ordering/truncation behavior), and that since_seq enables incremental retrieval. It omits buffer bounds or whether old entries are evicted, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with zero filler; the core purpose is front-loaded and the incremental-fetch hint follows naturally. Every sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, six-parameter tool with a fully described schema and no output schema, the description covers purpose, return ordering, and the key incremental pattern. It leaves the attach prerequisite and buffer-eviction behavior unstated, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so levels, keyword, exclude_keywords, limit, and target_id are fully documented in the schema itself. The description only elaborates on since_seq, which is already explained in the schema, so it adds little beyond the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Read) and precise resource (buffered console messages, uncaught exceptions, browser log entries) scoped to 'an attached page'. The resource is naturally distinct from siblings like attach/detach/evaluate_js, but the description never explicitly contrasts itself with them, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one concrete usage pattern: 'Pass since_seq from a previous call to get only new entries,' which is genuinely actionable for incremental polling. However, there is no when-not guidance, no prerequisites (e.g. must a page be attached first?), and no mention of alternatives, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_targetsList WebView pagesA
Read-only

List debuggable H5 pages running inside Android WebViews (and Chrome) on connected devices. Returns a target id for each page to pass to attach.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint annotation already declares this is a safe read. The description adds real behavioral value beyond that: it scopes the result set (WebView/Chrome pages on connected devices) and discloses the shape of what comes back (a target id per page for attach). It stops short of covering failure modes like no connected devices.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with what gets listed and followed by the one fact an agent needs next (the returned target id feeds attach). No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-arg listing tool with an annotation covering its safety profile, this covers purpose, scope, and the handoff to attach without an output schema. Minor omissions (empty-result behavior, whether filtering exists) do not block correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the schema imposes no burden; the baseline for a no-param tool is 4. The description appropriately says nothing about arguments rather than padding with irrelevant detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and a precise resource ('debuggable H5 pages running inside Android WebViews (and Chrome) on connected devices'), and it names the follow-up sibling action ('pass to attach'). An agent can distinguish this from attach/detach/evaluate_js immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the usage context clear implicitly by tying the output to the 'attach' step, so an agent knows to call this before attaching. It does not state when-not to use it or mention alternatives, keeping it short of full explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.1.1
    • First observedattach
    • First observeddetach
    • First observedevaluate_js
    • First observedget_console
    • First observedlist_targets

TDQS

A4.1/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a distinct step in the debug session: list_targets discovers pages, attach connects, get_console reads buffered logs, evaluate_js executes code, and detach disconnects. There is no meaningful overlap between any pair; an agent can select unambiguously.

Naming Consistency4/5

The dominant pattern is verb_noun (list_targets, get_console, evaluate_js), which is clean and readable. attach and detach are bare verbs, a minor but explainable deviation since their object is implied by the session model.

Tool Count5/5

Five tools is exactly right for a focused WebView debugging workflow — one per lifecycle stage with no filler. Nothing feels padded or missing at the count level.

Completeness4/5

The full core loop (discover, attach, observe console, evaluate JS, detach) is covered, including sequence-based log polling, so agents won't hit dead ends. Secondary debugging surfaces like network inspection, screenshots, or device-level listing are absent but not essential to the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables remote control of Android devices via ADB, including screen operations, input, app management, file transfer, and advanced tools like UI testing and performance analysis.
    25
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables an agent to inspect and interact with Android emulators or physical devices via ADB, capturing UI snapshots, tapping nodes, typing text, and reading app logs.
    10
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables debugging Flutter apps on Android by exposing the widget tree and source locations, supporting hot reload and pixel-level UI diffs, along with filtered Android logs, crash traces, and device interaction.
    26
    22 PyPI
    MIT