브라우저와 개발 서버 로그를 단일 타임라인으로 상관 분석하여 AI agent가 웹 및 React Native 애플리케이션을 디버깅할 수 있도록 지원합니다.
다른 이름 vincentvella/devloop, devloop-mcp
- 스타
- 2
- Tools
- 41
- 다운로드, 30일
- —
- 최신 버전
- 0.13.0
- 마지막 커밋
- 2026년 11월 10일
- 라이선스
- MIT
Devloop MCP란?
Devloop은(는) MCP server입니다. 브라우저와 개발 서버 로그를 단일 타임라인으로 상관 분석하여 AI agent가 웹 및 React Native 애플리케이션을 디버깅할 수 있도록 지원합니다. 41개 도구를 제공합니다. 예: dev_start, dev_stop, dev_status.
프로젝트 README에서 생성된 요약
Devloop MCP server 정보
Devloop는 브라우저와 개발 서버 로그를 타임스탬프가 포함된 단일 타임라인으로 동기화하여 통합 디버깅 환경을 제공합니다. 이를 통해 개발자와 AI agent는 프론트엔드 콘솔 에러와 백엔드 스택 트레이스를 동일한 시점의 데이터로 상관 분석할 수 있습니다. Puppeteer와 Chrome을 통한 웹 애플리케이션은 물론, iOS 및 Android 환경의 Expo와 React Native 프로젝트를 위한 모바일 개발도 지원합니다.
사용자는 Claude Code와 같은 도구를 위한 headless stdio 모드, HTTP/SSE를 통한 롱러닝 데몬, 또는 Cockpit이라 불리는 Electron 기반의 데스크톱 애플리케이션을 통해 서버와 상호작용할 수 있습니다. Cockpit 인터페이스에는 내장 브라우저 창과 모바일 테스트를 위한 실시간 대화형 디바이스 미러가 포함되어 있습니다. 네이티브 모바일 디버깅을 위해 이 시스템은 Metro, Hermes, iOS용 idb, Android용 adb와 통합되어 소스 맵이 적용된 스택과 네트워크 캡처를 제공합니다.
이 도구는 코드 분석에만 의존하기보다 기능을 실시간으로 검증해야 하는 엔지니어를 위해 설계되었습니다. 접근성 기반 요소 선택을 위한 browser_snapshot, 상호작용 시퀀스 재생을 위한 repro, 실패한 네트워크 요청과 에러를 그룹화하는 diagnose와 같은 특화된 도구를 제공합니다.
활용 사례
- 1프론트엔드 및 백엔드 에러 상관 분석AI agent는 공유된 단조 시계(monotonic clock)를 사용하여 브라우저 콘솔 에러를 특정 백엔드 스택 트레이스와 일치시킬 수 있습니다.
- 2React Native 애플리케이션 디버깅개발자는 통합 타임라인에서 JS 콘솔 에러와 네이티브 디바이스 로그를 확인하여 모바일 앱을 디버깅할 수 있습니다.
- 3기능 수정 사항 실시간 검증코드 변경 사항이 작동한다고 가정하는 대신, agent는 재현 시퀀스(reproduction sequence)를 사용하여 실행 중인 애플리케이션에서 수정 사항을 확인할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
Devloop MCP 설치 방법
형식 확인: 2026년 11월 10일Claude Code에 Devloop MCP 설치
$ claude mcp add devloop -- npx -y devloop-mcpCursor에 Devloop MCP 설치
~/.cursor/mcp.json
{
"mcpServers": {
"devloop": {
"command": "npx",
"args": [
"-y",
"devloop-mcp"
]
}
}
}VS Code에 Devloop MCP 설치
.vscode/mcp.json
{
"servers": {
"devloop": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"devloop-mcp"
]
}
}
}Claude Desktop에 Devloop MCP 설치
claude_desktop_config.json
{
"mcpServers": {
"devloop": {
"command": "npx",
"args": [
"-y",
"devloop-mcp"
]
}
}
}Codex에 Devloop MCP 설치
~/.codex/config.toml
[mcp_servers.devloop] command = "npx" args = ["-y", "devloop-mcp"]
Gemini CLI에 Devloop MCP 설치
~/.gemini/settings.json
{
"mcpServers": {
"devloop": {
"command": "npx",
"args": [
"-y",
"devloop-mcp"
]
}
}
}Devloop MCP 도구 41
README에서 감지됨dev_startdev_stopdev_statusnative_opennative_closenative_buildnative_doctorbrowser_navigatebrowser_backbrowser_screenshotbrowser_clickbrowser_type
| dev_start | — | |
| dev_stop | — | |
| dev_status | — | |
| native_open | — | |
| native_close | — | |
| native_build | — | |
| native_doctor | — | |
| browser_navigate | — | |
| browser_back | — | |
| browser_screenshot | — | |
| browser_click | — | |
| browser_type | — |
도구 41개 모두 보기도구 수 줄이기
browser_hoverbrowser_wait_for_idlebrowser_clear_storagebrowser_emulatebrowser_throttlebrowser_evalbrowser_snapshotbrowser_wait_forget_logsget_logs_aroundget_networkexport_hardiagnoseexport_bundleclear_logsreproproject_listproject_addproject_removepane_listpane_newpane_selectpane_closepane_poppane_set_labelext_listext_installext_removeext_set_enabled
| browser_hover | — | |
| browser_wait_for_idle | — | |
| browser_clear_storage | — | |
| browser_emulate | — | |
| browser_throttle | — | |
| browser_eval | — | |
| browser_snapshot | — | |
| browser_wait_for | — | |
| get_logs | — | |
| get_logs_around | — | |
| get_network | — | |
| export_har | — | |
| diagnose | — | |
| export_bundle | — | |
| clear_logs | — | |
| repro | — | |
| project_list | — | |
| project_add | — | |
| project_remove | — | |
| pane_list | — | |
| pane_new | — | |
| pane_select | — | |
| pane_close | — | |
| pane_pop | — | |
| pane_set_label | — | |
| ext_list | — | |
| ext_install | — | |
| ext_remove | — | |
| ext_set_enabled | — |
구성
DEVLOOP_DAEMON_IDLE_MS
| 이름 | 설명 | 유형 |
|---|---|---|
| DEVLOOP_DAEMON_IDLE_MS | — |
자동 검사
2026년 11월 12일에 실행됨전체 보고서 →자동 검사를 통과했습니다. 이는 보안 감사가 아닙니다. 코드를 직접 읽고 서버에 필요한 최소한의 권한만 부여하십시오. 검사 방식
- 소스 저장소 연결 및 접근 가능통과
- 오픈 소스 라이선스 (OSI)통과
- 최근 1년 내 커밋 또는 릴리스통과
- 패키지 이름이 인기 패키지와 유사하지 않음통과
- 원격 엔드포인트가 HTTPS 사용검사되지 않음
- 파괴적인 도구에 라벨 표시됨통과
- 모델에 대한 숨겨진 지침 없음통과
- 패키지와 의존성에 심각한 보안 권고 없음통과
README
GitHub에서 보기A unified dev-loop tool: it drives a browser and your dev server, pushing both sides into one timestamped buffer so you can correlate a browser console error with the backend stack trace from the same moment. It runs two ways from a shared core:
- Headless (stdio) — drives Chrome via Puppeteer, served over stdio. The lightweight mode Claude Code spawns per session. Run
devloop-mcp daemonto instead serve one shared, long-running instance over HTTP/SSE that many agents/sessions connect to (see Daemon mode). - Cockpit (Electron) — a single desktop window: tabbed browser panes (embedded
WebContentsViews driven via CDP) with a browser bar (back/forward/reload + address) beside a collapsible side panel that toggles between logs and a repro builder. Project picker, auto-navigate, pop-out targets. The renderer is React 19 + Tailwind v4 + Radix + lucide-react. Serves the same tools over HTTP.
Because every event (browser console/network/page-errors and server stdout/stderr) shares one monotonic clock, get_logs_around / repro return a correlated, cross-source slice of the timeline.
Native targets — Expo / React Native (iOS + Android)
The cockpit also drives Expo/React Native projects, not just web. Open a native project and you get one pane with a Web · iOS · Android target switcher, a bundler toggle (Metro) separate from a Build button (expo run:ios / expo run:android, with @expo/fingerprint staleness detection), and:
- JS console + errors over CDP via Metro's Hermes inspector (both platforms) — with source-mapped stacks (your bundled
index.bundle:1:…resolves to original.tsx). - RN network capture — an injected
XMLHttpRequesthook turns the app's fetch/XHR traffic into the samenetworktimeline rows as web (soget_network/export_har/ the network chip work for native too). - Native device logs merged onto the timeline as a
nativesource — iOSsimctl log stream, Androidlogcat. - A live, interactive device embedded in the pane — iOS via serve-sim (MJPEG, tap/scroll/type), Android via Expo's serve-emu (scrcpy H.264, up to 60fps, with tap/swipe/scroll/type). Screenshots on both.
- Agent-drivable interactions —
browser_snapshotreads the native accessibility tree (iOS via idb's UIKit a11y tree; Android viauiautomator dump) andbrowser_click/type/scroll/pressdrive the device by an element'spt:x,yref (from the snapshot) or its label — replayable throughrepro, openable over MCP vianative_open/native_build. The same agent tools as web, mapped onto native.
All of it lands on the same correlated timeline, app-scoped — the web dev-loop experience, for a native app. (macOS + Apple Silicon for the embedded iOS simulator; Android works wherever the Android SDK + an emulator do.)
iOS interactions need idb: brew install facebook/fb/idb-companion and pipx install fb-idb (use Python <3.14 — newer Python breaks fb-idb). Android interactions need the Android SDK platform-tools (adb) + a booted emulator. The cockpit's Settings → native readiness runs a per-platform preflight (iOS: idb · companion · booted sim; Android: adb · booted device) and shows the exact fix for anything missing; observation (logs/screenshots) works without the interaction tooling.
serve-sim is vendored into the cockpit and run via Electron's own Node, so the embedded simulator works out of the box — offline, no bun/node/npx or first-run fetch. (Running from source uses the copy in node_modules instead.)
Architecture
Three transports expose one shared core, which drives one of several substrates (a real browser, or — in the cockpit — a native device). Everything pushes onto a single timestamped timeline.
%%{init: {"flowchart": {"wrappingWidth": 700}}}%%
flowchart TD
clients["<b>MCP clients</b><br/>Claude Code · agents · mcporter"]
clients --> stdio & daemon & cockpit
stdio["<b>stdio</b><br/><i>spawned per session</i>"]
daemon["<b>daemon</b><br/><i>HTTP/SSE · one shared instance</i>"]
cockpit["<b>cockpit</b><br/><i>HTTP/SSE · Electron app</i>"]
stdio --> mcp
daemon --> mcp
cockpit --> mcp
mcp(["<b>MCP Server</b><br/><i>stdio transport, or HTTP/SSE for the daemon + cockpit</i>"])
mcp --> core
core["<b>shared core</b> · <i>transport- and substrate-agnostic</i><br/>the MCP tool layer + one unified, correlated timeline"]
core --> iface(["<b>IBrowserController · IBrowserManager · ITargetController</b><br/><i>capability-gated by the active target</i>"])
iface --> pup & elec & rn
pup["<b>web</b> · Puppeteer / Chrome<br/><i>stdio + daemon</i>"]
elec["<b>web</b> · Electron CDP panes<br/><i>cockpit · per-project partitions</i>"]
rn["<b>native</b> · React Native (Hermes)<br/><i>JS + network over Metro CDP</i>"]
rn -->|"idb / adb"| nd["<b>NativeDriver</b><br/>iOS idb · Android adb<br/>taps · snapshot · screens · logs"]
The tool layer never knows what's behind it — Puppeteer or Electron, stdio or HTTP, web page or native app. It's wired once at startup. The browser sits behind a single IBrowserController interface; the cockpit's pane manager implements the richer IBrowserManager (multiple panes, delegating browser_* to the active one — or to the native controller when an iOS/Android target is open). A capability layer gates tools by the active target, so an agent gets a clear message instead of a substrate error.
stdout is reserved for the MCP protocol in stdio mode; all human-facing output goes to stderr.
The layers
- Transports — three entrypoints over two protocols: stdio (one server per session) and HTTP/SSE (the long-running daemon, and the cockpit). All build the same MCP server bound to the tool layer; only the HTTP transports are multi-client (each connecting client gets its own session, one shared backend).
- Shared core — the tool layer (the MCP tools + a capability-gated dispatcher) over one unified, correlated timeline (server output, browser console/network/errors, native logs), backed by a separate full-capture network ring. The cross-cutting features the tools expose — a project registry, error diagnostics, source-map resolution, HAR export, and bug-report bundles — live here too.
- Browser substrates — a shared controller interface with two web implementations (Puppeteer/Chrome for headless; Electron
WebContentsViewpanes over CDP in the cockpit) and a native one (React Native over Hermes/Metro). Shared page-action + accessibility-snapshot logic and device/throttle emulation sit above them. - Native targets — an RN controller (JS/errors/network over Metro CDP) delegates taps + snapshots to a
NativeDriver(idb on iOS, adb on Android); native logs (simctl / logcat), screenshots + live mirrors, build orchestration (expo run), and a readiness preflight round it out. - State & isolation — an on-disk registry (projects / session / panes), per-project session partitions, and Chrome-extension management.
- Cockpit (Electron) — the desktop shell: a pane manager (per-project partitions, native routing), the React UI (timeline, browser bar, repro builder, target switch, Android mirror), the vendored serve-sim iOS mirror and serve-emu Android stream, the in-store "Add to Devloop" injection, and the in-app updater.
Install
Headless MCP (stdio) — no clone needed, register it with Claude Code:
claude mcp add devloop --scope user -- npx -y devloop-mcp
(Published as devloop-mcp on npm; Puppeteer fetches Chromium on first install.)
Cockpit (desktop app) — grab the installer for your OS from Releases (.dmg / .exe / .AppImage). macOS ships both Apple Silicon (arm64) and Intel (x64) builds. The app checks GitHub for a newer release on launch and prompts before downloading or installing — or trigger it yourself from settings → updates → check for updates.
From source (dev) — requires bun:
bun install
bun run app # build + launch the Electron cockpit
bun run start # or run the stdio MCP directly
Use it from your coding agent
Once it's registered, drop this into your CLAUDE.md (or any agent's rules file) so the agent drives features through Devloop and verifies them live instead of reasoning from the code alone:
## Devloop — use it for any web/mobile feature work
When you build, test, or debug a feature that runs in a **browser** or an **Expo /
React Native** app, drive it through **devloop** instead of reasoning from the code
alone. It puts the dev-server logs and the live browser/device on one correlated
timeline, so you can see what actually happened.
- **Start the loop:** `dev_start` (auto-detects the dev command), then
`browser_navigate` to the page — or `native_open` for an iOS/Android target.
- **Act, then verify — don't assume:** after a change, reproduce it with `repro`
(a navigate/click/type sequence) and read the result. Never claim a fix works
without exercising it in the running app.
- **Find/target elements** with `browser_snapshot` (returns clickable `ref`
selectors) — prefer it over screenshots.
- **When something breaks:** `diagnose` first (groups errors + failed requests),
then `get_logs_around` a timestamp to line up the browser console error with the
matching server stack trace from the same moment. `get_network` / `export_har`
for request detail.
- **Definition of done:** the feature is verified live in devloop — no console or
page errors, the expected network calls succeeded, the UI reflects the change —
not just "the code looks right."
- **Setup stays yours:** if a native build needs a toolchain that isn't installed,
devloop tells you exactly what's missing and the command to fix it — it
**diagnoses, it never installs or touches your toolchain.** Run the fix, then rebuild.
Register once: `claude mcp add devloop --scope user -- npx -y devloop-mcp`
Tools (46)
Dev server — runtime, no per-project registration needed
dev_start({ project?, cmd?, cwd? })— start a dev server and tee its logs. Specify it three ways: a saved registryproject; explicitcmd+cwd; or neither (cwddefaults to the server's dir,cmdauto-detected frompackage.jsonscripts:dev/develop/web/start/serve).dev_stop()— stop it. Kills the whole process group (sonext dev/metrograndchildren die too).dev_status()— running?, plus cmd/cwd/pid.
Native targets — Expo/React Native (cockpit only; needs Electron + a simulator/emulator)
native_open({ platform })— open the iOS simulator or Android device mirror for the active pane;browser_*then drive the native app (idb/adb) and JS + native logs stream to the timeline. Returnsok:falsewith a reason if the device/tooling isn't ready.native_close()— back to the pane's web content.native_build({ platform, cwd? })—expo run:ios/expo run:android, streamed to the timeline (cwddefaults to the active pane's project). Android returns a toolchain checklist instead of building if the SDK/JDK isn't set up.native_doctor()— re-check native readiness without building or opening: iOS + Android interactions + the Android build toolchain, each a ✓/✗ checklist with the fix for anything missing. Run it after installing a missing tool to confirm it's resolved.- In headless stdio/daemon mode these report that the cockpit is required (Puppeteer is web-only).
Browser control — act on the active pane
browser_navigate({ url })browser_back()·browser_forward()·browser_reload({ hard? })— history nav + reload (the browser bar's ←/→/⟲;hardignores cache).browser_screenshot({ fullPage? })→ PNG imagebrowser_click({ selector })browser_type({ selector, text })browser_hover({ selector })·browser_scroll({ selector? | x?, y? })·browser_select({ selector, value })·browser_press({ key, selector? })— keys likeEnter/Escape/Tab/ArrowDown.browser_wait_for_idle({ idleMs?, timeoutMs? })— wait until network settles.browser_clear_storage({ allOrigins? })— clear cookies / localStorage / IndexedDB / cache / service workers for the current origin (or the whole session) — log out / test a fresh user.browser_emulate({ device? | width?, height?, mobile?, deviceScaleFactor?, userAgent?, reset? })— emulate a device/viewport (device:iphone/ipad/pixel, or custom;reset→ desktop).browser_throttle({ profile })— network conditions:slow-3g/fast-3g/offline/none.browser_eval({ expression })— runs in page context (not blocked by CSP)browser_snapshot()— structured page snapshot: url, title, and interactive/landmark elements (role, accessible name, value/state, heading level) each with a CSS selectorrefusable bybrowser_click/browser_type. Prefer this over a screenshot to find/target elements reliably.browser_wait_for({ selector?, text?, timeoutMs? })— wait until a selector appears or text is present (after a navigation/async render). Returns{ ok, waitedMs }.
Logs & correlation
get_logs({ source?, stream?, grep?, app?, sinceSeq?, limit? })— unified tail.sourceisserver|browser;streamisstdout/stderr/console/network/pageerror.appscopes to one project's logs — it matches a pane's label (project name) or id (seepane_list) and filters both that pane's server and browser logs, regardless of which pane is active. Pass the lastseqassinceSeqto tail incrementally.get_logs_around({ ts, windowMs?, source?, app? })— the correlation tool: all events within ±windowMsof a timestamp, time-ordered across both sources (optionally scoped to oneapp).- The timeline shows network events that are failures or status ≥
DEVLOOP_NET_THRESHOLD(set it to0to surface everything inline), carrying richdetailon all substrates (Puppeteer / CDP / React Native): method, status, resource type, mime, duration, request + response headers, and capped request/response bodies. get_network({ grep?, app?, limit? })— every request from the full capture ring, independent of the threshold (vsget_logs, which shows only the curated timeline). Use it when a fast 200 you care about isn't on the timeline.export_har({ app? })— export the full network ring as a HAR 1.2 document (import into Chrome DevTools / Charles); complete regardless of the threshold. Scope to oneappif you like.diagnose({ windowMs?, app? })— triage what's broken right now: groups/dedupes repeated errors (console / page / server) with counts, lists failed/4xx-5xx network requests, and returns a one-line summary. Start here before digging throughget_logs.- Page errors carry a
resolvedStack— minified browser stack traces are mapped back to original source via the bundle's source map (the browser only de-minifies in its DevTools UI;error.stackstays compiled, so we resolve it for you). On the entry'sdetail. export_bundle({ app?, windowMs? })— a shareable bug-report bundle (JSON): diagnose summary + timeline + screenshots + HAR + repro. The cockpit's report button saves it as a self-contained HTML page.clear_logs()— reset before reproducing an issue.repro({ actions | action, waitFor?, settleMs?, stepSettleMs?, idleMs?, timeoutMs?, continueOnError?, clear? })— reproduce-and-correlate: clears the buffer, performs one action or a sequence, waits, and returns everything that happened on both sides across the sequence — with per-step results (steps[]), abyStreamcount, and a pre-filterederrorslist.actions: [{kind, ...}]— kinds:navigate/click/type/hover/scroll/select/press/eval/wait/none.action(singular) = one-step convenience.- Waits
stepSettleMs(default 300) between steps,settleMs(default 1000) after the last.waitFor: "networkidle"waits until no network activity foridleMs(default 500) up totimeoutMs(default 10000) — use it for slow/streaming responses (Expo's first web bundle takes ~12s). On timeout you still get what landed, with awaitNote. continueOnError(default false) — otherwise stops at the failing step (stoppedAtStep).
Project registry — saved projects, persisted to ~/.devloop/projects.json
project_list()— list saved projects (name, cwd, cmd, url, steps).project_add({ name, cwd, cmd?, url?, steps? })— save/replace a project (incl. a saved reprostepssequence), so you candev_start({ project })by name.project_remove({ name }).
Panes — multi-target (cockpit only; stdio mode is single-pane and reports so)
pane_list()— each pane:{ id, url, active, popped }. The active pane is whatbrowser_*/reprotarget; events are tagged with their paneid.pane_new({ url? })— open a new pane and make it active.pane_select({ id })— make a pane active.pane_close({ id }).pane_pop({ id })— detach a pane into its own standalone window (side-by-side targets).pane_set_label({ id, label })— rename a pane (same as double-clicking the tab).
Extensions — Chrome extension management (cockpit only)
ext_list()— installed extensions:{ id, name, version, enabled }.ext_install({ idOrUrl })— install by Chrome Web Store id/URL.ext_remove({ id })— uninstall.ext_set_enabled({ id, enabled })— enable/disable without uninstalling.
Console arguments
console.log(obj) is captured with arguments resolved to real values (e.g. [log] user {"id":7}), not JSHandle@object. The Electron substrate renders them synchronously from CDP previews; the Puppeteer substrate uses a reserve-then-fill pattern (stamp seq/ts synchronously at arrival, patch resolved args in afterward) so ordering matches emit order and interleaves correctly with server logs.
Headless mode (stdio)
Register once, at user scope — works for every project:
claude mcp add devloop --scope user -- npx -y devloop-mcp
Then, in any project: "dev_start and repro a navigate to /projects". dev_start defaults cwd to the project you're in and auto-detects the command.
| Var | Default | Meaning |
|---|---|---|
DEVLOOP_HEADLESS |
false |
"true" runs Chrome headless; default headful so you can watch. |
DEVLOOP_CHROME_PATH |
(bundled) | Explicit Chrome executable path. |
DEVLOOP_NET_THRESHOLD |
400 |
Log network responses with status >= this (failures always logged). |
DEVLOOP_ACTION_TIMEOUT |
10000 |
Cap (ms) on interactions — a wedged page fails fast instead of hanging. |
DEVLOOP_NAV_TIMEOUT |
30000 |
Cap (ms) on navigations. |
DEVLOOP_LOG_CAPACITY |
5000 |
Max buffered events. |
DEVLOOP_NET_RING |
3000 |
Max requests held in the full-capture network ring (get_network / export_har), independent of DEVLOOP_NET_THRESHOLD. |
DEVLOOP_DEV_CMD / DEVLOOP_DEV_CWD |
(none) | Optional dev-server auto-start on boot (normally use dev_start). |
DEVLOOP_HOME |
~/.devloop |
Registry location. |
Daemon mode (shared HTTP/SSE)
Run one long-running daemon yourself (stdio launches already do this per project; see Shared mode below) they all connect to over HTTP/SSE — many clients, one Devloop instance (one browser, one dev server, one correlated timeline):
devloop-mcp daemon # headless; serves MCP at http://localhost:7333/mcp
# then point any number of MCP clients at it:
claude mcp add --transport http devloop http://localhost:7333/mcp
Same backend + env vars as stdio (defaults headless; set DEVLOOP_HEADLESS=false to watch), and it auto-picks a free port from DEVLOOP_HTTP_PORT (default 7333), or any free port if the next ten are all taken. Each client gets its own MCP session but shares the same backend, so one agent's dev_start / navigation shows up on another's get_logs. (The Electron cockpit serves the very same HTTP transport — the daemon is just the headless version of it.)
Manage the daemon's lifecycle:
devloop-mcp daemon --status # is one running? (pid + url)
devloop-mcp daemon --stop # SIGTERM the running daemon
DEVLOOP_DAEMON_IDLE_MS=60000 devloop-mcp daemon # auto-exit 60s after the last client disconnects
Shared mode — on by default for stdio
You don't need to run a daemon yourself. A plain stdio launch (npx -y devloop-mcp) bridges to a daemon for its project: it connects to the one already running for that directory, or spawns and detaches one if there isn't one. Restarting Claude Code, /mcp reconnects, and new sessions in the same repo therefore reuse the same Chrome instead of opening another one. Two repos open at once get separate daemons, so their dev servers and timelines don't collide.
The stdio process becomes a thin proxy: it speaks stdio to the client and forwards tools to the daemon over HTTP. Chrome only opens when a browser tool is first used, never just because a session started. An auto-spawned daemon keeps stdio's visible browser (DEVLOOP_HEADLESS=true to hide it), runs in the project directory, and exits 10 minutes after its last session disconnects (DEVLOOP_DAEMON_IDLE_MS to change that). Run devloop-mcp daemon --status / --stop inside the project to manage that project's daemon. If the daemon goes away mid-session (stopped, crashed, or idled out), the bridge reconnects on the next call, starting a new daemon if needed, so you don't have to /mcp reconnect. If anything goes wrong at launch (the daemon won't start, etc.), the session falls back to a normal local instance, so it never just dies.
npx -y devloop-mcp --shared # or DEVLOOP_DAEMON=1: one global daemon shared by every project
npx -y devloop-mcp --local # or DEVLOOP_DAEMON=0: the old behavior, one browser per session
The global daemon advertises itself in $DEVLOOP_HOME/daemon.json, and per-project daemons in $DEVLOOP_HOME/daemons/.
Devloop MCP 질문
Devloop MCP를 Claude Code에 추가하려면 어떻게 하나요?
터미널에서 claude mcp add devloop -- npx -y devloop-mcp를 실행합니다. 모든 프로젝트에서 사용할 수 있게 하려면 --scope user를 추가합니다.
Devloop MCP를 Cursor에 추가하려면 어떻게 하나요?
~/.cursor/mcp.json를 열고 mcpServers 아래에 서버를 추가합니다. 위 설치 섹션에 표시된 Cursor 구성을 사용합니다.
Devloop MCP는 어떤 도구를 제공하나요?
41개 도구를 제공합니다. 예: dev_start, dev_stop, dev_status, native_open, native_close.
headless MCP 버전을 어떻게 설치하나요?
Claude Code에서 다음 명령어를 사용하여 등록할 수 있습니다: claude mcp add devloop --scope user -- npx -y devloop-mcp.
Devloop가 모바일 앱 개발을 지원하나요?
네, iOS 및 Android용 Expo와 React Native 프로젝트를 지원하며, JS 콘솔 에러, 네트워크 캡처, 네이티브 디바이스 로그를 제공합니다.
iOS 상호작용을 위해 무엇이 필요한가요?
iOS 상호작용을 위해서는 brew를 통해 idb companion를, pipx를 통해 fb-idb를 각각 설치해야 합니다.
Android에서도 Devloop를 사용할 수 있나요?
네, Android 상호작용을 위해서는 Android SDK platform-tools (adb)와 실행 중인 에뮬레이터가 필요합니다.