Skip to content

turin-dev/rish-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rish-mcp

Expose an Android phone's Shizuku shell (uid 2000, like adb shell) to AIs as an MCP toolwithout VPN, adb, or sshd. The phone holds a single outbound WebSocket to a relay on example.com; AIs call the relay's MCP endpoint.

┌─────────┐  MCP run_shell    ┌──────────────────────┐   WS (outbound)   ┌──────────────┐
│   AI    │ ──HTTPS+Bearer──▶ │  example.com relay+MCP  │ ◀── phone dials ──│  phone APK   │
│(Claude) │ ◀── stdout/code── │   (Node, Dokploy)    │ ── exec cmd ─────▶│ Shizuku→shell │
└─────────┘                   └──────────────────────┘                   └──────────────┘

Phone has zero inbound exposure (works behind SKT CGNAT). No VPN, no adb, no sshd.

Components

  • server/ — Node/TS. Streamable-HTTP MCP server (run_shell, list_devices)
    • WS relay the phone connects to. Bearer auth for AIs, shared token for the phone.
  • app/ — Android (Kotlin). One installable APK: binds a Shizuku UserService to run commands as shell uid, a foreground service holds the outbound WS, auto-starts on boot.

Build

# server (typecheck + e2e smoke test with a fake agent)
cd server && npm install && npx tsc && node test/smoke.mjs

# APK (Android SDK + Gradle run inside Docker; host stays clean)
cd app && ./build-apk.sh        # -> app/rish-mcp-agent.apk

Deploy (relay+MCP)

Tokens live in server/.env (gitignored). Deploy docker-compose.yml as a Dokploy Compose app with AI_TOKEN/DEVICE_TOKEN env, routed by Traefik to mcp.example.com. Add a Cloudflare A record mcp.example.com → <server-ip> (orange/proxied is fine for HTTPS+WSS over :443).

Install on phone

Fully headless when you already have a Shizuku shell (rish / adb). -g auto-grants Shizuku's API_V23 permission, and am extras provision the agent — no taps, no typing on the device:

SIZE   # not needed; stream the apk over stdin as the shell user
TOKEN=<DEVICE_TOKEN>

# 1. push + install with runtime perms granted (grants Shizuku too)
rish -c 'cat > /data/local/tmp/r.apk' < rish-mcp-agent.apk
rish -c 'pm install -r -g /data/local/tmp/r.apk; rm -f /data/local/tmp/r.apk'

# 2. provision relay URL + token and start the agent
rish -c "am start -n kr.scin.rishmcp/.MainActivity \
  --es relay wss://mcp.example.com/agent --es token $TOKEN --ez autostart true"

The foreground service connects out to the relay and survives reboot (BootReceiver). To re-point an already-running agent at a new relay, am force-stop kr.scin.rishmcp first, then re-run step 2 (the service reads config on fresh start).

Manual alternative: open the app, Grant Shizuku permission, paste relay URL + token, Save & Start.

Use from an AI (MCP client)

{
  "mcpServers": {
    "phone": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "headers": { "Authorization": "Bearer <AI_TOKEN>" }
    }
  }
}

Then the AI has tools run_shell({cmd, deviceId?, timeoutMs?}) and list_devices().

Security notes

  • This grants shell-level remote execution on the phone to anyone holding AI_TOKEN. Treat it like an SSH private key. Rotate by changing env + restarting the stack.
  • The phone only trusts the relay it dials; it never accepts inbound connections.
  • Scope is the owner's own device for personal automation.

About

Run an Android phone's Shizuku shell from AIs as an MCP tool — no VPN, adb, or sshd.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors