Skip to content

rdh073/mobile-mcp

Repository files navigation

mobile-mcp

Design baseline for an MCP server that lets LLM clients such as Claude, Codex, and ChatGPT interact with Android devices through a constrained UI automation runtime.

Local Bootstrap (Canonical SDK Mode)

The canonical operator path uses the official MCP Python SDK transports. All MCP clients that implement the standard protocol work against these paths.

SDK stdio (recommended for Claude Desktop, Cursor, and other MCP clients):

python3 -m mobile_mcp.bootstrap \
  --config configs/runtime.default.json \
  --register-demo-device \
  --transport sdk-stdio

SDK streamable-HTTP (recommended for production HTTP deployments):

python3 -m mobile_mcp.bootstrap \
  --config configs/runtime.default.json \
  --register-demo-device \
  --transport sdk-http \
  --http-port 8000

SDK streamable-HTTP with SQL stores:

python3 -m mobile_mcp.bootstrap \
  --config configs/runtime.sql.example.json \
  --migrate \
  --register-demo-device \
  --transport sdk-http \
  --http-port 8000

The SDK HTTP server exposes one endpoint:

  • POST /mcp — MCP protocol endpoint (streamable-HTTP, application/json or text/event-stream)
  • GET /metrics — Prometheus scrape endpoint when metrics are enabled

Run migrations before boot when using SQL stores:

MOBILE_MCP_DB_URL=sqlite:///runtime_state/runtime.db \
python3 -m mobile_mcp.bootstrap --migrate --config configs/runtime.default.json

Verify startup with:

python3 -m mobile_mcp.bootstrap --config configs/runtime.default.json --print-tools

For manual Inspector debugging, see MCP Inspector Check.

Install In Codex And Claude Code

Install the runtime into a local virtual environment first:

python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .

For Codex and Claude Code, use the canonical SDK stdio transport:

codex mcp add mobile-mcp -- \
  /absolute/path/to/mobile-mcp/.venv/bin/python \
  -m mobile_mcp.bootstrap \
  --config /absolute/path/to/mobile-mcp/configs/runtime.default.json \
  --register-adb-devices \
  --transport sdk-stdio
claude mcp add --scope user mobile-mcp -- \
  /absolute/path/to/mobile-mcp/.venv/bin/python \
  -m mobile_mcp.bootstrap \
  --config /absolute/path/to/mobile-mcp/configs/runtime.default.json \
  --register-adb-devices \
  --transport sdk-stdio

If you want a cwd-independent plain command that does not rely on an editable install already being active inside the venv, use /usr/bin/env and set PYTHONPATH explicitly:

[mcp_servers.mobile_mcp]
command = "/usr/bin/env"
args = [
  "PYTHONPATH=/absolute/path/to/mobile-mcp/src",
  "/absolute/path/to/mobile-mcp/.venv/bin/python3",
  "-m",
  "mobile_mcp.bootstrap",
  "--config",
  "/absolute/path/to/mobile-mcp/configs/runtime.default.json",
  "--register-adb-devices",
  "--transport",
  "sdk-stdio"
]
startup_timeout_sec = 60

If you prefer raw uv, keep it as a normal command and make the writable cache explicit:

If your MCP host launches servers inside a restricted sandbox and raw uv cannot write ~/.cache/uv, use the checked-in launcher instead:

[mcp_servers.mobile_mcp]
command = "/absolute/path/to/mobile-mcp/scripts/mobile-mcp-launch"
args = [
  "--config",
  "/absolute/path/to/mobile-mcp/configs/runtime.default.json",
  "--register-adb-devices",
  "--transport",
  "sdk-stdio"
]
startup_timeout_sec = 60

scripts/mobile-mcp-launch prefers /absolute/path/to/mobile-mcp/.venv/bin/python3, exports the repo src/ onto PYTHONPATH, and otherwise falls back to uv --no-sync with UV_CACHE_DIR=/tmp/mobile-mcp-uv-cache, which is friendlier to sandboxed Codex and Inspector launchers.

If you want a deterministic local device instead of a connected Android device, replace --register-adb-devices with --register-demo-device.

Auto-register connected real devices from local adb:

python3 -m mobile_mcp.bootstrap \
  --config configs/runtime.default.json \
  --register-adb-devices \
  --transport sdk-stdio

If adb discovery is temporarily unavailable during bootstrap, the runtime now logs a warning and still starts with zero registered adb devices. Pass --adb-discovery-required to keep the previous fail-fast behavior.

Run one bounded live operator check against a connected device:

python3 -m mobile_mcp.operator_checks \
  --config configs/runtime.default.json \
  --check-clipboard

Run paired live acceptance checks (lease isolation + paired workflow evidence):

python3 -m mobile_mcp.operator_checks \
  --config configs/runtime.default.json \
  --multi-device \
  --pair-key chat-sync

Run MCP client acceptance checks (initialize/list_tools/call_tool) across SDK stdio and SDK HTTP:

python3 -m mobile_mcp.client_acceptance \
  --config configs/runtime.default.json \
  --register-bridge-devices \
  --require-device

Local Bootstrap (Legacy Transports)

Legacy transports remain supported but are not the canonical operator path:

  • --transport stdio — line-oriented JSON-RPC over stdin/stdout (custom envelope)
  • --transport http — HTTP with /mcp/tools and /mcp/call (custom envelope)

Legacy stdio: provide one JSON tool call per line:

{"name":"devices.list"}
{"name":"exit"}

Legacy HTTP endpoints:

  • GET /mcp/tools returns tool metadata
  • POST /mcp/call dispatches one tool call payload

Repository Scaffold

The repository scaffold mirrors the ADR layers under src/mobile_mcp/:

  • mcp/ for the control plane
  • sessions/ and devices/ for orchestration and leasing
  • observation/, actions/, and backends/ for execution
  • workflow/ for retry, recovery, and loop policy
  • capabilities/, cache/, artifacts/, and memory/ for dynamic capability, semantic cache, evidence, and agent continuity

ADR Gate

Future work must pass the ADR gate before it is considered compliant:

  • python3 scripts/adr_guard.py
  • GitHub workflow in .github/workflows/adr-gate.yml
  • PR checklist in .github/pull_request_template.md
  • ADR impact template in docs/templates/adr-impact-assessment.md

Task Discipline

Execution order and state are tracked separately from the roadmap:

  • TODO.md is the explicit task queue derived from the roadmap
  • TASK.lock is the current workspace state snapshot that must be updated as work progresses

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages