---
title: "Codex and the iOS simulator: MCP setup | Mobster"
description: "Connect Mobster to OpenAI's Codex with codex mcp add, give it an AGENTS.md rule, and let it check your iOS app on a simulator with verdicts from assertions."
canonical: "https://mobster.dev/connectors/codex"
last-updated: "2026-10-08"
---

Connect Mobster to OpenAI's Codex with codex mcp add, give it an AGENTS.md rule, and let it check your iOS app on a simulator with verdicts from assertions.

# Codex and the iOS simulator: MCP setup

Connect Mobster to OpenAI's Codex with codex mcp add, give it an AGENTS.md rule, and let it check your iOS app on a simulator with verdicts from assertions.

## In Mobster for Mac

Settings › Connectors › **Add**, next to Codex.

## Or by hand

```
codex mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp
```

Config file: ~/.codex/config.toml

**Codex** by OpenAI

Status From OpenAI’s docs, read 8 October 2026

Setup One button in Mobster for Mac

Docs [OpenAI’s MCP docs](https://learn.chatgpt.com/docs/extend/mcp)

Download for Mac

Add Mobster to your agent

On this page

1. [Install Mobster for Mac](#install-mobster-for-mac)
2. [Add the server](#add-the-server)
3. [Check it’s connected](#check-its-connected)
4. [A first check: the streak after a lesson](#a-first-check-the-streak-after-a-lesson)
5. [Put the rule in AGENTS.md](#put-the-rule-in-agentsmd)
6. [Use a real iPhone](#use-a-real-iphone)
7. [Troubleshooting](#troubleshooting)
8. [Questions](#questions)
9. [Sources](#sources)

*A check file open in a code editor, the coding agent running it through Mobster: verify start, tap Check, verify finish. Failed, 2 of 3 passed. On the iPhone, the app's streak screen still shows 3 days, not 4.*

What Codex gets back from mobster verify on your app: the lesson and its “Great job!” pass, but the streak stays at 3, so the check fails.

Codex can build an iOS app from the terminal, but it can’t look at the result. Mobster’s MCP server gives it a headless iOS simulator and a verdict: Codex states what must be true, drives the app through Mobster’s tools, and gets passed or failed from assertions on the accessibility tree, with frames and a report. The same server can drive a real iPhone over USB.

You need an Apple silicon Mac with macOS 15 or later and Xcode with an iOS Simulator runtime. A real iPhone also needs Developer Mode and the WebDriverAgent runner, set up in Mobster for Mac ([Device setup](https://docs.mobster.dev/device-setup)).

## Install Mobster for Mac

[Get Mobster for Mac](https://mobster.dev/download), drag it to Applications and open it. Its MCP server is the agent inside the app, so the command every client starts is this path, with `mcp`:

```
/Applications/Mobster.app/Contents/MacOS/mobster-agent
```

The first check creates Mobster’s own simulator, boots it headless and builds WebDriverAgent, once per Xcode version. Mobster never touches your own simulators: each one it creates has a name that starts with “Mobster”.

## Add the server

In Mobster for Mac, open Settings › Connectors › Use Mobster from… and press **Add** next to Codex. It runs `codex mcp add` for you, and when the app holds your model key it passes the app’s settings file with `--env-file`, so Smart uses the same key.

By hand:

```
codex mcp add mobster -- /Applications/Mobster.app/Contents/MacOS/mobster-agent mcp
```

That writes a block to `~/.codex/config.toml`, which the Codex CLI, the IDE extension and the ChatGPT desktop app share. You can write the block yourself instead:

```
[mcp_servers.mobster]command = "/Applications/Mobster.app/Contents/MacOS/mobster-agent"args = ["mcp"]
```

A trusted project can carry its own `.codex/config.toml` with the same block, so everyone on the project gets the server.

Timeouts: Codex gives each tool call 60 seconds by default (`tool_timeout_sec`) and each server 10 seconds to start (`startup_timeout_sec`). Every Mobster call returns within 45 seconds and `wait` within 50, so the defaults hold. Work that takes longer, such as the first simulator boot or a Smart run, continues under a `run_id` that Codex polls with `wait`. For more margin:

```
[mcp_servers.mobster]command = "/Applications/Mobster.app/Contents/MacOS/mobster-agent"args = ["mcp"]tool_timeout_sec = 120
```

Key-less checks need no key: Codex drives with its own model, and Mobster judges. For Smart, where Mobster runs the steps itself on your OpenAI or Anthropic key, add your env file to the arguments. Mobster expands the `~` itself:

```
args = ["mcp", "--env-file", "~/.config/mobster/agent.env"]
```

## Check it’s connected

In the `codex` TUI, `/mcp` lists your active MCP servers and their tools. From the shell, `codex mcp list` shows the same. Then ask:

```
Call mobster's status tool and summarize it.
```

`status` names Mobster’s version, the simulator setup, whether Smart is on (and why not, when it’s off) and where runs go.

## A first check: the streak after a lesson

Say your app has lessons and a daily streak. A good first prompt for Codex:

```
Verify that finishing a lesson in my app takes the streak from 3 to 4 days.
```

Codex builds your app for the simulator, then makes these calls, the key-less form of a lesson check:

```
{"tool": "verify_start", "arguments": {  "app_path": "/abs/path/YourApp/.mobster/build/Build/Products/Debug-iphonesimulator/YourApp.app",  "launch_args": ["-SkipOnboarding", "YES"], "launch_env": {"STREAK_DAYS": "3"},  "open_url": "yourapp://lesson/last",  "steps": ["Pick the word that fills the blank, then tap Check.", "Tap Continue until the lesson ends."],  "expect": [{"text": "Lesson complete"}, {"value": {"id": "streak_days"}, "equals": 4}]}}{"tool": "tap", "arguments": {"run_id": "…", "target": {"id": "answer_cafe"}}}{"tool": "tap", "arguments": {"run_id": "…", "target": {"id": "lesson_check"}}}{"tool": "tap", "arguments": {"run_id": "…", "target": {"id": "lesson_continue"}}}{"tool": "verify_finish", "arguments": {"run_id": "…"}}
```

It passes when the streak goes up. When the lesson ends and the streak stays at 3, `verify_finish` fails with `value id=streak_days == 4 failed: was "3 days"`. That is the bug a screenshot glance misses and an assertion catches. `verify_finish` also returns the path to the run’s one-file HTML report and the overlay frame.

`app_path` must be absolute. Clients start servers in different folders, so Mobster refuses a relative path. [Test your iOS app with Codex](https://mobster.dev/blog/test-ios-app-with-codex) covers the loop, saving checks and rerunning them in scripts.

## Put the rule in AGENTS.md

Codex reads `AGENTS.md`. Add the rule with your scheme and app names:

```
## Verifying UI changesAfter you change a screen in this iOS app, verify it before you say it works.1. Build for the simulator:   xcodebuild -scheme <Scheme> -destination 'generic/platform=iOS Simulator' -derivedDataPath .mobster/build CODE_SIGNING_ALLOWED=NO build2. Call mobster's verify_start with app_path set to the absolute path of   .mobster/build/Build/Products/Debug-iphonesimulator/<App>.app, the steps in plain English, and expect:   what must be true when the steps are done.3. Drive with screen, tap, type_text and swipe, then call verify_finish.4. If the verdict is failed, fix the code and verify again. Report the verdict and the report path.
```

## Use a real iPhone

`list_devices` names every device Mobster can use: USB iPhones set up for it, Mobster’s simulators and WebDriverAgent addresses. Called with `device` and no `run_id`, the phone tools drive that device directly, outside a check. Mobster takes the device’s lock, and `stop` with the `device`, or 90 idle seconds, releases it for the Mac app and other commands.

Codex approves a tool, not a device: allowing `tap` on a simulator allows it on your phone. Keep the server to the phones you choose:

```
[mcp_servers.mobster]command = "/Applications/Mobster.app/Contents/MacOS/mobster-agent"args = ["mcp", "--allow-device", "Test iPhone"]
```

Any other real device is listed as `not_allowed` and refused. Simulators are always allowed.

Codex’s `default_tools_approval_mode` decides when it asks. With `writes`, it prompts for every tool that isn’t marked read-only. Mobster marks `status`, `screen`, `list_devices`, `wait`, `wait_for`, `read_notifications` and `unlock_status` as read-only in its MCP annotations, so Codex reads the screen freely and asks before `tap`, `type_text`, `swipe` and the rest. The server’s instructions also tell Codex to ask you before anything that sends, buys, posts or deletes on a real iPhone. A locked phone fails the call at once with “Your iPhone is locked. Unlock it and try again. No action was taken.”

## Troubleshooting

| Symptom | Fix |
|---|---|
| `/mcp` doesn’t show mobster | Check the block in `~/.codex/config.toml`. A project’s `.codex/config.toml` loads only in a trusted project |
| Codex says the server didn’t start in time | `startup_timeout_sec` defaults to 10 seconds. Raise it in the block, for example to 30 |
| The first `verify_start` returns `status: "preparing"` | The simulator is booting and WebDriverAgent is building. Codex calls `wait` |
| No `verify` tool | Smart is off. `status` says why: no key, a missing env file, or `--keyless` |
| `couldnt_run` | Read `reason.class` and `reason.fix` in the result. [Checks](https://docs.mobster.dev/checks) lists every class |

The [MCP reference](https://docs.mobster.dev/mcp-server) has every tool, and [Checks](https://docs.mobster.dev/checks) the assertion language.

## Questions

- ### Is Codex's default tool timeout long enough for Mobster?
  Yes. Codex allows 60 seconds per tool call by default, and every Mobster call returns within 45 seconds, wait within 50. Longer work continues under a run_id that Codex polls with wait. Set tool_timeout_sec = 120 if you want more margin.
- ### Where does Codex keep the Mobster server config?
  In ~/.codex/config.toml by default, which the Codex CLI, the IDE extension and the ChatGPT desktop app share. A trusted project can also have its own .codex/config.toml.
- ### Can Codex skip approval for Mobster's read-only tools?
  Yes. With default_tools_approval_mode set to writes, Codex prompts only for tools that aren't marked read-only. Mobster marks status, screen, list_devices, wait and its other read tools as read-only, so Codex asks before a tap and not before a screen read.
- ### Does Codex have an iOS simulator?
  Not one it can see on its own. Codex can build and launch your app with xcodebuild from its terminal, but reading and tapping the running app takes an MCP server. Mobster's gives Codex a headless simulator, each screen as a list of controls by name, and passed or failed from assertions.

## Sources

We read each of these on 8 October 2026. Reviewed by Andy Guo on 8 October 2026. Corrections are welcome at the [GitHub repo](https://github.com/RadishSoftware/mobster/issues).

- [Codex docs: Model Context Protocol](https://learn.chatgpt.com/docs/extend/mcp)
- [Codex docs: AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)
- [MCP specification: ToolAnnotations (readOnlyHint)](https://modelcontextprotocol.io/specification/2025-11-25/schema)
- [Apple: enabling Developer Mode on a device](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device)
- [Mobster docs: MCP server](https://docs.mobster.dev/mcp-server)
- [Mobster docs: checks](https://docs.mobster.dev/checks)
- [Mobster docs: device setup](https://docs.mobster.dev/device-setup)

Codex’s logo is a trademark of OpenAI, shown only to name the product. Mobster isn’t affiliated with or endorsed by OpenAI.

## Read next

- [Every MCP tool, in the reference](https://docs.mobster.dev/mcp-server)
- [Getting started with verify](https://docs.mobster.dev/verify)
- [Give Claude Code or Codex your real iPhone through MCP](https://mobster.dev/blog/give-claude-code-codex-a-real-iphone-mcp)
- [Test your iOS app with Codex](https://mobster.dev/blog/test-ios-app-with-codex)

## Other agents

- [Claude Code](https://mobster.dev/connectors/claude-code)
- [Cursor](https://mobster.dev/connectors/cursor)
- [VS Code](https://mobster.dev/connectors/vs-code)
- [Claude Desktop](https://mobster.dev/connectors/claude-desktop)
- [Gemini CLI](https://mobster.dev/connectors/gemini-cli)
- [opencode](https://mobster.dev/connectors/opencode)
- [Windsurf (Devin Desktop)](https://mobster.dev/connectors/windsurf)
