MCP Studio Mobile

MCP Studio Mobile

A thin remote-control client for MCP Studio. Stream your desktop's chat panel to your phone, send prompts back, switch tabs and projects — all over your own tunnel. No cloud infrastructure.

Architecture in one sentence. Phone holds a device token + a WebSocket. Desktop runs the MCPs, the agent loop, and the credential vault. The tunnel (Tailscale / Cloudflare / ngrok / ZeroTier) provides the network path; Studio operates no servers.

Install

Android · APK

  1. Open the Releases page and download the latest .apk.
  2. Tap the file in your downloads to install. Allow "install from unknown sources" if Android asks.
  3. Open MCP Studio Mobile. You should land on the empty pair screen.

iOS · TestFlight (coming)

iOS distribution via TestFlight is on the roadmap and requires an active Apple Developer enrollment. Until then, run via Expo Go for dev / personal use: open the Expo dev server URL from your developer's Mac in the Expo Go app.

Pair with desktop

Pairing is one-time per device. The desktop mints a 5-minute one-time token; you scan or paste it on the phone and the desktop exchanges it for a long-lived device token stored in the OS Secure Enclave / Keystore via Expo SecureStore.

  1. On desktop: open Settings → Mobile. Paste your tunnel URL in the field (or click Detect Tailscale URL). Click Enable.
  2. Click Generate pair code. A QR + mcpstudio://pair?u=…&t=… link appears (5-minute TTL).
  3. On the phone: open MCP Studio Mobile. Tap Scan QR / camera (or paste the link).
  4. Give the device a name (e.g. "Rohan's iPhone") → Pair.

The chat screen opens. You should see the connection dot turn green within a second, the desktop's active-tab transcript stream in, and a green pill in the desktop's Paired devices list with your device name.

The desktop persists the WebSocket port across enable / disable cycles in ~/.mcp-widget/mobile-control.json — your phone reconnects after a desktop restart without re-pairing.

Tunnel setup

The mobile app reaches the desktop at whatever URL your tunnel terminates at. Studio supports any. Pick what fits your threat model.

Tailscale (recommended)

Install Tailscale on both the Mac + the phone, log into the same tailnet. Then:

# On the Mac, in any terminal:
tailscale serve --bg http://localhost:<PORT>
# Replace <PORT> with whatever Studio's Settings → Mobile shows.

Your tunnel URL becomes https://<hostname>.<tailnet>.ts.net. Paste that in Studio's Tunnel URL field. The phone reaches it over the encrypted tailnet — no port forwarding, no public exposure.

Cloudflare Tunnel

cloudflared tunnel --url http://localhost:<PORT>

Returns a https://<random>.trycloudflare.com URL. Free, HTTPS-terminated, no account needed.

ngrok

ngrok http <PORT>

Returns https://<random>.ngrok.app. Free tier resets the URL on each session; ngrok config add-authtoken persists a custom URL.

ZeroTier

Same idea as Tailscale — both devices on the same ZeroTier network. Use the desktop's ZeroTier IP + the bound port: http://<zt-ip>:<PORT>.

Chat + transcript

The main screen mirrors your active desktop tab. Bubbles render markdown — code blocks, lists, tables, inline code — the same way desktop responses do.

Slash commands

Typing / in the input opens an autocomplete strip with the built-in commands. Tap one to fill the input, then send.

CommandWhat it does
/helpList every built-in command
/mcp-serversList installed MCPs (and tool counts)
/tabList / new / switch / close / rename tabs
/projectList / new / switch / delete / end projects
/build-mcpTell the desktop to open the MCP Builder
/clearClear the current tab's transcript (both ends)

Custom quick_commands declared by installed MCPs aren't surfaced in the mobile autocomplete yet — coming in a future update (currently they still work if you type them manually).

Tabs + projects

The desktop's tab list mirrors to the phone. Switch tabs from the desktop and the mobile transcript updates automatically. From the phone, the slash-command path (/tab switch …) drives the desktop the same way typing in the panel would.

Switching to a project (/project switch foo) changes the tab's project pointer and rebinds the transcript / agent context to that project's history. Projects persist server-side; the mobile is read-only on per-project storage.

Theme

Tap in the chat header → ThemeSystem / Light / Dark. System follows your OS appearance. The choice is persisted in SecureStore so it survives a relaunch.

Auto-updates

Production builds ship via Expo's OTA update channel. Every cold start, the app silently checks for a new JS bundle on its release branch (preview or production). If an update is ready, it downloads in the background and applies on the next launch — no app-store re-publish needed for JS-only changes.

Native package upgrades still require a fresh APK install (the release tag bumps signal those).

Troubleshooting

"Network request failed" or "Couldn't reach the desktop"

The phone can't reach the URL. Check, in order:

"500" error when scanning a QR

Server side: the desktop's pairings::add failed (rare — usually a corrupted ~/.mcp-widget/mobile-pairings.json). Quit Studio, delete that file, relaunch, generate a fresh pair code.

QR doesn't include the tunnel URL

Fill in the Tunnel URL field on the desktop before clicking Generate pair code. The URL is embedded in the QR via the u= query param. If it's empty, the mobile app prompts for it manually.

Build version mismatch

The mobile validates the server's schema_version in its hello snapshot. If the server is newer, you'll see a screen prompting you to update the app from the Releases page.

Privacy + security

Roadmap

What's shipped today, what's in progress, what's planned. Listed here before scope shifts during a sprint — adjust expectations accordingly.

✓ Shipped

  • QR pair + paste-link fallbackURL embedded in QR, scheme auto-flip
  • Live transcript streamingWebSocket with reconnect + heartbeat
  • Slash command autocompletebuilt-in commands
  • Markdown renderingcode, lists, tables, links via react-native-markdown-display
  • Tab + project switchingfrom the phone, drives desktop
  • Dark modeSystem / Light / Dark, persisted
  • OTA updatesvia Expo Updates

○ Planned

  • Push notificationsagent-done pings via Expo Push
  • Voice inputon-device ASR → prompt:submit
  • iOS TestFlightrequires Apple Developer cert
  • Custom quick command autocompleteprotocol extension: surface MCP-declared commands
  • Multi-desktop pickerSecureStore already stores an array
  • File / image attachmentssend screenshots / docs as prompt context
  • MCP install + settings from phonedrive Settings → MCP Servers remotely
  • Offline queuesend prompts while disconnected, flush on reconnect
  • App iconcurrently using Expo default