Deckhand
Provides preview and testing capabilities for Android apps via Android emulators and adb, including app installation, screenshots, accessibility tree inspection, and touch input control.
Supports building and previewing Expo-based React Native apps as one of the supported build recipes.
Enables fetching and building apps from GitHub repositories, including branches and pull requests, with support for multiple authentication methods.
Provides preview and testing capabilities for iOS apps via iOS simulators and simctl, including app installation, screenshots, accessibility tree inspection, and touch input control.
Supports building and previewing NativeScript-based apps as one of the supported build recipes.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@DeckhandTest PR #42 on iPhone 16 and Pixel 9"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Deckhand
Ask Claude for your app on any device — get a link.
Deckhand is an MCP server that runs on a Mac. Connect it to Claude (claude.ai, Claude Code, Routines — any MCP client) and ask:
"Test the onboarding screens on iOS 26 and Android 14 for PR #42"
You get back one calm page showing every device live, with full touch control — shareable publicly or behind a PIN. Claude can also see and drive the devices itself (screenshot, accessibility tree, tap/type) before it hands you the link.
For humans: set up Deckhand with an agent
Tell your coding agent:
Set up Deckhand on this Mac from https://github.com/Okam-AS/deckhand. Guide me step by step through the Cloudflare tunnel setup. When it is ready, give me the MCP connector URL and a pairing code so I can connect my agent.
Related MCP server: mobile-device-mcp
How it works
You ask — Claude calls
start_previewwith an app id, a ref/PR, and devices.Deckhand builds — checks out the branch into a worktree (or builds a registered local checkout in place), builds once per platform, installs on every device.
Devices boot in parallel — iOS simulators via
simctl, Android emulators viaavdmanager/adb.You get a link — a stable per-app share URL streaming all devices live, riding a Cloudflare tunnel. No VPN, no WebRTC, no TURN — if a network can reach claude.ai, it can view and control a preview.
Architecture
One Node process owns everything. Nothing but cloudflared is reachable from outside
the machine.
claude.ai / Claude Code / any MCP client share-link viewers (any browser)
│ HTTPS │ HTTPS/WSS
└───────────────────┬──────────────────────────┘
▼
cloudflared named tunnel → http://127.0.0.1:4300
│
┌───────────────────────────▼── deckhand server (loopback only) ──┐
│ │
│ /mcp MCP tools, bearer-authenticated │
│ /oauth/* per-client sign-in (pairing code) │
│ /s/<shareId> viewer page (device grid + controls) │
│ /s/<shareId>/dev/<id>/* scoped proxy → that device's stream │
│ │
│ auth → mcp tools → preview engine → devices → streaming │
│ │ │ │ │ │
│ audit log git worktrees simctl / serve-sim (iOS) │
│ + build recipes adb screenrecord │
│ (Android) │
└─────────────────────────────────────────────────────────────────┘
on-disk: ~/.deckhand/{config.yaml, apps.yaml, tokens.yaml, oauth.json, state.json, audit.jsonl}Building blocks
Module | What it does |
| The MCP surface: previews, screenshots, UI tree, test runs, app registration |
| Preview state machine, build recipes (Expo / RN / NativeScript), app-type detection, worktrees, dev-server lifecycle |
| iOS ( |
| Swappable |
| Share ids, PIN protection, and the scoped HTTP+WS proxy (video + input, nothing else) |
| Credential ladder: PAT → GitHub App → ambient |
|
|
| The single calm page: WebCodecs stream client, touch/keyboard input, device picker |
Stack: Node ≥ 22, TypeScript, ESM. No database, no SPA framework beyond the one viewer page, a ruthlessly short dependency list.
Two ways to run an app
Git mode — Deckhand clones the repo, fetches any ref or PR into a detached worktree, and builds there. Fully self-contained.
Local mode (daily dev loop) — register an existing checkout with
deckhand app add <id> --path <dir>. Built in place, never mutated: Deckhand reads the checkout's git state but never writes to it.restart_preview(or the viewer's Rebuild button) rebuilds on the same booted devices.
Security model
Everything binds loopback; the only way in is the Cloudflare named tunnel.
Nothing that touches a device or a repo is reachable without a credential: a per-client MCP credential (an OAuth grant, or a local bearer token), per-app share links (optionally PIN-gated). The OAuth discovery, registration and sign-in endpoints are open by construction — a client with no credential has to start somewhere — and grant nothing on their own: a request that reaches them needs a pairing code minted on the Mac with
deckhand pair.The MCP surface is capability-bounded — no arbitrary commands, only pre-registered apps and their repos' refs. Every call lands in an append-only audit log.
Secrets never travel through MCP; tokens never appear in argv, URLs, or logs.
PLAN.md describes what the system is — architecture, the MCP surface, the security model; background knowledge in docs/reference/.
Install it
Hand an agent this repo URL and it can do most of it. Two things it cannot, and they are both yours: a Cloudflare login (a browser and your account) and a hostname on a domain you own.
git clone https://github.com/Okam-AS/deckhand && cd deckhand
npm install
npm run build # viewer + landing
npx tsx server/src/cli.ts setup # ← run this first, with no argumentsWith no arguments, setup checks the machine and prints exactly what is missing
and who can fix it — the things it can install itself, and the things it
needs you for. Do those, then run it again with your hostname:
If the preflight asked for cloudflared tunnel login, run that yourself first — it
opens a browser and needs your own Cloudflare account, so it is the one step nothing
here can do for you. Then:
npx tsx server/src/cli.ts setup \
--hostname deckhand.yourdomain.com \
--web-host previews.yourdomain.com # optional, for web previewsIf you are the agent
Run
setupwith no arguments first. It labels every line with who acts, andfix:is the only one of the four you may run:fix:— yours to run.you:— a fix only a person at this Mac can do (an App Store install, an Apple ID, asudolicence accept, the machine's default Node). Relay the line as written and stop; re-runsetuponce they say it is done.BLOCKED — also relay-and-stop, but an errand off this machine: a browser and their Cloudflare account. Never attempt it —
cloudflared tunnel loginopens a browser and will hang you forever.ASK THE USER — questions to ask in the words given, not a report to paste at them. There is more than one: a fresh install asks for the hostname and, marked
(optional), a second hostname for web previews.
Install what it says you can install. Then ask the user for a hostname on a domain they have on Cloudflare, and run
setup --hostname <that>— adding--web-host <the second>if they wanted web previews.At the end, run
deckhand pairyourself and give the user the code it prints; they type it into the page Claude opens. Typing the command is yours, typing the code into their own browser is theirs.Xcode is a ~10 GB App Store download needing an Apple ID and a
sudolicence accept. Ask; do not claim to have done it.Android is optional. Without it, iOS previews work and Android does not —
doctorsays so as a warning rather than a failure.
setup creates the Cloudflare tunnel and DNS route, merges your cloudflared
config (rules for other services are carried through the merge, and the previous
file is copied to config.yml.bak before anything is written — so the one case
the merge cannot preserve, a config.yml that will not parse and so comes back as
nothing to merge with, is still recoverable by hand), links deckhand onto your
PATH, writes deckhand's config, prints your connector URL, installs the
LaunchAgents so it survives sleep and reboot, and runs doctor.
Re-run it any time: every step reports what it found and changes only what is missing, so it doubles as a repair tool.
Then register something to preview:
deckhand app add myapp --path /abs/path/to/a/checkout # local — no GitHub needed
deckhand app add myapp github.com/owner/repo # from git
deckhand doctor --device-only # boots a real sim + emulatorThen paste your connector URL into claude.ai → Settings → Connectors:
deckhand token # prints https://<your-hostname>/mcpThe URL is not a credential. In a Claude team or Enterprise organisation a connector is visible to everyone in it, so deckhand puts no secret in the URL — and admits nobody because they have it. Clicking Connect opens a page that ASKS for a pairing code — and the only place one exists is your Mac:
deckhand pair # mint a code; type it into the page Claude opens
deckhand connections # who holds a grant now
deckhand revoke <client-id> # take it back, effective next call, no restartA colleague who pastes the same URL is asked for a code they do not have. Nothing waits, nothing queues, and there is no list for a stranger to fill — the code exists only on your machine, for ten minutes, for one use.
Claude Code on the same Mac has no browser to sign in with, so it uses a local
credential instead: deckhand token add <name>, sent as an
Authorization: Bearer header. That one is a password — token list shows
which exist with the values masked, token url <name> prints one in full, and
token rm <name> revokes it on the running server.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA server enabling programmatic control over Android devices through ADB, providing capabilities like screenshot capture, UI layout analysis, and package management that can be accessed by MCP clients like Claude Desktop.799Apache 2.0
- AlicenseAqualityDmaintenanceMCP server that gives AI coding assistants the ability to see and interact with mobile devices. 49 tools for Android/iOS — AI-powered visual analysis (Claude + Gemini), smart tap/type by description, Flutter widget tree inspection, video recording, and test script generation. 4-tier element search with <1ms local matching. Free tier included, zero setup via npx.49793Business Source 1.1
- AlicenseAqualityCmaintenanceAn MCP server that enables Claude Code to visually test and control iOS simulators, Android emulators, and real devices through 22 automation tools. It automatically generates test reports with screenshots for mobile app testing directly from the terminal.24121MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for cross-platform mobile automation (iOS/Android) using accessibility trees and screenshots, enabling agents to interact with apps on simulators, emulators, and physical devices.7Apache 2.0
Related MCP Connectors
Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.
MCP server for Appcircle mobile CI/CD platform.
Remote MCP for Android CLI agent build gate, structured receipts, audit logs, and reviewer-ready evi
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Okam-AS/deckhand'
If you have feedback or need assistance with the MCP directory API, please join our Discord server