웹 애플리케이션 트러블슈팅을 위해 콘솔, 네트워크, DOM 및 디버거를 검사할 수 있는 실제 Chrome DevTools 액세스 권한을 AI 어시스턴트에게 제공합니다.
다른 이름 Dayananda-D/DevCDP
- 스타
- 2
- Tools
- —
- 다운로드, 30일
- —
- 최신 버전
- 5.0.1
- 마지막 커밋
- 2026년 9월 25일
- 라이선스
- MIT
devcdp MCP란?
devcdp은(는) MCP server입니다. 웹 애플리케이션 트러블슈팅을 위해 콘솔, 네트워크, DOM 및 디버거를 검사할 수 있는 실제 Chrome DevTools 액세스 권한을 AI 어시스턴트에게 제공합니다.
프로젝트 README에서 생성된 요약
devcdp MCP server 정보
DevCDP는 Model Context Protocol을 통해 AI 어시스턴트에게 Chrome DevTools에 대한 직접적인 액세스 권한을 제공합니다. 에이전트가 콘솔을 검사하고, 네트워크 요청을 모니터링하며, DOM을 쿼리하고, 디버거를 사용하여 소스 맵을 해결하거나 라이브 변수를 검사할 수 있도록 합니다. 이 도구는 에러 로그를 바탕으로 추측하는 대신, 애플리케이션이 실패하는 원인을 진단할 수 있는 어시스턴트를 원하는 웹 개발자를 위해 설계되었습니다.
서버는 Node 18+를 사용하여 로컬 머신에서 실행되며 Chrome 기반 브라우저가 필요합니다. Claude Code, Cursor, Gemini CLI, VS Code를 포함한 다양한 MCP 클라이언트와 호환됩니다. 사용자는 JSON 파일이나 환경 변수를 통해 자동 탭 그룹화, 사용자 정의 Chrome 플래그, 라이브니스 타임아웃과 같은 기능을 관리하도록 설정을 구성할 수 있습니다. 시스템은 안전하게 설계되어 실행 중인 스크립트를 중단하고 중단점이 애플리케이션을 무기한 정지 상태로 두지 않도록 보장합니다.
활용 사례
- 1웹 애플리케이션 오류 디버깅AI 어시스턴트가 콘솔 로그와 스택 트레이스를 검사하여 예외의 근본 원인을 식별할 수 있습니다.
- 2네트워크 트래픽 분석개발자가 에이전트를 통해 모든 인바운드 및 아웃바운드 요청을 모니터링하여 상태 코드와 응답 본문을 확인할 수 있습니다.
- 3DOM 및 스타일 검사어시스턴트가 셀렉터 쿼리를 수행하여 요소의 가시성, 기하학적 구조 및 계산된 스타일을 확인할 수 있습니다.
- 4소스 코드 단계별 실행에이전트가 원본 파일에 중단점을 설정하고 실행 중인 중첩된 객체 스코프를 검사할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
devcdp MCP 설치 방법
형식 확인: 2026년 11월 10일Cursor에 추가Goose에 추가Claude Code에 devcdp MCP 설치
$ claude mcp add devcdp -- npx -y devcdpCursor에 devcdp MCP 설치
~/.cursor/mcp.json
{
"mcpServers": {
"devcdp": {
"command": "npx",
"args": [
"-y",
"devcdp"
]
}
}
}VS Code에 devcdp MCP 설치
.vscode/mcp.json
{
"servers": {
"devcdp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"devcdp"
]
}
}
}VS Code CLI에 devcdp MCP 설치
$ code --add-mcp '{"name":"devcdp","type":"stdio","command":"npx","args":["-y","devcdp"]}'Claude Desktop에 devcdp MCP 설치
claude_desktop_config.json
{
"mcpServers": {
"devcdp": {
"command": "npx",
"args": [
"-y",
"devcdp"
]
}
}
}Codex에 devcdp MCP 설치
$ codex mcp add devcdp -- npx -y devcdpCodex config.toml에 devcdp MCP 설치
~/.codex/config.toml
[mcp_servers.devcdp] command = "npx" args = ["-y", "devcdp"]
Gemini CLI에 devcdp MCP 설치
$ gemini mcp add -s user devcdp npx -- -y devcdpGemini settings.json에 devcdp MCP 설치
~/.gemini/settings.json
{
"mcpServers": {
"devcdp": {
"command": "npx",
"args": [
"-y",
"devcdp"
]
}
}
}구성
DEVCDP_CHROME_PATHPath to the Chrome executable, when it is not on the default install path.
DEVCDP_LOG_LEVELServer log verbosity on stderr: debug, info, warn or error.
| 이름 | 설명 | 유형 |
|---|---|---|
| DEVCDP_CHROME_PATH | Path to the Chrome executable, when it is not on the default install path. | |
| DEVCDP_LOG_LEVEL | Server log verbosity on stderr: debug, info, warn or error. |
자동 검사
2026년 11월 14일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 이는 보안 감사가 아닙니다. 코드를 직접 읽고 서버에 필요한 최소한의 권한만 부여하십시오. 검사 방식
- 소스 저장소 연결 및 접근 가능dayananda-d/devcdp is public and reachablegithub.com/dayananda-d/devcdp ↗통과
- 패키지가 이 저장소를 소스로 명시devcdp names dayananda-d/devcdp as sourcenpmjs.com/package/devcdp ↗통과
- 빌드 출처(Sigstore 증명)No build attestation published for this release검사되지 않음
- 오픈 소스 라이선스 (OSI)MITspdx.org/licenses/MIT.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-09-25github.com/dayananda-d/devcdp ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음No popular package one edit away from devcdp통과
- 패키지 및 해당 종속성에 중요한 보안 권고 없음102 resolved dependencies checked; no critical advisoryosv.dev ↗통과
- 모델에 대한 숨겨진 지침 없음0 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨검사되지 않음
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기DevCDP
Real Chrome DevTools access for an AI assistant, over MCP. Your assistant reads the console, watches the network, queries the DOM, resolves source maps, sets breakpoints and inspects live variables — so it can tell you why something broke instead of guessing from a pasted error.
Works with any assistant that speaks MCP, and with any web app: nothing about a particular framework, product or company is built in.
74 tools — see docs/TOOLS.md for the full reference, generated from the server itself, and docs/PERFORMANCE.md for measured token costs and how to lower them.
What it does
| Console | Logs, warnings and uncaught exceptions with file, 1-based line and stack. |
| Network | Every request from the moment it attaches — method, status, timing, size, initiator, and response bodies on request. |
| DOM | Selector queries with real visibility and geometry, named computed styles, mutation history, iframe support, and structural dialog detection. |
| Sources | Loaded scripts, plus original pre-bundling files recovered from source maps — including external .map files behind authentication. Full-text search across both. |
| Debugger | Breakpoints on original files by original line, stepping, and scope inspection that expands nested objects instead of printing Object. |
| Discovery | Asks the app what it is: framework, routing, working selectors for its buttons and fields, its backend API surface, and your project's own docs. |
| Collaboration | You can take over at any time; what you click, choose and type is recorded and readable by the assistant. |
Four things it is careful about
It never fakes success. A breakpoint that cannot bind says bound: false and
explains why. A body Chrome has discarded says so. A capture from a pause that has
already resumed is marked stale. Every failure is {ok: false, code, message, hint}
with the next action named.
It tells you where its knowledge ends. Chrome cannot replay console history to a debugger that attaches later, so attaching reports exactly that rather than presenting an empty buffer as "no errors".
It cannot be stranded. Every call into the page is bounded on our side —
Runtime.evaluate's own timeout is enforced by the renderer, which is useless when
the renderer is what is stuck. A page wedged in an infinite loop fails in seconds
with the recovery path named, and DevCDP will abort the runaway script and retry by
itself.
It never leaves your app frozen. Breakpoints capture what you need and then
resume on their own. A pause held deliberately is still released after
maxPauseMs, and everything is cleaned up on disconnect.
Install
Requirements: Node 18+, Chrome, and an MCP-capable assistant.
Pick whichever fits your client. All of them run the same server on your machine; nothing is hosted.
Any MCP client, from npm. Add to the client's MCP config:
{ "mcpServers": { "devcdp": { "command": "npx", "args": ["-y", "devcdp"] } } }
On native Windows some clients need "command": "cmd", "args": ["/c", "npx", "-y", "devcdp"].
Claude Code, as a plugin (server plus a skill that tells Claude when to reach for which tool):
/plugin marketplace add Dayananda-D/DevCDP
/plugin install devcdp@devcdp
Cursor: ,
or add the JSON above to
~/.cursor/mcp.json.
Gemini CLI, as an extension that also carries the usage guidance:
gemini extensions install https://github.com/Dayananda-D/DevCDP
opencode: opencode mcp add, or in opencode.json:
{ "mcp": { "devcdp": { "type": "local", "command": ["npx", "-y", "devcdp"], "enabled": true } } }
Codex (CLI, desktop, VS Code extension), as a plugin:
codex plugin marketplace add Dayananda-D/DevCDP
VS Code: Install in VS Code, or run MCP: Add Server, choose NPM Package,
and enter devcdp. Copilot CLI: /mcp add with command npx -y devcdp. DevCDP is in
the official MCP Registry; the picker
inside VS Code shows GitHub's curated subset of that registry, which is a separate listing.
From source, with the setup wizard that also writes usage guidance into your assistant's instructions file: see Setup, next.
Then launch Chrome with remote debugging (debug-chrome.bat, or
chrome --remote-debugging-port=9222 --user-data-dir=<a separate profile>), open your
app, and describe the bug.
Setup
1. node initialize_MCP.js (or double-click initialize_MCP.bat)
2. Fully quit and reopen your assistant
3. Double-click debug-chrome.bat, open your app
4. Describe the bug
The wizard detects installed editors, writes the right config shape for each, and drops a launcher. It never overwrites a config file it cannot parse — it prints the snippet to paste instead — every write is atomic with one timestamped backup, and duplicate registrations from older installs are removed. That path is covered by 23 tests, because getting it wrong damages your machine rather than just failing.
Settings
Everything is optional. Ask the assistant to run devcdp_settings to see the
effective values and where each came from, or devcdp_settings_init to write an
annotated file you can edit.
Files are merged, later winning, so an install-wide baseline can be overridden per project:
<install>/devcdp.settings.json or <install>/settings.json
<cwd>/.devcdp/settings.json
<cwd>/devcdp.settings.json
then DEVCDP_* environment variables, then tool arguments. Comments and trailing
commas are tolerated.
| Setting | Default | |
|---|---|---|
toasts |
true |
show live status messages |
toastMs · toastOpacity · toastMaxVisible |
3500 · 0.78 · 3 |
how long, how visible, how many |
badge · badgeCorner · edgePulse |
true · "tc" · true |
the tab indicator and its breathing border |
badgeCorner positions |
tc · bc · tl · tr · bl · br |
where the overlay parks. Drag the chip to move it anywhere; that position is remembered per origin. Messages travel with it, so toastCorner follows badgeCorner |
showCursor · highlightInspected |
true · true |
show where interaction happens, and what was inspected |
ownerTimeoutMs |
45000 |
how long an indicator stays up without hearing from its session, before removing itself |
followNewTabs |
true |
mark and hold tabs the app opens for itself, so a popup is never an unmarked blind spot |
chromeProfile |
"isolated" |
or "default" to reuse your signed-in Chrome, or a path |
disableWebSecurity |
false |
leave off: it hides the CORS bugs you would be debugging |
chromeFlags |
[] |
extra Chrome flags |
evalTimeoutMs · toolTimeoutMs |
8000 · 30000 |
liveness ceilings |
autoResumeDefault · maxPauseMs |
true · 30000 |
autonomous pause control |
captureInputValues |
false |
always-on capture of typed values |
docsRoot |
auto | where to read your project's README and docs |
sharedMemoryDir |
null |
pool learned fixes across a team |
tabGroupMode |
"session" |
one tab group per session, or "single" for all |
docsRoot and sharedMemoryDir are the two worth setting: the first lets the
assistant learn your domain vocabulary, the second is what makes "the team's fixes
accumulate" actually true.
Multiple sessions at once
Several agents can debug on one machine safely. Each session claims a tab in a
registry under ~/.devcdp/registry/, taken atomically so two processes cannot win
the same tab. A session that dies stops heartbeating and its claim is reaped, so
nothing stays wedged.
- A new session gets an unclaimed tab; if all are taken it opens its own — on the page you wanted, not blank, and it says why.
- Reloading your assistant briefly overlaps two server processes, so a short grace period lets the departing one release its tab and the new one simply reattaches.
browser: 'new'launches a separate Chrome, own port and profile.window: 'new'gives the session its own browser window.sessions_listshows which session holds which tab.
Knowing which tab is in use
Every claimed tab carries a 1px edge border and a small identity chip. The border tells you who is driving:
- breathing blue glow — DevCDP is working
- still, green — it has handed control to you
- still, red — something failed
Three states, three colours, and each colour means exactly one thing regardless of how many sessions are running. Sessions are told apart by the chip text and by their own Chrome tab group — not by hue, which would turn the border into a puzzle when the only thing worth knowing at a glance is whether the tab is waiting for you.
Tabs the app opens for itself — window.open, target="_blank", a detail screen
in its own window — are marked and held too, labelled "opened tab". devtools_status
lists them under tabsAppOpened, with the call that switches to one.
The indicator cannot outlive the session that drew it. A normal finish — you close
the assistant, it disconnects, the session ends — removes the border immediately. If the
server is killed and never gets to clean up, the overlay notices it has stopped hearing
from its session and removes itself within ownerTimeoutMs (45s), taking the tab out of
its group with it. Either way, a border on screen means a session is genuinely there. For
one left behind by an older build, node scripts/sweep.mjs clears any that no live
session owns (--dry to look first).
Status messages appear as translucent, self-fading toasts. A ring follows pointer activity and a ripple marks each click, so an agent's actions are followable. When the debugger pauses, Chrome's own "Paused in debugger" banner appears — browser UI, adding nothing to your page.
None of it can intercept a click: the whole layer is pointer-events: none except
the confirmation button during a handover, which is 91×24px. There is a test that
fires real mouse events through it.
Real Chrome tab groups are drawn by the bundled extension, which puts each session's
tabs in a titled blue group. Chrome will not let a tool install an extension for you —
branded Google Chrome ignores --load-extension ("not allowed in Google Chrome", from its
own log) and does not expose Extensions.loadUnpacked over the debugging port — so pick
one of:
- No manual step: point
chromePathat Chromium or Chrome for Testing. Those builds allow the switch, so the extension loads itself and grouping just works. If such a binary is already on your machine,devtools_statustells you where it is. - Branded Chrome: install it once —
chrome://extensions→ Developer mode → Load unpacked → selectextension/. The debug profile is persistent and shared bydebug-chrome.batand DevCDP's own launcher, so once is once.
devtools_status.tabGrouping reports whether the tab is actually in a group, and when it
is not, whether that is because no extension is installed or because an installed one
failed — with the error. Nothing else depends on grouping: the border, the chip and
window:'new' all work without it.
Working with the assistant
You do not have to wait to be asked. Click, type, choose — it is recorded, and the
assistant reads it with session_get_user_actions: which element, which option,
and the value you typed.
Ctrl+Shift+D in the tab hands control to you explicitly. That also opens the window in which typed values are captured, so "use this reference" reaches the assistant. Outside that window values stay private, and password-like fields are redacted either way.
When the assistant needs something only you can do, it asks on the page and waits for the I've done it ✓ button. That button is the only unambiguous signal — Chrome reports automation input as trusted too, so an action cannot be proven human, and the tools say so rather than pretending.
A typical investigation
"The save button does nothing. Find the exact line."
devtools_connect— attaches, claims the tab, marks itsource_search("save")— finds the handler by content, no path neededdebugger_set_breakpoint(file, line)— repliesbound: true- the click is triggered
debugger_get_capture— scope, console and network from the pause, one call- the answer is a value that was actually observed, at a line that actually exists
Breakpoints resume themselves, so the click that tripped one still completes.
When you know the function but not the file — which is the usual case with a framework —
debugger_set_breakpoint_at_function("app.store.save") asks the engine where that
function was defined and breaks at its first statement. Searching for a name in source
text is unreliable: a function assigned as Foo.bar = function cannot be found by
searching "bar: function", and that query happily returns unrelated methods on other
classes instead.
A capture stays small even on a framework object graph: the variable that matters is
printed, and anything too large says what it is ("constructor", 77747 bytes expanded)
so you can read just the part you want with debugger_evaluate_at_frame.
Security
The launcher uses a separate Chrome profile, so your everyday browsing is untouched, and leaves web security enabled — disabling it hides exactly the cross-origin failures you would be debugging.
Typed values are not recorded unless you enable it or are actively collaborating, and password-like fields stay redacted regardless.
Remote debugging gives full control of the browser profile to anything that can reach the port. Use the debug profile for development, not for personal accounts.
Layout
index.js entry point
server.js shim for older configs pointing here
src/
core/ config, context, buffers, structured errors, tool registry
cdp/ connection, target selection, session claim registry, launching
browser/ the injected in-page agent
debug/ source maps, scope expansion
store/ learned-memory store
tools/ one module per tool group
extension/ companion extension for Chrome tab groups
plugins/devcdp/ Claude Code plugin: manifest, launcher, skill (generated)
server.json MCP Registry manifest; must agree with package.json
scripts/gen-docs.mjs regenerates docs/TOOLS.md and the plugin skill
docs/TOOLS.md full tool reference (generated)
docs/PUBLISHING.md how each marketplace listing is made and kept current
test/
validate.mjs offline checks, no browser needed
installer.test.mjs the setup wizard, against real files
integration.mjs real Chrome against a fixture app
fixture-app/ small app with a staged bug and a real source map
BACKLOG.md every defect found, its fix, and what remains
Working on DevCDP
node scripts/call.mjs <tool> '<json>' call one tool, see the exact response and its cost
node scripts/mcp-probe.mjs the same thing over real MCP, raw JSON-RPC
Breakpoints, logs, and the traps this codebase has already fallen into: docs/DEBUGGING.md.
Tests
npm run validate offline checks
npm run test:installer the setup wizard
npm test all three suites
npm run docs regenerate the tool reference
199 checks. The integration suite attaches to a page that has already finished
loading, because that is the case the previous version got wrong. npm run validate fails if docs/TOOLS.md is out of date, so the reference cannot drift.
Troubleshooting
Tools not appearing — fully quit the assistant (tray/menu, not just the window) and reopen. Re-run the wizard if still missing.
"Chrome is not reachable" — launch via debug-chrome.bat, then check
http://localhost:9222/json/version. Only one Chrome can own a port.
A breakpoint never fires — debugger_list_breakpoints and look at bound. An
unbound breakpoint reports why.
Support the project
DevCDP is free and MIT-licensed, built and maintained by one person. If it saved you a debugging afternoon, sponsoring on GitHub keeps it moving. Teams wanting a hosted setup, shared learned memory across engineers, or an onboarding workshop can open an issue to start the conversation.
Privacy and license
DevCDP runs locally and sends nothing anywhere except to the MCP client you connected it to: PRIVACY.md. MIT licensed: LICENSE.
A selector finds nothing — dom_list_frames; the content may be in an iframe.
Retry with frame: 'all'.
Empty console or network right after attaching — expected. Capture starts at
attach; page_reload replays the page with DevCDP watching.
The page stops responding — its main thread is blocked, usually a loop in app
JS. page_interrupt aborts the running script; reloading will not free it.
A tab is unavailable — sessions_list shows which session holds it.
devcdp MCP 질문
devcdp MCP를 Claude Code에 추가하려면 어떻게 하나요?
터미널에서 claude mcp add devcdp -- npx -y devcdp를 실행합니다. 모든 프로젝트에서 사용할 수 있게 하려면 --scope user를 추가합니다.
devcdp MCP를 Cursor에 추가하려면 어떻게 하나요?
~/.cursor/mcp.json를 열고 mcpServers 아래에 서버를 추가합니다. 위 설치 섹션에 표시된 Cursor 구성을 사용합니다.
어시스턴트가 콘솔에서 무엇을 볼 수 있나요?
어시스턴트는 로그, 경고 및 처리되지 않은 예외에 접근할 수 있으며, 여기에는 파일 이름, 1부터 시작하는 라인 번호 및 스택 트레이스가 포함됩니다.
소스 맵은 어떻게 처리하나요?
인증 뒤에 있는 외부 .map 파일을 포함하여 번들링 전의 원본 파일을 복구하기 위해 소스 맵을 해석할 수 있으며, 전체 텍스트 검색을 지원합니다.
어시스턴트가 사용하는 동안 웹 앱과 상호작용할 수 있나요?
네, 언제든지 제어권을 가져올 수 있습니다. 사용자의 클릭, 선택 및 타이핑은 기록되어 어시스턴트가 읽을 수 있습니다.
스크립트가 무한 루프에 빠지면 어떻게 되나요?
서버는 페이지 호출에 대해 타임아웃을 적용합니다. 페이지가 무한 루프에 빠진 경우 DevCDP가 실행 중인 스크립트를 중단하고 자동으로 재시도합니다.