flutter-ios-bridge-mcp
Ship Flutter apps to iOS from Windows or Linux — no Mac needed.
An MCP server that gives your AI assistant (Claude Desktop, Claude Code, Cursor, VS Code Copilot, Windsurf…) the tools to build, sign, test and upload iOS apps. It connects your machine to the Apple parts of the toolchain:
| Backend | What it gives you | Needs |
|---|---|---|
| Project tools (always on) | ios_doctor finds iOS-only problems before you burn CI minutes; ios_* tools fix Info.plist, bundle id, deployment target, Podfile — no Xcode |
nothing |
| GitHub Actions macOS runners | Simulator .app, unsigned IPA (for sideloading), signed IPA, TestFlight upload; pulls errors and artifacts back |
GitHub repo + token |
| App Store Connect API | Certificates from a locally generated CSR (no Keychain), provisioning profiles, bundle ids, capabilities, devices, TestFlight builds & groups | Apple Developer account + API key |
| Remote Mac over SSH (optional) | Sync → build → run on the iOS Simulator → screenshots returned to the AI → logs, deep links | any Mac you can SSH into |
| USB iPhone (optional) | List devices, install IPAs, read syslog from Windows/Linux | pymobiledevice3 + Apple USB driver |
Install
pipx install flutter-ios-bridge-mcp # from PyPI
pipx install git+https://github.com/guru-prasath-j/flutter-ios-bridge-mcp.git # latest from GitHub
# optional: USB iPhone support
pipx inject flutter-ios-bridge-mcp pymobiledevice3
Then:
flutter-ios-bridge-mcp init # writes a commented config.toml (or use env vars)
flutter-ios-bridge-mcp status # shows what is configured
flutter-ios-bridge-mcp doctor path/to/flutter_app # iOS audit, no AI needed
Connect it to your MCP client
Claude Desktop (%APPDATA%\Claude\claude_desktop_config.json on Windows, ~/.config/Claude/… on Linux):
{
"mcpServers": {
"flutter-ios-bridge": {
"command": "flutter-ios-bridge-mcp",
"env": {
"FIB_PROJECT_PATH": "C:/Users/me/code/my_app",
"GITHUB_TOKEN": "github_pat_...",
"ASC_KEY_ID": "ABC123XYZ",
"ASC_ISSUER_ID": "00000000-0000-0000-0000-000000000000",
"ASC_PRIVATE_KEY_PATH": "C:/keys/AuthKey_ABC123XYZ.p8"
}
}
}
}
Claude Code: claude mcp add flutter-ios-bridge -- flutter-ios-bridge-mcp
VS Code / Cursor (.vscode/mcp.json / .cursor/mcp.json): same command + env shape.
No pipx on PATH? Use "command": "pipx", "args": ["run", "flutter-ios-bridge-mcp"].
Configuration
Environment variables win over config.toml (%APPDATA%\flutter-ios-bridge\config.toml on Windows,
~/.config/flutter-ios-bridge/config.toml elsewhere; override with FIB_CONFIG).
| Variable | Purpose |
|---|---|
FIB_PROJECT_PATH |
Default Flutter project |
GITHUB_TOKEN |
Fine-grained PAT: Actions R/W, Secrets R/W, Contents R. Falls back to gh auth token |
FIB_GITHUB_REPO |
owner/repo (default: read from the project's git remote) |
ASC_KEY_ID, ASC_ISSUER_ID, ASC_PRIVATE_KEY_PATH |
App Store Connect API key (Users and Access → Integrations → App Store Connect API, role App Manager or Admin) |
FIB_MAC_HOST, FIB_MAC_USER, FIB_MAC_KEY_PATH / FIB_MAC_PASSWORD, FIB_MAC_PORT, FIB_MAC_REMOTE_DIR |
Optional remote Mac |
Signing material created by the tool lives in ~/.flutter-ios-bridge/signing/ (private keys are chmod 600). Back it up —
the certificate private key never leaves your machine except as an encrypted GitHub secret.
The zero-Mac path to TestFlight
Ask your assistant "Ship my app to TestFlight" (or use the built-in ship_to_testflight prompt). Under the hood:
ios_doctor→ fix bundle id (com.example.*is rejected), missing permission strings for your plugins, deployment target / Podfile mismatch, icon alpha channel…ci_generate_workflow→ commit & push.github/.ci_trigger_build(build_type="unsigned-ipa")→ci_wait_for_run→ on failureci_get_logspulls the exact Xcode/CocoaPods errors so the assistant can fix them.- Create the app record once in App Store Connect (Apple's API can't create apps).
signing_quick_setup(profile_kind="app-store")— CSR → Apple Distribution certificate →.p12→ App Store profile → GitHub secrets. All from Windows/Linux.ci_trigger_build(build_type="signed-ipa", testflight=true).testflight_builds→testflight_distribute(export compliance + beta groups).
Testing on a real iPhone without a Mac
- Ad-hoc:
asc_register_device(reads the UDID over USB) →signing_quick_setup(profile_kind="ad-hoc")→ci_trigger_build(build_type="signed-ipa", export_method="ad-hoc")→ci_download_artifacts→device_install_app→device_syslogfor crash logs. - Free Apple ID: build
unsigned-ipaand sideload with Sideloadly / AltStore (7-day signature). - Simulator: needs macOS; with a remote Mac use
mac_run_on_simulator+mac_screenshot.
Tools
| Group | Tools |
|---|---|
| status | bridge_status |
| project | ios_doctor, ios_get_info_plist, ios_set_info_plist_value, ios_remove_info_plist_key, ios_get_build_settings, ios_set_bundle_identifier, ios_set_deployment_target |
| CI | ci_generate_workflow, ci_trigger_build, ci_list_runs, ci_wait_for_run, ci_get_logs, ci_download_artifacts, ci_cancel_run, ci_set_signing_secrets |
| signing / ASC | signing_quick_setup, signing_inspect, asc_list, asc_register_bundle_id, asc_enable_capability, asc_register_device, asc_revoke_certificate, asc_download_profile, testflight_builds, testflight_distribute |
| remote Mac | mac_doctor, mac_sync_project, mac_build, mac_list_simulators, mac_boot_simulator, mac_run_on_simulator, mac_install_simulator_app, mac_screenshot, mac_simulator_logs, mac_open_url, mac_exec, mac_fetch_file |
| USB device | device_list, device_info, device_install_app, device_list_apps, device_uninstall_app, device_syslog |
| prompts | ship_to_testflight, fix_ios_build |
Costs and limits
- GitHub-hosted macOS minutes are free on public repos; private repos consume your Actions minutes at a 10× rate (check GitHub's current pricing). A clean Flutter iOS build takes roughly 8–20 minutes.
- Publishing to TestFlight/App Store requires a paid Apple Developer Program membership.
- Apple caps the number of distribution certificates;
signing_quick_setupreuses the one it created, andasc_revoke_certificatefrees a slot. - Windows USB access needs Apple's driver (install Apple Devices from the Microsoft Store, or iTunes);
Linux needs
usbmuxd.
Security
- Tokens and keys are read from env/config only; nothing is sent anywhere except GitHub and Apple APIs (and your own Mac over SSH).
- GitHub secrets are encrypted locally with the repo's public key (libsodium sealed box) before upload.
- The CI workflow creates a throwaway keychain per run and deletes it afterwards.
Development
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]" && pytest
npx @modelcontextprotocol/inspector flutter-ios-bridge-mcp # poke at the tools
MIT © Guruprasath J
Release files for flutter-ios-bridge-mcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flutter_ios_bridge_mcp-0.1.0.tar.gz | 73.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flutter_ios_bridge_mcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.0 kB
Release files / flutter_ios_bridge_mcp-0.1.0.tar.gz
| Download URL | flutter_ios_bridge_mcp-0.1.0.tar.gz |
|---|---|
| Size | 73.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
67138e9b1cfe8f0e11a7c863000351e1a8f569ec40f798686090097cdfdc0c35
|
|
BLAKE2b-256 checksum How to use checksums |
dfe4f24eb19e1154212abfd6217655b2ee76427189dd6a532796c0bd2d302acd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / flutter_ios_bridge_mcp-0.1.0-py3-none-any.whl
| Download URL | flutter_ios_bridge_mcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 47.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2de523363a2a1730c877da2d6cfb16d6a429d2d151e5579905255f975f3dd1ce
|
|
BLAKE2b-256 checksum How to use checksums |
8be54a962a6e8aabdfd0d72722f4ddd47798c358c7fed93ad5521b725a051011
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log