simlock
병렬 코딩 에이전트가 동일 시뮬레이터를 놓고 충돌하지 않도록 제어 평면 제공
iOS 시뮬레이터와 상호작용하기 위한 MCP 서버
MCP server for interacting with the iOS simulator
개발 도구TypeScriptGitHub @joshuayoes직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A Model Context Protocol (MCP) server for interacting with iOS simulators. This server allows you to interact with iOS simulators by getting information about them, controlling UI interactions, and inspecting UI elements.
Security Notice: Command injection vulnerabilities present in versions < 1.3.3 have been fixed. Please update to v1.3.3 or later. See SECURITY.md for details.
https://github.com/user-attachments/assets/a88e449c-8f1d-46a5-9816-0f97e071c460
This project has been featured and mentioned in various publications and resources:
get_booted_sim_idDescription: Get the ID of the currently booted iOS simulator
Parameters: No Parameters
open_simulatorDescription: Opens the iOS Simulator application
Parameters: No Parameters
ui_describe_allDescription: Describes accessibility information for the entire screen in the iOS Simulator
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
}
ui_tapDescription: Tap on the screen in the iOS Simulator
Parameters:
{
/**
* Press duration in seconds (decimal numbers allowed)
*/
duration?: string;
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** The x-coordinate */
x: number;
/** The y-coordinate */
y: number;
}
ui_typeDescription: Input text into the iOS Simulator
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/**
* Text to input
* Format: up to 500 characters; ASCII printable characters only (method "type")
*/
text: string;
/**
* "type" (default) or "paste"
*/
method?: "type" | "paste";
/**
* Method "paste" only: clear the focused field first (default false)
*/
replace?: boolean;
}
method: "type" (the default) presses keys as on a US keyboard, so on other layouts such as French AZERTY it types the wrong characters ([email protected] becomes ,obiletest2exq,ple:co,). Use method: "paste" for non-US keyboard layouts or non-ASCII text; it takes a few seconds per call instead of about 230 ms: about 2 s (about 5 s with replace: true) when iOS doesn't ask to allow pasting, and up to about 11 s when it does (seen on iOS 26.5 and 27). Tap the text field first: the text is pasted into the focused field through the simulator pasteboard, iOS's "Allow Paste" prompt is tapped for you, and the field is read back to confirm (for secure fields, only the length). The previous pasteboard text is restored afterwards (non-text content such as an image is not), unless the prompt is still on screen when the call gives up; then the text stays on the pasteboard and the error tells you to tap the allow button instead of retrying. replace: true clears the field first (e.g. after "type" produced wrong characters). Paste mode rejects empty text and newlines. It needs fb-idb 1.5.1+ and a recent idb_companion (1.1.8 lacks --api axbridge, so every paste fails with "No focused text field found"; brew upgrade idb-companion, then idb kill).
ui_swipeDescription: Swipe on the screen in the iOS Simulator
Parameters:
{
/**
* Swipe duration in seconds (decimal numbers allowed)
*/
duration?: string;
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** The starting x-coordinate */
x_start: number;
/** The starting y-coordinate */
y_start: number;
/** The ending x-coordinate */
x_end: number;
/** The ending y-coordinate */
y_end: number;
/** The size of each step in the swipe (default is 1) */
delta?: number;
}
ui_describe_pointDescription: Returns the accessibility element at given co-ordinates on the iOS Simulator's screen
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** The x-coordinate */
x: number;
/** The y-coordinate */
y: number;
}
ui_find_elementDescription: Searches the accessibility tree and returns elements matching the given criteria
Parameters:
{
/** Array of search strings. An element matches if ANY string matches against its AXLabel or AXUniqueId */
search: string[];
/** Filter by element type (e.g. 'Button', 'StaticText', 'Group'). Case-insensitive exact match */
type?: string;
/** Match mode: 'substring' (default) or 'exact' */
matchMode?: "substring" | "exact";
/** Whether search matching is case-sensitive (default: false) */
caseSensitive?: boolean;
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
}
ui_viewDescription: Get the image content of a compressed screenshot of the current simulator view
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
}
screenshotDescription: Takes a screenshot of the iOS Simulator
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** File path where the screenshot will be saved. If relative, it uses the directory specified by the `IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR` env var, or `~/Downloads` if not set. */
output_path: string;
/** Image format (png, tiff, bmp, gif, or jpeg). Default is png. */
type?: "png" | "tiff" | "bmp" | "gif" | "jpeg";
/** Display to capture (internal or external). Default depends on device type. */
display?: "internal" | "external";
/** For non-rectangular displays, handle the mask by policy (ignored, alpha, or black) */
mask?: "ignored" | "alpha" | "black";
}
record_videoDescription: Records a video of the iOS Simulator using simctl directly
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** Optional output path. If not provided, a default name will be used. The file will be saved in the directory specified by `IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR` or in `~/Downloads` if the environment variable is not set. */
output_path?: string;
/** Specifies the codec type: "h264" or "hevc". Default is "hevc". */
codec?: "h264" | "hevc";
/** Display to capture: "internal" or "external". Default depends on device type. */
display?: "internal" | "external";
/** For non-rectangular displays, handle the mask by policy: "ignored", "alpha", or "black". */
mask?: "ignored" | "alpha" | "black";
/** Force the output file to be written to, even if the file already exists. */
force?: boolean;
}
stop_recordingDescription: Stops the simulator video recording using killall
Parameters: No Parameters
install_appDescription: Installs an app bundle (.app or .ipa) on the iOS Simulator
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** Path to the app bundle (.app directory or .ipa file) to install */
app_path: string;
}
launch_appDescription: Launches an app on the iOS Simulator by bundle identifier
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** Bundle identifier of the app to launch (e.g., com.apple.mobilesafari) */
bundle_id: string;
/** Terminate the app if it is already running before launching */
terminate_running?: boolean;
/** Optional environment variables passed via SIMCTL_CHILD_ to simctl launch */
env?: Record<string, string>;
}
Notes: Environment variables are passed using SIMCTL_CHILD_ because simctl launch does not support --env/--envs on all Xcode versions.
Example:
{
"bundle_id": "com.example.app",
"terminate_running": true,
"env": {
"FOO": "bar",
"BAZ": "qux"
}
}
terminate_appDescription: Terminates a running app on the iOS Simulator by bundle identifier. Useful for testing cold-start flows and verifying crash recovery without reinstalling the app.
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** Bundle identifier of the app to terminate (e.g., com.apple.mobilesafari) */
bundle_id: string;
}
open_urlDescription: Opens a URL or deep link in the iOS Simulator. Handles https:// URLs (via Safari), custom URL schemes, and universal links — essential for testing deep-link routing and OAuth redirect flows.
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
/** The URL or deep link to open (e.g., https://example.com or myapp://screen/detail) */
url: string;
}
list_appsDescription: Lists all installed apps on the iOS Simulator with their bundle identifiers and display names, sorted alphabetically. Removes the need to look up bundle IDs manually before calling launch_app or terminate_app.
Parameters:
{
/**
* Udid of target, can also be set with the IDB_UDID env var
* Format: UUID (8-4-4-4-12 hexadecimal characters)
*/
udid?: string;
}
This MCP server allows AI assistants integrated with a Model Context Protocol (MCP) client to perform Quality Assurance tasks by making tool calls. This is useful immediately after implementing features to help ensure UI consistency and correct behavior.
After a feature implementation, instruct your AI assistant within its MCP client environment to use the available tools. For example, in Cursor's agent mode, you could use the prompts below to quickly validate and document UI interactions.
Verify UI Elements:
Verify all accessibility elements on the current screen
Confirm Text Input:
Enter "QA Test" into the text input field and confirm the input is correct
Check Tap Response:
Tap on coordinates x=250, y=400 and verify the expected element is triggered
Validate Swipe Action:
Swipe from x=150, y=600 to x=150, y=100 and confirm correct behavior
Detailed Element Check:
Describe the UI element at position x=300, y=350 to ensure proper labeling and functionality
Show Your AI Agent the Simulator Screen:
View the current simulator screen
Take Screenshot:
Take a screenshot of the current simulator screen and save it to my_screenshot.png
Record Video:
Start recording a video of the simulator screen (saves to the default output directory, which is `~/Downloads` unless overridden by `IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR`)
Stop Recording:
Stop the current simulator screen recording
Install App:
Install the app at path/to/MyApp.app on the simulator
Launch App:
Launch the Safari app (com.apple.mobilesafari) on the simulator
Agents can waste a lot of iterations tapping and swiping their way to a deeply nested route. When your app registers a URL scheme (or Universal Link), it's usually faster to jump directly to the target screen instead of navigating there step by step.
You can open a deep link with uri-scheme:
npx uri-scheme open "myapp://products/42" --ios
This targets the currently booted simulator. Under the hood it's equivalent to:
xcrun simctl openurl booted "myapp://products/42"
Both work for custom schemes (myapp://...) and web URLs (https://..., which
trigger Universal Links if your app is configured for them).
Example prompt:
Open the deep link myapp://products/42 in the simulator, then verify the product
details screen is shown
Use this to shorten agent loops: deep link to the screen under test, then use the
UI tools (ui_describe_all, ui_tap, ui_view, …) to validate it.
idb_companion binary plus the fb-idb Python client. See TROUBLESHOOTING.md for install steps, and ui_type for the versions method: "paste" needsThis section provides instructions for integrating the iOS Simulator MCP server with different Model Context Protocol (MCP) clients.
Cursor manages MCP servers through its configuration file located at ~/.cursor/mcp.json.
Edit your Cursor MCP configuration file. You can often open it directly from Cursor or use a command like:
# Open with your default editor (or use 'code', 'vim', etc.)
open ~/.cursor/mcp.json
# Or use Cursor's command if available
# cursor ~/.cursor/mcp.json
Add or update the mcpServers section with the iOS simulator server configuration:
{
"mcpServers": {
// ... other servers might be listed here ...
"ios-simulator": {
"command": "npx",
"args": ["-y", "ios-simulator-mcp"]
}
}
}
Ensure the JSON structure is valid, especially if mcpServers already exists.
If you prefer pnpm, use its dlx runner instead:
{
"mcpServers": {
"ios-simulator": {
"command": "pnpm",
"args": ["dlx", "ios-simulator-mcp"]
}
}
}
Restart Cursor for the changes to take effect.
git clone https://github.com/joshuayoes/ios-simulator-mcp
cd ios-simulator-mcp
npm install
# or, using pnpm (installs from the committed pnpm-lock.yaml):
pnpm install
npm run build
# or:
pnpm run build
mcpServers section, pointing to your local build:
{
"mcpServers": {
// ... other servers might be listed here ...
"ios-simulator": {
"command": "node",
"args": ["/full/path/to/your/ios-simulator-mcp/build/index.js"]
}
}
}
Important: Replace /full/path/to/your/ with the absolute path to where you cloned the ios-simulator-mcp repository.Claude Code CLI can manage MCP servers using the claude mcp commands or by editing its configuration files directly. For more details on Claude Code MCP configuration, refer to the official documentation.
claude mcp add command:
claude mcp add ios-simulator npx ios-simulator-mcp
# or, with pnpm:
claude mcp add ios-simulator -- pnpm dlx ios-simulator-mcp
claude mcp add command, pointing to your local build:
claude mcp add ios-simulator -- node "/full/path/to/your/ios-simulator-mcp/build/index.js"
Important: Replace /full/path/to/your/ with the absolute path to where you cloned the ios-simulator-mcp repository.| Variable | Description | Example |
|---|---|---|
IOS_SIMULATOR_MCP_FILTERED_TOOLS | A comma-separated list of tool names to filter out from being registered. | screenshot,record_video,stop_recording |
IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR | Specifies a default directory for output files like screenshots and video recordings. If not set, ~/Downloads will be used. This can be handy if your agent has limited access to the file system. | ~/Code/awesome-project/tmp |
IOS_SIMULATOR_MCP_IDB_PATH | Specifies a custom path to the IDB executable. If not set, idb will be used (assuming it's in your PATH). Useful if IDB is installed in a non-standard location. | ~/bin/idb or /usr/local/bin/idb |
{
"mcpServers": {
"ios-simulator": {
"command": "npx",
"args": ["-y", "ios-simulator-mcp"],
"env": {
"IOS_SIMULATOR_MCP_FILTERED_TOOLS": "screenshot,record_video,stop_recording",
"IOS_SIMULATOR_MCP_DEFAULT_OUTPUT_DIR": "~/Code/awesome-project/tmp",
"IOS_SIMULATOR_MCP_IDB_PATH": "~/bin/idb"
}
}
}
}
MIT