Requirements
| Part | What you need |
|---|---|
| Android phone | Android 7.0 or later with the ScreenSync MCP app (tested with 2.5.7, build 35) |
| Screen capture | No root and no ADB. Android asks for your consent each session (MediaProjection). |
| Control tools | Tap, swipe, type and launch app run through ADB from the hub, with the phone on USB or wireless debugging. |
| Computer | Windows, macOS or Linux with Node.js 18 or later for the hub (tested with hub 1.14.4). |
| Network | Phone and computer on the same network. The Google Drive fallback is optional. |
| AI client | Any MCP client that runs local stdio servers: Claude Code, Claude Desktop, Cursor or VS Code. |
| Browser tools (optional) | Chrome or Edge with the ScreenSync browser extension 1.14.4. |
Install the hub on your computer
You need: Node.js 18+; Android phone with the ScreenSync MCP app (or ADB for control tools).
- Download the hub zip from https://www.screensyncmcp.tech/extension.html and unzip it anywhere on your computer.
- Windows: double-click
start-hub.bat· macOS/Linux:sh start-hub.sh(ornode screensync-hub.js). Needs free Node 18+. - The terminal prints a pairing link + QR and serves on
http://localhost:3000— keep it running. - Scan the QR with the ScreenSync Android app; install the browser extension from the same page.
- Developers: the extension source is public —
git clone https://github.com/KhizarJamshaidIqbal/screensync-extension.git(the clone root IS the extension folder; Load unpacked on it). Hub + app source stay private.
start-hub.batsh start-hub.shLeave that terminal open: the hub has to keep running while your agent works.
Connect your AI client
Every client below runs the hub the same way: the command node with the path to screensync-hub.js as its argument. Replace <HUB_DIR> with the folder where you unzipped the hub (on Windows, use forward slashes or doubled backslashes inside JSON) and <TOKEN> with the hub's SCREEN_SYNC_TOKEN (default: screensync-local-dev).
Claude Code
Add the server to .mcp.json (project root):
{
"mcpServers": {
"screensync": {
"command": "node",
"args": ["<HUB_DIR>/screensync-hub.js"],
"env": { "SCREEN_SYNC_TOKEN": "<TOKEN>" }
}
}
}Or register it from the terminal with one command:
claude mcp add screensync node "<HUB_DIR>/screensync-hub.js"Claude Desktop
Open claude_desktop_config.json (Settings → Developer) and add the server:
{
"mcpServers": {
"screensync": {
"command": "node",
"args": ["<HUB_DIR>/screensync-hub.js"],
"env": { "SCREEN_SYNC_TOKEN": "<TOKEN>" }
}
}
}Restart the client after saving. Then try a first prompt such as “Take a screenshot of my phone and tell me which app is open.”
Cursor, VS Code and any other stdio MCP client
Any client that runs local (stdio) MCP servers needs the same three values: the command node, one argument with the full path to screensync-hub.js, and the SCREEN_SYNC_TOKEN environment variable. Where the config lives and the top-level key differ between clients, so check your client's MCP docs. Two common layouts:
- Cursor:
.cursor/mcp.jsonin your project (or~/.cursor/mcp.jsonfor every project), using the samemcpServersblock as Claude Code above. - VS Code:
.vscode/mcp.jsonin your workspace, with aserverskey and"type": "stdio":
{
"servers": {
"screensync": {
"type": "stdio",
"command": "node",
"args": [
"<HUB_DIR>/screensync-hub.js"
],
"env": {
"SCREEN_SYNC_TOKEN": "<TOKEN>"
}
}
}
}HTTP only (no MCP client)
Tools that do not speak MCP can call the hub over HTTP at http://<HUB-IP>:3000 with the header Authorization: Bearer <TOKEN>. The browser extension uses this mode — no stdio needed.
ChatGPT's web app connects only to remote HTTPS MCP servers. The ScreenSync MCP hub runs on your computer and speaks MCP over stdio, so ChatGPT web cannot use it today.
Pair the phone with the hub
Open the ScreenSync MCP app and scan the QR code that the hub prints in its terminal (or shows at /pair).
Automatic discovery (mDNS service _screensync-hub._tcp): The phone app auto-discovers via mDNS. Browsers cannot use mDNS — the extension probes localhost and accepts manual URLs / pairing links.
If you pair by hand, the app and extension accept any of these formats:
screensync://pair?url=http%3A%2F%2F<IP>%3A3000&token=<TOKEN>
{"url":"http://<IP>:3000","token":"<TOKEN>"}
http://<IP>:3000#<TOKEN>Grant the screen-capture prompt when the app asks. Frames then stream to the hub, and your agent can call get_latest_screenshot.
Turn on the control tools (ADB)
Capture needs nothing more. To let the agent tap, swipe, type and launch apps, the hub sends those actions through ADB:
- Install ADB (Android platform-tools) on the computer that runs the hub.
- On the phone, turn on developer options, then USB debugging or wireless debugging.
- Connect the phone by cable or pair it for wireless debugging, accept the prompt on the phone, and check that it is listed:
adb devicesWith more than one device attached, set SCREEN_SYNC_ADB_TARGET to the phone's serial. If adb is not on your PATH, point SCREEN_SYNC_ADB_BIN at it.
Environment variables
| Variable | What it does | Default |
|---|---|---|
SCREEN_SYNC_TOKEN | Bearer pairing token shared by app, extension and agents | screensync-local-dev |
SCREEN_SYNC_PORT | HTTP port | 3000 |
SCREEN_SYNC_HOST | Bind address | 0.0.0.0 |
SCREEN_SYNC_DATA_DIR | Frame/inspection/patch storage root | ./data |
SCREEN_SYNC_ADB_TARGET | Optional: pin a specific ADB device serial | — |
SCREEN_SYNC_ADB_BIN | Optional: path to the adb binary | adb |
Change SCREEN_SYNC_TOKEN from its default before you run the hub on a shared network, and use the same value in the app, the extension and your MCP config.
HTTP endpoints
The hub serves these on port 3000. Endpoints marked “Bearer token” need Authorization: Bearer <TOKEN>.
| Endpoint | Auth | Purpose |
|---|---|---|
GET /health | None | Liveness + latest frame time |
GET /pair | None | Human pairing page with QR |
GET /api/pair | None | Machine pairing payload {url, token, link} |
GET /api/events | Bearer token | SSE live stream: frame | inspection | patch | tool | agent_connect |
GET /api/screens/latest | Bearer token | Latest screenshot as base64 data URL |
POST /api/screens/upload | Bearer token | Push a capture (phone app) |
GET /api/device/status | Bearer token | Phone link state (streaming, linked_no_frames or no_phone), last frame age, device model, retained frames |
GET /api/mcp/catalog | Bearer token | Full tool/prompt/resource catalog |
GET /api/inspections/latest | Bearer token | Bug regions published by the agent |
GET /api/patches/latest | Bearer token | Latest git patch from the agent |
POST /api/control/:action | Bearer token | Run any control_* tool by its short name: status, screenshot, tap (count 2 = double tap), long_press, swipe, swipe_until, scroll, type, key, tap_text, open_url, launch_app (launch still works). A missing required argument returns 400 MISSING_ARG. |
Troubleshooting
- Hub not reachable — ensure
start-hub.bat/start-hub.sh(ornode screensync-hub.js) is running and your firewall allows port 3000 on the LAN. - 401 Unauthorized — the token must match
SCREEN_SYNC_TOKENon the hub (default: screensync-local-dev). - 429 Too many live connections —
/api/eventsallows 10 concurrent clients; close another dashboard. - Extension shows offline on another machine — grant the LAN origin permission in the extension's setup step.
Still stuck? Email info@epsoldev.com with the hub's terminal output.
Privacy and next steps
Frames go from the phone to the hub over your own network with the bearer token, and nothing goes to EpsolDev servers. Screenshots that your AI agent requests are sent to that agent's model provider, so close sensitive apps before a session. The data policy lists where every byte is stored.
- Learn how capture, control and live streaming work in the screen MCP guide.
- See how ScreenSync MCP stacks up: compare Android MCP servers.
- Give the agent your browser too with the ScreenSync browser extension.
- Back to the Android MCP server for Claude home page.