Automation and AI
Pandapi is built to be driven by programs: shell scripts, CI jobs, daemons, and LLM agents. This page collects the patterns. Command details: Command-Reference and docs/API.md.
Why this API scripts well
- One JSON object per line, over a socket or the bundled CLI: trivially consumable from any language,
jq-friendly. - Self-describing:
api.describereturns all 110 commands with one-line descriptions, the 19 event types, and the machine-readable security model. - Structured errors
{code, message, retryable}: retry loops branch on a stable code, not message text. - Blocking conveniences:
instances.start {wait}andops.waitremove polling boilerplate. - Replayable events: monotonic
seq+ a 4096-event ring means a supervisor that restarts loses nothing recent. - Headless mode: the whole thing runs GUI-less on a server (see Quickstart).
Shell patterns
# Retry-on-retryable wrapper
call() {
for i in 1 2 3; do
out=$(ekaii-launcher --api "$1" --api-params "${2:-{}}") && { echo "$out"; return 0; }
echo "$out" | jq -e '.error.retryable' >/dev/null || { echo "$out" >&2; return 1; }
sleep 2
done
return 1
}
# Provision, launch, watch, tear down
call instances.ensure '{"name":"ci","version":"26.2","loader":"fabric"}'
op=$(call content.install '{"name":"ci","files":[{"modrinth":{"project_id":"AANobbMI"}}]}' | jq '.data.op')
call ops.wait "{\"op\":$op,\"timeout_secs\":600}"
call instances.start '{"name":"ci","wait":"running","timeout_secs":600}'
call logs.tail '{"name":"ci","min_level":"ERROR","tail":50}'
call instances.kill '{"name":"ci"}'
For a Python client with id correlation, see Quickstart.
Idempotent provisioning and IaC
instances.ensure: create-if-absent plus apply configuration, in one idempotent call. The building block for declarative setups.content.sync: reconcile an instance's mods folder to a desired set, keyed by provenance (Modrinth/CurseForge project ids). Manual mods are left alone;remove_extraprunes managed strays.state.export: a revisioned snapshot of the whole launcher (per-instance SHA-1revision, folded into aglobal_revision). Compare revisions across runs for cheap drift detection, and archive the document as backup.launcher.plan: diff a desired-state document against reality and get back a replayable list of API calls (create/modify/deleteactions); it changes nothing itself. Review, then replay.instances.manifest: a content-hashed manifest of one instance including the effective JVM flags, recomputed without launching.instances.snapshot/instances.restore: tagged point-in-time copies of mods/config for safe experiments.content.resolve: dry-run version resolution before committing to an install.
Observation: events, webhooks, metrics
- Events: subscribe with server-side filters, e.g. only
{"types": ["op.finished", "game.crash"]}. For headless game observation, enablegame.capturefirst (before launching), then consumegame.outputand the semanticgame.ready/game.crash/game.server_connected/game.player_chatevents. - Webhooks (
hooks.register, local-only): the launcher POSTs matching event lines to your URL with an optional HMAC-SHA256 signature (x-pandora-signature), so a service can react without holding a subscription. Hooks survive restarts. - Prometheus (
metrics.prometheus): OpenMetrics text (pandora_up,pandora_uptime_seconds,pandora_instances_running,pandora_instance_rss_bytes{instance}); serve it from a scrape endpoint of your own.metrics.instances,metrics.storage,health.checkandbackend.pingcover the rest. - Dev loop:
content.dev_linksymlinks freshly built jars into an instance;content.bisect_start/bisect_stepbinary-search a broken modpack;diagnostics.analyzeclassifies crashes into likely causes with suggestions.
Driving Pandapi from an LLM
The API was shaped with agents in mind: a single self-description call, stable machine-readable errors, and an event stream that doubles as an observation channel.
A minimal agent loop:
- Bootstrap: call
api.describeand putcommands,eventsandsecurityin the system context. The model now knows every command, what each does, and what its token can reach. - Act: the model emits
{"cmd": ..., "params": ...}; the harness executes it and returns the response verbatim,ok: truedata andok: falseerrors alike (the{code, message, retryable}object is designed to be reasoned over). - Wait: when a response contains
{"op": N}, the harness runsops.waitand returns the finished op, including itserrorslot and anyvisit_url(e.g. Microsoft login needing a human). - Observe: a second connection subscribed with a
typesfilter (e.g.op.finished,game.ready,game.crash,notification) feeds events back into the context as observations.
Guardrails, all built in (see Network-Mode-and-Security):
- Run the agent against the network transport with a scoped token rather than the fully-trusted local socket:
readfor observe-only agents;writewithoutaccounts/settingsfor most tasks. - The path jail bounds every path the agent can reference; execution-vector fields (
jvm_flags,wrapper_command, ...) are refused over the network outright, so a prompt-injected agent cannot turn the launcher into an arbitrary-code runner. - The local-only set keeps credential minting, host control, webhook registration and the server pinger out of reach.
Today, an LLM harness with shell access (Claude Code or similar) can drive the CLI directly; any tool-use harness can wrap the socket in a generic pandapi(cmd, params) tool fed by api.describe.
MCP
A dedicated MCP server (pandapi-mcp) is planned as Phase 1 of the ecosystem roadmap: tools/resources auto-generated from api.describe, event and log resources (pandapi://events, pandapi://instance/logs), scope/redaction/path-jail inheritance, and loopback/tunnel transport. It is not shipped yet; until it lands, use the CLI or socket patterns above. See Ecosystem for the full plan.
The boundary
Pandapi launches and observes the real Minecraft client: it can start/kill the game, read the console and semantic events, and manage accounts, instances and content. It cannot inject in-game input or chat. Agents that need to act in-world (move, mine, chat) drive a headless bot framework alongside Pandapi; the hub-and-actors architecture for that is the subject of Ecosystem.