# Devloop (npm · devloop-mcp)

Browser + dev-server logs on one correlated timeline, for Claude Code and AI agents.

- Trust score: 81/100 (high trust)
- Change this week: +57
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `devloop-mcp`: 81/100 (this document), [markdown](https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp.md), [page](https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp)

## Channel facts

- Registry: `npm`
- Package: `devloop-mcp`
- Version: `0.10.2`
- Transport: `stdio`

## Trust breakdown

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

Scored 2026-08-03.

- **Supply Chain Security**: 89/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 27 of 29 dependencies flagged as unhealthy (27 deprecated).
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to vincentvella/devloop).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 11 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 81/100
  - AI-judged instruction clarity (excellent).
  - Tool/resource definitions use about 4050 tokens (~88/item across 46 items; 46 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 23/100
  - Stability observed for 7 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add vincentvella-devloop -- npx -y devloop-mcp
```

### Codex

```bash
codex mcp add vincentvella-devloop -- npx -y devloop-mcp
```

### opencode

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

### OpenClaw

```bash
openclaw mcp add vincentvella-devloop --command npx --arg -y --arg devloop-mcp
```

### Hermes

```yaml
mcp_servers:
  vincentvella-devloop:
    command: "npx"
    args: ["-y", "devloop-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "vincentvella-devloop": {
      "command": "npx",
      "args": [
        "-y",
        "devloop-mcp"
      ]
    }
  }
}
```

## Changelog

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

### 2026-08-03 (score 81, +1)

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

### 2026-08-02 (score 80, +15)

- [security regression] Provenance: pass → unverified
- [security regression] Install scripts: pass → unverified
- [security regression] Known CVEs: pass → unverified
- [security improvement] Malware scan: unverified → pass
- [security] The attested source repository moved: vincentvella/devloop
- [functional regression] Dependency health: 0.94 → 0.14
- [functional regression] License: pass → unverified
- [functional regression] Dependency health: 0.94 → unverified
- [functional regression] Maintenance: pass → unverified
- [functional improvement] Stability: unverified → 0.20
- [functional] Licence: MIT

### 2026-07-31 (score 65, +2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 63, +17)

- [security regression] Malware scan: pass → unverified
- [security improvement] Install scripts: unverified → pass
- [security improvement] Provenance: unverified → pass
- [security improvement] Known CVEs: unverified → pass
- [security] The attested source repository moved: vincentvella/devloop
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → 0.94
- [functional improvement] Maintenance: unverified → pass
- [functional] Licence: MIT

### 2026-07-28 (score 46, +22)

- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: unverified
- [functional] First check of Tool coverage: 100
- [functional] First check of Schema quality: pass
- [functional] First check of Schema quality: fail

### 2026-07-27 (score 24)

First indexed and scored.

## MCP tools (46)

### `browser_navigate` (~70 tokens)

Navigate the active pane to a URL (full page load). Returns the resolved URL and HTTP status. Use browser_back / browser_forward to move through history, browser_reload to refresh the same URL.

Input parameters:

- `url` (string, required): Absolute URL to load (e.g. http://localhost:3000/path).

### `browser_back` (~46 tokens)

Go back one entry in the active pane's history (no-op if there's nothing to go back to). Pairs with browser_forward; use browser_navigate to go to a new URL.

### `browser_forward` (~46 tokens)

Go forward one entry in the active pane's history (no-op if there's nothing to go forward to). Pairs with browser_back; use browser_navigate to go to a new URL.

### `browser_reload` (~50 tokens)

Reload the active pane's current page. Use browser_navigate to change URL instead.

Input parameters:

- `hard` (boolean): Ignore the cache (hard reload). Default false. Cockpit only; ignored under Puppeteer.

### `browser_screenshot` (~53 tokens)

Capture a PNG screenshot of the active page. To find/target elements, prefer browser_snapshot (returns selectors).

Input parameters:

- `fullPage` (boolean): Capture the full scrollable page, not just the viewport (default false).

### `browser_click` (~59 tokens)

Click the element matching a CSS selector (real mouse click). For keyboard keys use browser_press; to only hover use browser_hover.

Input parameters:

- `selector` (string, required): CSS selector of the element to click (e.g. a `ref` from browser_snapshot).

### `browser_type` (~70 tokens)

Type text into the element matching a CSS selector (focuses, then types). For single keys use browser_press; for <select> use browser_select.

Input parameters:

- `selector` (string, required): CSS selector of the input/textarea to type into.
- `text` (string, required): Text to type into the focused element.

### `browser_eval` (~79 tokens)

Evaluate a JavaScript expression in the active page (via CDP) and return its value. Runs in the page's main world and can mutate page state. Prefer browser_snapshot for reading structure and browser_click/type for interactions.

Input parameters:

- `expression` (string, required): A JavaScript expression evaluated in the page; its result is returned (JSON-serializable values).

### `browser_hover` (~46 tokens)

Hover the pointer over an element to trigger hover menus/tooltips. Does not click — use browser_click for that.

Input parameters:

- `selector` (string, required): CSS selector of the element to hover over.

### `browser_scroll` (~94 tokens)

Scroll an element into view (pass selector), or scroll the window to coordinates (pass x and y). Provide a selector OR x+y, not both.

Input parameters:

- `selector` (string): CSS selector to scroll into view. Omit to scroll the window instead.
- `x` (number): Window scroll-x in pixels (used when no selector).
- `y` (number): Window scroll-y in pixels (used when no selector).

### `browser_select` (~70 tokens)

Set the value of a <select> (or input) and fire input/change events. For typing free text use browser_type.

Input parameters:

- `selector` (string, required): CSS selector of the <select> or input.
- `value` (string, required): The option's value attribute (not its visible label) to select.

### `browser_press` (~75 tokens)

Press a single key (e.g. Enter, Escape, Tab, ArrowDown) on the page. For typing text use browser_type.

Input parameters:

- `key` (string, required): Key name to press, e.g. Enter, Escape, Tab, ArrowDown.
- `selector` (string): Optional CSS selector to focus before pressing the key.

### `browser_emulate` (~179 tokens)

Emulate a device/viewport on the active page. Pass a `device` preset, or custom `width`+`height`. `reset: true` restores a desktop viewport. For network conditions use browser_throttle instead.

Input parameters:

- `device` (string): Device preset to emulate. Use this OR width+height.
- `deviceScaleFactor` (number): Device pixel ratio (e.g. 2 for retina). Default 1.
- `height` (number): Custom viewport height in CSS pixels (with width).
- `mobile` (boolean): Emulate a mobile device (touch + mobile UA hints). Default false.
- `reset` (boolean): Restore the default desktop viewport and clear emulation.
- `userAgent` (string): Override the User-Agent string.
- `width` (number): Custom viewport width in CSS pixels (with height).

### `browser_throttle` (~57 tokens)

Throttle the active page's network conditions to a named profile. Use `none` to clear. For viewport/device emulation use browser_emulate.

Input parameters:

- `profile` (string, required): Network profile to apply; `none` removes throttling.

### `browser_clear_storage` (~77 tokens)

Clear the active page's storage — cookies, localStorage, IndexedDB, cache, service workers — for the current origin. Set allOrigins to wipe the whole browser session. Use to log out or test a fresh-user flow; reload afterward.

Input parameters:

- `allOrigins` (boolean): Wipe the entire session, not just the current origin.

### `browser_wait_for_idle` (~85 tokens)

Wait until network activity settles (no requests for idleMs). Returns { ok }. To wait for a specific element/text use browser_wait_for.

Input parameters:

- `idleMs` (number): Quiet period with no requests that counts as idle, in ms (default 500).
- `timeoutMs` (number): Max time to wait before giving up, in ms (default 10000).

### `browser_snapshot` (~135 tokens)

Capture a structured snapshot of the active page: url, title, and the interactive + landmark elements (role, accessible name, value/state, heading level), each with a CSS selector `ref`. Pass a returned `ref` to browser_click / browser_type. Caps at 250 elements by default (raise `limit` for dense pages); `truncated:true` means the cap was hit. Prefer this over browser_screenshot to find and target elements reliably.

Input parameters:

- `limit` (number): Max elements to return (default 250). Raise it for dense pages (large tables / long forms) where the default truncates the snapshot.

### `browser_wait_for` (~116 tokens)

Wait until a CSS selector appears or text is present on the page (e.g. after a navigation or async render). Returns { ok, waitedMs } — ok=false on timeout. To wait for the network to go quiet instead, use browser_wait_for_idle.

Input parameters:

- `selector` (string): CSS selector to wait for.
- `text` (string): Substring of page text to wait for (if no selector).
- `timeoutMs` (number): Max time to wait before giving up, in ms (default 10000).

### `get_logs` (~201 tokens)

Return recent events from the unified buffer (server stdout/stderr + browser console/network/pageerror), newest last. Filter by source, stream, grep, and tail incrementally with sinceSeq. Scope to one project's logs with `app`. For events around a specific moment use get_logs_around; to triage errors first use diagnose.

Input parameters:

- `app` (string): Scope to a specific app/project — matches a pane's label (project name) or id (see pane_list). Omit for all apps.
- `grep` (string): Case-insensitive regex (or substring if invalid).
- `limit` (number): Max events (default 200).
- `sinceSeq` (number): Only events with seq >= this (for incremental tailing).
- `source` (string): Limit to one source: server, browser, or native.
- `stream` (string): Limit to one stream, e.g. stdout, stderr, console, network, pageerror.

### `get_logs_around` (~129 tokens)

Return ALL events (server + browser) within +/- windowMs of a timestamp, time-ordered — the correlation tool. E.g. the browser console error and the backend stack trace from the same moment. Timestamps come from the `ts` field on any event.

Input parameters:

- `app` (string): Optional: scope to one app/project (pane label or id; see pane_list).
- `source` (string): Optional: limit to one side.
- `ts` (number, required): Center timestamp (ms since epoch).
- `windowMs` (number): Half-window in ms (default 500).

### `clear_logs` (~37 tokens)

Clear the event buffer (irreversible). Call before reproducing an issue for a clean window. Note: repro clears for you unless clear=false.

### `export_bundle` (~109 tokens)

Export a shareable bug-report bundle as one JSON object: the diagnose summary, the timeline (logs), captured screenshots, a HAR of network, and repro steps if provided. For just the network log use export_har; for a quick triage use diagnose.

Input parameters:

- `app` (string): Scope to one app/project (pane label or id; see pane_list). Omit for all.
- `windowMs` (number): Only include events from the last N ms (default: the whole buffer).

### `diagnose` (~92 tokens)

Triage what's broken right now: group repeated errors (browser console/page errors + server errors) with counts, list failed/4xx-5xx network requests, and return a one-line summary. Start here before digging through get_logs.

Input parameters:

- `app` (string): Scope to one app/project (pane label or id).
- `windowMs` (number): Only consider events from the last N ms (default: all).

### `export_har` (~96 tokens)

Export captured network requests as a HAR 1.2 document (importable into Chrome DevTools / Charles). Covers ALL requests (the full network ring, independent of DEVLOOP_NET_THRESHOLD — bodies kept for the curated subset: failures + status ≥ threshold). To browse requests in JSON use get_network.

Input parameters:

- `app` (string): Scope to one app/project (pane label or id; see pane_list). Omit for all.

### `get_network` (~118 tokens)

List captured network requests (the full ring — every request, independent of DEVLOOP_NET_THRESHOLD). Each row has method/url/status/timing/headers (bodies for the curated subset). Unlike get_logs (curated timeline only); for an importable HAR file use export_har.

Input parameters:

- `app` (string): Scope to one app/project (pane label or id).
- `grep` (string): Substring match on the request line (status/method/url).
- `limit` (number): Max rows (most recent), default 200.

### `dev_start` (~153 tokens)

Start a dev server and tee its logs into the buffer. Three ways to specify it: (1) `project` — a saved registry project (resolves cmd/cwd); (2) explicit `cmd`+`cwd`; (3) neither — `cwd` defaults to the server's directory and `cmd` is auto-detected from package.json. Explicit cmd/cwd override the project's. Stop it with dev_stop; check it with dev_status.

Input parameters:

- `cmd` (string): Full dev command. If omitted, auto-detected from package.json.
- `cwd` (string): Project directory. Defaults to the server's cwd.
- `project` (string): Name of a saved project (see project_list).

### `dev_stop` (~29 tokens)

Stop the running dev server (SIGTERM). Returns whether one was running. Start one with dev_start.

### `project_list` (~34 tokens)

List saved projects (name, cwd, cmd, url) from the registry. Add with project_add, remove with project_remove.

### `project_add` (~97 tokens)

Save (or replace) a project in the registry so you can dev_start it by name. Replaces any existing project with the same name.

Input parameters:

- `cmd` (string): Dev command (optional; auto-detected if omitted).
- `cwd` (string, required): Project directory.
- `name` (string, required): Unique project name (used to dev_start it later).
- `url` (string): Default URL to open in the browser pane (optional).

### `project_remove` (~51 tokens)

Remove a saved project from the registry by name (irreversible; doesn't stop a running server). List names with project_list.

Input parameters:

- `name` (string, required): Name of the saved project to remove (see project_list).

### `pane_list` (~46 tokens)

List browser panes (multi-target): each has id, url, active. The active pane is what browser_*/repro act on. Switch with pane_select. (Cockpit only.)

### `pane_new` (~210 tokens)

Open a new browser pane and make it active. Optionally navigate it to a URL and/or scope it to a project. Pass a saved `project` (resolves cwd/cmd/url/name), or explicit `cwd`/`cmd`/`label`, to scope the pane — cwd isolates its storage partition and names it. With none of these it's a blank, unscoped pane. To switch panes use pane_select; to close use pane_close. (Cockpit only.)

Input parameters:

- `cmd` (string): Dev command to associate with the pane (used by a later dev_start).
- `cwd` (string): Project directory to scope the pane to (isolates its storage partition).
- `label` (string): Display name for the pane (defaults to the project name or cwd basename).
- `project` (string): Name of a saved project to scope this pane to (see project_list).
- `url` (string): Optional URL to open (else the project's URL, else a blank pane).

### `pane_select` (~51 tokens)

Make a pane active so subsequent browser_*/repro calls target it. Find ids with pane_list. (Cockpit only.)

Input parameters:

- `id` (string, required): Id of the pane to activate (from pane_list).

### `pane_close` (~54 tokens)

Close a browser pane by id (irreversible). To detach a pane into its own window instead, use pane_pop. (Cockpit only.)

Input parameters:

- `id` (string, required): Id of the pane to close (from pane_list).

### `pane_pop` (~62 tokens)

Detach a pane into its own standalone window (to view targets side-by-side). Closing that window re-docks the pane. pane_close removes it. (Cockpit only.)

Input parameters:

- `id` (string, required): Id of the pane to pop out (from pane_list).

### `pane_set_label` (~73 tokens)

Set a pane's display label (the tab name). Also what `app` filters match in get_logs/diagnose. (Cockpit only.)

Input parameters:

- `id` (string, required): Id of the pane to label (from pane_list).
- `label` (string, required): New display label (e.g. the project name).

### `dev_status` (~33 tokens)

Report whether the dev server is running, plus its cmd/cwd/pid. Start/stop with dev_start/dev_stop.

### `native_open` (~134 tokens)

Open a native target for the active pane (Expo/React Native): the iOS simulator or the Android device mirror. browser_* (snapshot/click/type/scroll/press/screenshot) then drive the native app via idb/adb, and JS + native logs stream to the timeline. Cockpit-only (needs the Electron app + a booted simulator/emulator). Returns ok:false with a reason if the device/tooling isn't ready. Build the app first with native_build; close with native_close.

Input parameters:

- `platform` (string, required): Which native target to open: ios (simulator) or android (emulator mirror).

### `native_close` (~36 tokens)

Close the active native target; browser_* route back to the pane's web content. (Cockpit only.) Open one with native_open.

### `native_build` (~150 tokens)

Build + launch the native dev build for the active pane (`expo run:ios` / `expo run:android`); output streams to the timeline. Cockpit-only, local build. Needs the native toolchain (Xcode for iOS; Android SDK + `adb` + a JDK + `$ANDROID_HOME` for Android). If the Android toolchain isn't set up it returns `started:false` with a checklist of exactly what to install, instead of failing cryptically. After it boots, use native_open to drive it.

Input parameters:

- `cwd` (string): Project directory to build; defaults to the active pane's project.
- `platform` (string, required): Which platform to build: ios or android.

### `native_doctor` (~118 tokens)

Report native readiness without building or opening anything: iOS simulator interactions, Android device interactions, and the Android local build toolchain — each a ✓/✗ checklist with the fix for anything missing. Cockpit-only, read-only. Re-probes live each call — run it after installing a missing tool to confirm it's resolved before native_build / native_open, or proactively before a long build. Returns { ios, androidInteractions, androidBuild }, each { ready, checks, summary }. native_build to build; native_open to drive a device.

### `ext_list` (~40 tokens)

List Chrome extensions (loaded + disabled): id, name, version, enabled. (Cockpit only.) Install with ext_install, toggle with ext_set_enabled.

### `ext_install` (~60 tokens)

Install a Chrome extension from a Web Store id or URL (downloads from the Web Store). Returns the updated list. (Cockpit only.) Remove with ext_remove.

Input parameters:

- `input` (string, required): Extension id (32 chars) or a Chrome Web Store URL.

### `ext_remove` (~60 tokens)

Remove (uninstall/unload) a Chrome extension by id (irreversible for store extensions). (Cockpit only.) To keep it but turn it off, use ext_set_enabled.

Input parameters:

- `id` (string, required): Extension id to remove (see ext_list).

### `ext_set_enabled` (~68 tokens)

Enable or disable a Chrome extension by id without uninstalling. Returns the updated list. (Cockpit only.) To uninstall entirely, use ext_remove.

Input parameters:

- `enabled` (boolean, required): true to enable, false to disable.
- `id` (string, required): Extension id to toggle (see ext_list).

### `repro` (~302 tokens)

One-shot reproduce-and-correlate: clear the buffer (unless clear=false), perform one action OR a sequence in order, wait for async console/network/server events to land, then return EVERYTHING that happened on both sides plus per-step results and an errors summary. Use a sequence for flows like navigate → click → type → click submit.

Input parameters:

- `action` (object): A single action (convenience for a one-step sequence). Ignored if `actions` is given.
- `actions` (array): Sequence of actions performed in order. Use this OR `action`.
- `clear` (boolean): Clear the buffer first (default true).
- `continueOnError` (boolean): Keep going if a step fails (default false: stop after the failing step).
- `idleMs` (number): Quiet period that counts as idle for waitFor=networkidle (default 500).
- `settleMs` (number): Fixed wait after the FINAL action for waitFor=settle (default 1000).
- `stepSettleMs` (number): Fixed wait BETWEEN steps for waitFor=settle (default 300).
- `timeoutMs` (number): Max wait for waitFor=networkidle before giving up (default 10000).
- `waitFor` (string): How to wait after each action: 'settle' = fixed sleep; 'networkidle' = wait until no network activity (more reliable for slow/streaming). Default 'settle'.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp#diagnostics

## Score history

- 2026-08-03: 81
- 2026-08-02: 80
- 2026-08-01: 65
- 2026-07-31: 65
- 2026-07-30: 63
- 2026-07-28: 46
- 2026-07-27: 24

## Links

- npm package: https://www.npmjs.com/package/devloop-mcp
- Socket report: https://socket.dev/npm/package/devloop-mcp
- Repository: https://github.com/vincentvella/devloop
- Website: https://devloop.build/
- Changelog RSS feed: https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/vincentvella-devloop/devloop-mcp
