💻 CLI Reference
The ghost CLI is the primary entry point for Ghost in the Droid. It’s task-first: a bare positional is an agent task; a reserved first token is a subcommand.
ghost "check reddit for AI news" --device asus # run a task (marquee use)ghost devices # list connected phonesghost setup # first-run wizardghost mcp install --client claude-code # wire into your agent clientghost up # boot server + dashboardInstalled by pip install ghost-in-the-droid. Three binaries ship:
| Binary | Status | Notes |
|---|---|---|
ghost | ✅ primary | Task-first CLI (since v1.3.0) |
gitd | ⚠️ deprecated | Prints warning, still works, delegates to ghost legacy path |
android-agent | ⚠️ deprecated | Same as gitd |
Grammar
Section titled “Grammar”- A bare positional is treated as an agent task, run against a device —
ghost "check reddit" --device asus - A reserved first token is a subcommand —
ghost devices,ghost skill list - Reserved verbs win. To run a task whose first word is a reserved verb, quote it:
ghost "record my day" --forces prompt mode explicitly:ghost -- up my code coverage
Reserved subcommands: devices, setup / configure, config, mcp, up, doctor, login, skill, help
Precedence chain
Section titled “Precedence chain”Everywhere config is read, precedence is:
explicit flag >
GHOST_*env var >~/.ghost/config.toml> built-in / detected default
This applies to backend, model, mode, and device selection consistently.
Running a task
Section titled “Running a task”ghost "<task>" [--device D] [--mode fast|vision|reason] [--backend B] [--model M]The bare-positional invocation. Runs a live agent turn: takes your task text, picks a device + LLM backend + mode, and drives the phone via the 62-tool MCP surface.
Flags:
| Flag | Aliases | Default | Description |
|---|---|---|---|
--device | -d, --udid | auto-pick sole device | Device alias (from ~/.ghost/devices.toml) or raw ADB serial / ios:<udid> |
--mode | fast | fast (text-only), vision (screenshot-driven), reason (deeper multi-step) | |
--backend | resolved | Provider slug: claude-code, anthropic, openrouter, ollama, vllm, on-device | |
--model | backend default | Specific model id (e.g. claude-sonnet-4.5, gpt-oss-20b, gemma-3-1b-it) |
Examples:
# Simplest — auto-picks the sole connected phone + configured backend + fast modeghost "open Instagram and DM alex hey"
# Explicit device alias + reasoning modeghost "book me the earliest gym slot tomorrow" --device asus --mode reason
# Force a specific backend + modelghost "summarize my inbox" --backend openrouter --model anthropic/claude-sonnet-4.5
# iOSghost "post my Duolingo streak screenshot to X" --device ios:00008110-...First-run behavior: if ~/.ghost/config.toml doesn’t exist AND no GHOST_BACKEND env is set AND no --backend flag is passed AND stdin is a TTY, ghost drops into the setup wizard before running your task, then resumes.
Device selection failure modes:
- No
--deviceand no configured default and exactly one device connected → auto-picks with a warning - Zero devices → error, suggests
ghost setup - Two or more devices → error listing candidates, requires explicit
--device
ghost devices
Section titled “ghost devices”ghost devicesList connected Android + iOS devices with model name, configured alias, and platform.
Example output:
asus-rog-8f7d2a1c ASUS ROG Phone 7 (asus) [android]galaxy-a15-9c8f Samsung Galaxy A15 (a15) [android]ios:00008110-... iPhone 15 Pro (main) [ios]
Aliases in ~/.ghost/devices.toml: asus→asus-rog-8f7d2a1c, a15→galaxy-a15-9c8f, main→ios:00008110-...iOS discovery requires IOS_APPIUM_URL / IOS_DEVICE_UDID to be set — see iOS Setup. Android discovery via adb devices.
ghost setup (aliased as ghost configure)
Section titled “ghost setup (aliased as ghost configure)”First-run wizard, or non-interactive scripted config.
Interactive
Section titled “Interactive”ghost setupDetects available LLM backends (checks for claude CLI, ANTHROPIC_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY, local Ollama, local vLLM, on-device app), lists them ranked, asks for:
- Backend choice
- Model (defaults to backend default; for Ollama, picks a local model)
- Device nickname (auto-suggests
phoneif one device connected) - Default mode (
fast/vision/reason)
Writes ~/.ghost/config.toml + ~/.ghost/devices.toml. Confirms with the written path.
Non-interactive (scripted)
Section titled “Non-interactive (scripted)”ghost setup --backend BACKEND [--model MODEL] [--mode MODE] [--device ALIAS:SERIAL]| Flag | Default | Description |
|---|---|---|
--backend | required | Provider slug (see Precedence chain for valid values) |
--model | backend default | Specific model id, blank = backend default |
--mode | fast | fast / vision / reason |
--device | none | ALIAS:SERIAL to register an alias, or bare SERIAL (alias == serial) |
Example:
ghost setup --backend anthropic --model claude-sonnet-4.5 --mode reason --device asus:asus-rog-8f7d2a1cFails with exit 2 if not a TTY and --backend is not provided.
ghost config
Section titled “ghost config”Read + write the flat, whitelisted keys in ~/.ghost/config.toml.
ghost config path # print config pathghost config get <dotted.key> # print current valueghost config set <dotted.key>=<val> # set + saveKnown keys:
| Key | Type | Notes |
|---|---|---|
backend.name | string | Provider slug (claude-code, anthropic, openrouter, ollama, vllm, on-device) |
backend.model | string | Model id (backend-specific) |
defaults.mode | string | fast / vision / reason (validated) |
defaults.device | string | Alias from devices.toml, or raw serial |
dashboard.port | int | Port for ghost up dashboard (default from settings) |
Examples:
ghost config path # → /home/user/.ghost/config.tomlghost config get backend.name # → anthropicghost config set defaults.mode=reason # → defaults.mode = reasonghost config set dashboard.port=5057Unknown keys exit 2 with a list of valid keys. Invalid values (e.g. mode=warp) exit 2 with a helpful error.
ghost mcp install
Section titled “ghost mcp install”Register Ghost’s MCP server with your agent client. All clients get the same stdio server (android-agent-mcp binary, server name android-agent), so the 62-tool surface is identical everywhere.
ghost mcp install --client <name>--client | Config file written | Merge behavior |
|---|---|---|
claude-code | claude mcp add (falls back to project-local .mcp.json) | CLI adds; file falls back if claude not on PATH |
cursor | ~/.cursor/mcp.json | Merged into mcpServers map |
codex | ~/.codex/config.toml | Appended [mcp_servers.android-agent] block; no-op if already present |
opencode | ~/.config/opencode/opencode.json | Merged into mcp map with type: local, enabled: true |
agy | ~/.gemini/config/mcp_config.json | Merged into mcpServers map (Antigravity CLI) |
antigravity | (alias for agy) | Same as agy — early docs used this spelling |
Merge-not-clobber: all JSON writes read + merge existing config (never overwrite), so your other MCP servers stay intact. Malformed existing JSON is a hard error (fix or remove the file first).
Example:
ghost mcp install --client claude-code # → Registered 'android-agent' with Claude Code (claude mcp add).ghost mcp install --client cursor # → Registered 'android-agent' in ~/.cursor/mcp.json (Cursor).ghost up
Section titled “ghost up”Boot the FastAPI server + Vue dashboard.
ghost up [--host HOST] [--port PORT]| Flag | Default | Description |
|---|---|---|
--host | 127.0.0.1 | Bind host. Use 0.0.0.0 to expose on LAN. |
--port | from dashboard.port in config, else settings default (5055) | Bind port |
Loads .env from the current working directory if present (uvx/pipx runs work from anywhere). Serves:
- Dashboard at
http://<host>:<port>/ - REST API under
/api/*— see REST Endpoints - Swagger UI at
/docs - Scheduler daemon in a background thread
Ctrl+C stops the server cleanly.
ghost doctor
Section titled “ghost doctor”Environment preflight — green / yellow / red checklist.
ghost doctorChecks:
- Python version + Ghost install
adbon PATH + version- Connected devices (Android + iOS)
- Configured backend + credentials / usability
- Port availability for
ghost up - Required Python deps
- Optional: MLX / MediaPipe / llama.cpp availability for on-device paths
Exit codes:
0— all checks passed (warnings OK)1— at least one fail; prints hints per failed check
ghost login
Section titled “ghost login”Sign into Ghost’s claude-code backend via your Claude Max / Pro subscription — no API key needed.
ghost login [--relogin]Delegates to claude auth login (Anthropic’s own OAuth flow). Ghost never handles or stores the token; the claude CLI owns it (refresh included). If claude isn’t installed, prints install instructions and exits 1.
| Flag | Description |
|---|---|
--relogin | Force re-authentication even if already signed in |
ghost skill …
Section titled “ghost skill …”Manage the skill library. Skills live in the packaged gitd/skills/ dir plus user-installed skills in ~/.ghost/skills/.
ghost skill install <target> [--force]ghost skill listghost skill update <name>ghost skill remove <name> [--force]ghost skill validate <path>ghost skill search <query>ghost skill install
Section titled “ghost skill install”Install a skill from the registry, a GitHub URL, or a local path.
| Arg / flag | Description |
|---|---|
target | Registry name (e.g. tiktok), GitHub URL, or local path to a skill dir |
--force, -f | Install even if validation fails |
Examples:
ghost skill install tiktok # registryghost skill install https://github.com/user/my-skill # GitHubghost skill install ./my-skill # local pathghost skill install ./flaky-skill --force # bypass validationghost skill list
Section titled “ghost skill list”List installed skills (packaged + user-installed).
ghost skill update <name>
Section titled “ghost skill update <name>”Re-fetch the latest version of an installed skill. Reads repo_url from the skill’s skill.yaml and re-clones/copies. Errors if the skill isn’t installed or has no repo_url.
ghost skill remove <name> [--force]
Section titled “ghost skill remove <name> [--force]”Remove a user-installed skill. --force allows removing built-in packaged skills too.
ghost skill validate <path>
Section titled “ghost skill validate <path>”Validate a skill directory against the schema without installing. Useful for skill authors.
ghost skill search <query>
Section titled “ghost skill search <query>”Search the registry by name + description.
For skill execution (running an installed skill against a device), see the Advanced section below or the Skill System docs.
Environment variables
Section titled “Environment variables”Ghost respects these environment variables. Precedence: flag > env > config.toml > default.
GHOST_* — CLI overrides
Section titled “GHOST_* — CLI overrides”| Variable | Overrides | Notes |
|---|---|---|
GHOST_BACKEND | --backend / backend.name | Provider slug |
GHOST_MODEL | --model / backend.model | Model id |
GHOST_MODE | --mode / defaults.mode | fast / vision / reason |
GHOST_CONFIG_DIR | ~/.ghost/ location | Testing / non-default homes |
GHOST_HOME_OVERRIDE | $HOME for MCP install | Testing |
Provider credentials
Section titled “Provider credentials”Only needed if you use the corresponding backend:
| Variable | Used by | Notes |
|---|---|---|
ANTHROPIC_API_KEY | --backend anthropic | Direct Anthropic API |
OPENROUTER_API_KEY | --backend openrouter | OpenRouter (multi-model gateway) |
OPENAI_API_KEY | (OpenAI-compatible flows) | See installation docs |
OLLAMA_BASE_URL | --backend ollama | Default http://localhost:11434 |
GITD_VLLM_BASE_URL | --backend vllm | Your vLLM / llama.cpp OpenAI-compatible endpoint |
No key needed for: claude-code (uses your Claude Max/Pro subscription via ghost login), on-device (runs on the phone itself — see On-Device LLM).
Full environment variable reference (feature gates, iOS setup, observability): Installation → Optional AI Features.
Config files
Section titled “Config files”All under ~/.ghost/ (overridable with GHOST_CONFIG_DIR):
| File | Purpose |
|---|---|
~/.ghost/config.toml | Default backend, model, mode, device, dashboard port |
~/.ghost/devices.toml | alias = "serial" map (also editable via ghost setup + set_device_alias) |
~/.ghost/skills/ | User-installed skills (installed via ghost skill install) |
~/.ghost/logs/ | CLI logs |
config.toml schema (all sections + keys optional):
[backend]name = "anthropic"model = "claude-sonnet-4.5"
[defaults]mode = "reason"device = "asus"
[dashboard]port = 5055devices.toml:
[devices]asus = "asus-rog-8f7d2a1c"a15 = "galaxy-a15-9c8f"main = "ios:00008110-0012345678901234"Deprecated aliases
Section titled “Deprecated aliases”gitd and android-agent are the pre-v1.3.0 CLI names. They still work — they map to the same underlying entry point — but print a deprecation warning:
⚠ 'gitd' is deprecated — use 'ghost' insteadMigration is straightforward: replace gitd <cmd> with ghost <cmd> (all subcommands are compatible: up, doctor, login, skill). Scripts using gitd should be updated but won’t break.
Advanced / power-user
Section titled “Advanced / power-user”For programmatic / advanced use, Ghost exposes several Python module entrypoints beyond the ghost CLI:
Run a skill workflow directly
Section titled “Run a skill workflow directly”python -m gitd.skills._run_skill \ --skill tiktok \ --workflow upload_video \ --device YOUR_DEVICE_SERIAL \ --params '{"video_path": "/tmp/video.mp4"}'This is what the scheduler calls internally for skill_workflow and skill_action jobs. See Skill System.
App Explorer (BFS state grapher)
Section titled “App Explorer (BFS state grapher)”python -m gitd.skills.auto_creator \ --package com.zhiliaoapp.musically \ --device YOUR_DEVICE_SERIAL \ --max-depth 3 --max-states 20 --settle 1.5| Flag | Default | Description |
|---|---|---|
--package | required | Android package name |
--device | required | ADB serial |
--max-depth | 3 | BFS depth |
--max-states | 20 | Max unique states |
--settle | 1.5 | Seconds after each tap |
--output | auto | Output directory |
Used to bootstrap a skill from an unknown app. See Skill Creator.
MCP server standalone
Section titled “MCP server standalone”android-agent-mcp # or: python -m gitd.mcp_serverRuns the MCP server on stdio. ghost mcp install --client <name> wires this up for you — you rarely invoke it directly.
python -m pytest tests/ -vDEVICE=<serial> python -m pytest tests/test_04_crawl.py -vTest suite requires a connected device for integration tests; unit tests run without one.
Related
Section titled “Related”- Installation — setup prerequisites, env var grid
- Connect a Phone — ADB pairing walkthrough
- iOS Setup — Appium XCUITest + WebDriverAgent
- REST Endpoints — HTTP API served by
ghost up - Skill System — how skills work
- Skill Creator — auto-explorer that compiles skills
- MCP Server — the 62-tool surface
- MCP Clients — client-side setup for Claude Code, Cursor, Codex, Antigravity, etc.
- Scheduler — how jobs run in the background