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.

Metro MCP

NPM · METRO-MCP · SCANNED SEP 21

MCP server for React Native/Expo runtime debugging, inspection, and automation via Metro/CDP

Available components

+4 this week 90 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 Security99
  • No malware found by supply-chain analysis.Pass
  • No known CVEs affecting this package version or its production dependencies.Pass
  • No install/post-install scripts declared.Pass
  • 5 of 43 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency97
  • Source repository is publicly reachable at the declared URL. View diagnostics → Pass
  • Cryptographically verified build provenance (signed, bound to steve228uk/metro-mcp). View diagnostics → Pass
  • Clear OSI-approved license (MIT).Pass
  • Actively maintained (last published 16 days ago).Pass
  • Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
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 (good).Pass
  • Tool/resource definitions use about 6585 tokens (~62/item across 105 items; 88 tools + 17 resources), lean.Pass
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management60
  • Stability observed for 18 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage96
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 89% of tool parameters carry a description.Partial
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
  • An AI judge read all 90 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
  • Supports UI / widget rendering.Pass
Install

How do I install the Metro MCP server?

Metro MCP runs locally as an npm package, launched with npx -y metro-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 · metro-mcp

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

  • 21 Sept 26 +1

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

  • 19 Sept 26 +1

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

  • 17 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 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 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 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 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

  • 12 Sept 26 0
    • Security disclosure: unverified → fail functional
  • 11 Sept 26 +1
    • Security disclosure: fail → unverified functional
  • 8 Sept 26 +1

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

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/metro-mcp@0.15.0

Provenance Verified

A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.

Result Verified
Ecosystem npm
Reason Verified
Discovered via Registry attestation endpoint
Source repo steve228uk/metro-mcp
Certificate issuer https://token.actions.githubusercontent.com
Certificate SAN https://github.com/steve228uk/metro-mcp/.github/workflows/publish.yml@refs/tags/v0.15.0
Rekor log index 2715930430
Predicate type https://slsa.dev/provenance/v1
Subject digest sha512:a2adae7e32186f50e7e305a441e66742f4d441bf92fcf2e15165f94fae5b44321e5644856af9ea7d6d7a35490703c2357312c883985cf32064f97fab7

Background: How many MCP packages publish verified provenance →

Dependencies 43 packages
Packages resolved 43
Stale 5
Tree resolution Complete

Background: SBOMs and build attestations, explained →

MCP tools · 88 exposed · ~6,214 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
list_debug_globals ~55

Auto-discover well-known global debugging objects (Redux stores, Apollo Client, Expo Router, React DevTools hook, etc.) available in the app runtime.

NameTypeReqDescription
detailedbooleanInclude top-level keys for each discovered global

No output schema declared.

No examples provided.

list_devices ~34

List connected devices and debuggable targets from Metro bundler.

NameTypeReqDescription
rescanbooleanRescan all Metro ports

No output schema declared.

No examples provided.

list_directory ~111

List files and directories in an app sandbox path. Call get_app_directories first to obtain the root path.

NameTypeReqDescription
bundleIdstringApp bundle ID (iOS) or package name (Android). Required when path is omitted; also used for Android run-as access.
pathstringAbsolute directory path to list. Defaults to the app data container root (bundleId required).
platformstring
recursivebooleanRecursively list subdirectories (returns raw text)

No output schema declared.

No examples provided.

list_elements ~62

Get labelled or interactive elements from the focused React screen. Check traversal.complete before treating an empty elements array as definitive.

NameTypeReqDescription
interactiveOnlybooleanReturn only elements with onPress handlers
maxDepthinteger
maxNodesinteger

No output schema declared.

No examples provided.

list_permissions ~68

List all app permission statuses on the connected iOS simulator or Android emulator. Returns compact text: one name=status line per permission.

NameTypeReqDescription
bundleIdstringBundle ID (iOS) or package name (Android). Auto-detected if omitted.
platformstringTarget platform

No output schema declared.

No examples provided.

list_routes ~27

List registered route names from available navigation state. Uninitialized nested navigators are not discoverable.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_simulators ~43

List available iOS simulators or Android emulators.

NameTypeReqDescription
bootedOnlybooleanShow only booted/running devices
platformstring

No output schema declared.

No examples provided.

list_test_recordings ~42

List all previously saved test recordings in ~/.metro-mcp/recordings/. Returns filenames and sizes. Use load_test_recording to load one for test generation.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_url_schemes ~53

List URL schemes registered by an installed iOS app or Android package.

NameTypeReqDescription
bundleIdstringBundle ID to check (auto-detected if not provided)
platformstringTarget platform

No output schema declared.

No examples provided.

load_test_recording ~69

Load a previously saved recording from disk and make it available for test generation. After loading, call generate_test_from_recording with any format to regenerate the test. Use list_test_recordings to see available files.

NameTypeReqDescription
filenamestringyesName of the saved recording (without .json extension)

No output schema declared.

No examples provided.

long_press ~104

Long press using a React handler by label/testID, then semantic native input through SimView or IDB when the handler is unavailable. Explicit coordinates use native input directly; native results identify the backend and dispatch state.

NameTypeReqDescription
durationnumberDuration in milliseconds
labelstringAccessibility label or testID of the element to long press
platformstring
xnumberX coordinate
ynumberY coordinate

No output schema declared.

No examples provided.

open_app_settings ~62

Open the connected app's system settings page using React Native Linking.openSettings().

NameTypeReqDescription
bundleIdstringBundle ID (iOS) or package name (Android). If supplied, it must match the connected app.
platformstringTarget platform

No output schema declared.

No examples provided.

open_deeplink ~64

Open a URL or deep link on the connected iOS simulator or Android device.

NameTypeReqDescription
platformstring
urlstringyesURL or deep link to open (e.g., "myapp://screen/details" or "https://example.com/path")

No output schema declared.

No examples provided.

open_devtools ~53

Open the React Native DevTools debugger panel in Chrome. Connects through the CDP proxy so DevTools and the MCP can share the same Hermes connection.

NameTypeReqDescription
openbooleanAttempt to open the browser automatically

No output schema declared.

No examples provided.

press_button ~40

Press a device button (HOME, BACK, VOLUME_UP, etc.).

NameTypeReqDescription
buttonstringyesButton to press
platformstring

No output schema declared.

No examples provided.

profile_action ~124

Profile a specific JavaScript expression or code path in a single call. Starts profiling, evaluates the expression, waits for it to complete (plus optional extra duration), then stops and returns the top functions by self time. Use instead of calling start_profiling / stop_profiling manually for focused measurements.

NameTypeReqDescription
expressionstringyesJavaScript expression to profile (can be an async IIFE)
extraMsintegerAdditional milliseconds to wait after the expression resolves before stopping (default 0)
topNintegerNumber of top functions to return

No output schema declared.

No examples provided.

read_file ~126

Read the contents of a file from the app sandbox. Enforces a configurable size cap (default 50 KB, max 1 MB) to avoid flooding context.

NameTypeReqDescription
bundleIdstringApp package name (Android, for run-as access to private files)
encodingstringOutput encoding. Use base64 for binary files (images, SQLite, etc.)
maxBytesnumberMaximum bytes to read (default 50 KB, hard cap 1 MB)
pathstringyesAbsolute path to the file
platformstring

No output schema declared.

No examples provided.

reload_app ~53

Reload the connected app and verify a fresh runtime. Uses Page.reload, with a directed Metro message fallback only for a verified app/device peer.

NameTypeReqDescription
timeoutintegerMaximum time in milliseconds to submit and verify the reload

No output schema declared.

No examples provided.

reset_permissions ~126

Reset one or all permissions for the app on the connected iOS simulator or Android emulator. On iOS, omitting service resets all services. On Android, omitting service resets all runtime permissions.

NameTypeReqDescription
bundleIdstringBundle ID (iOS) or package name (Android). Auto-detected if omitted.
platformstringTarget platform
servicestringiOS: specific service to reset (e.g. "location"); omit to reset all. Android: permission name (e.g. "CAMERA"); omit to reset all runtime permissions.

No output schema declared.

No examples provided.

revoke_permission ~121

Revoke a permission from the app on the connected iOS simulator or Android emulator.

NameTypeReqDescription
bundleIdstringBundle ID (iOS) or package name (Android). Auto-detected if omitted.
platformstringTarget platform
servicestringyesiOS: simctl service (calendar, contacts, contacts-limited, location, location-always, microphone, motion, photos, photos-add, media-library, reminders, siri). Android: runtime permission (e.g. "CAMER…

No output schema declared.

No examples provided.

run_command ~67

Execute a custom command registered by the app. Pass parameters as a JSON object.

NameTypeReqDescription
namestringyesCommand name to execute
paramsobjectParameters to pass to the command
timeoutnumberMax ms to wait for async commands (default 15000)

No output schema declared.

No examples provided.

save_test_recording ~77

Save the current recording events to disk as JSON so they can be reloaded later. Useful for regenerating the same flow in a different test format without re-recording. Files are saved to ~/.metro-mcp/recordings/<filename>.json.

NameTypeReqDescription
filenamestringyesName for the saved recording (without .json extension)

No output schema declared.

No examples provided.

search_network ~98

Search network requests by URL pattern, method, or status code.

NameTypeReqDescription
devicestringDevice key or "all". Defaults to current device.
errorsOnlybooleanShow only failed requests
limitnumberMaximum number of results to return
methodstringHTTP method filter
statusCodenumberHTTP status code filter
urlPatternstringURL substring or regex pattern

No output schema declared.

No examples provided.

setup_statusline ~77

Writes the Metro CDP connection status script to ~/.claude/metro-mcp-statusline.sh. Does not modify settings.json — tell the user to add it to their status line themselves (e.g. ask Claude: "/statusline add the script at ~/.claude/metro-mcp-statusline.sh"). Only works with Claude Code.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

start_heap_sampling ~69

Start Hermes heap allocation sampling via CDP HeapProfiler. Records memory allocation call stacks to identify where objects are being allocated. Call stop_heap_sampling to retrieve the top allocation sites.

NameTypeReqDescription
samplingIntervalintegerAverage bytes between samples (default 32768). Lower = more detail, higher overhead.

No output schema declared.

No examples provided.

start_profiling ~118

Start profiling the running React Native app. Primary path: injects into the React DevTools hook (__REACT_DEVTOOLS_GLOBAL_HOOK__) via evalInApp — captures all component render durations without requiring <Profiler> wrappers, works on all architectures. Fallback (legacy arch only): CDP Profiler domain for JS CPU call-graph sampling. Perform the interaction you want to measure, then call stop_profiling.

NameTypeReqDescription
samplingIntervalintegerCDP fallback only: sampling interval in microseconds (default 1000).

No output schema declared.

No examples provided.

start_test_recording ~89

Inject interaction interceptors into the running app via the React fiber tree. Captures taps, text entry, long presses, keyboard submits, and scroll/swipe gestures — with no changes to your app code. Works with ScrollView, FlatList, SectionList, FlashList, and other scroll containers. Call stop_test_recording when done, then generate_test_from_recording to get the test.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

stop_heap_sampling ~57

Stop heap allocation sampling and return the top allocation sites. Shows which functions are allocating the most memory, useful for diagnosing memory leaks. Must call start_heap_sampling first.

NameTypeReqDescription
topNintegerNumber of top allocation sites to return

No output schema declared.

No examples provided.

stop_profiling ~92

Stop profiling and return an analysis of the captured data. DevTools hook mode: returns top components by total render duration across all commits. CDP mode: returns top JS functions by self time and total time. Must call start_profiling first.

NameTypeReqDescription
includeNativebooleanCDP mode only: include native/internal Hermes frames.
topNintegerNumber of top entries to return.

No output schema declared.

No examples provided.

stop_test_recording ~54

Stop the active recording, retrieve all captured events, and store them for test generation. Returns a summary of what was recorded. Call generate_test_from_recording next to produce Appium, Maestro, or Detox test code.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

swipe ~56

Scroll through React, then use installed SimView or IDB on iOS and the selected ADB serial on Android. Native results identify the backend and dispatch state.

NameTypeReqDescription
directionstringyesSwipe direction
platformstring

No output schema declared.

No examples provided.

symbolicate ~47

Symbolicate a stack trace using Metro bundler source maps. Converts minified/bundled locations back to original source files.

NameTypeReqDescription
stackarrayyesArray of stack frames to symbolicate

No output schema declared.

No examples provided.

take_screenshot ~49

Capture a screenshot from the connected iOS simulator or Android device.

NameTypeReqDescription
deliverystringReturn a retained temporary file path or an inline MCP image
platformstringTarget platform

No output schema declared.

No examples provided.

tap_element ~98

Tap by label, testID, or logical device-point coordinates. Uses React handlers, then installed SimView or IDB on iOS and adb on Android. Coordinates use native input directly; native results identify the backend and dispatch state.

NameTypeReqDescription
labelstringAccessibility label, aria-label, or testID to tap
platformstring
xnumberX coordinate
ynumberY coordinate

No output schema declared.

No examples provided.

type_text ~98

Type text into an input field. Targets a specific input by testID/label, or the first visible TextInput. Uses the React handler first, then SimView or IDB on iOS and the selected ADB serial on Android.

NameTypeReqDescription
platformstring
testIDstringtestID or accessibilityLabel of the TextInput to target (defaults to first visible input)
textstringyesText to type

No output schema declared.

No examples provided.

wait_for_condition ~116

Poll a JavaScript expression in the app until it returns a truthy value, then return that value. Useful for waiting on state changes, loading flags, API responses, or any async condition. Example: wait for globalThis.myStore?.isLoaded === true.

NameTypeReqDescription
expressionstringyesJS expression to evaluate; polling stops when it returns truthy
pollIntervalintegerHow often to check in milliseconds (default 500)
timeoutintegerMaximum wait time in milliseconds (default 10000)

No output schema declared.

No examples provided.

wait_for_element ~147

Poll the component tree until an element matching the given testID or accessibilityLabel appears. Returns element info on success. Use after tap_element, navigate(), or any action that triggers async screen transitions or data loading — instead of immediately calling the next tool. Returns traversal metadata immediately when the bounded search is incomplete.

NameTypeReqDescription
maxDepthintegerMaximum fiber depth inspected per poll
maxNodesintegerMaximum fibers inspected per poll
pollIntervalintegerHow often to check in milliseconds (default 500)
selectorstringyestestID or accessibilityLabel to wait for
timeoutintegerMaximum wait time in milliseconds (default 10000)

No output schema declared.

No examples provided.

wait_for_navigation ~98

Poll the active navigation route until it matches the expected route name, then return. Requires the navigation plugin to be set up (get_current_route must work). Use after tap_element on a link or after dispatching a navigate() action.

NameTypeReqDescription
routeNamestringyesExpected route name to wait for (e.g. "HomeScreen", "ProfileTab")
timeoutintegerMaximum wait time in milliseconds (default 10000)

No output schema declared.

No examples provided.

Common questions

What is the Metro MCP server?

Metro MCP is listed in the public MCP registry as io.github.steve228uk/metro-mcp. MCP server for React Native/Expo runtime debugging, inspection, and automation via Metro/CDP. This page covers its npm package (metro-mcp).

Is the Metro MCP server safe to use?

Metro MCP scores 90 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. 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 Metro MCP server expose?

Metro MCP exposes 88 tools: get_console_logs, clear_console_logs, get_network_requests, get_request_details, get_response_body, and 83 more. Their descriptions and schemas cost roughly 6,214 tokens of context every time the server is loaded.

Is the Metro MCP server still maintained?

Metro 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 Metro MCP server under?

Metro MCP declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.