{
  "markdown": "# iphone-mirror-mcp\n\n[![CI](https://github.com/nickatnight96/iphone-mirror-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/nickatnight96/iphone-mirror-mcp/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n![Platform: macOS 15+](https://img.shields.io/badge/platform-macOS%2015%2B-lightgrey)\n![Swift 6](https://img.shields.io/badge/Swift-6-orange)\n[![Listed on mcpservers.org](https://img.shields.io/badge/mcpservers.org-listed-blue)](https://mcpservers.org/servers/nickatnight96/iphone-mirror-mcp)\n[![Clones](https://img.shields.io/endpoint?url=https%3A%2F%2Fnickatnight96.github.io%2Fiphone-mirror-mcp%2Ftraffic%2Fbadges%2Fclones.json)](https://github.com/nickatnight96/iphone-mirror-mcp/blob/traffic-data/traffic/history.json)\n[![Views](https://img.shields.io/endpoint?url=https%3A%2F%2Fnickatnight96.github.io%2Fiphone-mirror-mcp%2Ftraffic%2Fbadges%2Fviews.json)](https://github.com/nickatnight96/iphone-mirror-mcp/blob/traffic-data/traffic/history.json)\n\n**Let any LLM drive a real iPhone.**\n\nAn MCP server that controls a physical iPhone through the built-in macOS\n**iPhone Mirroring** app, and automates **Xcode** development testing — build,\ntest, install, and launch on simulators and devices, then operate the app on\nthe mirrored screen with taps, swipes, typing, and OCR.\n\nNo jailbreak. Nothing installed on the phone. No XCUITest target.\n\n```\nrun_on_iphone (build → install → launch on the paired iPhone)\n   → screenshot / read_screen / tap / paste_text     drive the app on-device\n   → wait_for_text / tap with expect / sim_log       assert what the user sees\n```\n\n**63 tools.** Works with Claude, GPT, Gemini, local models — anything that\nspeaks MCP over stdio.\n\n---\n\n## Quick start\n\n```sh\ngit clone https://github.com/nickatnight96/iphone-mirror-mcp.git\ncd iphone-mirror-mcp\n./install.sh\n```\n\nThe installer checks your machine, builds a release binary, verifies\npermissions end to end, and prints the exact config for your client.\n\nThen, for Claude Code:\n\n```sh\nclaude mcp add --scope user iphone-mirror -- ~/.local/bin/iphone-mirror-mcp\n```\n\nOr for any other MCP client:\n\n```json\n{\n  \"mcpServers\": {\n    \"iphone-mirror\": {\n      \"command\": \"/Users/YOU/.local/bin/iphone-mirror-mcp\"\n    }\n  }\n}\n```\n\nAsk your model:\n\n> Take a screenshot of my iPhone and tell me what app is open.\n\nOr grab the `.mcpb` bundle from the\n[latest release](https://github.com/nickatnight96/iphone-mirror-mcp/releases/latest)\nif your client installs MCP bundles and you would rather skip the toolchain\n(see the [caveats](docs/getting-started.md#or-install-the-mcp-bundle) — it is\nad-hoc signed but not notarized).\n\n**→ [Full getting-started guide](docs/getting-started.md)** ·\n**[per-client config](docs/clients.md)**\n\n## Requirements\n\n- **macOS 15+** with iPhone Mirroring, paired to an **iOS 18+** iPhone (nearby,\n  locked, same Apple Account)\n- **Xcode** — for the `xcode_*`, `device_*`, and `sim_*` tools\n- **Accessibility** and **Screen Recording** permission, granted to the app\n  that *launches* the server (your terminal, or the desktop app hosting your\n  client) — [details](docs/getting-started.md#2-grant-permissions)\n\nCheck everything at once:\n\n```sh\niphone-mirror-mcp doctor\n```\n\nIt tests all four permissions, captures a real frame, and confirms macOS is\nactually delivering synthetic input — rather than just reading permission\nflags. Run it before you suspect anything else.\n\n## What it can do\n\n| | |\n|---|---|\n| **Session & health** | `status`, `doctor`, `mirror_launch`, `mirror_restart` |\n| **See the screen** | `screenshot`, `annotated_screenshot` (every element boxed + numbered), `read_screen` (OCR with tappable centers), `find_text`, `find_image`, `record_screen` |\n| **Wait properly** | `wait_for_text`, `wait_for_screen_change`, `scroll_to` |\n| **Input** | `tap` (with `expect` verification), `double_tap`, `long_press`, `swipe`, `drag`, `type_text`, `paste_text` (emoji/CJK via clipboard), `read_clipboard`, `press_key`, `shake`, `batch` |\n| **Navigate** | `home`, `app_switcher`, `spotlight`, `launch_app`, `open_url` |\n| **Notifications** | `notifications`, `notification_click` |\n| **Xcode** | `xcode_list`, `xcode_build`, `xcode_test`, `xcresult_attachments` |\n| **Real devices** | `run_on_iphone`, `devices`, `device_install`, `device_launch`, `device_info`, `device_apps`, `device_uninstall` |\n| **Simulators** | `run_on_sim` plus the full `simctl` belt — push, GPS, privacy grants, status bar, appearance, logs, media |\n\n**→ [Complete tool reference](docs/tools.md)** — all 63, with parameters,\ngenerated from the server's own catalog so it cannot drift.\n\n## Coordinate contract\n\nEvery `x`/`y` is a **pixel position in the most recent screenshot**, origin\ntop-left. At input time the window bounds are re-queried and the pixel maps\nproportionally into the current bounds — so a window that moved or was resized\nbetween screenshot and tap still receives the tap in the right place.\n\n## Documentation\n\n| | |\n|---|---|\n| **[Getting started](docs/getting-started.md)** | Install → permissions → first tap |\n| **[Connecting a client](docs/clients.md)** | Claude Code, Claude Desktop, Cursor, VS Code, Zed, Codex, Windsurf |\n| **[Tool reference](docs/tools.md)** | All 63 tools and their parameters |\n| **[Recipes](docs/recipes.md)** | Driving an app, the on-device test loop, notifications, batching |\n| **[Troubleshooting](docs/troubleshooting.md)** | Symptoms → causes → fixes |\n| **[Architecture](docs/architecture.md)** | How input actually reaches the phone |\n| **[Limitations](docs/limitations.md)** | What this genuinely cannot do |\n\n## Known limitations\n\nTested, not guessed — the [full list](docs/limitations.md) explains why.\n\n- **Pinch and rotate cannot be synthesized.** Trackpad gestures do not travel\n  the CGEvent pipeline; an event tap sees nothing during a physical pinch, so\n  there is nothing to reproduce.\n- **One phone at a time** — device switching has no scriptable menu.\n- **The session pauses whenever the phone is unlocked or picked up.** Apple's\n  design; resuming needs it locked again.\n- **No accessibility tree** — OCR and template matching are the element model.\n  Face ID, Control Center, and hardware buttons are unreachable, and DRM\n  content captures black.\n\n## Security\n\nThis server can see and control whatever iPhone the Mac is paired with while\nmirroring is active. **Treat it like handing your unlocked phone to the\nmodel.** Run it only from clients you trust.\n\nThe phone locks the session the moment it is picked up or unlocked physically,\nwhich is a real kill switch. `paste_text` briefly places text on the Mac\nclipboard and restores what was there; `read_clipboard` reads it.\n\nSee [SECURITY.md](SECURITY.md) for the trust model and how to report a\nvulnerability.\n\n## Contributing\n\nIssues and pull requests welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n```sh\nscripts/run_tests.sh                    # build + unit/protocol tests + CLI smoke\nMIRROR_MCP_LIVE=1 scripts/run_tests.sh  # + live tests (real window, capture, input)\n```\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 7091,
  "sha": "d94b419d38d518c86f70bc5ae8ca62e32face6adee1228cd7d4f13ef78c4949d",
  "repo_slug": "nickatnight96/iphone-mirror-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_nickatnight96_iphone_mirror_mc_dff74ee0/readme"
}