chrome-dev-mcp
chrome-dev-mcp lets an AI agent attach to an already-running Chrome tab over CDP to debug, inspect, and interact with a live web page.
Tab management: list open tabs and switch the server's connected tab.
Page inspection: read URL/title, HTML, computed CSS, screenshots or regions, the DevTools-selected element, and run arbitrary JS in global scope.
Navigation: navigate or reload the tab, optionally bypassing cache, waiting for load or a pause.
Console: read console messages and uncaught exceptions, including pre-connect history; filter by level and page-load scope.
Debugger: set/remove/list breakpoints, pause/resume/terminate, step over/into/out, inspect call stack and scopes, and evaluate expressions in a paused frame.
Network: list HTTP requests with filters and optional headers; fetch response bodies on demand.
Capture buffers: clear the server's console and/or network capture buffers.
Limitations: it does not auto-track the active tab, does not support iframes/workers/service workers, does not capture WebSocket frames, and breakpoints are not shared with DevTools.
Connects to a running Chrome tab via the Chrome DevTools Protocol (CDP) to provide debugging capabilities such as page inspection, console log retrieval, breakpoint management, and step-through execution.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@chrome-dev-mcpGet the current page URL"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
chrome-dev-mcp
●An MCP server that attaches to an already-running Chrome tab for real runtime debugging: breakpoints, stepping, and scope variables — plus JS/CSS inspection, console logs, and network capture. Built for web frontend development.
●It talks plain CDP through chrome-remote-interface — no DevTools SDK, no bundled browser — so it debugs the tab you already have open, in your own Chrome, instead of launching an isolated instance.
Demo video
Debugging js
Inspecting html and css
Related MCP server: chrome-devtools-mcp-lite
Why This Exists
●Currently, chrome-devtools-mcp is still focused more on browser automation and inspection than full runtime debugging, though it is clearly moving toward exposing more DevTools capabilities, as described in this Let your Coding Agent debug your browser session with Chrome DevTools MCP.
●Meanwhile, the underlying debugging capabilities are already available through tools such as chrome-remote-interface and @jridgewell/trace-mapping.
●This project exists as a faster, independent implementation focused specifically on making Chrome runtime debugging usable for AI agents before similar functionality is officially available in chrome-devtools-mcp.
Architectural difference from chrome-devtools-mcp
●chrome-devtools-mcp runs DevTools SDK models (TargetManager, DebuggerModel, NetworkManager, etc.) directly in Node.js via chrome-devtools-frontend's /mcp/mcp.js entrypoint, backed by a Puppeteer CDP connection — capabilities that go beyond what the raw Chrome DevTools Protocol exposes directly.
●That approach comes with trade-offs: chrome-devtools-frontend is a very large package (it mirrors the entire Chrome DevTools frontend codebase), and the approach relies on the internal structure of the DevTools page remaining stable across Chrome versions.
●This project takes the opposite approach: plain CDP via chrome-remote-interface, no DevTools SDK, minimal dependencies. The result is a lightweight server that is easy to install, audit, and extend.
Limitations
■ Does not track Chrome's active tab automatically. CDP does not expose a tab-switch event, so switching tabs in Chrome does not change the MCP connection — use switch_tab to explicitly reconnect to the tab you want.
■ Iframes, workers, and service workers are not supported at present.
■ WebSocket frames are not captured.
■ Not designed to run alongside chrome-devtools-mcp. Both register overlapping tool names and maintain independent debugger state against the same Chrome target, which causes confusion for the AI and potential state conflicts.
■ Breakpoints are not shared with DevTools. Chrome keeps breakpoints per CDP connection: those set through set_breakpoint never appear in DevTools' Breakpoints pane and cannot be removed there (use remove_breakpoint; Chrome also drops them when this server disconnects or switches tabs), and those set in DevTools never appear in list_breakpoints. Pausing is shared, though — DevTools pauses on this server's breakpoints too, and resuming or stepping from either side applies to both.
■ DevTools' "Deactivate breakpoints" (Ctrl+F8) has no effect while this server is debugging the tab. Chrome turns breakpoints off only once every debugger connected to the tab has turned them off, and this server never does — so the page still pauses on DevTools' breakpoints, on debugger; statements, and on this server's breakpoints. This server starts debugging a tab with its first call to get_console_logs, navigate_tab, reload_tab, switch_tab or a debugger tool such as set_breakpoint, and stops when it disconnects or switches to another tab.
Prerequisites
Node.js 22+
Google Chrome
Usage
Chrome
▲Launch Chrome with remote debugging enabled.
chrome.exe --remote-debugging-port=9222 --user-data-dir=C:\chrome-debug-profile
# --user-data-dir can be any empty directory; it keeps the debug session isolated from your normal Chrome profile.▲Verify remote debugging is active by opening http://localhost:9222/json in a browser — it should return a JSON list of debuggable targets.
▲Open the page you want to debug. The MCP server connects to the active tab at startup. To switch to a different tab later, ask the AI to switch — it will use list_tabs and switch_tab as needed.
Claude Code configuration
Through npm package
With a fixed version
▲Install npm package globally.
npm install -g chrome-dev-mcp▲Add the server to Claude Code's MCP.
claude mcp add --transport stdio chrome-dev -- chrome-dev-mcp▲Claude Code's config(~/.claude.json) will look like this:
"mcpServers": {
"chrome-dev": {
"type": "stdio",
"command": "chrome-dev-mcp",
"args": [],
"env": {}
}
},Always use the latest version
▲Add the server to Claude Code's MCP.
claude mcp add --transport stdio chrome-dev -- npx -y chrome-dev-mcp@latest
# '-y' is not supportted at 20260522. We may change the config below directory.▲Claude Code's config(~/.claude.json) will look like this:
"mcpServers": {
"chrome-dev": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"chrome-dev-mcp@latest"
],
"env": {}
}
},Through local project
▲Clone this project to local.
▲Add the server to Claude Code's MCP.
claude mcp add --transport stdio chrome-dev -- node "path/to/chrome-dev-mcp/dist/index.js"▲Claude Code's config(~/.claude.json) will look like this:
"mcpServers": {
"chrome-dev": {
"type": "stdio",
"command": "node",
"args": ["path/to/chrome-dev-mcp/dist/index.js"],
"env": {}
}
}Validation
●run claude mcp list, and it will print chrome-dev: xxxxx - ✓ Connected.
MCP Tools
☆25 tools in seven groups — six domains plus one cross-cutting tool:
Group | Tools | Covers |
Tab management | 2 | Discovering tabs, and choosing which one this server is attached to |
Page inspection | 6 | The live page: URL and title, HTML, computed CSS, screenshots, the DevTools-selected element, and arbitrary evaluation |
Navigation | 2 | Loading a URL or reloading, and waiting until the new page has loaded or paused |
Console | 1 | Console messages and uncaught exceptions, including output from before this server connected |
Debugger | 11 | Breakpoints, stepping, call stack, scopes, frame-scoped evaluation |
Network | 2 | Requests captured from connect time onward, plus response bodies fetched on demand |
Capture buffers | 1 |
|
☆All 25 serve one workflow. Two things come first, in either order: the agent learns what goes wrong, and the page reaches the state where it does — by hand, or through the agent's own navigate_tab, reload_tab and breakpoints. From there the agent reads whatever explains it — a console error, a network response, the DOM and its computed CSS, or a paused call stack and its scopes. Once a fix is in, the same tools confirm it: reload_tab, then read again.
☆Several pairs below look mergeable and are deliberately not — docs/tool-boundaries.md records which, and why.
Tab management
Tool | Description |
| List all open Chrome page tabs as |
| Connect this server to another tab by |
Page inspection
Tool | Description |
| Current page URL and title as |
| Full page HTML (capped at 20,000 chars) |
| Run arbitrary JavaScript in global scope, with DevTools console semantics: top-level |
| Computed CSS values for the given properties on the first element matching a CSS selector |
| PNG screenshot of the current viewport, or of one |
| Tag, id, classes, attributes, and outerHTML of the element marked via |
Navigation
Tool | Description |
| Load a URL in the connected tab and wait for the new page's load event — or for execution to pause first, in which case the call stack is returned |
| Reload the connected tab and wait the same way as |
▲Both work while paused at a breakpoint: the pause ends with the old page, and breakpoints hit again in the new one — so "set a breakpoint, then reload_tab" stops in the page's startup code and returns the call stack where it paused.
▲A failed navigation is reported as an error, not as loaded — Chrome still loads its own error page in that case and fires its load event — and a page whose load event does not fire within 30s comes back as still-loading.
Console
Tool | Description |
| All messages visible in the DevTools Console, including output that predates this server's connection. Exceptions are reported with their full stack trace (source-mapped when available). Filterable by level ( |
Debugger
Tool | Description |
| Paused status, pause reason, hit breakpoints, and full call stack with file + line, source-mapped when possible (with the position in the loaded script alongside) |
| Variable values inside a call frame scope ( |
| Evaluate a JS expression in a paused call frame's scope — reads local variables, closures, and |
| Set a breakpoint by source file + line (mapped through source maps), or by script URL / regex; supports conditions |
| Remove a breakpoint by its ID |
| All breakpoints active in this session |
| Pause JS at the next statement that runs, returning the call stack if that happens within 2s. On an idle page the pause stays pending until script runs — a timer, a click, an |
| Resume after a pause or breakpoint. With |
| Run the current statement without stepping into the functions it calls, and pause at the next one; returns the new call stack |
| Step into the function the current statement calls, or to the next statement if it calls none; returns the new call stack |
| Run the rest of the current function and pause in its caller; returns the new call stack |
▲The three step tools work only while paused, and go by statement rather than by line, since a minified line holds many statements. A step past the end of an event handler or timer callback — from its last statement, or out of it — pauses at the first statement of whatever script runs next, which may be unrelated code. When a step has not paused within 5s, the result lists the possible reasons: the step went past the end of the code that was running, the code is waiting at an await, or the page is not responding.
Network
Tool | Description |
| HTTP requests captured from the connected tab — method, URL, resource type, status, transferred size, duration, initiator, and failure reason. Redirects appear as one record per hop. Filter by URL substring, resource type, or status class ( |
| Response body for one |
▲Unlike get_console_logs, network capture is not retroactive: Network.enable() has no history replay, so capture begins when this server connects to the tab and nothing before that is visible. Requests belonging to a previous page are then pruned on navigation, mirroring the DevTools Network panel default — the new document's own request is kept.
Capture buffers
Tool | Description |
| Discard the console and/or network buffers this server holds, so the next read shows only what happens afterwards. Pick with |
▲Affects this server only — nothing is cleared in Chrome or in the DevTools UI, and capture keeps running. Clearing cannot be undone: console entries are gone for good, since Console.enable() replays history only at attach time, while cleared network requestIds still resolve in get_network_response_body for as long as Chrome itself holds the body.
Typical debugging workflow
◆Bring Chrome to the desired state manually — navigate to a specific route, trigger a flow, or pause at a breakpoint.
◆Ask the AI what you want to investigate, and it will call get_debugger_state, get_scope_variables, etc. automatically when needed.
◆To share a specific DOM element with the AI during debugging, select it in the Elements panel, then run this in the DevTools console:
window.$0 = $0;The AI can then call get_inspected_element to read its tag, attributes, and HTML.
# Example sequence Claude might use
get_debugger_state → { paused: true, callStack: [{ functionName: "handleClick", url: "...", lineNumber: 42 }] }
get_scope_variables → [{ name: "event", type: "object", value: "MouseEvent" }, ...]
evaluate_at_frame → expression: "dropTargets.map(t => t.id)" → ["list-1", "list-2"]
evaluate_at_frameruns in the paused frame's scope and can read local variables, whereasevaluate_jsruns in the global scope and cannot. They stay separate tools so that the pause state — which the caller cannot see — is carried by the tool name instead of an optional parameter:evaluate_jsnever silently answers from the wrong scope, andevaluate_at_framenever silently answers from the global one.
Development
●Install dependencies by pnpm install, and then:
pnpm dev # development (tsx watch)
pnpm build # tsc type-check + compile to dist/
pnpm start # run compiled build
pnpm test # run vitestAvailable Tools
25 toolsclear_capturesADestructiveIdempotent
Discard the buffers this server holds, so a following get_console_logs / get_network_requests shows only what happens next. Affects this server only: nothing is cleared in Chrome or in the DevTools UI, and capture keeps running — no reconnect or reload is needed. Cannot be undone. Console entries are gone for good, because Console.enable() replays history only at attach time. Cleared network requestIds still resolve in get_network_response_body for as long as Chrome itself holds the body; once Chrome drops it the error says the data was discarded rather than that the id is unknown. Works without a connected tab.
| Name | Required | Description | Default |
|---|---|---|---|
| targets | No | Which buffers to clear. Defaults to both. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cleared | Yes | Entries dropped per target; a target absent from `targets` is absent here |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses irreversibility ('Cannot be undone'), the replay-at-attach console behavior, the fact that cleared network requestIds may still resolve in get_network_response_body, and that clearing does not affect the DevTools UI. This is exactly the kind of behavioral detail an agent needs to avoid dangerous assumptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place: purpose, scope, irreversibility, edge-case behavior, and operational requirements. It is dense but not padded, and the core purpose is front-loaded before the caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive action with a single optional parameter, the description covers the effect, the scope, the irreversibility, the nuance about cleared network request bodies, and the no-tab requirement. Nothing an agent needs to safely invoke this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the optional 'targets' array with a default of both console and network, so parameter semantics are clear from the schema. The description adds general context that buffers are server-side but does not further describe the targets parameter, so it adds no significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Discard the buffers this server holds' and ties it to get_console_logs / get_network_requests. It unambiguously distinguishes itself from clearing Chrome or the DevTools UI, so an agent knows exactly what this tool does and what it does not do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the precise usage context: call this before a following get_console_logs / get_network_requests to start fresh, and notes that capture keeps running so no reconnect/reload is needed. It also states a key boundary — nothing in Chrome or the DevTools UI is cleared — and that it works without a connected tab, giving the agent clear conditions for when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
evaluate_at_frameA
Evaluate a JavaScript expression in the scope of a paused call frame — it reads local variables, closure variables and the current this, which evaluate_js cannot. Only works while execution is paused: when it is not, this returns an error rather than silently falling back to global scope. Results come back as a preview — class name plus a first level of properties, marked … where Chrome truncated it — readable, not parseable as the value. Use get_debugger_state to find frame indices.
| Name | Required | Description | Default |
|---|---|---|---|
| expression | Yes | JS source evaluated as-is. A function is not called — wrap it: `(() => { ... })()` | |
| frameIndex | No | Call frame index (0 = top frame); use get_debugger_state to find available frames |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry only a title, so the description bears the full disclosure burden and does it well: the paused-state requirement, the error-instead-of-fallback behavior, and the shape of the return value (class name plus first-level properties, `…` where Chrome truncated, human-readable rather than parseable). That last point is critical since no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core capability, then scope differentiation, then the hard precondition, then the return-format caveat. Every sentence carries information an agent needs; nothing is restated from the schema or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain returns and does so (preview-shaped, truncated, not machine-parseable). Preconditions, error behavior, and frame discovery are all covered, so an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (expression, frameIndex) are already fully documented in the schema, including the wrap-a-function-in-an-IIFE note and the 0 = top frame convention. The description adds only the get_debugger_state pointer for frame indices, which the schema also contains. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Evaluate a JavaScript expression in the scope of a paused call frame') and immediately delimits scope against the sibling evaluate_js by naming what it can read that evaluate_js cannot (locals, closures, `this`). An agent can distinguish the two tools without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit precondition ('Only works while execution is paused') with the failure mode spelled out (error, no silent fallback to global scope), plus a routing instruction to get_debugger_state for frame indices and an explicit contrast with evaluate_js. Both when-to-use and when-not-to-use are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
evaluate_jsA
Evaluate a JavaScript expression in the page, in global scope, with the same semantics as the DevTools console. Returns the real value when it serialises; objects that cannot (DOM nodes, Errors, Maps, class instances) come back as a preview instead: class name plus a first level of properties, marked … where Chrome truncated it — readable, not parseable as the value. Top-level await works, but an expression that merely RETURNS a promise is NOT awaited — it comes back as a pending Promise, exactly as in the console. The call returns as soon as your expression finishes its synchronous work, before queued microtasks run, so the state triggered by a click is not visible in the same call: put await Promise.resolve() between the click and the read, or read in a second call. At a breakpoint this still evaluates globally and cannot see local or closure variables — use evaluate_at_frame for those. For the element selected in the Elements panel ($0), use get_inspected_element.
| Name | Required | Description | Default |
|---|---|---|---|
| expression | Yes | JS source evaluated as-is. A function is not called — wrap it: `(() => { ... })()` |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Only a title annotation exists, so the description carries the behavioral burden and does so richly: serialization vs. preview for DOM nodes/Errors/Maps, top-level await semantics, returned-promise non-awaiting, and microtask timing. It stops short of noting any permissions/limits or error behavior when the expression throws, 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Information is front-loaded — core behavior, then return-value caveats, then the async-timing gotcha, then sibling routing. It is long and sentence-dense with some em-dash nesting, but nearly every clause conveys a distinct operational caveat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must explain return values, and it does: real values when serialisable, class-name-plus-first-level previews otherwise, marked truncation. Combined with the async-timing and scope limitations, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and already notes functions are not called, so the baseline is 3. The description adds value by specifying the expression is evaluated in global scope with DevTools-console semantics, clarifying how the argument is interpreted beyond the schema's wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Evaluate a JavaScript expression in the page, in global scope') and immediately scopes it against related capabilities. It names evaluate_at_frame and get_inspected_element explicitly so an agent can distinguish it from siblings without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use/alternatives: use evaluate_at_frame for local/closure variables at a breakpoint, get_inspected_element for $0, and put `await Promise.resolve()` or make a second call when reading state after a click. The routing conditions are stated, not inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_computed_styleARead-only
Get computed CSS values for the given properties on the element matched by selector.
| Name | Required | Description | Default |
|---|---|---|---|
| selector | Yes | CSS selector for the target element | |
| properties | Yes | CSS property names to return (kebab-case or camelCase) |
Output Schema
| Name | Required | Description |
|---|---|---|
| styles | Yes | Map of property name → computed value. Keys match the input `properties` verbatim (case preserved). Values are `getComputedStyle` output; unknown properties yield empty string. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true, the annotation covers the safety profile. The description adds the 'computed' qualifier, clarifying that it returns resolved styles rather than inline or default values, but does not disclose edge cases like missing elements or invalid property names.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no fluff. Every word contributes to clarifying the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two well-defined parameters and an output schema, the description is sufficient. It conveys the essential function, though it omits any mention of error behavior or handling of non-matching selectors, which would be useful but not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline applies. The description paraphrases the schema ('given properties' and 'element matched by selector') without adding additional semantic details such as return format or default behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves computed CSS values for specified properties on a selector-matched element, using a specific verb and resource. It distinguishes from sibling tools like get_html or get_title by focusing on computed styles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives such as evaluate_js or get_inspected_element. The description simply states the operation without context on selection criteria or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_console_logsARead-only
Return browser console messages and uncaught exceptions, including the history already visible in DevTools before this server connected. Exceptions are reported with their full stack trace (source-mapped when available). Reloading or navigating the page does NOT clear this buffer: output from the old document stays and the new one is appended to it, so an entry carries from when it predates the document showing now. Replayed entries carry no timestamp — Chrome hands its backlog over without one.
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | Filter by log level / type. Omit to return all levels. | |
| limit | No | Maximum number of most-recent entries to return | |
| since | No | How far back to read: a lower bound rather than a label to match, since each value INCLUDES the newer ones. `current-page-load` is only the document showing now, which answers "did my change introduce a new error" — reload, ask for it, and an empty result is a real answer. `earlier-page-load` adds the pages this connection watched come and go; `before-connect` (the default) adds the backlog that was already in DevTools before it attached. | before-connect |
Output Schema
| Name | Required | Description |
|---|---|---|
| logs | Yes | Oldest first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, so the safety bar is lower, yet the description adds substantial behavior beyond it: source-mapped stack traces, a buffer that survives reloads/navigation with old entries preserved, an entry-level `from` marker for pre-document output, and the caveat that replayed entries carry no `timestamp` because Chrome supplies none. These are exactly the quirks an agent would otherwise misread as bugs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then the buffer caveat, then the timestamp caveat — a sensible ordering with no filler. Slightly redundant with the existing output schema in its closing notes on `from` and `timestamp`, though those notes carry semantic value the schema alone may not convey.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read tool with an output schema and readOnly annotations, this covers everything an agent needs: what is returned, that stack traces may be source-mapped, that the buffer is cumulative across navigations, and how to interpret entries that predate the current document. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including a detailed `since` enum doc that already explains the layered lower-bound semantics, so the baseline is 3. The description reinforces the pre-connect backlog concept but adds no parameter-level detail (no format, no interaction with `limit`/`level`) beyond what the schema already spells out.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Return') plus concrete resource ('browser console messages and uncaught exceptions'), with an explicit scope qualifier: it includes DevTools history that predates the server connection. That scope statement alone separates it from every sibling in the list, since no other tool surfaces console output or exceptions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the semantics of the buffer thoroughly, but never states when to reach for this tool versus alternatives (e.g. get_debugger_state, evaluate_js, get_network_requests) or what a good reason to call it is. Guidance is implied by the note about navigating not clearing the buffer, but no explicit when-to-use or when-not-to-use is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_debugger_stateARead-only
Get the debugger state: whether execution is paused, the pause reason, hit breakpoints and the full call stack. A pause is reported whatever caused it. hitBreakpoints lists only breakpoints set through this server, so it is empty at a breakpoint set in DevTools. Positions are 1-based, and source-mapped where the script has a source map. A source-mapped frame also gives compiledUrl/compiledLine/compiledColumn, its position in the loaded script.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| paused | Yes | |
| reason | No | Pause reason (e.g. "other" for a breakpoint, "step", "exception"). Present only when paused. |
| callStack | No | Source-mapped positions when available. Present only when paused. |
| hitBreakpoints | No | IDs of breakpoints hit. Present only when paused. |
| droppedBreakpoints | No | Breakpoints set by `source` whose file has changed since: removed, and reported here once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already declaring the safety profile, the description adds substantial non-obvious behavior: pauses are reported regardless of cause, hitBreakpoints only reflects breakpoints set through this server and is therefore empty at DevTools breakpoints, positions are 1-based, and source-mapped frames expose compiledUrl/compiledLine/compiledColumn. These are exactly the traps an agent would otherwise misread as 'no breakpoint hit'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Five tight sentences, front-loaded with the returned data before the caveats. Every sentence carries distinct information — content, reporting guarantee, breakpoint-source caveat, coordinate convention, source-map extras — with no restatement of the name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value shape need not be spelled out here, and the description still pre-explains the trickiest fields. The one gap is environmental: it never states prerequisites (e.g., that a tab must be inspected/attached) for the state to be meaningful.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate beyond the schema. Baseline for a no-parameter tool is 4; the description does not need to add more.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb plus resource ('Get the debugger state') immediately followed by an enumeration of exactly what is included: paused status, pause reason, hit breakpoints, full call stack. This clearly separates it from siblings such as list_breakpoints (breakpoint inventory) and get_scope_variables (frame variables).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the agent must infer this is the tool to call when it needs to know if/where execution is paused. There is no explicit routing statement such as 'call before step_over/evaluate_at_frame' or guidance on when to prefer list_breakpoints or get_scope_variables. The 'hitBreakpoints' caveat is a data caveat rather than a when-to-use rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_htmlARead-only
Get the full HTML source of the currently connected tab (document.documentElement.outerHTML). Truncated to 20000 characters for large pages; a truncated result ends with a … marker giving how much was cut and the real length of the document, so a short result is never ambiguous between "small page" and "cut off here".
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses the exact 20000-character truncation behavior, the truncation marker format, and how 'short result' ambiguity is resolved. This is exactly the kind of behavioral detail an agent needs to interpret output correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two efficient sentences: the first states the action and scope, the second covers the only significant edge case (truncation) and its marker. No filler or redundant schema repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter read-only tool with no output schema, the description provides the complete contract: source retrieval method, size limit, truncation indicator, and ambiguity resolution. Nothing needed to invoke or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so there is nothing to document beyond the already-vacuous schema coverage. The description instead spends its text on return behavior, which is appropriate for a no-input tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the full HTML source of the currently connected tab'. It also specifies the exact implementation via `document.documentElement.outerHTML`, which clearly distinguishes it from siblings like get_title, get_url, and get_computed_style.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use case is clear from the stated resource and output: call this when the full page HTML is needed. It does not explicitly name alternatives or exclusion cases, so it falls just short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_inspected_elementARead-only
Get the element marked for MCP inspection. To mark an element: select it in the Elements panel, then run window.$0 = $0 in the DevTools console. Returns an error if no element is marked.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| tagName | Yes | |
| className | No | |
| outerHTML | Yes | First 5000 characters of element outerHTML |
| attributes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already covers the safety profile, and the description adds real behavioral context beyond that: the prerequisite that an element must be marked first, and the explicit failure mode ('Returns an error if no element is marked'). Not a contradiction — it is a read that depends on prior DevTools console state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences: what it does, how to satisfy the precondition, and what happens on failure — front-loaded and with no wasted text. The ordering puts the purpose before the setup detail, which is the right priority for an agent scanning tools.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters, an output schema already covering the return shape, and readOnlyHint annotations, the only remaining gaps would be preconditions and failure modes — both of which the description supplies. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description usefully clarifies that the 'input' is external DevTools state ($0) rather than a tool argument, which prevents the agent from hunting for a missing parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get the element marked for MCP inspection') and makes the scope distinct from siblings like get_html and get_computed_style, which read arbitrary page state rather than a user-marked element. An agent can tell immediately what this returns 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite workflow ('select it in the Elements panel, then run `window.$0 = $0` in the DevTools console'), which is exactly the context an agent needs to advise a user on setup. It does not, however, name an alternative for the case where no element is marked (e.g. get_html), so the when-not path is only implied by the error statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_requestsARead-only
Return HTTP requests captured from the connected tab — method, URL, resource type, status, transferred size, duration, initiator, and failure reason. Capture starts when this server connects to the tab: requests issued before that are NOT visible (unlike get_console_logs, which replays pre-connect history). Requests belonging to a previous page are pruned on navigation, mirroring the DevTools Network panel default; the new document request itself is kept. A redirect chain appears as one record per hop, sharing a requestId and distinguished by hop. WebSocket frames are not captured. In a bulk listing, a URL ending in … is truncated and not usable — query its requestId for it in full. size is compressed on-the-wire bytes; canceled marks an abort (e.g. navigating away), usually not a real failure.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of most-recent requests to return | |
| status | No | Filter by response status class, or by outcome: `failed` = network error/blocked, `pending` = still in flight. | |
| requestId | No | Return only this request, including every hop of its redirect chain. Pair with headerKeys to inspect one request in full. | |
| urlFilter | No | Case-insensitive substring match on the full (untruncated) request URL | |
| headerKeys | No | Return only these headers, matched case-insensitively, on both requestHeaders and responseHeaders. Omit to return no headers. Pass ["*"] for every header — that is bounded only by `limit`, so use it with `requestId` or a small limit. | |
| resourceType | No | Filter by CDP resource type. Any casing is accepted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| requests | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Read-only is already covered by annotations, yet the description adds substantial extra context: capture-start timing, pruning on navigation with the new document request retained, one record per redirect hop keyed by requestId/hop, WebSocket frames excluded, and what `canceled` versus `failed` mean. That is exactly the kind of non-obvious behavior an agent cannot infer from readOnlyHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the return payload, then each subsequent sentence carries a distinct behavioral fact with no filler. It is dense — several independent caveats are packed into one paragraph — which costs some scannability but not correctness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values needn't be explained, yet field semantics (`size`, `canceled`, `hop`, truncated URLs) are covered anyway, along with capture-window limits and pruning rules. Nothing an agent needs to call this correctly or interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning on top: it explains the bulk-listing truncation behavior tied to `limit`, tells the agent to pair requestId with headerKeys for full detail, and clarifies that returned `size` is compressed on-the-wire bytes rather than a decoded length. It stops short of covering the status/resourceType filter trade-offs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Return HTTP requests captured from the connected tab') and enumerates exactly which fields come back (method, URL, status, size, duration, initiator, failure reason). It also names a sibling (get_console_logs) to contrast scope, so an agent can distinguish it 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational guidance: capture only starts at connect time, pre-connect history is unavailable (explicitly contrasted with get_console_logs), and truncated URLs must be re-queried by requestId. It does not state exclusions among the network siblings (e.g., when to use get_network_response_body instead), so it falls short of a full when/when-not/alternatives treatment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_response_bodyARead-only
Fetch the response body for one requestId from get_network_requests. Bodies are never buffered by this server — they are read from Chrome on demand, and Chrome discards them on navigation or when its own buffer limits are exceeded, so fetch promptly and before navigating away. Chrome stores at most one body per requestId, so for a redirect chain only the final hop has a body. Returns a JSON metadata block, then the body as a separate text block — kept separate so a large body is not JSON-escaped. Metadata carries requestId, base64Encoded (boolean; true when the body is base64, as CDP reports it), byteLength and method/url/status/mimeType, the last four replaced by a note when the capture buffer no longer holds the request, plus truncated: true when the body was cut at 50000 characters. A binary body is never returned: metadata carries omitted and there is no second content block.
| Name | Required | Description | Default |
|---|---|---|---|
| requestId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the readOnlyHint annotation, disclosing buffering behavior, navigation-related loss, redirect-chain semantics, return format, truncation at 50000 characters, handling of binary bodies, and the `note` replacement mechanism. This is rich behavioral context that an agent cannot infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries distinct, high-value information: purpose, timing caveats, redirect behavior, return structure, metadata fields, error/omission cases. It is front-loaded with the core purpose and progresses logically through caveats and output details without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains what the agent will receive: a JSON metadata block, a separate text body, all metadata fields, the `note`/`truncated`/`omitted` variants, and binary-body behavior. Critical timing and lifecycle caveats are also covered, making the tool callable without further inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines requestId as a string with 0% description coverage. The description compensates by explaining that the requestId comes from get_network_requests and represents a captured network request, which is the key meaning an agent needs. It does not detail format constraints, but the derivation from get_network_requests is sufficient for correct use.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource: 'Fetch the response body for one requestId from get_network_requests.' This clearly distinguishes the tool from its sibling get_network_requests and other capture tools, so an agent can immediately know what it does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong timing guidance: fetch promptly and before navigating away because Chrome discards bodies. It also references get_network_requests as the source of requestIds. It does not explicitly enumerate when-not-to-use scenarios or name alternative tools, but the context is clear enough for correct routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_page_infoARead-only
Get the URL and title of the currently connected tab, as { url, title }. Still answers while the page is not responding.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| title | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds a genuinely non-obvious behavioral fact — that it responds even when the page is unresponsive — which is exactly the kind of context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with what is returned, with the caveat about unresponsive pages appended. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A trivial no-arg read with annotations and an output schema, so almost nothing needs saying. The only minor omission is what happens if no tab is connected (error vs. empty result), which an agent might want to know before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so there is nothing for the description to disambiguate; baseline applies. The stated return shape is a small bonus, though an output schema already exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb and resource ("Get the URL and title of the currently connected tab") plus the exact return shape `{ url, title }`. It implicitly distinguishes itself from list_tabs/switch_tab by scoping to the already-connected tab, but never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the resilience note ("still answers while the page is not responding") hints at when it is preferable to evaluate_js or get_html, but the description never states when to use this instead of list_tabs or switch_tab, nor any preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scope_variablesARead-only
Inspect variable values in a call frame scope. Only works when execution is paused. Use get_debugger_state first to find available frame indices.
| Name | Required | Description | Default |
|---|---|---|---|
| scopeType | No | Scope type to inspect | local |
| frameIndex | No | Call frame index (0 = top frame) |
Output Schema
| Name | Required | Description |
|---|---|---|
| variables | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description adds that the tool only functions while paused and that frame indices come from get_debugger_state, giving important operational context. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences that front-load the purpose and include essential usage guidance without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the readOnlyHint, complete parameter schema, and presence of an output schema, the description fully covers the tool's context, prerequisites, and usage, making it complete for an inspection tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers both parameters with descriptions, but the description adds the crucial link between frameIndex and the debugger state, enhancing parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Inspect' with the resource 'variable values in a call frame scope,' clearly distinguishing it from debugger control tools like pause_execution or evaluate_at_frame.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states a precondition ('Only works when execution is paused') and directs users to call get_debugger_state first to obtain frame indices, providing clear usage guidance and a sibling alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_breakpointsARead-only
List breakpoints tracked by this server (set via set_breakpoint). Breakpoints set outside this server (DevTools UI, other CDP clients, prior sessions) are not visible — CDP has no API to enumerate them.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| breakpoints | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, and the description adds meaningful behavioral context beyond that: it only shows breakpoints created through this server, and explains the CDP limitation (no API to enumerate all breakpoints). This is valuable for setting expectations, though it does not detail the response format (which an output schema likely covers).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two clear sentences, front-loaded with the action and scope, and adds a useful caveat without any wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and an output schema present, the description needs only to clarify the tool's scope and limitations, which it does thoroughly. The note about CDP's enumeration limitation is an important piece that makes the description self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description carries no parameter burden. A baseline of 4 is appropriate since there is nothing additional to explain.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'breakpoints tracked by this server', distinct from sibling tools like set_breakpoint/remove_breakpoint. It also differentiates by explicitly excluding breakpoints set via DevTools UI or other CDP clients, which removes ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: use this to list breakpoints set via set_breakpoint on this server. It implicitly warns against expecting externally-set breakpoints by stating they are not visible, which guides when not to use this tool. It does not name an alternative explicitly, but the context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tabsARead-only
List open Chrome page tabs with their targetIds, titles and URLs. active marks a tab showing on screen — the selected tab of a window that is not minimised or fully covered, so several windows mean several — and is absent if the tab did not answer. connected marks the tab this server acts on; selecting another tab in Chrome does not change it, only switch_tab does.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| tabs | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description adds genuinely non-obvious behavior: `active` reflects on-screen visibility with the multi-window caveat, and the field is absent if the tab did not answer — an important signal about partial results that 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core purpose, then the two ambiguous output fields. Every clause carries information; the nested em-dash aside about minimised/covered windows is slightly convoluted but resolves a real ambiguity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read tool with an output schema and readOnlyHint, this covers what an agent needs: what is listed, what the two flag fields mean, and which tab is actionable. It leaves unstated only edge cases such as zero open tabs or whether all windows/profiles are included.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description correctly does not waste space on inputs and instead spends its budget on output-field semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List open Chrome page tabs') plus the exact fields returned (targetIds, titles, URLs). It is immediately distinguishable from siblings like switch_tab or get_page_info, which act on a tab rather than enumerate them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context: the `connected` field identifies the tab this server acts on and notes that only switch_tab changes it, which implicitly frames this as the discovery step before switching. It never states an explicit 'use this when' or an exclusion against get_page_info, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pause_executionAIdempotent
Pause JavaScript at the next statement that runs, and return the call stack if that happens within 2s. On an idle page nothing runs, so the pause stays pending until script next does — a timer, an event, a click — and get_debugger_state reports it once it lands.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare idempotent/non-destructive; the description supplies the real behavioral substance: a 2s window, what is returned (the call stack), and that a miss leaves the pause pending rather than failing. That pending-state semantics is exactly the kind of trait annotations cannot express and prevents the agent from retrying unnecessarily.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The primary behavior and the 2s return condition come first, and the idle-page caveat with the recovery path follows in the same breath.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter tool with no output schema, the description covers what happens, what comes back (call stack), the timing boundary, and the degenerate case. Nothing an agent needs to call it or interpret the result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is no parameter semantics to add or omit. The description correctly spends no words on inputs and instead covers behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (pause) and precise resource/scope (JavaScript execution at the next statement), plus the return value (the call stack). An agent can distinguish this from set_breakpoint or resume_execution without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the crucial conditional case: on an idle page nothing runs, so the pause stays pending until a timer/event/click triggers script, and it routes the agent to get_debugger_state to check. It gives clear context but never explicitly contrasts with set_breakpoint (pause at a chosen line) or step_over, so sibling selection is still partly inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reload_tabADestructive
Reload the connected tab and wait up to 30s for the new page's load event — or for execution to pause first, e.g. on a breakpoint hit during startup, in which case the call stack is returned. outcome is "loaded", "paused" or "still-loading" (the new page is in place but its load event had not fired by the deadline). Breakpoints carry over to the reloaded page. Also works while paused, no need to resume first: the pause ends with the old page.
| Name | Required | Description | Default |
|---|---|---|---|
| ignoreCache | No | Bypass the HTTP cache, as Shift+F5 does. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | |
| note | No | |
| title | No | |
| reason | No | Pause reason. Present only when paused. |
| outcome | Yes | "loaded": the load event fired. "paused": execution paused before it did — see callStack. "same-document": only the #hash changed, so there is no load to wait for. "still-loading": the page committed but its load event did not fire in time. "download": the URL was handed to the download manager and the page did not change. |
| callStack | No | Same shape as get_debugger_state. Present only when paused. |
| droppedBreakpoints | No | Breakpoints set by `source` whose file has changed since: removed, and reported here once. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the destructiveHint/openWorldHint annotations: discloses the 30s deadline, the three possible outcomes including the 'still-loading' edge case, breakpoint carryover to the new page, and that an active pause terminates with the old page. This is exactly the behavioral context an agent needs to interpret results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and the timeout, then the outcome enumeration. The middle sentence is dense but each clause carries real information; only mild tightening could improve it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, yet the description still explains the outcome values and the paused-at-startup case, which is the key ambiguity for this tool. Nothing critical to correct invocation or result interpretation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter ignoreCache is fully documented in-schema as Shift+F5. The description never mentions the parameter, so it adds nothing here — baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Reload the connected tab') and immediately distinguishes itself from navigate/switch siblings by implying same-URL reload. The scope ('the connected tab') is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context: use it after source changes, and explicitly says it 'also works while paused, no need to resume first'. No explicit exclusion versus navigate_tab, but the reload-vs-navigate distinction is implied clearly enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_breakpointADestructive
Remove a breakpoint by ID. The ID is invalidated; use set_breakpoint to restore (returns a new ID).
| Name | Required | Description | Default |
|---|---|---|---|
| breakpointId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, but the description adds meaningful context: the ID becomes invalidated after removal and restoration produces a new ID. This informs the agent about side effects beyond the basic destructive flag, which is valuable behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary action, and every word adds value. It includes the key caveat (ID invalidation) and a hint about restoration without unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple destructive operation with one parameter and no output schema, the description covers the essential behavior, side effects, and an alternative. It does not mention error handling or return values, but these are not critical for such a focused tool given the siblings and annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only a required breakpointId string with no description (0% coverage). The description identifies it as 'a breakpoint by ID', linking the parameter to its role, but does not explain how to obtain the ID or its expected format. This is adequate but leaves some gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Remove a breakpoint') and the resource ('by ID'), making the tool's function unambiguous. It also distinguishes itself from sibling tools like set_breakpoint and list_breakpoints by focusing on removal and noting the restoration path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides practical guidance: it explicitly mentions using set_breakpoint to restore a removed breakpoint, which implies a clear alternative. It also notes the invalidation of the ID, helping the agent decide when this tool is appropriate. A brief mention of prerequisites (e.g., needing an existing breakpoint ID) would make it fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_executionADestructive
Resume execution while paused; it runs until the next breakpoint or pause. Returns at once rather than waiting for one.
| Name | Required | Description | Default |
|---|---|---|---|
| terminate | No | Resume, but skip the rest of the paused function and of its callers, finally blocks included, e.g. to stop an endless loop. The page may be left half-updated; reload_tab gives a clean state. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real value beyond the sparse annotations: it discloses that the call is non-blocking ('returns at once rather than waiting'), which is critical for an agent's control flow, and implies a paused-state prerequisite. It omits what happens if the debugger is not paused, and with only destructiveHint=true in annotations the description could say more about side effects of resuming.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, no waste, with the core behavior (runs to next breakpoint) and the non-blocking contract front-loaded. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, the essentials are present, but the description never says what a resume returns (e.g. resulting debugger state or pause location) or how it fails when not paused. With thin annotations, a bit more behavioral context would complete the picture.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'terminate' parameter is documented richly in the schema itself (half-updated page, reload_tab remediation). The description adds nothing about parameters, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('Resume execution') plus the scope of the resume ('runs until the next breakpoint or pause'), which implicitly distinguishes it from the single-step siblings like step_over/step_into. It stops short of naming those siblings, so the differentiation must be inferred.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'While paused' implies the precondition, so an agent can infer when the tool is applicable. However, it never states which sibling to use instead for single-stepping (step_over, step_into, step_out) or that pause_execution is the inverse, leaving the choice unguided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotARead-only
Capture a PNG screenshot of the current viewport (the visible page area only — not the full scrollable page, not the browser chrome, not DevTools), or of one rectangle of it with region. Captured at the tab's native pixel size unless you cap it with maxEdge; a capture that was scaled or cut says so in a note beside the image, which for a region also gives the CSS rect the image covers and how many image pixels a CSS pixel became. A tab that is not painting is raised in its window first, which changes which tab is selected there.
| Name | Required | Description | Default |
|---|---|---|---|
| region | No | Capture only this rectangle instead of the whole viewport. CSS pixels, measured from the top-left of the visible area — the same space `getBoundingClientRect()` reports in, so an element's box can be passed straight through. Usually the right way to answer a question about exact pixels: a small region at native size costs far less than the whole viewport. Pad it a few pixels when judging alignment — an exact box crop puts the element's own antialiased edge in its outer row, and an offset only reads against its surroundings. Cut down to whatever part of it is on screen; a region entirely off screen is an error. | |
| maxEdge | No | Longest side of the returned image, counted in its own pixels rather than CSS pixels, so the same value gives the same image on a 1x and a 2x tab. Scales down `region` when one is given, the viewport otherwise. -1 (the default), or any value at or above the capture's native pixel size, returns native pixels — use that when the answer depends on exact pixels (1px offsets, blurred edges, subpixel text). Otherwise size it for whatever will read the image: cost scales with AREA, so halving this quarters it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals important behaviors: captures only visible area, scaled/cut captures produce a note with CSS rect and pixel conversion, and non-painting tabs are raised to the front, changing tab selection. It also explains cost scaling with area. These details go well beyond what annotations provide, giving the agent a clear model of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph that front-loads the core function, then layers region and maxEdge guidance, and ends with the tab-raising side effect. Every sentence contributes value; it is efficient though slightly long. The structure is logical and easy to follow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the capture scope, region behavior, maxEdge scaling, cost implications, side effects on tab selection, and even error conditions (off-screen region). With no output schema, it implicitly clarifies that a PNG is returned. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters have detailed descriptions in the schema. The tool description adds some usage guidance (e.g., 'Usually the right way to answer a question about exact pixels') but does not introduce new parameter semantics beyond the schema. This matches the baseline of 3 for fully documented parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Capture'), a precise resource (the current viewport or a region of it), and explicitly excludes full-page, browser chrome, and DevTools. It clearly distinguishes this as the only visual capture tool among siblings, so an agent knows exactly what it does and what it does not.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong context on when to use region vs the whole viewport, when to use native pixel size vs maxEdge, and even advises padding for alignment. However, it does not explicitly contrast with alternative tools (e.g., get_html or evaluate_js) for gathering visual information, though none of those are screenshots. The guidance is otherwise clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_breakpointAIdempotent
Set a breakpoint at a 1-based line (and column) of a file. Name the file with source — a path like "src/App.tsx", or the url of a frame get_debugger_state or get_console_logs reported. Either way the position is mapped through source maps into the code Chrome runs, so that code must already be loaded. url/urlRegex instead take a position in the script exactly as Chrome loads it, so a source-mapped position given to them lands on the wrong line or never binds; use a frame's compiledUrl/compiledLine/compiledColumn. The script need not be loaded yet: an empty resolvedLocations means no loaded script matches yet, and the breakpoint binds when one loads — or never, if the URL is wrong. A source breakpoint is removed once its file changes, so set it again after an edit; the next state or navigation result lists it under droppedBreakpoints. A url/urlRegex breakpoint is kept through edits, so it may then stop on other code, or not at all.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Exact URL of the script as Chrome loaded it. Provide this, urlRegex or source; if both url and urlRegex, urlRegex takes precedence. | |
| source | No | File to break in, as in your project: a path like "src/App.tsx" — more of it when the name alone matches several loaded files — an absolute path, or a source-mapped url. lineNumber and columnNumber are positions in this file. | |
| urlRegex | No | Regex on the URL of the script as Chrome loaded it. Provide this, url or source; if both url and urlRegex, urlRegex takes precedence. | |
| condition | No | JS expression; breakpoint triggers only when truthy | |
| lineNumber | Yes | Line number (1-indexed) | |
| columnNumber | No | Column number, 1-indexed (optional) |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| breakpointId | Yes | |
| resolvedLocations | Yes | Where Chrome bound it in each loaded script, 1-based; source* give the source-mapped position. May be empty for url/urlRegex if the script is not loaded yet; the breakpoint will bind automatically when Chrome parses the script |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply idempotentHint, so the description carries the behavioral load and does so richly: pending binding when no script matches (`resolvedLocations` empty), binding on later load, and the crucial asymmetry that `source` breakpoints are dropped on file edit (surfaced under `droppedBreakpoints`) while `url`/`urlRegex` ones persist and may then stop on the wrong code.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action and coordinate base, then the targeting rules, then lifecycle caveats. Dense but purposeful; the source-map paragraph is long, though nearly every clause prevents a concrete failure mode.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be spelled out, and the description still explains the two return fields that change agent behavior (`resolvedLocations`, `droppedBreakpoints`). For a 6-parameter tool with subtle source-map semantics, nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantics beyond it: how `source` positions are remapped through source maps, why `url`/`urlRegex` positions are not, and the precedence/persistence consequences of choosing each. Conditional-expression behavior and column semantics are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+coordinate system: "Set a breakpoint at a 1-based line (and column) of a file." It is clearly distinguishable from the list_breakpoints/remove_breakpoint siblings, which it never gets confused with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes between the three targeting modes: `source` maps through source maps into Chrome code, while `url`/`urlRegex` take positions exactly as Chrome loads them, with a warning that a source-mapped position given to them 'lands on the wrong line or never binds'. It also names the sibling that supplies the right coordinates (a frame's `compiledUrl`/`compiledLine`/`compiledColumn` from get_debugger_state).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_intoA
While paused, step into the function the current statement calls, or to the next statement if it calls none. After an event handler or timer callback returns, the step stays in effect: it pauses at the first statement of whatever script runs next, which may be unrelated code. Returns the new call stack, or a note if execution has not paused again within 5s.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important non-obvious behavior beyond annotations: the step remains active after event handlers or timer callbacks, may pause in unrelated code, returns the new call stack, and times out after 5 seconds if execution does not pause. These details are critical for correct use.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two dense sentences with the primary action front-loaded and no wasted wording. The added callback/timeout details are relevant and efficiently expressed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description provides the return behavior, timeout behavior, and the paused-state precondition. This is complete enough for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so there is no parameter semantics to explain. The baseline for a zero-parameter tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific debugger action and distinguishes its behavior from a simple next-statement step by specifying that it steps into the called function when possible. An agent can understand exactly what the tool does relative to stepping generally.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states the key precondition 'While paused' and explains the resulting behavior in edge cases. It does not explicitly name when to prefer step_over or step_out instead, so it lacks full sibling routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_outA
While paused, run the rest of the current function and pause in its caller. An event handler or timer callback has no caller, so stepping out of one pauses in whatever script runs next. Returns the new call stack, or a note if execution has not paused again within 5s.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only supply destructiveHint=false and a title, so the description carries most of the burden and does well: it discloses that execution actually resumes, what comes back (the new call stack), and the 5-second timeout fallback. It omits what happens if the tool is invoked when not paused, which is the main remaining gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core semantics, then the edge case, then the return behavior. No sentence is padding — each adds a distinct operational fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter debugger operation with no output schema, the description covers precondition, edge-case behavior, return content, and timeout — everything an agent needs to call it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. There is nothing for the description to disambiguate, and nothing about invocation is left unclear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and mechanism: run the rest of the current function and pause in its caller. That uniquely identifies step-out semantics, but it never names the sibling alternatives (step_over, step_into, resume_execution) so an agent must infer the contrast from the definition alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening clause 'While paused' establishes the required debugger state, and the event-handler/timer caveat tells the agent what happens in the case where no caller exists. It stops short of explicit routing guidance — it never says to prefer step_over or step_into in particular situations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
step_overA
While paused, run the current statement without stepping into the functions it calls, and pause at the next statement. After an event handler or timer callback returns, the step stays in effect: it pauses at the first statement of whatever script runs next, which may be unrelated code. Returns the new call stack, or a note if execution has not paused again within 5s.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial behavioral detail beyond the annotations: it explains that the step remains in effect after event handlers or timer callbacks, that execution may pause in unrelated code, and that it returns a new call stack or a 5-second timeout note.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three focused sentences, front-loads the core stepping behavior, and every sentence contributes useful operational context without waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description is complete enough: it covers the paused prerequisite, the stepping behavior, the timeout behavior, and what the tool returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so parameter semantics are not applicable; the baseline score of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and operation: run the current statement without stepping into called functions, then pause at the next statement. It implicitly distinguishes itself from step_into by specifying that it does not enter function calls, though it does not explicitly name sibling tools such as step_into or step_out.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The prerequisite 'While paused' gives clear context for when the tool is applicable, and the stepping semantics imply when to prefer it over step_into. However, there is no explicit when-not guidance or named alternative tool comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
switch_tabA
Connect this server to another Chrome tab, without bringing it to the front. Breakpoints this server set in the previous tab are removed. A pause there ends, unless DevTools is open on that tab. The console and network buffers are emptied and refilled from the new tab.
| Name | Required | Description | Default |
|---|---|---|---|
| targetId | Yes | Target ID from list_tabs |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| title | Yes | |
| targetId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry only a title, so the description must do all the work, and it does: it discloses that breakpoints from the previous tab are removed, that an existing pause ends unless DevTools is attached, and that console/network buffers are cleared and refilled. These are exactly the destructive side effects an agent needs before re-targeting a debugger session.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each carrying distinct information: the core action first, then the non-focusing property, then two concrete state-effects. No filler and the most important constraint is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and covers return values, and the side-effect profile is fully spelled out. The only gap is failure/edge behavior — what happens if targetId is stale or the tab is closed — which an agent would likely want before switching.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter already documents itself as a target ID from list_tabs. The description says nothing about targetId, so it adds no meaning beyond the schema — baseline 3 under a fully documented schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — connect the server to another Chrome tab — and adds a distinguishing scope note ('without bringing it to the front') that separates it from a plain tab activation. It implicitly contrasts with navigate_tab/reload_tab by framing itself as a re-targeting of the server rather than an action on page content, but no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: reach for this when you need to operate on a different tab. There is no explicit 'use this when X, not Y' and no prerequisite statement (e.g., that the target must already be open or obtainable via list_tabs) — that hint lives only in the schema. Adequate but inferential.
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.
12 tool updates
v2.0.0- Changed
evaluate_at_frame1 field changed- changed
Input schema / properties / expression / descriptionPrevious value: -"JS expression to evaluate"New value: +"JS source evaluated as-is. A function is not called — wrap it: `(() => { ... })()`"
- Changed
evaluate_js1 field changed- added
Input schema / properties / expression / descriptionAdded value: +"JS source evaluated as-is. A function is not called — wrap it: `(() => { ... })()`"
- Changed
get_console_logs5 fields changed- added
Input schema / properties / sinceAdded value: +{ + "default": "before-connect", + "description": "How far back to read: a lower bound rather than a label to match, since each value INCLUDES the newer ones. `current-page-load` is only the document showing now, which answers \"did my change introduce a new error\" — reload, ask for it, and an empty result is a real answer. `earlier-page-load` adds the pages this connection watched come and go; `before-connect` (the default) adds the backlog that was already in DevTools before it attached.", + "enum": [ + "before-connect", + "earlier-page-load", + "current-page-load" + ], + "type": "string" +} - added
Output schema / properties / logs / descriptionAdded value: +"Oldest first." - added
Output schema / properties / logs / items / properties / fromAdded value: +{ + "enum": [ + "before-connect", + "earlier-page-load" + ], + "type": "string" +} - added
Output schema / properties / logs / items / properties / timestamp / descriptionAdded value: +"When this server received the entry. Absent on `before-connect` entries." - changed
Output schema / properties / logs / items / requiredPrevious value: -[ - "timestamp", - "type", - "text" -]New value: +[ + "type", + "text" +]
- Changed
get_debugger_state4 fields changed- added
Output schema / properties / callStack / items / properties / compiledColumnAdded value: +{ + "type": "number" +} - added
Output schema / properties / droppedBreakpointsAdded value: +{ + "description": "Breakpoints set by `source` whose file has changed since: removed, and reported here once.", + "items": { + "additionalProperties": false, + "properties": { + "breakpointId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "reason": { + "type": "string" + } + }, + "required": [ + "breakpointId", + "location", + "reason" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / noteAdded value: +{ + "type": "string" +} - changed
Output schema / properties / reason / descriptionPrevious value: -"Pause reason (e.g. \"breakpoint\", \"exception\"). Present only when paused."New value: +"Pause reason (e.g. \"other\" for a breakpoint, \"step\", \"exception\"). Present only when paused."
- Added
get_page_info - Removed
get_title - Removed
get_url - Changed
list_tabs3 fields changed- removed
Output schema / properties / tabs / items / properties / active / descriptionRemoved value: -"True if this tab is the current MCP target" - added
Output schema / properties / tabs / items / properties / connectedAdded value: +{ + "type": "boolean" +} - changed
Output schema / properties / tabs / items / requiredPrevious value: -[ - "targetId", - "title", - "url", - "active" -]New value: +[ + "targetId", + "title", + "url", + "connected" +]
- Added
navigate_tab - Added
reload_tab - Changed
resume_execution1 field changed- added
Input schema / properties / terminateAdded value: +{ + "default": false, + "description": "Resume, but skip the rest of the paused function and of its callers, finally blocks included, e.g. to stop an endless loop. The page may be left half-updated; reload_tab gives a clean state.", + "type": "boolean" +}
- Changed
set_breakpoint11 fields changed- added
Input schema / properties / sourceAdded value: +{ + "description": "File to break in, as in your project: a path like \"src/App.tsx\" — more of it when the name alone matches several loaded files — an absolute path, or a source-mapped url. lineNumber and columnNumber are positions in this file.", + "type": "string" +} - changed
Input schema / properties / url / descriptionPrevious value: -"Exact script URL. Provide this or urlRegex; if both, urlRegex takes precedence."New value: +"Exact URL of the script as Chrome loaded it. Provide this, urlRegex or source; if both url and urlRegex, urlRegex takes precedence." - changed
Input schema / properties / urlRegex / descriptionPrevious value: -"URL regex pattern. Provide this or url; if both, urlRegex takes precedence."New value: +"Regex on the URL of the script as Chrome loaded it. Provide this, url or source; if both url and urlRegex, urlRegex takes precedence." - added
Output schema / properties / noteAdded value: +{ + "type": "string" +} - changed
Output schema / properties / resolvedLocations / descriptionPrevious value: -"May be empty if the script is not loaded yet; the breakpoint will bind automatically when Chrome parses the script"New value: +"Where Chrome bound it in each loaded script, 1-based; source* give the source-mapped position. May be empty for url/urlRegex if the script is not loaded yet; the breakpoint will bind automatically when Chrome parses the script" - removed
Output schema / properties / resolvedLocations / items / properties / scriptIdRemoved value: -{ - "type": "string" -} - added
Output schema / properties / resolvedLocations / items / properties / sourceAdded value: +{ + "type": "string" +} - added
Output schema / properties / resolvedLocations / items / properties / sourceColumnAdded value: +{ + "type": "number" +} - added
Output schema / properties / resolvedLocations / items / properties / sourceLineAdded value: +{ + "type": "number" +} - added
Output schema / properties / resolvedLocations / items / properties / urlAdded value: +{ + "type": "string" +} - changed
Output schema / properties / resolvedLocations / items / requiredPrevious value: -[ - "scriptId", - "lineNumber" -]New value: +[ + "url", + "lineNumber", + "columnNumber" +]
1 tool update
v1.4.3- Changed
screenshot2 fields changed- added
Input schema / properties / maxEdgeAdded value: +{ + "default": -1, + "description": "Longest side of the returned image, counted in its own pixels rather than CSS pixels, so the same value gives the same image on a 1x and a 2x tab. Scales down `region` when one is given, the viewport otherwise. -1 (the default), or any value at or above the capture's native pixel size, returns native pixels — use that when the answer depends on exact pixels (1px offsets, blurred edges, subpixel text). Otherwise size it for whatever will read the image: cost scales with AREA, so halving this quarters it.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / regionAdded value: +{ + "description": "Capture only this rectangle instead of the whole viewport. CSS pixels, measured from the top-left of the visible area — the same space `getBoundingClientRect()` reports in, so an element's box can be passed straight through. Usually the right way to answer a question about exact pixels: a small region at native size costs far less than the whole viewport. Pad it a few pixels when judging alignment — an exact box crop puts the element's own antialiased edge in its outer row, and an offset only reads against its surroundings. Cut down to whatever part of it is on screen; a region entirely off screen is an error.", + "properties": { + "height": { + "exclusiveMinimum": 0, + "type": "number" + }, + "width": { + "exclusiveMinimum": 0, + "type": "number" + }, + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y", + "width", + "height" + ], + "type": "object" +}
4 tool updates
v1.4.0- Added
clear_captures - Changed
get_console_logs1 field changed- removed
Input schema / properties / clearRemoved value: -{ - "default": false, - "description": "Clear the buffer after returning entries", - "type": "boolean" -}
- Added
get_network_requests - Added
get_network_response_body
10 tool updates
v1.3.0- Removed
element_from_point - Changed
get_computed_style4 fields changed- added
Input schema / properties / propertiesAdded value: +{ + "description": "CSS property names to return (kebab-case or camelCase)", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / selector / descriptionAdded value: +"CSS selector for the target element" - changed
Input schema / requiredPrevious value: -[ - "selector" -]New value: +[ + "selector", + "properties" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "styles": { + "additionalProperties": { + "type": "string" + }, + "description": "Map of property name → computed value. Keys match the input `properties` verbatim (case preserved). Values are `getComputedStyle` output; unknown properties yield empty string.", + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "styles" + ], + "type": "object" +}
- Changed
get_console_logs1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "logs": { + "items": { + "additionalProperties": false, + "properties": { + "stackTrace": { + "items": { + "additionalProperties": false, + "properties": { + "columnNumber": { + "type": "number" + }, + "functionName": { + "type": "string" + }, + "lineNumber": { + "type": "number" + }, + "url": { + "type": "string" + } + }, + "required": [ + "functionName", + "url", + "lineNumber", + "columnNumber" + ], + "type": "object" + }, + "type": "array" + }, + "text": { + "type": "string" + }, + "timestamp": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "timestamp", + "type", + "text" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "logs" + ], + "type": "object" +}
- Changed
get_debugger_state1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "callStack": { + "description": "Source-mapped positions when available. Present only when paused.", + "items": { + "additionalProperties": false, + "properties": { + "columnNumber": { + "type": "number" + }, + "compiledLine": { + "type": "number" + }, + "compiledUrl": { + "type": "string" + }, + "functionName": { + "type": "string" + }, + "index": { + "type": "number" + }, + "lineNumber": { + "type": "number" + }, + "scopeTypes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "url": { + "type": "string" + } + }, + "required": [ + "index", + "functionName", + "url", + "lineNumber", + "columnNumber", + "scopeTypes" + ], + "type": "object" + }, + "type": "array" + }, + "hitBreakpoints": { + "description": "IDs of breakpoints hit. Present only when paused.", + "items": { + "type": "string" + }, + "type": "array" + }, + "paused": { + "type": "boolean" + }, + "reason": { + "description": "Pause reason (e.g. \"breakpoint\", \"exception\"). Present only when paused.", + "type": "string" + } + }, + "required": [ + "paused" + ], + "type": "object" +}
- Changed
get_inspected_element1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "attributes": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "className": { + "type": "string" + }, + "id": { + "type": "string" + }, + "outerHTML": { + "description": "First 5000 characters of element outerHTML", + "type": "string" + }, + "tagName": { + "type": "string" + } + }, + "required": [ + "tagName", + "attributes", + "outerHTML" + ], + "type": "object" +}
- Changed
get_scope_variables1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "variables": { + "items": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "preview": { + "type": "string" + }, + "type": { + "type": "string" + }, + "value": {} + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "variables" + ], + "type": "object" +}
- Changed
list_breakpoints1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "breakpoints": { + "items": { + "additionalProperties": false, + "properties": { + "breakpointId": { + "type": "string" + }, + "location": { + "description": "Human-readable \"url:line\" label", + "type": "string" + } + }, + "required": [ + "breakpointId", + "location" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "breakpoints" + ], + "type": "object" +}
- Added
list_tabs - Changed
set_breakpoint11 fields changed- changed
Input schema / properties / columnNumber / descriptionPrevious value: -"Column number (optional)"New value: +"Column number, 1-indexed (optional)" - added
Input schema / properties / columnNumber / maximumAdded value: +9007199254740991 - added
Input schema / properties / columnNumber / minimumAdded value: +1 - changed
Input schema / properties / columnNumber / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / lineNumber / maximumAdded value: +9007199254740991 - added
Input schema / properties / lineNumber / minimumAdded value: +1 - changed
Input schema / properties / lineNumber / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / url / descriptionPrevious value: -"Exact script URL, or omit to use urlRegex"New value: +"Exact script URL. Provide this or urlRegex; if both, urlRegex takes precedence." - changed
Input schema / properties / urlRegex / descriptionPrevious value: -"URL regex pattern (alternative to exact url)"New value: +"URL regex pattern. Provide this or url; if both, urlRegex takes precedence." - changed
Input schema / requiredPrevious value: -[ - "url", - "lineNumber" -]New value: +[ + "lineNumber" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "breakpointId": { + "type": "string" + }, + "resolvedLocations": { + "description": "May be empty if the script is not loaded yet; the breakpoint will bind automatically when Chrome parses the script", + "items": { + "additionalProperties": false, + "properties": { + "columnNumber": { + "type": "number" + }, + "lineNumber": { + "type": "number" + }, + "scriptId": { + "type": "string" + } + }, + "required": [ + "scriptId", + "lineNumber" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "breakpointId", + "resolvedLocations" + ], + "type": "object" +}
- Added
switch_tab
20 tool updates
v1.1.0- First observed
element_from_point - First observed
evaluate_at_frame - First observed
evaluate_js - First observed
get_computed_style - First observed
get_console_logs - First observed
get_debugger_state - First observed
get_html - First observed
get_inspected_element - First observed
get_scope_variables - First observed
get_title - First observed
get_url - First observed
list_breakpoints - First observed
pause_execution - First observed
remove_breakpoint - First observed
resume_execution - First observed
screenshot - First observed
set_breakpoint - First observed
step_into - First observed
step_out - First observed
step_over
TDQS
Scored across 25 tools
Each tool targets a distinct resource and operation: tab/page control, network capture, console capture, DOM/CSS inspection, and debugger stepping/evaluation are clearly separated. Even closely related pairs like evaluate_js vs evaluate_at_frame and get_debugger_state vs list_breakpoints have explicit scope boundaries in their descriptions.
Almost all tools follow a predictable snake_case verb_noun or verb_action pattern: get_*, list_*, set_*, remove_*, navigate_tab, reload_tab, step_over, evaluate_js, clear_captures. The main minor deviation is the noun-only screenshot, so the set is highly consistent but not perfectly uniform.
25 tools is at the upper end, but the server spans several genuine DevTools domains: tabs, DOM/CSS, JS evaluation, network, console, and debugging. Each tool maps to a distinct DevTools operation, though a few debugger controls could conceivably be consolidated.
Coverage is strong for inspection and debugging: navigation, screenshots, DOM/CSS reads, JS evaluation, console/network capture, breakpoints, stepping, and scope inspection. Notable gaps remain around DOM interaction, tab lifecycle, script source retrieval, and request headers, but evaluate_js provides partial workarounds for some.
Maintenance
Related MCP Connectors
Live browser debugging for AI assistants — DOM, console, network via MCP.
A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,
Official Browserless MCP server: browser automation, scraping, screenshots and PDFs for AI agents.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceMCP server that connects AI agents to a real Chrome browser via a WebSocket extension bridge, enabling over 40 browser control tools without debug mode or profile isolation.-
- AlicenseNot gradedqualityDmaintenanceA lightweight MCP server that enables AI assistants to control Chrome DevTools via CDP for debugging tasks like navigation, screenshots, and JavaScript execution.MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server that connects to a Chrome extension to enable AI agents to control browser tabs, execute automation, and interact with web pages via tools.120 npmMIT
- FlicenseNot gradedqualityDmaintenanceMCP server that connects AI agents to browser DevTools via CDP, enabling real-time access to console logs, network requests, and page state.-