Deck API
The local HTTP API a running Mandeck serves on 127.0.0.1:7717, and the three clients that speak it.
Drive the running deck
The app serves a local HTTP API (the Deck API) on 127.0.0.1:7717
(override: MANDECK_API_PORT). It is on whenever the app runs. Auth is a bearer
token the app mints at ~/Library/Application Support/dev.mandeck.native/cli-token
(MANDECK_STATE_DIR overrides the dir name for test instances).
TOKEN=$(cat "$HOME/Library/Application Support/dev.mandeck.native/cli-token")
curl -s http://127.0.0.1:7717/v1/health # no auth — is a deck here?
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:7717/v1/sessions
Three equivalent clients, pick one:
- CLI —
scripts/mandeck(install to/opt/homebrew/bin/mandeckviascripts/install-cli.sh). Bots must call that path, not a shell alias namedmandeck(on some machines that alias is something else entirely).mandeckwith no args lists sessions — address, pane uuid, agent, state; act on the uuid, the address is a position that moves.agents,jobs,events [since],messages <id>wrap the read routes so a bot never needs raw curl.job spawn|send|wait|reportis the bot lifecycle;job spawnprints onejob<TAB>session<TAB>paneline, and on 409 (that agent+cwd already live) still prints it for the existing pane and exits 2 — the prompt was not delivered. Invalid args print usage. No repo checkout? The deck serves its own CLI:
curl -so /opt/homebrew/bin/mandeck http://127.0.0.1:7717/cli/mandeck \
&& chmod +x /opt/homebrew/bin/mandeck
- MCP —
scripts/mandeck-mcp.mjs(also served at/cli/mandeck-mcp.mjs), a stdio MCP server exposing the same operations as tools, for agents that are MCP clients (Claude Code, Codex, Gemini CLI, Cursor) — a bot on a shell uses the CLI instead. Dual-era: speaks spec 2026-07-28 (stateless, per-request_meta,server/discover) and still answers a legacyinitialize. Register:
{ "mcpServers": { "mandeck": { "command": "node",
"args": ["/path/to/mandeck-mcp.mjs"] } } }
Approving tools. Consent lives in the client, not the protocol. Every tool
carries annotations: reads (deck_sessions, deck_screen, deck_messages,
deck_jobs, deck_job_state, deck_job_wait, deck_job_report,
deck_agents, deck_events, deck_tabs, deck_history, deck_projects,
deck_accounts, deck_health) are readOnlyHint; deck_close, deck_send,
deck_key are destructiveHint; the rest are additive. The profile to
install is read = free, act = ask, close = only your own panes — and the
last one is enforced by the deck (403 without force), not by trust:
- Claude Code
settings.json:"permissions": {"allow": ["mcp__mandeck__deck_sessions", "mcp__mandeck__deck_screen", "mcp__mandeck__deck_messages", "mcp__mandeck__deck_jobs", "mcp__mandeck__deck_job_state", "mcp__mandeck__deck_job_wait", "mcp__mandeck__deck_job_report", "mcp__mandeck__deck_events", "mcp__mandeck__deck_agents", "mcp__mandeck__deck_health"]}— everything else prompts (Claude Code does not auto-approve on annotations). - Codex CLI
config.toml:[mcp_servers.mandeck] default_tools_approval_mode = "writes"prompts only for tools not marked read-only. - Gemini CLI policy: a rule on
toolAnnotations = { readOnlyHint = true }→allow. - Raw HTTP — the table below.