Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.serkan-ozal/browser-devtools-mcp

NPM · BROWSER-DEVTOOLS-MCP · 2 COMPONENTS · SCANNED SEP 21

Playwright browser & Node.js MCP. ARIA refs, screenshots, ref-based interactions.

0 this week 66 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →

Supply Chain Security75
  • No malware found by supply-chain analysis.Pass
  • CVE check failed: a known high-severity CVE affects sharp 0.34.5, a direct dependency. A fixed version is available. View diagnostics → Fail
  • Runs a script at install time (postinstall) that we could not recognise. It may be perfectly ordinary, but we do not read the published tarball, so we cannot say what it does. View diagnostics → Partial
  • 67 of 246 dependencies flagged as unhealthy (1 deprecated). View diagnostics → Partial
Provenance & Transparency6
Schema Quality & AI Usability80
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 8731 tokens (~171/item across 51 items; 51 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management87
  • Stability observed for 26 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage93
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 75% of tool parameters carry a description.Partial
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety75
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 0 of 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "debug_remove-probe" implies "remove" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
  • An AI judge read all 52 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the io.github.serkan-ozal/browser-devtools-mcp server?

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

npm · browser-devtools-mcp

# add to Claude Code
claude mcp add serkan-ozal-browser-devtools-mcp -- npx -y browser-devtools-mcp
// .cursor/mcp.json
{
  "mcpServers": {
    "serkan-ozal-browser-devtools-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "browser-devtools-mcp"
      ]
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "serkan-ozal-browser-devtools-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "browser-devtools-mcp"
      ]
    }
  }
}
# add to Codex CLI
codex mcp add serkan-ozal-browser-devtools-mcp -- npx -y browser-devtools-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "serkan-ozal-browser-devtools-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "browser-devtools-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add serkan-ozal-browser-devtools-mcp --command npx --arg -y --arg browser-devtools-mcp
# ~/.hermes/config.yaml
mcp_servers:
  serkan-ozal-browser-devtools-mcp:
    command: "npx"
    args: ["-y", "browser-devtools-mcp"]
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "serkan-ozal-browser-devtools-mcp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "browser-devtools-mcp"
      ]
    }
  }
}
# add to Vellum
assistant mcp add serkan-ozal-browser-devtools-mcp -t stdio -c npx -a -y browser-devtools-mcp
// mcp.json
{
  "mcpServers": {
    "serkan-ozal-browser-devtools-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "browser-devtools-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 20 Sept 26 +1

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

  • 19 Sept 26 −3
    • Stability: pass → 0.80 functional
  • 18 Sept 26 0
    • Stability: 0.97 → pass security
  • 17 Sept 26 +1

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

  • 15 Sept 26 +1

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

  • 13 Sept 26 +1

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

  • 12 Sept 26 −3
    • Stability: pass → 0.80 functional
  • 11 Sept 26 0
    • Stability: 0.97 → pass security
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 21 Sept 2026 · Analysed npm/browser-devtools-mcp@0.9.1

Provenance No attestation

The registry publishes no build provenance for this version, so there is nothing to verify.

Result No attestation
Ecosystem npm

Background: How many MCP packages publish verified provenance →

Install scripts 1 script
Hook Tier Command
postinstall unreviewed node postinstall.cjs

Background: Why install scripts are a supply-chain risk →

Vulnerabilities 2 findings
ID CVE Severity Vector Fix available
GHSA-f88m-g3jw-g9cj high yes
GHSA-rgj7-g3m4-5g8c high yes

Background: What a vulnerability scan can and cannot prove →

Dependencies 246 packages
Packages resolved 246
Deprecated 1
Stale 66
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 51 exposed · ~7,792 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
a11y_take-aria-snapshot ~218

ARIA snapshot of the page or a scoped element. Returns a tree with refs (e1, e2, ...) and a refs map. Use refs in interaction tools: selector "e1" or "@e1" to click/fill that element. Output includes URL, title, and YAML tree. Refs are valid until next snapshot or navigation. interactiveOnly: only interactive elements get refs; omit for content roles (headings, etc.) too. cursorInteractive: true adds refs for clickable elements without ARIA (e.g. div with cursor:pointer/onclick). Use with a11y_take-ax-tree-snapshot for full UI analysis.

NameTypeReqDescription
compactbooleanOmit structural nodes without content.
cursorInteractivebooleanInclude cursor:pointer / onclick elements.
interactiveOnlybooleanOnly interactive elements get refs.
maxDepthintegerMax tree depth; 0 = root only.
selectorstringScope to this element; omit for full page.
NameTypeReqDescription
outputstringyesIncludes the page URL, title, and a YAML-formatted accessibility tree with [ref=e1] etc.
refsobjectyesMap of ref id to { role, name?, selector, nth? }. Use selector "e1" or "@e1" in interaction tools.

No examples provided.

a11y_take-ax-tree-snapshot ~327

Combines Chromium AX tree with runtime visual diagnostics (bounding box, visibility, viewport). Use to detect: elements with role/name but hidden or off-screen; layout/geometry issues; overlap/occlusion (enable checkOcclusion). When investigating UI/layout or when clicks fail on seemingly visible elements, set checkOcclusion:true—it uses elementFromPoint() at center+corners to find what is actually on top. boundingBox is from getBoundingClientRect() (viewport coords; layout box only). selectorHint is best-effort (data-testid/data-selector/id). Use with a11y_take-aria-snapshot for full UI analysis.

NameTypeReqDescription
checkOcclusionbooleanUse elementFromPoint to detect what is on top.
includeRuntimeVisualbooleanInclude bounding box and visibility.
includeStylesboolean
onlyInViewportboolean
onlyVisibleboolean
rolesarrayARIA/AX role names to include; omit for default set. Standard roles: ARIA https://w3c.github.io/aria/#role_definitions, Chromium AX https://chromium.googlesource.com/chromium/src/+/main/ui/accessibil…
stylePropertiesarrayCSS property names when includeStyles.
textPreviewMaxLengthinteger
NameTypeReqDescription
axNodeCountintegeryesTotal number of nodes returned by Chromium Accessibility.getFullAXTree before filtering.
candidateCountintegeryesNumber of DOM-backed AX nodes that passed role filtering before enrichment.
enrichedCountintegeryesNumber of nodes included in the final enriched snapshot output.
nodesarrayyesList of enriched DOM-backed AX nodes combining accessibility metadata with visual diagnostics.
titlestringyesThe document title of the page at the time of the snapshot.
truncatedBySafetyCapbooleanyesIndicates whether the result set was truncated by an internal safety cap to prevent excessive output size.
urlstringyesThe current page URL at the time the AX snapshot was captured.

No examples provided.

content_get-as-html ~118

Gets the HTML content of the current page. By default, all <script> tags are removed from the output unless "removeScripts" is explicitly set to "false".

NameTypeReqDescription
cleanHtmlboolean
maxLengthinteger
minifyboolean
removeCommentsboolean
removeMetaboolean
removeScriptsboolean
removeStylesboolean
selectorstringSelector or ref; omit for full document.
NameTypeReqDescription
outputstringyesThe requested HTML content of the page.

No examples provided.

content_get-as-text ~51

Gets the visible text content of the current page.

NameTypeReqDescription
maxLengthintegerTruncate after this many characters.
selectorstringLimit text to this container; omit for full page.
NameTypeReqDescription
outputstringyesThe requested text content of the page.

No examples provided.

content_save-as-pdf ~68

Saves the current page as a PDF file.

NameTypeReqDescription
formatstringPage size.
marginobjectMargin (e.g. 1cm).
namestring
outputPathstring
printBackgroundbooleanBackground.
NameTypeReqDescription
filePathstringyesFull path of the saved PDF file.

No examples provided.

content_start-recording ~101

Starts video recording of the browser page. Recording captures all page interactions until content_stop-recording is called. Uses Playwright's native screencast API — works in all modes (headless, headed, persistent, CDP attach). Only supported on Chromium-based browsers.

NameTypeReqDescription
namestringName for the video file (without extension). Defaults to "recording".
outputDirstringDirectory where the video file will be saved.
NameTypeReqDescription
messagestringyesStatus message.
startTimestampnumberWall-clock time (ms since epoch) of the video's first frame. Use this to align video time with other timestamps (logs, network events). A given event's position in the video is `(eventTimestampMs - s…

No examples provided.

content_stop-recording ~42

Stops video recording of the browser page and saves the video file. Must be called after content_start-recording. The video is saved as a WebM file.

Input schema present but exposes no named parameters.

NameTypeReqDescription
filePathstringFull path of the saved video file.

No examples provided.

content_take-screenshot ~187

Takes a screenshot of the current page or a specific element. Do NOT use for page structure—use ARIA/AX snapshots instead. Use only for visual verification (design check, visual bug, contrast, layout). Screenshot is saved to disk; use includeBase64 only when the file cannot be read from the returned path (e.g. remote, container).

NameTypeReqDescription
annotatebooleanOverlay ARIA ref labels.
annotateContentbooleanAnnotate headings.
annotateCursorInteractivebooleanAnnotate cursor:pointer elements.
fullPageboolean
includeBase64booleanBase64 fallback.
namestring
outputPathstring
qualityintegerJPEG quality 0–100.
selectorstringSelector/ref; omit=viewport.
typestring
NameTypeReqDescription
annotationsarrayWhen annotate is true, list of refs and bounding boxes. When selector is set: only annotations overlapping the element, box relative to that element. When fullPage is true: box is document-relative (…
filePathstringyesFull path of the saved screenshot file.
imageobjectImage data included only when "includeBase64" input parameter is set to true.

No examples provided.

debug_add-watch ~91

Adds a watch expression to be evaluated at every breakpoint hit. Watch expression results are included in the snapshot's watchResults field. Examples: - "user.name" - "this.state" - "items.length" - "JSON.stringify(config)" Watch expressions are evaluated in the context of the paused frame.

NameTypeReqDescription
expressionstringyesExpression evaluated at every tracepoint hit (e.g. user.name).
NameTypeReqDescription
expressionstringyesThe watch expression
idstringyesWatch expression ID
messagestringyesStatus message

No examples provided.

debug_clear-probe-snapshots ~104

Clears snapshots captured by tracepoints, logpoints, and/or exceptionpoints. Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, clears all. Optional `probeId`: clear only snapshots for this probe (for tracepoint/logpoint).

NameTypeReqDescription
probeIdstringClear only this probe (tracepoint/logpoint).
typesarrayClear only these types; omit for all.
NameTypeReqDescription
exceptionpointClearednumberyesExceptionpoint snapshots cleared
logpointClearednumberyesLogpoint snapshots cleared
messagestringyesStatus message
tracepointClearednumberyesTracepoint snapshots cleared

No examples provided.

debug_clear-probes ~77

Removes tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watches`. If omitted or empty, clears all.

NameTypeReqDescription
typesarrayWhich probe types to clear: tracepoint, logpoint, watches. If omitted or empty, all are cleared.
NameTypeReqDescription
logpointsClearednumberyesNumber of logpoints cleared
messagestringyesStatus message
tracepointsClearednumberyesNumber of tracepoints cleared
watchesClearednumberyesNumber of watch expressions cleared

No examples provided.

debug_get-probe-snapshots ~267

Retrieves snapshots captured by tracepoints, logpoints, and/or exceptionpoints. Optional `types`: array of `tracepoint`, `logpoint`, `exceptionpoint`. If omitted or empty, returns all. Response fields: `tracepointSnapshots`, `logpointSnapshots`, `exceptionpointSnapshots`. Optional `probeId` filters tracepoint or logpoint snapshots; `fromSequence` and `limit` apply per type. Output trimming: by default only the top 5 call stack frames are returned, only `local` scope(s) are included, and variables per scope are capped at 20. Override with maxCallStackDepth, includeScopes, maxVariablesPerScope.

NameTypeReqDescription
fromSequenceintegerSnapshots with sequence > this (polling).
includeScopesarrayScope types to include. Default [local] (local only to keep payload small).
limitinteger
maxCallStackDepthintegerMax call stack frames per snapshot. Default 5.
maxVariablesPerScopeintegerMax variables per scope. Default 20.
probeIdstringFilter by this probe ID (tracepoint/logpoint).
typesarrayReturn only these types; omit for all.
NameTypeReqDescription
exceptionpointSnapshotsarrayyesExceptionpoint snapshots
logpointSnapshotsarrayyesLogpoint snapshots
tracepointSnapshotsarrayyesTracepoint snapshots

No examples provided.

debug_list-probes ~62

Lists tracepoints, logpoints, and/or watch expressions. Optional `types`: array of `tracepoint`, `logpoint`, `watch`. If omitted or empty, returns all.

NameTypeReqDescription
typesarrayList only these types; omit for all.
NameTypeReqDescription
logpointsarrayyesLogpoints
tracepointsarrayyesTracepoints
watchesarrayyesWatch expressions

No examples provided.

debug_put-exceptionpoint ~75

Sets the exception tracepoint state: - "none": Don't capture on exceptions - "uncaught": Capture only on uncaught exceptions - "all": Capture on all exceptions (caught and uncaught) When an exception occurs, a snapshot is captured with exception details.

NameTypeReqDescription
statestringyes
NameTypeReqDescription
currentStatestringyesCurrent state
messagestringyesStatus message
previousStatestringyesPrevious state

No examples provided.

debug_put-logpoint ~279

Puts a logpoint at the specified location. When the logpoint is hit, the logExpression is evaluated and the result is captured in the snapshot's logResult field. Logpoints are lightweight - they only capture the log expression result, NOT call stack or watch expressions. Use tracepoints for full debug context. urlPattern matches script URLs (e.g., "app.js"). Auto-escaped, do not add backslashes. logExpression: a single JavaScript expression (e.g. "user.name", "JSON.stringify({ a, b })", or "{ discountAmount, finalAmount, n }"). Object literals are supported; for maximum compatibility prefer a single variable or JSON.stringify(...). Returns resolvedLocations: 0 means pattern didn't match any loaded scripts.

NameTypeReqDescription
columnNumberinteger1-based column.
conditionstringOnly log when this expression is true.
hitConditionstringHit-count condition (e.g. > 5).
lineNumberintegeryes1-based line in script.
logExpressionstringyesJS expression to evaluate and log (e.g. user.name, JSON.stringify({ a, b }), or { x, y }).
urlPatternstringyesGlob pattern for script URL (e.g. **/app.js).
NameTypeReqDescription
columnNumbernumberColumn number
conditionstringCondition expression
hitConditionstringHit count condition
idstringyesDebug point ID
lineNumbernumberyesLine number
logExpressionstringyesLog expression
resolvedLocationsnumberyesNumber of locations where logpoint was resolved
urlPatternstringyesURL pattern

No examples provided.

debug_put-tracepoint ~219

Puts a non-blocking tracepoint at the specified location. When hit, a snapshot of the call stack and local variables is captured automatically without pausing execution. The urlPattern matches script URLs. Special characters are auto-escaped. Examples: - "app.js" matches scripts containing "app.js" - "bundle.min.js" matches scripts containing "bundle.min.js" DO NOT escape characters yourself (e.g., don't use "app\.js"). Returns resolvedLocations: number of scripts where the tracepoint was set. If 0, the pattern didn't match any loaded scripts.

NameTypeReqDescription
columnNumberinteger1-based column.
conditionstringOnly trigger when this expression is true.
hitConditionstringHit count (e.g. == 5, >= 10, % 10 == 0).
lineNumberintegeryes1-based line.
urlPatternstringyesGlob pattern for script URL (e.g. **/app.js).
NameTypeReqDescription
columnNumbernumberColumn number
conditionstringCondition expression
hitConditionstringHit count condition
idstringyesTracepoint ID
lineNumbernumberyesLine number
resolvedLocationsnumberyesNumber of locations where tracepoint was resolved
urlPatternstringyesURL pattern

No examples provided.

debug_remove-probe ~75

Removes a tracepoint, logpoint, or watch expression by ID. `type`: `tracepoint`, `logpoint`, or `watch`. `id`: the probe or watch ID (from list-probes).

NameTypeReqDescription
idstringyesProbe or watch ID from list-probes.
typestringyes
NameTypeReqDescription
messagestringyesStatus message
removedbooleanyesWhether the probe or watch was removed

No examples provided.

debug_resolve-source-location ~136

Resolves a generated/bundled code location to its original source via source maps. Useful for translating minified stack traces or bundle line numbers to original TypeScript/JavaScript source. Requires a page with debugging context (debugging is auto-enabled on first use). Input: generated script URL, line, column (1-based). Output: original source path, line, column when a source map is available.

NameTypeReqDescription
columninteger1-based column; default 1.
lineintegeryes1-based line in generated code.
urlstringyesGenerated script URL (bundle).
NameTypeReqDescription
columnnumberColumn number in original source (1-based)
linenumberLine number in original source (1-based)
namestringOriginal identifier name if available
resolvedbooleanyesWhether the location was resolved to original source
sourcestringOriginal source file path

No examples provided.

debug_status ~49

Returns the current debugging status including: - Whether debugging is enabled - Source map status - Exceptionpoint state - Count of tracepoints, logpoints, and watches - Snapshot statistics

Input schema present but exposes no named parameters.

NameTypeReqDescription
enabledbooleanyesWhether debugging is enabled
exceptionBreakpointstringyesExceptionpoint state (none, uncaught, all)
hasSourceMapsbooleanyesWhether source maps are loaded
logpointCountnumberyesNumber of logpoints
snapshotStatsyesSnapshot statistics
tracepointCountnumberyesNumber of tracepoints
watchExpressionCountnumberyesNumber of watch expressions

No examples provided.

execute ~677

Batch-execute multiple tool calls in a single request via custom JavaScript. Reduces round-trips and token usage. **IMPORTANT** - The code is already run inside an async function. Pass only the body (statements). Do NOT wrap in `async function() { ... }` or `async () => { ... }` — that causes a syntax error. Write `await callTool(...); return x;` directly. **IMPORTANT:** - `page` (Playwright Page) is available in the VM — use it for navigation or `page.evaluate()`. - Prefer interaction tools with refs (e1, e2 from a11y_take-aria-snapshot); use raw Playwright only as last resort. - `document`/`window` are not in the VM — use `page.evaluate(() => { ... })` to run code in the browser. - Use `waitForNavigation: true` on interaction_click when the click navigates. - After navigation, do not continue with refs from the previous page — take fresh refs with a11y_take-aria-snapshot first. Bindings: - await callTool(name, input, returnOutput?): async — always use with await. Returns the tool output for in-code use. returnOutput=true also includes it in the response toolOutputs array; false (default) omits it. Throws on failure — execution stops at the first error; partial toolOutputs/logs are still returned. On failure, failedTool in the response identifies which tool caused the error. Max 50 callTool invocations per execution. - console.log/warn/error: captured in the response logs array. - sleep(ms): async delay. Built-ins: Math, JSON, Date, RegExp, Number, String, Boolean, Array, Object, Promise, Map, Set, WeakMap, WeakSet, Symbol, Proxy, Reflect, URL, URLSearchParams, TextEncoder/Decoder, structuredClone, crypto.randomUUID(), AbortController, setTimeout/clearTimeout. NOT available: require, import, process, fs, Buffer, fetch. **Example** — fill form, submit (with navigation wait), then snapshot and screenshot: await callTool('interaction_fill', { selector: 'e3', value: 'user@test.com' }); await callTool('interaction_fil…

NameTypeReqDescription
codestringyesJavaScript code: the body only (no async function wrapper). Use await callTool(name, input, returnOutput?) and return for result. Do NOT wrap in async function() { ... }.
timeoutMsintegerWall-clock timeout for the entire execution in ms, including awaited tool calls and sleep (default: 30000, max: 120000).
NameTypeReqDescription
errorstringError message on failure. Partial toolOutputs/logs are still returned.
failedToolobjectPresent when a callTool invocation caused the error.
logsarrayyesCaptured console.log/warn/error calls.
resultReturn value of the code (JSON-safe). Undefined on error or when nothing is returned.
toolOutputsarrayyesTool outputs where callTool was called with returnOutput=true.

No examples provided.

interaction_click ~162

Clicks an element. Accepts selector or ref (e.g. e1, @e1). Set waitForNavigation: true when the click opens a new page — waits for navigation then for network idle so snapshot/screenshot see full content.

NameTypeReqDescription
selectorstringyesCSS selector or ref from a11y snapshot (e.g. e1, @e1).
timeoutMsintegerWait for element, ms. Default 10000.
waitForNavigationbooleanWait for navigation triggered by click (parallel with click). Use when click opens a new page.
waitForTimeoutMsintegerTimeout for navigation and for network idle wait (ms). Only when waitForNavigation is true. Default 30000.

Structured output declared, but exposes no named fields.

No examples provided.

interaction_drag ~92

Drags an element to a target location. Accepts CSS selectors or refs (e.g. e1, @e1) from the last ARIA snapshot.

NameTypeReqDescription
sourceSelectorstringyesCSS selector or ref for the element to drag.
targetSelectorstringyesCSS selector or ref for the drop target.
timeoutMsintegerWait for elements, ms. Default 10000.

Structured output declared, but exposes no named fields.

No examples provided.

interaction_fill ~84

Fills out an input field. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

NameTypeReqDescription
selectorstringyesCSS selector or ref from a11y snapshot for the input.
timeoutMsintegerWait for element, ms. Default 10000.
valuestringyes

Structured output declared, but exposes no named fields.

No examples provided.

interaction_hover ~75

Hovers an element on the page. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

NameTypeReqDescription
selectorstringyesCSS selector or ref from a11y snapshot.
timeoutMsintegerWait for element, ms. Default 10000.

Structured output declared, but exposes no named fields.

No examples provided.

interaction_press-key ~214

Presses a keyboard key with optional "hold" and auto-repeat behavior. Key facts: - keyboard.press(key, { delay }) does NOT trigger OS-style auto-repeat. - Some UI behaviors (especially scrolling) require repeated keydown events. - Use repeat=true + holdMs to approximate real keyboard holding. Execution logic: - If selector is provided, the element is focused first. - If holdMs is omitted or repeat=false: → a single keyboard.press() is executed. - If holdMs is provided AND repeat=true: → keyboard.press() is called repeatedly until holdMs elapses.

NameTypeReqDescription
holdMsintegerMs between keydown and keyup.
keystringyesKey name (e.g. Enter, ArrowDown, Space).
repeatbooleanRepeat key while holdMs (e.g. for scroll).
repeatIntervalMsinteger
selectorstringFocus this element first; omit for page focus.
timeoutMsinteger

Structured output declared, but exposes no named fields.

No examples provided.

interaction_resize-viewport ~130

Resizes the PAGE VIEWPORT using Playwright viewport emulation (page.setViewportSize). This affects: - window.innerWidth / window.innerHeight - CSS media queries (responsive layouts) - Layout, rendering and screenshots Notes: - This does NOT resize the OS-level browser window. - Runtime switching to viewport=null (binding to real window size) is not supported by Playwright. If you need real window-driven responsive behavior, start the BrowserContext with viewport: null and use the window resize tool instead.

NameTypeReqDescription
heightintegeryes
widthintegeryes
NameTypeReqDescription
requestedobjectyesRequested viewport configuration.
viewportobjectyesViewport metrics observed inside the page after resizing.

No examples provided.

interaction_resize-window ~172

Resizes the REAL BROWSER WINDOW (OS-level window) for the current page using Chrome DevTools Protocol (CDP). This tool works best on Chromium-based browsers (Chromium/Chrome/Edge). It is especially useful in headful sessions when you run with viewport emulation disabled (viewport: null), so the page layout follows the OS window size. Important: - If Playwright viewport emulation is enabled (viewport is NOT null), resizing the OS window may not change page layout. - On non-Chromium browsers (Firefox/WebKit), CDP is not available and this tool will fail.

NameTypeReqDescription
heightintegerRequired when state=normal.
statestringWhen not normal, width/height may be ignored.
widthintegerRequired when state=normal.
NameTypeReqDescription
afterobjectyesWindow bounds after resizing.
beforeobjectyesWindow bounds before resizing.
requestedobjectyesRequested window change parameters.
viewportobjectyesPage viewport metrics after resizing (helps verify responsive behavior).

No examples provided.

interaction_scroll ~246

Scrolls the page viewport or a specific scrollable element. Modes: - 'by': Scrolls by a relative delta (dx/dy) from the current scroll position. - 'to': Scrolls to an absolute scroll position (x/y). - 'top': Scrolls to the very top. - 'bottom': Scrolls to the very bottom. - 'left': Scrolls to the far left. - 'right': Scrolls to the far right. Use this tool to: - Reveal content below the fold - Jump to the top/bottom without knowing exact positions - Bring elements into view before clicking - Inspect lazy-loaded content that appears on scroll

NameTypeReqDescription
behaviorstring
dxnumber
dynumber
modestringby=dx,dy; to=x,y; or edge (top/bottom/left/right).
selectorstringScrollable container: ref (e.g. from latest <a11y_take-aria-snapshot>), getBy… expression, or CSS. Omit for viewport.
xnumber
ynumber
NameTypeReqDescription
afterobjectyesScroll metrics after the scroll action.
beforeobjectyesScroll metrics before the scroll action.
behaviorstringyesThe scroll behavior used.
canScrollXbooleanyesWhether horizontal scrolling is possible (scrollWidth > clientWidth).
canScrollYbooleanyesWhether vertical scrolling is possible (scrollHeight > clientHeight).
isAtBottombooleanyesWhether the scroll position is at the very bottom.
isAtLeftbooleanyesWhether the scroll position is at the far left.
isAtRightbooleanyesWhether the scroll position is at the far right.
isAtTopbooleanyesWhether the scroll position is at the very top.
maxScrollXnumberyesMaximum horizontal scrollLeft (scrollWidth - clientWidth).
maxScrollYnumberyesMaximum vertical scrollTop (scrollHeight - clientHeight).
modestringyesThe scroll mode used.
selectorstring|nullyesThe selector of the scroll container if provided; otherwise null (document viewport).

No examples provided.

interaction_select ~84

Select an option in a dropdown. Accepts a CSS selector or a ref from the last ARIA snapshot (e.g. e1, @e1).

NameTypeReqDescription
selectorstringyesCSS selector or ref from a11y snapshot for the dropdown.
timeoutMsintegerWait for element, ms. Default 10000.
valuestringyes

Structured output declared, but exposes no named fields.

No examples provided.

navigation_go-back-or-forward ~441

Navigates to the previous or next page in history. - `direction: "back"` — previous page in history. - `direction: "forward"` — next page in history. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If cannot go back/forward, returns empty response. By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot. When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).

NameTypeReqDescription
directionstringyes
includeScreenshotbooleanTake a screenshot after navigation; saved to disk (default: OS temp dir). Use includeBase64 only when file cannot be read from path.
includeSnapshotbooleanReturn ARIA snapshot with refs.
screenshotOptionsobjectOptions when includeScreenshot is true. Same semantics as <content_take-screenshot> (outputPath/name default to tmp and "screenshot").
snapshotOptionsobjectOptions when includeSnapshot is true. Same as <a11y_take-aria-snapshot>.
timeoutintegerMax wait ms. 0=no timeout.
waitForNavigationbooleanWait for navigation then for network idle before snapshot/screenshot. Default true.
waitForTimeoutMsintegerTimeout for navigation and network idle wait (ms). Only when waitForNavigation is true. Default 30000.
waitUntilstringPlaywright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after history navigation.
NameTypeReqDescription
imageobjectWhen includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.
okbooleanContains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.
outputstring
refsobject
screenshotFilePathstringWhen includeScreenshot is true: full path of the saved screenshot file.
statusintegerContains the status code of the navigated page (e.g., 200 for a success).
statusTextstringContains the status text of the navigated page (e.g. usually an "OK" for a success).
urlstringContains the URL of the navigated page.

No examples provided.

navigation_go-to ~475

Navigates to the given URL. **NOTE**: The tool either throws an error or returns a main resource response. The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return empty response. **By default** (`includeSnapshot: true`), an ARIA snapshot with refs is taken after navigation and returned in `output` and `refs`; you can use refs (e1, e2, ...) in interaction tools without calling a11y_take-aria-snapshot separately. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false). Set `includeSnapshot: false` to get only url/status/ok. When `includeScreenshot: true`, the screenshot is always saved to disk; `screenshotFilePath` is returned. By default `outputPath` is the OS temp dir and `name` is "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the returned path (e.g. remote, container).

NameTypeReqDescription
includeScreenshotbooleanTake a screenshot after navigation; saved to disk (default: OS temp dir). Use includeBase64 only when file cannot be read from path.
includeSnapshotbooleanReturn ARIA snapshot with refs after nav.
screenshotOptionsobjectOptions when includeScreenshot is true. Same semantics as <content_take-screenshot> (outputPath/name default to tmp and "screenshot").
snapshotOptionsobjectOptions when includeSnapshot is true. Same as <a11y_take-aria-snapshot>.
timeoutintegerMax wait ms. 0=no timeout.
urlstringyes
waitForNavigationbooleanWait for navigation then for network idle before snapshot/screenshot. Default true.
waitForTimeoutMsintegerTimeout for navigation and network idle wait (ms). Only when waitForNavigation is true. Default 30000.
waitUntilstringPlaywright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after navigation.
NameTypeReqDescription
imageobjectWhen includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.
okbooleanContains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.
outputstringWhen includeSnapshot is true: page URL, title, and ARIA tree with refs.
refsobjectWhen includeSnapshot is true: map of ref id (e1, e2, ...) to role/name/selector for use in interaction tools.
screenshotFilePathstringWhen includeScreenshot is true: full path of the saved screenshot file.
statusintegerContains the status code of the navigated page (e.g., 200 for a success).
statusTextstringContains the status text of the navigated page (e.g. usually an "OK" for a success).
urlstringContains the URL of the navigated page.

No examples provided.

navigation_reload ~365

Reloads the current page. In case of multiple redirects, the navigation resolves with the response of the last redirect. If the reload does not produce a response, returns empty response. By default (includeSnapshot: true), an ARIA snapshot with refs is returned. Use `snapshotOptions` for `interactiveOnly` (default false) and `cursorInteractive` (default false), same as a11y_take-aria-snapshot. When `includeScreenshot: true`, the screenshot is saved to disk; `screenshotFilePath` is returned. Default path/name: OS temp dir and "screenshot" (same as content_take-screenshot). Use `screenshotOptions.includeBase64: true` only when the file cannot be read from the path.

NameTypeReqDescription
includeScreenshotbooleanTake a screenshot after reload; saved to disk (default: OS temp dir).
includeSnapshotbooleanReturn ARIA snapshot with refs.
screenshotOptionsobjectOptions when includeScreenshot is true. Same semantics as <content_take-screenshot> (outputPath/name default to tmp and "screenshot").
snapshotOptionsobjectOptions when includeSnapshot is true. Same as <a11y_take-aria-snapshot>.
timeoutintegerMax wait ms.
waitForNavigationbooleanWait for reload then for network idle before snapshot/screenshot. Default true.
waitForTimeoutMsintegerTimeout for reload and network idle wait (ms). Only when waitForNavigation is true. Default 30000.
waitUntilstringPlaywright navigation lifecycle: when the main frame reaches this state. Does not use Playwright networkidle; use waitForNavigation for session network-idle after reload.
NameTypeReqDescription
imageobjectWhen includeScreenshot and screenshotOptions.includeBase64 are true: image sent as separate image content part.
okbooleanContains a boolean stating whether the reloaded page was successful (status in the range 200-299) or not.
outputstring
refsobject
screenshotFilePathstringWhen includeScreenshot is true: full path of the saved screenshot file.
statusintegerContains the status code of the reloaded page (e.g., 200 for a success).
statusTextstringContains the status text of the reloaded page (e.g. usually an "OK" for a success).
urlstringContains the URL of the reloaded page.

No examples provided.

o11y_get-console-messages ~90

Retrieves console messages/logs from the browser with filtering options.

NameTypeReqDescription
limitobject
searchstringFilter by message text.
sequenceNumberintegerIncremental: only messages with sequence > this.
timestampintegerOnly messages at or after this Unix ms.
typestringFilter by level (this level or higher).
NameTypeReqDescription
messagesarrayyesRetrieved console messages.

No examples provided.

o11y_get-http-requests ~147

Retrieves HTTP requests from the browser with filtering options.

NameTypeReqDescription
includeRequestHeadersbooleanInclude request headers in each item. Default false.
includeResponseBodybooleanInclude response body in each item. Default false.
includeResponseHeadersbooleanInclude response headers in each item. Default false.
limitobject
okboolean2xx only.
resourceTypestringType filter.
sequenceNumberintegerIncremental: only requests with sequence > this.
statusobjectHTTP status range.
timestampintegerOnly requests at or after this Unix ms.
NameTypeReqDescription
requestsarrayyesRetrieved HTTP requests.

No examples provided.

o11y_get-trace-context ~37

Gets the OpenTelemetry trace context (trace id and tracestate) from the live browser page when OTEL is enabled.

Input schema present but exposes no named parameters.

NameTypeReqDescription
traceIdstringThe OpenTelemetry compatible trace id of the current session if available.
traceStatestringThe W3C tracestate value of the current session if available.

No examples provided.

o11y_get-web-vitals ~109

Collects Web Vitals (LCP, INP, CLS, TTFB, FCP) with Google thresholds and recommendations. Call after navigation or user actions; use waitMs for more stable LCP/CLS/INP. Some metrics may be unavailable depending on browser and interactions.

NameTypeReqDescription
includeDebugbooleanInclude entry counts and LCP element hint.
waitMsintegerMs to wait before reading (e.g. let LCP settle).
NameTypeReqDescription
debugobjectOptional debug details.
metricsobjectyesRaw metric values (null if unavailable).
notesarrayyesNotes about metric availability, browser limitations, and interpretation.
ratingsobjectyesRatings computed from Google thresholds.
recommendationsobjectyesRecommendations based on the measured values and their ratings.
timestampMsintegeryesUnix epoch timestamp (ms) when the metrics were captured.
titlestringyesCurrent page title.
urlstringyesCurrent page URL.

No examples provided.

o11y_new-trace-id ~28

Generates new OpenTelemetry compatible trace id and sets it to the current session.

Input schema present but exposes no named parameters.

NameTypeReqDescription
traceIdstringyesThe generated new OpenTelemetry compatible trace id.

No examples provided.

o11y_set-trace-context ~82

Sets or clears the OpenTelemetry trace context. Empty traceId clears the MCP-pinned trace id (new browser traces get random ids). Empty traceState clears tracestate. Non-empty traceState must be valid W3C tracestate (comma-separated key=value list).

NameTypeReqDescription
traceIdstring
traceStatestring

Structured output declared, but exposes no named fields.

No examples provided.

react_get-component-for-element ~221

Finds React component(s) for a DOM element via React Fiber (best-effort). Give selector or (x,y); we resolve the element, find __reactFiber$ on it or ancestors, then build the component stack from the host fiber that owns that node. Fiber is not a public API—results vary by dev/prod build; names can be displayName, wrappers, or minified. wrappersDetected/wrapperFrames help with memo/forwardRef/context. If hostMapping.strategy is ancestor-fallback, use a more specific selector or deeper node for better accuracy.

NameTypeReqDescription
includePropsPreviewbooleanIf true, includes a best-effort, truncated props preview for the nearest component.
maxPropsPreviewCharsintegerMaximum characters for props preview (after safe stringification).
maxStackDepthinteger
selectorstringTarget element; takes precedence over x/y.
xintegerViewport X when selector omitted.
yintegerViewport Y when selector omitted.
NameTypeReqDescription
reactobjectyes
targetobjectyes

No examples provided.

react_get-element-for-component ~266

Maps a React component instance to the DOM elements it renders (DOM footprint) by traversing the Fiber graph. Prefer an anchor (anchorSelector or anchorX/anchorY) to target the instance; optionally add a query (componentName, fileNameHint, lineNumber) to search Fiber. With both, we rank candidates and pick the best match near the anchor. React DevTools hook gives reliable root discovery (getFiberRoots); without it we fall back to DOM scan for __reactFiber$ (best-effort). For more reliable roots in a persistent browser, install the React Developer Tools Chrome extension. Debug source is best-effort and may be missing in some builds.

NameTypeReqDescription
anchorSelectorstringAnchor selector/ref.
anchorXintegerViewport X when anchorSelector omitted.
anchorYintegerViewport Y when anchorSelector omitted.
componentNamestring
fileNameHintstringFile hint.
lineNumberinteger
matchStrategystring
maxElementsinteger
maxMatchesinteger
onlyInViewportboolean
onlyVisibleboolean
textPreviewMaxLengthinteger
NameTypeReqDescription
candidatesarrayyesRanked candidate matches (best-first).
componentyes
elementsarrayyes
fiberDetectedbooleanyesTrue if DOM appears to contain React Fiber pointers (__reactFiber$...).
notesarrayyes
reactDetectedbooleanyesTrue if __REACT_DEVTOOLS_GLOBAL_HOOK__ looks available.
rootDiscoverystringyesHow roots were discovered.

No examples provided.

scenario-add ~129

Adds a new scenario. A scenario is a reusable JS script (like execute) that can call tools via callTool(). Scenarios are stored on disk under the scenarios.json file (project-level by default, or global with scope="global").

NameTypeReqDescription
descriptionstringyesDescription of what this scenario does.
namestringyesUnique scenario name (used as key).
scopestringStorage scope (default: project).
scriptstringyesJavaScript code to execute. Same sandbox as <execute>: use await callTool(name, input, returnOutput?) to invoke tools.
NameTypeReqDescription
scenarioobjectyes

No examples provided.

scenario-delete ~40

Deletes a scenario by name.

NameTypeReqDescription
namestringyesName of the scenario to delete.
scopestringStorage scope (default: project).
NameTypeReqDescription
deletedbooleanyesWhether the scenario was found and deleted.

No examples provided.

scenario-list ~55

Lists all available scenarios. When scope is omitted, returns scenarios from both project and global scopes (project overrides global for same name).

NameTypeReqDescription
scopestringFilter by scope. Omit to list from both (project overrides global).
NameTypeReqDescription
scenariosarrayyes

No examples provided.

scenario-run ~108

Runs a saved scenario by name. Looks up the scenario in project scope first, then global. The scenario's JS script runs in the same sandbox as execute: callTool(), console, sleep are available. Scenarios can compose other scenarios via callTool('scenario-run', { name: '...' }). Max recursion depth: 5.

NameTypeReqDescription
namestringyesName of the scenario to run.
timeoutMsintegerWall-clock timeout in ms (default: 30000).
NameTypeReqDescription
errorstring
failedToolobject
logsarrayyes
result
scenarioNamestringyes
toolOutputsarrayyes

No examples provided.

scenario-search ~71

Searches scenarios by query across both project and global scopes. Uses configurable search strategy (SEARCH_STRATEGY or SCENARIO_SEARCH_STRATEGY env var). Returns matching scenarios ranked by relevance.

NameTypeReqDescription
limitintegerMaximum number of results (default: 10).
querystringyesSearch query.
NameTypeReqDescription
scenariosarrayyes

No examples provided.

scenario-update ~72

Updates an existing scenario's description and/or script.

NameTypeReqDescription
descriptionstringNew description (omit to keep current).
namestringyesName of the scenario to update.
scopestringStorage scope (default: project).
scriptstringNew script (omit to keep current).
NameTypeReqDescription
scenarioobjectyes

No examples provided.

stub_clear ~58

Clears stubs installed. - If stubId is provided, clears only that stub. - If stubId is omitted, clears all stubs for the current session/context.

NameTypeReqDescription
stubIdstringRemove this stub; omit to clear all.
NameTypeReqDescription
clearedCountintegeryesNumber of stubs removed.

No examples provided.

Common questions

What is the io.github.serkan-ozal/browser-devtools-mcp server?

io.github.serkan-ozal/browser-devtools-mcp is listed in the public MCP registry as io.github.serkan-ozal/browser-devtools-mcp. Playwright browser & Node.js MCP. ARIA refs, screenshots, ref-based interactions. This page covers its npm package (browser-devtools-mcp).

Is the io.github.serkan-ozal/browser-devtools-mcp server safe to use?

io.github.serkan-ozal/browser-devtools-mcp scores 66 out of 100 on VerifyMCP. We recorded 2 known advisories against it as of 21 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.serkan-ozal/browser-devtools-mcp server expose?

io.github.serkan-ozal/browser-devtools-mcp exposes 51 tools: a11y_take-aria-snapshot, a11y_take-ax-tree-snapshot, content_get-as-html, content_get-as-text, content_save-as-pdf, and 46 more. Their descriptions and schemas cost roughly 7,792 tokens of context every time the server is loaded.

Is the io.github.serkan-ozal/browser-devtools-mcp server still maintained?

io.github.serkan-ozal/browser-devtools-mcp is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

What licence is the io.github.serkan-ozal/browser-devtools-mcp server under?

io.github.serkan-ozal/browser-devtools-mcp declares the Elastic-2.0 licence, which is not on the OSI-approved list. Read the terms before using it at work, and note this covers the source only, not the cost of any service it calls.