Windsurf (Devin Desktop) and the iOS simulator: MCP setup
Windsurf is now Devin Desktop, and its MCP config moved. Add Mobster for Cascade and Devin Local in one file, and let it check your iOS app on a simulator.
The short version
Install Mobster CLI, then run:
devin mcp add -s user mobster -- mobster mcpConfig file: ~/.config/devin/mcp_config.json
From the docs. This setup follows Cognition's MCP documentation, read on 8 October 2026. Mobster's MCP server is tested with Claude Code; we haven't run it in Windsurf (Devin Desktop) ourselves yet. Cognition’s MCP docs.
Windsurf has become Devin Desktop. Its Linux package repositories still say windsurf, the package is now devin-desktop, the docs moved to docs.devin.ai, and Devin’s MCP docs give a new path for the MCP config file. Whichever agent you use there, Devin Local or the Cascade agent, Mobster gives it the same thing: an iOS app running on a headless simulator Mobster manages, screens read as lists of controls by name, and a verdict of passed or failed from assertions on the accessibility tree. 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 or with mobster serve --manage-device (Device setup).
Install Mobster CLI
curl -fsSL https://mobster.dev/install.sh | shor
brew install radishsoftware/tap/mobstermobster version
which mobster
mobster sim doctor --fixKeep the path which mobster prints: a desktop app may not see your shell’s PATH.
Add the server
Devin Desktop has two agents. Devin Local, the default for new tabs, reads its MCP servers from the Devin CLI’s config files. Cascade, now the legacy agent, reads mcp_config.json. At user scope they share one file, so this command covers both:
devin mcp add -s user mobster -- mobster mcpWithout -s, devin mcp add writes to the project’s .devin/mcp_config.local.json, which is git-ignored; -s project writes .devin/mcp_config.json for the team. The user file is ~/.config/devin/mcp_config.json, or the same path under $XDG_CONFIG_HOME when that is set. To write it by hand, open it from Cascade: the … menu at the top right of the Cascade panel, then Open MCP config file.
{ "mcpServers": { "mobster": { "command": "/opt/homebrew/bin/mobster", "args": ["mcp"] } }}Replace the path with your own from which mobster. Cascade has no MCP marketplace or one-click install, so the file is the way in.
Key-less checks need no key: the agent drives with its own model, and Mobster judges. For Smart, where Mobster runs the steps itself on your OpenAI or Anthropic key, add "--env-file", "~/.config/mobster/agent.env" after "mcp" in args. Mobster expands the ~ itself, and the key never sits in the config.
Devin’s MCP pages don’t state a tool-call timeout. Mobster keeps calls short: each returns within 45 seconds and wait within 50. The first simulator boot and Smart runs continue under a run_id that the agent polls with wait.
Check it’s connected
devin mcp list
devin mcp get mobsterThen ask the agent:
Call mobster's status tool and tell me what it says.A first check: a settings toggle
Daybreak, the sample app in the CLI’s repository, has a Daily reminder switch on its Settings screen, with the accessibility identifier daily_reminder. Start with a launch-only smoke check of that screen: no steps, one expectation.
Build Daybreak for the simulator. Launch it with -DaybreakSkipOnboarding YES, open daybreak://settings,
and verify the daily_reminder switch is on screen. No steps.The agent calls verify_start with the absolute app_path, the launch arguments, the deep link and the expectation, then verify_finish:
{"tool": "verify_start", "arguments": { "app_path": "/abs/path/examples/ios/Daybreak/.build/Build/Products/Debug-iphonesimulator/Daybreak.app", "launch_args": ["-DaybreakSkipOnboarding", "YES"], "open_url": "daybreak://settings", "steps": [], "expect": [{"visible": {"id": "daily_reminder"}}]}}{"tool": "verify_finish", "arguments": {"run_id": "…"}}Mobster installs the app, opens the deep link through WebDriverAgent, and decides on one settled read. The next step checks the behaviour as well as the screen: tap the switch, relaunch, open Settings again and expect {"value": {"id": "daily_reminder"}, "equals": true}. That is Daybreak’s reminder.yaml, and with -DaybreakBug reminder-not-saved it fails with value id=daily_reminder == true failed: was off.
Put the rule in AGENTS.md
Devin Desktop’s docs treat an AGENTS.md at the repository root as an always-on rule for Cascade. Add:
## 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. With a USB iPhone’s name as device and no run_id, screen, tap, type_text, swipe, alert, open_url, launch_app and home act on the phone directly. Mobster holds the phone’s lock until stop with the device, or 90 idle seconds.
Devin Local uses the Devin CLI’s permission modes, which can be scoped to MCP tools. Whatever you allow covers a tool, not a device: allowing tap for simulator work allows it on your phone. Keep the server to the phones you choose:
"args": ["mcp", "--allow-device", "Test iPhone"]Any other real device is listed as not_allowed and refused. disabledTools in the server’s entry can remove tools you never want called, such as install_app. Mobster’s MCP annotations mark status, screen, list_devices, wait, wait_for, read_notifications and unlock_status as read-only, and its instructions tell the agent to ask you before anything that sends, buys, posts or deletes on a real iPhone. A locked phone stops the call at once with “Your iPhone is locked. Unlock it and try again. No action was taken.”
Troubleshooting
| Symptom | Fix |
|---|---|
| mobster doesn’t appear after you edit a config file | Use the file Devin’s MCP docs name, ~/.config/devin/mcp_config.json, or add the server with devin mcp add -s user |
| Cascade says it has too many tools | Cascade allows 100 tools across all servers. Add the ones you don’t need to disabledTools |
| mobster doesn’t start | Use the full path from which mobster in command |
The first verify_start returns status: "preparing" | The simulator is booting and WebDriverAgent is building. The agent calls wait, or run mobster sim doctor --fix first |
couldnt_run, or no verify tool | reason.fix in the result says what to do. status says why Smart is off |
The MCP reference lists every tool and argument.
Questions
Where is Windsurf's mcp_config.json now?
Windsurf is now Devin Desktop, and its MCP docs give ~/.config/devin/mcp_config.json on macOS, or the same path under XDG_CONFIG_HOME when that's set. devin mcp add -s user writes that file for you.
Does Mobster count against Cascade's tool limit?
Yes. Cascade can use at most 100 tools across all servers, and Mobster offers about two dozen. If you hit the limit, list the ones you don't need in the server's disabledTools.
Does the same config work for Devin Local and Cascade?
Yes, at user scope. devin mcp add -s user writes ~/.config/devin/mcp_config.json, the file Cascade's MCP settings also read. Devin Local is the default agent for new tabs, and Cascade is now the legacy agent.
Sources
We read each of these on 8 October 2026. Reviewed by Andy Guo on . Corrections are welcome at the GitHub repo.
Windsurf (Devin Desktop)’s logo is a trademark of Cognition, shown only to name the product. Mobster isn’t affiliated with or endorsed by Cognition.