Atlas / MCP servers / steve228uk / Metro

MetroBLOCK

mcp/steve228uk/metro-2

🚇 A plugin-based MCP server for React Native runtime debugging, inspection, and automation. Connects to Metro bundler via Chrome DevTools Protocol — no app code changes needed for most features.

Verdict
BLOCK
Grade
D
Trust score
64 /100
Exposed tools
39 38r · 1w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
83
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

[](https://vscode.dev/redirect/mcp/install?name=metro-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22metro-mcp%22%5D%2C%22env%22%3A%7B%7D%7D) [](https://cursor.com/en/install-mcp?name=metro-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1ldHJvLW1jcCJdLCJlbnYiOnt9fQ==)

A plugin-based MCP server for React Native runtime debugging, inspection, and automation. Connects to Metro bundler via Chrome DevTools Protocol — no app code changes needed for most features.

Works with Expo, bare React Native, and any project using Metro + Hermes.

Contents

  • Quick Start
  • Requirements
  • How It Works
  • Features
  • Chrome DevTools
  • Claude Code Status Bar
  • Test Recording
  • App Integration
  • Configuration
  • Custom Plugins
  • Compatibility

Quick Start

Claude Code

claude mcp add metro-mcp -- npx -y metro-mcp
# or with Bun
claude mcp add metro-mcp -- bunx metro-mcp

Codex

codex mcp add metro-mcp -- npx -y metro-mcp
# or with Bun
codex mcp add metro-mcp -- bunx metro-mcp

Codex stores MCP servers in ~/.codex/config.toml by default, and the Codex CLI and IDE extension share that configuration.

If you prefer to configure it manually:

[mcp_servers.metro-mcp]
command = "npx"
args = ["-y", "metro-mcp"]

OpenCode

Run OpenCode's interactive MCP installer:

opencode mcp add

Choose a local server, name it metro-mcp, and use npx -y metro-mcp as the command.

If you prefer to configure it manually, add th

Read from source at commit 166cd90168bbOBSERVED · 2026-10-07
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.

claude-code (npm)
claude mcp add metro-mcp -- npx -y [email protected]
03

Exposed tools (39)

38 read · 1 write · 0 destructive.

ToolRiskDescription
ErrorsreadRecent uncaught exceptions from the React Native app
accessibilityreadAccessibility auditing via fiber tree inspection
actionreadThe user action to trace (e.g.,
automationreadWait and polling tools for reliable E2E automation with async state changes
bundleIdreadiOS bundle ID or Android app package (required for Appium)
commandsreadCustom app commands via global.__METRO_BRIDGE__.commands
componentsreadReact component tree inspection via bounded fiber traversal
consolereadConsole log collection and filtering
debug-globalsreadDiscover well-known global debugging objects in the app runtime
deeplinkreadCross-platform deep link testing
descriptionreadOptional: describe what you were doing when the crash occurred
devicereadDevice and connection information
devtoolsreadOpen React Native DevTools via the CDP proxy
environmentreadInspect app runtime environment: build flags, platform constants, and a filtered subset of process.env
error_messagereadOptional: specific error message to investigate
errorsreadException collection with auto-symbolication
evaluatereadJavaScript expression evaluation in the app runtime
filesystemreadBrowse and read files in the app sandboxed directories
flowreadFlow to record (e.g.
formatreadOutput format: appium, maestro, or detox (default: appium)
inspect-pointreadCoordinate-based React component inspection (experimental)
metro-endpoint-fixturereadExposes the current Metro endpoint for runtime tests
navigationreadReact Navigation / Expo Router state inspection
networkreadNetwork request tracking via CDP Network domain
permissionsreadInspect and manage app permissions on iOS Simulator and Android Emulator
platformreadTarget platform for Appium: ios, android, or both (default: ios)
profilerreadCPU profiling via React DevTools hook (primary) or CDP Profiler domain, plus React render tracking
profiler-datawriteRaw JSON profiling data: React DevTools commit data or CDP Profile object, plus React render records.
profiler-flamegraphreadHuman-readable profiling output: React DevTools component chart or CPU flamegraph, plus React render chart from <Profiler> components.
promptsreadGuided debugging and testing workflows
reduxreadRedux state inspection via Runtime.evaluate
scenarioreadDescription of the interaction that causes the leak (e.g.
simulatorreadUnified iOS simulator / Android emulator device control
sourcereadStack trace symbolication via Metro
statuslinereadWrites CDP connection state to a file for Claude Code status bar integration
storagereadAsyncStorage reading via Runtime.evaluate
test-recorderreadUnified mobile test recorder: captures taps, text entry, swipes and navigation via fiber patching; generates Appium, Maestro, and Detox tests
ui-interactreadUI automation via React handlers, SimView, IDB, and adb
url_patternreadOptional: URL pattern to focus on
04

Trust audit

BLOCKgrade D · trust 64/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryFAIL
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)WARN
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
declared (3 observation(s))
Shell
declared (4 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (15)

HIGHInventory / provenance · inv.suspicious_name · CWE-1104
src/utils/payload.ts
payload.ts
Why it matters. member named after an attack tool
Fix. remove or justify
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/plugin.ts:213
exec(command: string): Promise<string>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/utils/native-input.ts:18
exec(command: string): Promise<string>;
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHSupply chain · supply.typosquat · CWE-829, CWE-1357
package.json
preact ~ react
Why it matters. dependency name one edit from a popular package
Fix. verify the package; likely typosquat
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/server.ts:903
const resp = await fetch(`http://127.0.0.1:${lockData.port}/json`, {
MEDIUMPrompt injection · prompt.hidden_style · CWE-94, CWE-1427
docs/changelog.md:23
<span style="color: var(--vp-c-text-2); font-size: 0.9em;">{{ formatDate(release.date) }}</span>
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/plugins/accessibility.test.ts:39
evalInApp: async (expression) => new Function('globalThis', `return ${expression};`)(runtime),
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/utils/fiber.test.ts:53
const evaluateExpression = new Function(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/fixtures/metro-endpoint-plugin.ts:2
import { definePlugin } from '../../src/plugin.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
tests/fixtures/native-result-plugin.ts:2
import { definePlugin, nativeToolResult } from '../../src/plugin.js';
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:140
This serves Streamable HTTP at `http://127.0.0.1:8765/mcp`. The endpoint supports both the 2025-era MCP handshake and the 2026-07-28 negotiation; `/sse` and `/messages` are intentionally unavailable.
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
docs/configuration.md:57
Streamable HTTP is available at `http://127.0.0.1:8765/mcp` for both supported client eras. `/sse` and `/messages` return `404`.
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/daemon-leases.test.ts:199
url = 'http://127.0.0.1:8765/mcp',
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/daemon.test.ts:97
return await fn(`http://127.0.0.1:${port}/mcp`);
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@babel/parser, @clack/prompts, @modelcontextprotocol/client, @modelcontextprotocol/node, @modelcontextprotocol/server, chrome-launcher, chromium-edge-launcher, metro-bridge
Why it matters. 15 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 166cd90168bbfull audit observations/trust-audit/mcp-server/steve228uk__metro-2.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-07166cd90168bbBLOCKD64first audit
06

Questions

What is the Metro MCP server?

🚇 A plugin-based MCP server for React Native runtime debugging, inspection, and automation. Connects to Metro bundler via Chrome DevTools Protocol — no app code changes needed for most features.

What tools does Metro expose?

39 in total: 38 read-only, 1 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is Metro safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (64/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does Metro need?

No credential environment variables were found in its source, so it appears to need none.

How does Metro run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as metro-mcp at 0.15.0.

How current is this page?

The grade is for one exact copy of the source (166cd90168bb), read on 2026-10-07. The repository is watched and re-audited when it changes.

Advertisement