iOS模拟器控制协议

通过macOS无障碍API控制iOS模拟器的MCP服务器,支持UI树检查、元素交互、应用生命周期管理等功能。

  • by DAWNCR0W
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 DAWNCR0W/ios-simulator-mcp

使用说明

한국어 README

iOS Simulator MCP

Control iOS Simulator via macOS Accessibility APIs


概述

iOS模拟器MCP 是一个模型上下文协议(MCP)服务器,允许AI代理 通过macOS辅助功能API检查和操作iOS模拟器UI。支持 通过simctl进行UI树检查、元素交互、应用生命周期, 等待实用程序、长按和滚动助手、断言和屏幕截图。

特性

  • UI树检查(AX层次结构)
  • 按标识符/标签点击元素
  • 文本输入到字段中
  • 启动/停止/重置应用程序(simctl)
  • 启动/关闭模拟器、安装/卸载应用程序、打开URL(simctl)
  • 读/写模拟器剪贴板(simctl)
  • 创建/删除/擦除模拟器,列出运行时和设备类型(simctl)
  • 应用程序数据和隐私实用程序(列出应用程序、容器、推/拉、隐私)
  • 媒体自动化(添加媒体、屏幕录制)
  • 屏幕截图(simctl)
  • 权限警报处理(允许/拒绝)
  • 等待实用程序、状态检查、滚动助手、断言、重试助手
  • 通过标题子字符串定位特定的模拟器窗口
  • STDIO和HTTP传输

需求

  • macOS(苹果硅或英特尔)
  • Python 3.11+(系统Python 3.9无法运行)
  • Xcode+iOS模拟器
  • 运行服务器的终端/应用程序的访问权限

授予访问权限

  1. 系统设置→ 隐私和安全→ 无障碍
  2. 添加您的终端应用程序(terminal/iTerm2)或Python可执行文件
  3. 启用切换

性能和可靠性调整

这些环境变量是可选的,可用于调整延迟和行为:

  • IOS_SIM_SIMCTL_TIMEOUT_SECONDS (默认值: 12.0)
  • IOS_SIM_SIMCTL_RETRY_COUNT (默认值: 1,仅限只读命令)
  • IOS_SIM_SIMCTL_RETRY_BACKOFF_SECONDS (默认值: 0.15)
  • IOS_SIM_BOOTED_CACHE_TTL_SECONDS (默认值: 0.4)
  • IOS_SIM_ACCESSIBILITY_TRUST_CACHE_TTL_SECONDS (默认值: 2.0)
  • IOS_SIM_STRICT_ACTIONS (默认值: false)

当 IOS_SIM_STRICT_ACTIONS=true,辅助功能驱动的按下和滚动操作失败 当不存在可操作的目标时,显式地返回跳过的成功。

安装

家酿

brew tap DAWNCR0W/ios-simulator-mcp
brew install ios-simulator-mcp

来源(发展)

git clone https://github.com/DAWNCR0W/ios-simulator-mcp.git
cd ios-simulator-mcp

brew install python@3.11
python3.11 -m venv .venv
source .venv/bin/activate

pip install -r requirements.txt
pip install -e .

依赖关系文件:

  • requirements.txt --运行时依赖关系
  • requirements-dev.txt --测试/开发依赖关系

快速开始

1) 启动模拟器

xcrun simctl boot "iPhone 15 Pro"
open -a Simulator

2) 运行MCP服务器

ios-simulator-mcp --transport stdio

可选基准

为核心只读操作运行快速本地基准测试:

PYTHONPATH=. python scripts/benchmark.py --iterations 20

注:本手动步骤主要用于直接测试/调试。在典型使用中(Claude Code、Codex、Gemini CLI等), 当您添加MCP配置时,客户端会为您启动stdio服务器,因此您通常不需要自己运行它。

或者直接用Python运行:

python3 -m lib.main --transport stdio

3) 配置您的AI客户端

克劳德代码

claude mcp add --transport stdio ios-simulator -- ios-simulator-mcp --transport stdio

项目范围:

claude mcp add --transport stdio --scope project ios-simulator -- ios-simulator-mcp --transport stdio

光标

创建 ~/.cursor/mcp.json (全球)或 .cursor/mcp.json (项目):

{
  "mcpServers": {
    "ios-simulator": {
      "type": "stdio",
      "command": "ios-simulator-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}

Codex(CLI或IDE扩展)

codex mcp add ios-simulator -- ios-simulator-mcp --transport stdio

或编辑 ~/.codex/config.toml:

[mcp_servers.ios-simulator]
command = "ios-simulator-mcp"
args = ["--transport", "stdio"]

克劳德桌面(可选)

添加 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "ios-simulator": {
      "command": "ios-simulator-mcp",
      "args": ["--transport", "stdio"]
    }
  }
}

API 参考

所有工具返回:

{
  "success": true,
  "message": "Operation completed",
  "data": { }
}

核心业务

  • list_ui_elements()
  • tap_element(identifier: str)
  • input_text(identifier: str, text: str)
  • launch_app(bundle_id: str, device_id: str = None)
  • stop_app(bundle_id: str, device_id: str = None)
  • reset_app(bundle_id: str, device_id: str = None)
  • list_simulators()
  • take_screenshot(device_id: str = None, output_path: str = None)
  • list_runtimes()
  • list_device_types()
  • create_simulator(name: str, device_type_id: str, runtime_id: str)
  • delete_simulator(device_id: str)
  • erase_simulator(device_id: str = None, all_devices: bool = False)
  • list_installed_apps(device_id: str = None)
  • app_info(bundle_id: str, device_id: str = None)
  • get_app_container(bundle_id: str, device_id: str = None, container_type: str = None)
  • push_file(source_path: str, destination_path: str, device_id: str = None)
  • pull_file(source_path: str, destination_path: str, device_id: str = None)
  • set_privacy(action: str, service: str, bundle_id: str = None, device_id: str = None)
  • add_media(media_paths: list[str], device_id: str = None)
  • start_recording(device_id: str = None, output_path: str = None)
  • stop_recording(device_id: str = None)
  • boot_simulator(device_id: str = None)
  • shutdown_simulator(device_id: str = None)
  • install_app(app_path: str, device_id: str = None)
  • uninstall_app(bundle_id: str, device_id: str = None)
  • open_url(url: str, device_id: str = None)
  • set_clipboard(text: str, device_id: str = None)
  • get_clipboard(device_id: str = None)
  • handle_permission_alert(action: str = "allow")
  • allow_permission_alert()
  • deny_permission_alert()
  • set_target_simulator_window(title_contains: str = None)

等待实用程序

  • wait_for_element(identifier: str, timeout: float = 10.0)
  • wait_for_any_element(identifiers: list[str], timeout: float = 10.0)
  • wait_for_element_gone(identifier: str, timeout: float = 10.0)
  • wait_for_text(text: str, timeout: float = 10.0)

元素状态检查

  • is_element_visible(identifier: str)
  • is_element_enabled(identifier: str)
  • get_element_text(identifier: str)
  • get_element_attribute(identifier: str, attribute: str)
  • get_element_actions(identifier: str)
  • get_element_count(identifier: str)
  • find_elements(query: str, max_results: int = 10)

手势

  • scroll_to_element(identifier: str, max_scrolls: int = 10, direction: str = "down")
  • double_tap(identifier: str, interval: float = 0.1)
  • long_press(identifier: str, duration: float = 1.0)

断言

  • assert_element_exists(identifier: str)
  • assert_element_not_exists(identifier: str)
  • assert_element_visible(identifier: str)
  • assert_element_enabled(identifier: str)
  • assert_text_equals(identifier: str, expected: str)
  • assert_text_contains(identifier: str, substring: str)
  • assert_element_count(identifier: str, expected_count: int)

重试实用程序

  • tap_element_with_retry(identifier: str, retries: int = 3, interval: float = 0.5)
  • input_text_with_retry(identifier: str, text: str, retries: int = 3, interval: float = 0.5)

配置

环境变量:

变量 描述 默认值
IOS_SIM_GRID_STEP 回退元素发现的网格步长 40
IOS_SIM_MAX_DEPTH UI树遍历的最大深度 60
IOS_SIM_LOG_LEVEL 日志记录级别(DEBUG, INFO, WARNING, ERROR) INFO
IOS_SIM_DEVICE_ID simctl的默认模拟器设备ID 自动检测
IOS_SIM_ACTIVATE_APP 操作前激活模拟器应用程序(0 禁用焦点窃取) 0

例子:

export IOS_SIM_LOG_LEVEL=DEBUG
export IOS_SIM_ACTIVATE_APP=0
ios-simulator-mcp --transport stdio

发展

pip install -r requirements-dev.txt
pytest -q -rs

许可证

麻省理工学院