Download
Docs/Drive the deck/Deck API

Deck API

The local HTTP API a running Mandeck serves on 127.0.0.1:7717, and the three clients that speak it.

Raw markdown

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:

  • CLIscripts/mandeck (install to /opt/homebrew/bin/mandeck via scripts/install-cli.sh). Bots must call that path, not a shell alias named mandeck (on some machines that alias is something else entirely). mandeck with 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|report is the bot lifecycle; job spawn prints one job<TAB>session<TAB>pane line, 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
  • MCPscripts/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 legacy initialize. 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.