rn-sim-mcp

rn-sim-mcp

An MCP server that composes XcodeBuildMCP and ios-simulator-mcp, adding React Native inspection tools to read the component tree, resolved styles, and perform layout audits on iOS simulators.

Category
Visit Server

README

rn-sim-mcp

ci npm license node

One MCP server for React Native iOS simulator work.

If you drive a React Native app from a coding agent, this gives the agent a single, small tool surface for building, running, and actually inspecting what is on screen.

It does two things:

  1. Composes XcodeBuildMCP and ios-simulator-mcp behind a single allowlisted tool surface.
  2. Adds React Native inspection tools that read the React tree, not the native view hierarchy: component tree by testID, resolved styles merged across the component chain, and arithmetic layout auditing.

That second part is the reason it exists. Plenty of tooling can tap a button on a simulator. Very little can tell an agent which React component owns that button, what style actually resolved onto it, or whether its tap target is too small, and none of it in a form that does not flood the agent's context.

Requires macOS with Xcode, Node 22 or newer, and a React Native dev build with Metro running for the rn_ tools.

New here? Install takes about a minute, and CONTRIBUTING.md has a tour of the codebase if you want to change something.

Install

Nothing to install. It runs on bare node with zero dependencies, so npx fetches one 15 kB tarball.

Claude Code

claude mcp add rn-sim -- npx -y rn-sim-mcp

VS Code, Cursor, or anything else using mcp.json

{
  "servers": {
    "rn-sim": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "rn-sim-mcp"]
    }
  }
}

Remove any existing xcodebuildmcp or ios-simulator-mcp entries. This server proxies both, and running them alongside it doubles the tool surface for no benefit.

Then start Metro in your app:

npx react-native start

Confirm the app is attached with the rn_debug_targets tool. Zero targets means the app is not connected.

Configuration

Variable Effect
METRO_URL Metro origin, default http://localhost:8081. Must be a local origin.
RN_SIM_MCP_NO_UPSTREAM Skip upstream composition and expose only this package's own tools.

Why compose instead of fork

Both upstreams are MIT licensed, so merging their source would have been legal. It would also have been a mistake. Both are actively developed, XcodeBuildMCP is now maintained by Sentry, and a fork inherits their bug backlog while losing every upstream fix from that day forward.

Composing gets the same result the merge was after. One entry in mcp.json, one curated tool list, and zero vendored code to maintain. The allowlist in src/upstream.mjs is the important part: an unfiltered merge would expose well over a hundred tools and drown the agent's context, which is the problem this package exists to solve.

Upstream versions are pinned there deliberately rather than floating on @latest.

Why it has no dependencies

MCP over stdio is newline-delimited JSON-RPC 2.0, so src/jsonrpc.mjs implements both halves in about 170 lines.

The result runs with bare node, with no install step, no build, and no dist to drift out of date. It also means npx has one small tarball to fetch instead of a dependency tree, which matters for a server an agent launches on every session.

Output follows AXI

Tool results are the largest token cost in an agent session, so every response follows the AXI (Agent eXperience Interface) standards.

TOON, not JSON. Field names are declared once per collection instead of on every row. Measured on this server's own component tree output at 50 rows:

Characters Approx. tokens
JSON 4079 1020
TOON 1533 384

A 62% saving on a call the agent makes constantly.

Minimal default schemas. rn_component_tree returns testID and component, nothing else. The ancestor chain is the verbose field, so it sits behind includePath: true.

Pre-computed aggregates. Lists report the true total, not just the page: count: 50 of 171 total. sim_screenshot_hires returns width and height alongside the path, because scale is the reason you called it.

Definitive empty states. 0 layout issues found (15 elements inspected) rather than an empty array that makes an agent re-run the call with different arguments to check the zero was real.

Truncation with an escape hatch. rn_eval previews long values and reports the true size rather than dropping the field.

Structured errors that name the fix.

error: testID is required
help: Run rn_component_tree to list the testIDs on screen

Contextual disclosure. List responses carry a few next steps, so the tool surface is discovered by using it rather than by reading this file.

Tools

React Native inspection (this package)

Tool Use it for
rn_component_tree Which components are on screen, by testID. Takes limit, includePath, onlyTestIds
rn_styles Resolved style merged across the component chain, plus props, for one testID
rn_eval Evaluate an expression inside the running app
rn_debug_targets Confirm the app is attached to Metro

Visual and geometry (this package)

Tool Use it for
sim_screenshot_hires Full-resolution lossless PNG via simctl, with dimensions
ui_layout_audit Zero-size elements, tap targets under 44pt after hitSlop, horizontal overflow
ui_check_alignment Whether elements share an edge, to a tolerance, as a number

Proxied

session_show_defaults, session_set_defaults, list_sims, list_schemes, build_sim, build_run_sim, test_sim, launch_app_sim, stop_app_sim, open_sim, snapshot_ui, screenshot from XcodeBuildMCP. ui_describe_all, ui_find_element, ui_tap, ui_swipe, ui_type from ios-simulator-mcp.

Proxied results pass through in the upstream's own format. Only this package's own tools emit TOON.

Use the right screenshot

sim_screenshot_hires exists because the proxied screenshot downscales. Measured on an iPhone 17:

Resolution Per pixel
proxied screenshot 368 x 800 JPEG 1.09pt
sim_screenshot_hires 1206 x 2622 PNG 0.33pt

JPEG compression is not the problem; mean luminance drift against a lossless reference is 0.26/255. Resolution is. Use the proxied one to answer "which screen am I on" and this one for anything where a pixel is the unit of the question.

Better still, do not measure layout from an image at all. ui_layout_audit and ui_check_alignment read exact frames, so alignment is arithmetic.

Known limits

Every one of these is a good place to contribute, and most are filed as issues.

  • The React Native tools need Metro and a dev build. ui_layout_audit degrades gracefully and reports hitSlopResolved: false when it cannot reach the app.
  • Styles created through StyleSheet.create arrive as opaque registered IDs and surface as registeredStyleId rather than being silently dropped. Inline and array styles resolve fully.
  • rn_component_tree walks React internals through the DevTools hook, so a React major upgrade can break it.
  • CDP Network domain needs React Native 0.83, so network inspection is not agent-readable below that.
  • macOS and iOS only. Android and the emulator are unimplemented rather than impossible, and the CDP layer would largely carry over.

Roadmap

Help wanted on any of these. None of them require deep familiarity with the codebase to start.

Idea Where it lands
Android and emulator support a sibling to src/capture.mjs, plus an upstream in src/upstream.mjs
Resolve StyleSheet.create IDs to real style objects src/cdp.mjs
CDP Network domain for React Native 0.83+ src/cdp.mjs
Harden the fiber walk against React internals changes src/cdp.mjs

Have a different idea? Open an issue or start a discussion. Questions are welcome as issues too, including "how do I use this" ones.

Security

rn_eval executes arbitrary JavaScript in the running app. Dev builds only.

More importantly: component names, props, labels and logs returned by these tools include server-controlled content such as user-generated text or CMS strings. Treat all of it as untrusted data, never as instructions.

Metro connections are restricted to local origins, so a malicious tool argument cannot turn this into a request forger against internal hosts.

The upstream servers run builds and shell commands with your credentials, which is why their versions are pinned in src/upstream.mjs.

To report a vulnerability, see SECURITY.md. Please do not open a public issue for one.

Contributing

Contributions are welcome, and small ones are genuinely useful: a typo, a clearer error message, or a note about a React Native version that behaves differently all count.

git clone https://github.com/atz-dsampath/rn-sim-mcp.git
cd rn-sim-mcp
npm test          # protocol contract and CDP deadlines, no simulator needed
npm run smoke     # full surface against a booted simulator

There is no install step and no build. npm test needs no network, Xcode or simulator, so you can work on most of this from any machine.

CONTRIBUTING.md has a tour of the eight modules, an explanation of why the MCP transport is hand-rolled, and what to expect on a pull request. See also the Code of Conduct.

License

MIT. See LICENSE.

XcodeBuildMCP and ios-simulator-mcp are separate MIT-licensed projects, spawned as child processes rather than vendored. Credit for everything under Proxied belongs to them.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured