# io.github.Dayananda-D/devcdp (npm · devcdp)

Chrome DevTools for AI assistants: console, network, DOM, source maps, breakpoints, live variables.

- Trust score: 84/100 (high trust)
- Change this week: +2
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-17

## Components

- npm · `devcdp`: 84/100 (this document), [markdown](https://verifymcp.io/servers/dayananda-d-devcdp/devcdp.md), [page](https://verifymcp.io/servers/dayananda-d-devcdp/devcdp)

## Channel facts

- Registry: `npm`
- Package: `devcdp`
- Version: `5.0.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-17.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 31 of 95 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 37 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 76/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 9569 tokens (~129/item across 74 items; 74 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 100/100
  - No destabilizing schema changes in the last 30 days.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 2 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 74 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the io.github.Dayananda-D/devcdp MCP server?

io.github.Dayananda-D/devcdp runs locally as an npm package, launched with npx -y devcdp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add dayananda-d-devcdp -- npx -y devcdp
```

### Cursor

```json
{
  "mcpServers": {
    "dayananda-d-devcdp": {
      "command": "npx",
      "args": [
        "-y",
        "devcdp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "dayananda-d-devcdp": {
      "command": "npx",
      "args": [
        "-y",
        "devcdp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add dayananda-d-devcdp -- npx -y devcdp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "dayananda-d-devcdp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "devcdp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add dayananda-d-devcdp --command npx --arg -y --arg devcdp
```

### Hermes

```yaml
mcp_servers:
  dayananda-d-devcdp:
    command: "npx"
    args: ["-y", "devcdp"]
```

### Netclaw

```json
{
  "McpServers": {
    "dayananda-d-devcdp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "devcdp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add dayananda-d-devcdp -t stdio -c npx -a -y devcdp
```

### Other

```json
{
  "mcpServers": {
    "dayananda-d-devcdp": {
      "command": "npx",
      "args": [
        "-y",
        "devcdp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-17 (score 84, 0)

- [security] Stability: 0.97 → pass

### 2026-10-16 (score 84, +1)

No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-14 (score 83, +1)

No change was recorded against any check on this day. Stability & Change Management went from 87 to 90. That category is still filling its 30-day observation window: 26 days of observed history at the previous scan, 27 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-13 (score 82, 0)

- [functional regression] Security disclosure: unverified → fail

### 2026-10-12 (score 82, +16)

- [security improvement] Malware scan: unverified → pass

### 2026-10-11 (score 66, −16)

- [security regression] Malware scan: pass → unverified
- [functional regression] Security disclosure: fail → unverified

### 2026-10-04 (score 82, +1)

No change was recorded against any check on this day. Stability & Change Management went from 80 to 83. That category is still filling its 30-day observation window: 24 days of observed history at the previous scan, 25 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-02 (score 81, +1)

No change was recorded against any check on this day. Stability & Change Management went from 73 to 77. That category is still filling its 30-day observation window: 22 days of observed history at the previous scan, 23 at this one. The score rises as the window fills, whether or not the server changes.

## MCP tools (74)

### `workflow_guide` (~54 tokens)

How to use DevCDP effectively: the observe/act division of labour, the fastest path from a bug report to an exact line, and the traps worth knowing. Call it once at the start of a debugging session.

### `devtools_connect` (~214 tokens)

Attach to a Chrome tab over the DevTools Protocol and start observing it (console, network, DOM, debugger). Claims the tab so no other DevCDP session can drive it, marks it visibly in the browser, and reports what was loaded before we attached. Call this once at the start of a debugging session.

Input parameters:

- `allow_new_tab` (boolean): If every tab is already claimed by another session, open a new one instead of failing.
- `browser` (string): 'new' launches a separate isolated Chrome on the next free port — a browser no other session has touched.
- `host` (string): Chrome host.
- `port` (number): Chrome remote-debugging port.
- `target` (string): 'visible' (the tab on screen) | 'url-match:<substring>' | 'index:<n>' from list_tabs | 'new' | a URL substring.
- `window` (string): 'new' gives this session its own browser window — the fallback when Chrome tab groups are unavailable.

### `devtools_status` (~46 tokens)

Connection health and buffer accounting: which tab is attached, how many console/network/script entries are held, whether the debugger is paused, and whether anything has been evicted from the buffers.

### `devtools_disconnect` (~57 tokens)

Detach cleanly: resume the page if it is paused at a breakpoint, remove every breakpoint we set, remove the in-page badge, and release the tab claim so another session can use it. Always call this when you are done.

### `list_tabs` (~99 tokens)

List the debuggable tabs in Chrome with their index, title, URL, whether each is the visible one, and which DevCDP session (if any) currently owns it. Use the index with target:'index:<n>' in devtools_connect.

Input parameters:

- `host` (string): Chrome host.
- `port` (number): Chrome remote-debugging port.
- `probe` (boolean): Check which tab is really visible (one extra round trip).

### `sessions_list` (~49 tokens)

Show every DevCDP session currently running on this machine and the tabs each one holds. Use it to understand why a tab is unavailable, or to confirm two agents are not fighting over the same page.

### `page_navigate` (~63 tokens)

Navigate the attached tab to a URL. Returns as soon as the navigation is committed, not when loading finishes — wait for a specific request with network_wait_for_request, or for text with Playwright, before asserting.

Input parameters:

- `url` (string, required): Absolute URL to open.

### `page_interrupt` (~84 tokens)

Abort the JavaScript the page is currently running. Use it when a tool reports PAGE_UNRESPONSIVE — an infinite loop or a long synchronous task has blocked the main thread. This is the only thing that frees it: reloading and navigating do not, because the blocked thread never processes them. The page keeps its DOM and state; only the in-flight script is killed.

### `page_reload` (~58 tokens)

Reload the attached tab. Useful right after attaching, because console history and network traffic from before the attach cannot be recovered — a reload replays everything with DevCDP watching.

Input parameters:

- `bypass_cache` (boolean): Ignore the HTTP cache (hard reload).

### `console_get_logs` (~170 tokens)

Read console output captured since attach: logs, warnings, uncaught exceptions with file, line and stack. Pass cursor=nextCursor from a previous call to get only what is new. Note that Chrome does not replay messages logged before DevCDP attached — reproduce the action or call page_reload to see those.

Input parameters:

- `clear` (boolean): Empty the buffer after reading.
- `cursor` (number): Return only entries with seq greater than this. 0 for everything held.
- `include_agent` (boolean): Include DevCDP's own diagnostics, normally hidden so they cannot be mistaken for app errors.
- `level` (string): Only this level.
- `limit` (number): Maximum entries to return (most recent first in the buffer order).
- `since` (string): ISO timestamp lower bound.

### `console_evaluate` (~117 tokens)

Run a JavaScript expression in the page and return its value. On failure returns the full exception detail (message, 1-based line and column, URL, stack). Use it to read app state; use debugger_evaluate_at_frame instead when you are paused and need a local variable.

Input parameters:

- `await_promise` (boolean): Await the result if the expression returns a promise.
- `expression` (string, required): JavaScript to evaluate in the page's main frame.
- `timeout_ms` (number): Abandon the evaluation after this long.

### `runtime_evaluate_many` (~87 tokens)

Evaluate several named expressions in one round trip and get a map of name to result. Use it to sample a lot of app state at once instead of paying a round trip per question. Individual failures are reported per entry rather than aborting the batch.

Input parameters:

- `await_promise` (boolean): Await promise results.
- `expressions` (array, required): Array of { name, expression } objects.

### `console_clear` (~39 tokens)

Empty the console buffer so that what you read next belongs only to the action you are about to take. Does not touch the browser's own console display.

### `network_get_requests` (~254 tokens)

List HTTP requests captured since attach, with method, status, duration, size and initiator. Filter by URL substring, method, status or failures only. Response bodies are opt-in via include_bodies because they are large. Capture starts when DevCDP attaches, so requests from before that are not here — reload to see them.

Input parameters:

- `failed_only` (boolean): Only network failures and 4xx/5xx responses.
- `include_bodies` (boolean): Include response bodies, subject to max_body_bytes.
- `include_headers` (boolean): Include request and response headers.
- `include_post_data` (boolean): Include request payloads.
- `limit` (number): Maximum requests to return.
- `max_body_bytes` (number): Per-body byte cap when include_bodies is set.
- `method` (string): Only this HTTP method, e.g. POST.
- `min_status` (number): Only responses with status >= this, e.g. 400 for problems.
- `offset` (number): Skip this many of the newest matches, for paging back in time.
- `status` (number): Only this exact response status.
- `url_filter` (string): Only requests whose URL contains this substring.

### `network_wait_for_request` (~131 tokens)

Block until a request whose URL contains url_filter completes, then return it. Event driven, so there is no polling. Call this immediately AFTER triggering the action, or pass a filter that has not fired yet — a request that already completed is returned straight away. Gives up after timeout_ms and tells you so.

Input parameters:

- `allow_existing` (boolean): Satisfy immediately from an already-completed matching request.
- `method` (string): Also require this HTTP method.
- `timeout_ms` (number): Give up after this long.
- `url_filter` (string, required): Substring the request URL must contain.

### `network_get_response_body` (~98 tokens)

Fetch the full response body for one requestId from network_get_requests. Chrome discards bodies when the page navigates, so read them while the page is still on the same document.

Input parameters:

- `max_body_bytes` (number): Byte cap; 0 means no limit.
- `requestId` (string): Deprecated spelling of request_id; both work.
- `request_id` (string): The requestId field from a network_get_requests row.

### `network_clear` (~39 tokens)

Empty the network buffer so the next thing you read belongs only to the action you are about to take. Does not affect the browser's own Network panel.

### `dom_query` (~222 tokens)

Query elements by CSS selector and return tag, id, classes, text, attributes, geometry and real visibility. Ask for computed styles by naming the properties you want. Set frame:'all' to search inside iframes too — single-page apps often render the screen you care about in a child frame.

Input parameters:

- `fields` (array): Restrict the returned keys, e.g. ['tag','id','text','visible'].
- `frame` (string): 'main' (default), 'all', or a substring of a frame's origin/name.
- `include_attrs` (boolean): Include every HTML attribute of each match. Off by default: attributes dominate the response on real apps.
- `include_html` (boolean): Include a truncated outerHTML for each match.
- `limit` (number): Maximum elements to return.
- `selector` (string, required): CSS selector.
- `styles` (array): Computed style properties to read, e.g. ['display','zIndex','color'].
- `visible_only` (boolean): Drop elements that are not actually rendered.

### `dom_list_frames` (~48 tokens)

List the frames and JavaScript execution contexts in the attached tab. Use it when a selector finds nothing — the content may live in an iframe, which needs frame:'all' on dom_query.

### `dom_get_html` (~99 tokens)

Get the inner or outer HTML of the first element matching a selector, truncated to a byte budget. Useful for understanding structure you cannot infer from dom_query alone.

Input parameters:

- `frame` (string): 'main' (default), or a substring of a frame's origin/name.
- `inner` (boolean): innerHTML instead of outerHTML.
- `max_bytes` (number): Truncate beyond this many characters.
- `selector` (string, required): CSS selector.

### `dom_get_mutations` (~87 tokens)

DOM changes recorded since the last call — what was added, removed or re-attributed, and where. Use it after an action to see whether the app re-rendered at all, which distinguishes 'handler never ran' from 'handler ran and produced nothing'.

Input parameters:

- `clear` (boolean): Drain the buffer as you read it.
- `limit` (number): Maximum records to return.

### `dialog_detect` (~92 tokens)

Detect modal dialogs, alerts and confirmation overlays that are visible right now, with their title, message and button labels. Detection is structural — ARIA roles, the dialog element, and stacked-overlay geometry — so it works regardless of which UI framework drew it. Call it after any action that might raise a prompt.

Input parameters:

- `frame` (string): 'main' (default) or 'all' to include iframes.

### `ui_click` (~348 tokens)

Click an element, identified by CSS selector, visible text or test id. Waits until it is actually clickable — rendered, enabled, stopped moving, and not covered by anything — then dispatches real (trusted) mouse events, and reports what the click caused: requests fired, console errors, whether the DOM changed at all. If it never became clickable it says which of those conditions failed and what was in the way.

Input parameters:

- `button` (string): Which mouse button.
- `click_count` (number): 2 for a double-click.
- `exact` (boolean): Require the whole text to match rather than a substring.
- `force` (boolean): Skip the hit-test and click the centre regardless of what is on top. A last resort — it is how you click the wrong thing.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `modifiers` (array): Held while clicking: shift, ctrl, alt, meta.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_hover` (~234 tokens)

Move the pointer over an element and leave it there. Use before clicking anything that only appears on hover — dropdown menus, row action buttons, tooltips — because those elements do not exist to click until something is hovering over their parent.

Input parameters:

- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_drag` (~203 tokens)

Drag one element onto another — reordering rows, moving a card between columns, resizing a split. Dispatches a real press, several intermediate moves and a release, because drag implementations almost always ignore a press followed immediately by a release somewhere else.

Input parameters:

- `frame` (string): 'main' (default) or a substring of a frame's origin/name.
- `selector` (string): CSS selector for what to drag.
- `steps` (number): Intermediate move events. More is slower but survives pickier drag handlers.
- `testid` (string): Test id of what to drag.
- `text` (string): Visible text of what to drag.
- `timeout_ms` (number): How long to wait for either element to become actionable.
- `to_selector` (string): CSS selector for where to drop it.
- `to_testid` (string): Test id of where to drop it.
- `to_text` (string): Visible text of where to drop it.

### `ui_scroll` (~178 tokens)

Scroll the page, or scroll a specific container. Needed before interacting with anything in a virtualised list or grid, where rows outside the viewport do not exist in the DOM at all — scrolling is what creates them.

Input parameters:

- `dx` (number): Horizontal pixels; positive is right.
- `dy` (number): Vertical pixels; positive is down.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name.
- `selector` (string): CSS selector of the container to scroll. Omit to scroll the page.
- `testid` (string): Test id of the container to scroll.
- `text` (string): Visible text inside the container to scroll.
- `timeout_ms` (number): How long to wait for the container.
- `to` (string): Jump instead of scrolling by an amount.

### `ui_press` (~338 tokens)

Press a key — Enter to submit, Tab to move on, Escape to dismiss, arrows to move through a list or grid. Optionally focuses an element first. This is the tool for keyboard-driven screens, where clicking the control is not how the application expects to be used.

Input parameters:

- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `key` (string, required): Key name: Enter, Tab, Escape, Backspace, Delete, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Home, End, PageUp, PageDown, Space.
- `modifiers` (array): Held while pressing: shift, ctrl, alt, meta.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots. Optional: focuses this element first.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting). Optional: focuses this element first.
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input. Optional: focuses this element first.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.
- `times` (number): Press it this many times.

### `ui_fill` (~360 tokens)

Set the value of a text field, textarea or contenteditable in one step: assign it and fire input and change. Fast, and it does NOT go through the browser's key-event pipeline — no keydown, no keypress — so the field's own input rules never run. maxlength, digits-only keypress guards and input masks are all bypassed, which is exactly what you want to put a value past a mask and test what happens downstream, and exactly what you do not want when reproducing what a user did: it can leave the field in a state the UI itself would not allow. Use ui_type for that, and for anything reacting per keystroke such as a typeahead.

Input parameters:

- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `submit` (boolean): Press Enter afterwards.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.
- `value` (string, required): The text to put in the field. Pass an empty string to clear it.

### `ui_type` (~367 tokens)

Type into a field one character at a time with real key events, through the same input pipeline a person's keyboard uses — so the field's own rules apply: maxlength truncates, a keypress guard rejects what it rejects, and a mask reformats as it goes. This is the tool for reproducing user behaviour, and for anything reacting per keystroke: search-as-you-type, autocomplete, validation-on-key. Slower than ui_fill by design. Note that typing leaves the field focused and `change` fires on blur, so pass submit:true (or press Tab) when the application validates on change.

Input parameters:

- `clear_first` (boolean): Select all and delete before typing.
- `delay_ms` (number): Pause between keystrokes. Raise it if the field drops characters.
- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `submit` (boolean): Press Enter afterwards.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `text_to_type` (string, required): Characters to type.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_select` (~286 tokens)

Choose an option in a dropdown, by visible label or by value. Handles a native <select> directly; for the custom dropdowns most applications actually use — a div that opens a list — it opens the control and clicks the matching option. Reports the options it could see when nothing matches, which is usually the whole answer.

Input parameters:

- `by` (string): Match the label, the value, or either.
- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `option` (string, required): The option's visible label, or its value attribute.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_check` (~254 tokens)

Set a checkbox or radio to a specific state, rather than toggling it blindly. Reads the current state first and clicks only if it differs, so calling it twice does not undo the first call — the usual way a 'toggle' helper leaves a form in the wrong state.

Input parameters:

- `checked` (boolean): The state you want.
- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_upload` (~240 tokens)

Attach one or more local files to a file input, without opening the operating system's file picker — which automation cannot drive at all. Give the absolute paths of files on the machine running Chrome.

Input parameters:

- `exact` (boolean): Require the whole text to match rather than a substring.
- `files` (array, required): Absolute paths to the files to attach.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_wait_for` (~303 tokens)

Block until the page reaches a state: an element appears, disappears, becomes enabled, or some text shows up. This is the honest alternative to guessing a sleep — it returns as soon as the condition holds, and when it does not, it says what the page looked like instead of just timing out.

Input parameters:

- `contains_text` (string): Also require the element to contain this text.
- `exact` (boolean): Require the whole text to match rather than a substring.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name. Single-page apps often render the screen you want in a child frame.
- `nth` (number): Which match to use when several qualify, 0-based.
- `role` (string): Narrow the matches to this ARIA role.
- `selector` (string): CSS selector. Descends into open shadow roots.
- `state` (string): What to wait for: 'visible' (default), 'hidden', 'enabled', 'detached', or 'stable' (present and no longer moving).
- `testid` (string): Value of a test attribute (data-testid and friends — see the testAttributes setting).
- `text` (string): Visible text on the control. Matches the innermost element that carries it, and follows a <label> to its input.
- `timeout_ms` (number): How long to wait for the element to become actionable before giving up.

### `ui_inspect` (~148 tokens)

List what can be interacted with on the current screen — buttons, links, inputs, selects and anything with an interactive ARIA role — with the target you would use to reach each one. Use it when a selector fails and you need to see what is really there. Far cheaper than dumping the DOM, and it names elements the way these tools expect them to be named.

Input parameters:

- `filter` (string): Only controls whose text, id or name contains this.
- `frame` (string): 'main' (default) or a substring of a frame's origin/name.
- `kind` (string): Restrict to one family of control.
- `limit` (number): Maximum controls to return.

### `page_screenshot` (~405 tokens)

Capture what is on screen: the viewport, the whole scrollable page, one element, or an explicit rectangle. Name the element the same way as the ui_* tools — by CSS selector, by the text a person reads, or by test id — so snipping a region does not require working out coordinates. DevCDP's own badge and messages are hidden first, so the image shows the application and nothing else. Written to a file and returned as a path; pass inline:true when you need to look at it yourself, which costs a great deal of context.

Input parameters:

- `format` (string): Image format. jpeg is far smaller for photographic content; png is exact.
- `full_page` (boolean): Capture the whole scrollable page, not just the viewport. Ignored when a target or rect is given.
- `hide_overlay` (boolean): Hide DevCDP's badge and messages for the capture. Turn off only when the overlay itself is what you are looking at.
- `inline` (boolean): Also return the image itself so you can see it. Expensive — a large capture can cost more context than every tool description combined.
- `max_width` (number): Scale the capture down to at most this many pixels wide. Keeps a full-page shot to a sane size.
- `nth` (number): Which match to use when several qualify, 0-based.
- `quality` (number): 1-100, for jpeg and webp only.
- `rect` (object): Explicit page-coordinate region { x, y, width, height }. Overrides any element target.
- `save_to` (string): Absolute path to write to. Defaults to a timestamped file in the screenshotDir setting.
- `selector` (string): CSS selector of the element to capture. Descends into open shadow roots.
- `testid` (string): Test attribute value of the element to capture.
- `text` (string): Visible text of the element to capture.

### `source_list_scripts` (~106 tokens)

List the JavaScript files loaded in the page, with size and whether each has a source map. This is indexed the moment DevCDP attaches, so it works on a page that was already open. Filter by URL substring to find the file you need before setting a breakpoint.

Input parameters:

- `filter` (string): Only scripts whose URL contains this substring.
- `limit` (number): Maximum scripts to return.
- `with_source_maps` (boolean): Only scripts that carry a source map.

### `source_search` (~169 tokens)

Search the text of every loaded script — and every original file recoverable from source maps — for a string or regular expression. This is the fastest way to locate a handler when you know a function name, a message or a field name but not the file. Returns file, 1-based line and the matching line.

Input parameters:

- `context_chars` (number): Characters of the matching line to return.
- `ignore_case` (boolean): Case-insensitive search.
- `include_original_sources` (boolean): Also search original files from source maps.
- `max_results` (number): Stop after this many matches.
- `query` (string, required): Text or regular expression to find.
- `regex` (boolean): Treat query as a regular expression.
- `url_filter` (string): Only search scripts whose URL contains this.

### `source_get_script` (~102 tokens)

Read the source Chrome actually loaded, by scriptId or URL substring, optionally a line range. Lines come back numbered so the numbers you quote to a breakpoint are the numbers you saw.

Input parameters:

- `end_line` (number): Last line to return (1-based).
- `script_id` (string): scriptId from source_list_scripts.
- `start_line` (number): First line to return (1-based).
- `url` (string): URL substring identifying the script.

### `source_list_files` (~75 tokens)

List the original source files recoverable from the page's source maps — the pre-bundling file tree. Use it to discover real file paths before calling source_get_file or setting a breakpoint on an original file.

Input parameters:

- `filter` (string): Only paths containing this substring.
- `limit` (number): Maximum paths to return.

### `source_get_file` (~116 tokens)

Read an original pre-bundling source file via the page's source maps. Falls back to the loaded script when no map is available, and always tells you which of the two you got, so a bundle line is never mistaken for an original one.

Input parameters:

- `end_line` (number): Last line to return (1-based).
- `path` (string, required): Original file path or a suffix of it, e.g. 'components/SaveButton.tsx'.
- `start_line` (number): First line to return (1-based).

### `debugger_set_breakpoint` (~223 tokens)

Set a breakpoint and report honestly whether Chrome could bind it. Accepts either a loaded script URL (a substring is resolved to the exact script) or an original pre-bundling file path, which is translated through the source map. Set auto_resume:true when the action is being driven by an automation tool, so the page does not stay frozen and time that action out.

Input parameters:

- `auto_resume` (boolean): Default true: capture scope/console/network on hit, then resume, so the page is never left frozen and the action that tripped it completes. Pass false to hold the pause for stepping; released after m…
- `column` (number): 1-based column, when several statements share a line.
- `condition` (string): JavaScript condition — pause only when it is truthy, e.g. 'id === 42'.
- `line` (number, required): 1-based line number, as shown by source_get_script / source_get_file.
- `url` (string, required): Script URL, URL substring, or original source path.

### `debugger_set_breakpoint_at_function` (~209 tokens)

Set a breakpoint on a function you can name, without knowing which file it lives in. Give any expression that evaluates to a function — 'app.saveOrder', 'MyClass.prototype.load', a framework helper — and DevCDP finds its definition and breaks at its first statement. Use this when you know what runs but not where it is defined; use debugger_set_breakpoint when you already have a file and line.

Input parameters:

- `auto_resume` (boolean): Default true: capture scope/console/network on hit, then resume, so the page is never left frozen and the action that tripped it completes. Pass false to hold the pause for stepping; released after m…
- `condition` (string): JavaScript condition — pause only when it is truthy, e.g. 'id === 42'.
- `function_expression` (string, required): JavaScript evaluating to the function itself — no call parentheses. For example 'app.store.save', not 'app.store.save()'.

### `debugger_list_breakpoints` (~49 tokens)

List the breakpoints DevCDP has set, including whether each is actually bound to executable code. An unbound breakpoint will never fire — check here first when a breakpoint 'is not hitting'.

### `debugger_remove_breakpoint` (~46 tokens)

Remove one breakpoint by its breakpointId. Use debugger_remove_all_breakpoints to clear them in one call.

Input parameters:

- `breakpoint_id` (string, required): breakpointId from debugger_set_breakpoint.

### `debugger_remove_all_breakpoints` (~49 tokens)

Remove every breakpoint DevCDP set, and resume the page if it is currently paused. Call this before handing the browser back to a human, so they do not find a frozen app.

### `debugger_pause` (~64 tokens)

Pause JavaScript execution at the next statement the page runs, and hold it so you can inspect and step. The page is frozen while held, so DevCDP releases it automatically after maxPauseMs if you have not resumed — no human ever has to press resume in Chrome.

### `debugger_resume` (~45 tokens)

Resume execution and drop any hold. Breakpoints resume themselves by default, so this is only needed after an explicit pause, after stepping, or after a breakpoint set with auto_resume:false.

### `debugger_step_over` (~74 tokens)

Step over from the current pause and stop at the next statement. Stepping implies you want the pause held, so it will not auto-resume between steps — but it is still released automatically after maxPauseMs if you stop. The new location and scope are available from debugger_get_state and debugger_get_scope once it settles.

### `debugger_step_into` (~74 tokens)

Step into from the current pause and stop at the next statement. Stepping implies you want the pause held, so it will not auto-resume between steps — but it is still released automatically after maxPauseMs if you stop. The new location and scope are available from debugger_get_state and debugger_get_scope once it settles.

### `debugger_step_out` (~74 tokens)

Step out from the current pause and stop at the next statement. Stepping implies you want the pause held, so it will not auto-resume between steps — but it is still released automatically after maxPauseMs if you stop. The new location and scope are available from debugger_get_state and debugger_get_scope once it settles.

### `debugger_get_state` (~43 tokens)

Where execution is paused right now: the reason, and the full call stack with function names and 1-based file positions. Returns paused:false when the page is running.

### `debugger_get_scope` (~134 tokens)

Read the variables in scope at a paused call frame, with objects and arrays expanded rather than printed as 'Object'. Includes `this`. Anything omitted for size is explicitly marked, so you never have to guess whether you saw the whole value.

Input parameters:

- `depth` (number): How many levels of nested objects to expand. 3 covers object → array → record.
- `frame_index` (number): 0 is the innermost frame; see debugger_get_state for the stack.
- `include_global` (boolean): Include the global scope (thousands of properties).
- `max_properties` (number): Maximum properties per object.

### `debugger_evaluate_at_frame` (~95 tokens)

Evaluate an expression in the scope of a paused call frame, so local variables and closures are in scope. This is how you confirm a hypothesis with a real value rather than inferring one.

Input parameters:

- `depth` (number): How deep to expand an object result.
- `expression` (string, required): JavaScript evaluated in the frame's scope.
- `frame_index` (number): Which frame; 0 is innermost.

### `debugger_get_capture` (~64 tokens)

Everything captured automatically at the last breakpoint hit — scope for the top frames, recent console output and recent network requests — in one call instead of four. Tells you whether the pause is still current or has already resumed, so a stale snapshot is never mistaken for live state.

### `notify_user` (~91 tokens)

Show a short status line to the human, in the badge on the page you are debugging. This is the only channel the user actually sees — call it before a slow or surprising step so a frozen-looking app is explained. Keep it to a few words.

Input parameters:

- `action` (string, required): What you are doing.
- `detail` (string, required): Short human-readable detail, e.g. 'checking the save handler'.

### `session_start` (~100 tokens)

Open a debugging session with a goal and an ordered list of steps, so progress is tracked and a failed step can fall back to asking the human. Use it for multi-step reproductions; a single-question investigation does not need it.

Input parameters:

- `goal` (string, required): What you are trying to find out or prove.
- `steps` (array, required): Ordered steps, each { id, description, actor }. actor is 'agent', 'user' or 'either'.

### `session_step_done` (~56 tokens)

Mark the current step complete with what you found, and advance. Returns the next step, or allDone when the plan is finished.

Input parameters:

- `result` (string): What this step established — a real observed value, not a guess.

### `session_step_failed` (~76 tokens)

Report that you cannot complete the current step yourself. Checks memory for a known recovery first, then tells you how to hand over to the human. Use it for anything automation genuinely cannot do — a login you have no credentials for, a challenge, a physical device.

Input parameters:

- `reason` (string, required): Why the step could not be completed.

### `session_ask_user` (~115 tokens)

Ask the human to do something in the browser, and show the request in the on-page badge with a confirmation button. Returns immediately — poll session_poll_user_action for the outcome. Also relay the instruction in your reply, so it is visible whether or not they are looking at the browser window.

Input parameters:

- `instruction` (string, required): Exactly what the person should do, in one sentence.
- `wait_for` (string): What counts as done. 'confirmation' — the on-page button — is the only unambiguous one.

### `session_poll_user_action` (~47 tokens)

Check whether the human has completed what session_ask_user requested. Returns acted:false while waiting. Poll at a human pace — a few seconds apart — rather than in a tight loop.

### `session_get_user_actions` (~134 tokens)

What the human has done in the browser — clicks, typed values, chosen options, submissions — and the element each one touched. Works whether or not you asked, so unprompted help is still readable. Pass the cursor back for only what is new. Values are captured during a handover or takeover; sensitive fields stay redacted.

Input parameters:

- `cursor` (number): Only actions newer than this seq. 0 for everything retained.
- `kinds` (array): Restrict to these kinds, e.g. ['click','input_change','option_chosen'].
- `limit` (number): Maximum actions to return.

### `session_get_activity` (~83 tokens)

Unified timeline of everything observed in this session — console output, requests, navigations, dialogs, clicks, pauses and handovers, in order. Use it to reconstruct what happened when a step behaved unexpectedly.

Input parameters:

- `limit` (number): Maximum entries.
- `since` (string): ISO timestamp lower bound.
- `types` (array): Restrict to these activity types.

### `session_get_status` (~37 tokens)

Where the session plan stands: the goal, each step's status, which step is current, and whether a human handover is outstanding.

### `session_end` (~41 tokens)

Close the session and return a summary. Does not detach — call devtools_disconnect to release the tab and clear breakpoints when you are finished with the browser entirely.

### `session_get_state` (~140 tokens)

One snapshot of console output, network requests and DOM mutations together, instead of three separate calls. Pass the cursors back on the next call to get only what is new. This is the cheapest way to see the effect of an action.

Input parameters:

- `errors_only` (boolean): Restrict console to warnings and errors, and network to failures.
- `log_cursor` (number): Only console entries newer than this seq.
- `log_limit` (number): Maximum console entries.
- `mut_limit` (number): Maximum DOM mutation records.
- `net_filter` (string): Only requests whose URL contains this.
- `net_limit` (number): Maximum network requests.

### `memory_get` (~143 tokens)

Look up what previous sessions learned about this app — failures and the recovery that worked. Returns short summaries so it is cheap to call at the start of a session; pass full:true or an id to read one in detail. Search it whenever a step fails, before asking the user for help.

Input parameters:

- `category` (string): Restrict to one category.
- `full` (boolean): Return complete entries instead of summaries.
- `id` (string): Return this single entry in full.
- `limit` (number): Maximum entries to return.
- `query` (string): Words to match against category, failure, recovery, pattern or URL. Omit for the most recent.

### `memory_record` (~196 tokens)

Record a failure and the recovery that worked, so a later session can skip the dead end. Call it after any user-assisted recovery or non-obvious workaround. All four fields are required and validated — a vague entry is worse than none, because it costs context on every future lookup.

Input parameters:

- `category` (string, required): What kind of problem this was.
- `failure` (string, required): What went wrong, concretely. e.g. 'Clicking Save did nothing because the form was still validating.'
- `pattern` (string, required): The reusable rule for next time. e.g. 'Wait for the validation spinner to clear before clicking Save.'
- `recovery` (string, required): What actually resolved it, as steps someone could repeat.
- `shared` (boolean): Write to the shared team store instead of local, if one is configured.
- `url_pattern` (string): URL substring this applies to, so it can be matched to a page later.

### `memory_import_legacy` (~62 tokens)

One-off import of a v4 Markdown memory file into the current store, skipping the malformed entries v4's missing validation produced. Run once after upgrading, then delete the old file.

Input parameters:

- `path` (string, required): Full path to the old memorymanagement.md.

### `app_discover` (~65 tokens)

Ask the running page what it is: which UI libraries it uses, how it routes, how many frames it has, and its actual interactive surface — visible buttons, fields, grids and tabs with working selectors. Call this once before driving an unfamiliar app, instead of guessing selectors.

### `api_discover` (~115 tokens)

Build a map of the backend the page actually talks to: endpoints grouped with ids collapsed, call counts, status codes, timings and failures — plus an OpenAPI/Swagger specification if the server publishes one at a standard path. Use it to understand the API surface, and to see at a glance which calls are failing.

Input parameters:

- `include_static` (boolean): Include scripts, styles, images and fonts, not just data calls.
- `probe_openapi` (boolean): Also try standard OpenAPI discovery paths on the page's origin.

### `docs_search` (~129 tokens)

Search the project's own documentation — README and any markdown/text/pdf docs under the configured docs root — and return matching passages with file and line. Use it to learn what a screen, field or business term means in this app, instead of inferring it from the UI. Set docsRoot in your settings file if the docs live elsewhere.

Input parameters:

- `context_lines` (number): Lines of surrounding context per hit.
- `max_results` (number): Maximum passages to return.
- `query` (string, required): Words or a phrase to look for.
- `root` (string): Override the docs root for this call.

### `docs_outline` (~75 tokens)

List the documentation available under the docs root, with each file's headings, so you can see what the project documents before searching. A good first call when you do not yet know the app's vocabulary.

Input parameters:

- `max_files` (number): Maximum files to describe.
- `root` (string): Override the docs root for this call.

### `devcdp_settings` (~99 tokens)

Show every DevCDP setting: its effective value, where that value came from (default, which settings file, or which environment variable), which files were searched and loaded, and any that failed to parse or were not recognised. Use it before changing configuration, and to check a change actually took effect.

Input parameters:

- `changed_only` (boolean): Only settings that are not at their default.
- `group` (string): Only one group of settings.

### `devcdp_settings_init` (~83 tokens)

Write a settings file containing every option with its current value and an explanation, so it can be edited by hand. Refuses to overwrite an existing file unless you say so.

Input parameters:

- `overwrite` (boolean): Replace the file if it already exists.
- `path` (string): Where to write it. Defaults to devcdp.settings.json in the install directory.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/dayananda-d-devcdp/devcdp#diagnostics

## Score history

- 2026-10-17: 84
- 2026-10-16: 84
- 2026-10-15: 83
- 2026-10-14: 83
- 2026-10-13: 82
- 2026-10-12: 82
- 2026-10-11: 66
- 2026-10-04: 82
- 2026-10-03: 81
- 2026-10-02: 81
- 2026-10-01: 80
- 2026-09-30: 80
- 2026-09-29: 79
- 2026-09-28: 79
- 2026-09-27: 78
- 2026-09-26: 78
- 2026-09-25: 78
- 2026-09-24: 77
- 2026-09-23: 77
- 2026-09-22: 76
- 2026-09-21: 76
- 2026-09-20: 75
- 2026-09-19: 75
- 2026-09-18: 74
- 2026-09-17: 74
- 2026-09-16: 70
- 2026-09-15: 70
- 2026-09-14: 70
- 2026-09-13: 70
- 2026-09-12: 70

## Common questions

### What is the io.github.Dayananda-D/devcdp MCP server?

io.github.Dayananda-D/devcdp is an MCP server listed in the public MCP registry as io.github.Dayananda-D/devcdp. Chrome DevTools for AI assistants: console, network, DOM, source maps, breakpoints, live variables. This page covers its npm package (devcdp).

### Is the io.github.Dayananda-D/devcdp MCP server safe to use?

io.github.Dayananda-D/devcdp scores 84 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 17 October 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the io.github.Dayananda-D/devcdp MCP server expose?

io.github.Dayananda-D/devcdp exposes 74 tools: workflow_guide, devtools_connect, devtools_status, devtools_disconnect, list_tabs, and 69 more. Their descriptions and schemas cost roughly 9,569 tokens of context every time the server is loaded.

### Is the io.github.Dayananda-D/devcdp MCP server still maintained?

io.github.Dayananda-D/devcdp is still listed as active in the MCP registry. We last reached this channel on 17 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the io.github.Dayananda-D/devcdp MCP server under?

io.github.Dayananda-D/devcdp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/devcdp
- Socket report: https://socket.dev/npm/package/devcdp
- Repository: https://github.com/Dayananda-D/DevCDP
- Changelog RSS feed: https://verifymcp.io/servers/dayananda-d-devcdp/devcdp.xml
- Changelog JSON feed: https://verifymcp.io/servers/dayananda-d-devcdp/devcdp.json
- HTML version of this page: https://verifymcp.io/servers/dayananda-d-devcdp/devcdp
