Skip to main content

Install with Docker

Clone, log in, bring Compose up, hit a completion. That’s the whole loop.

Prerequisites

  • Git
  • Docker and Docker Compose
  • Host credentials (see Auth):
    • ~/.codex from codex login (needed for Codex models)
    • ~/.gemini after scripts/sync-antigravity-auth.sh (Gemini 3.x / Antigravity)
    • Claude Code OAuth via .env CLAUDE_CODE_OAUTH_TOKEN (optional — don’t bind-mount ~/.claude.json)

Clone and start

git clone https://github.com/teslashibe/open-agent-api.git
cd open-agent-api

codex login
# optional:
# scripts/sync-antigravity-auth.sh

docker compose up --build -d

That builds/runs teslashibe/open-agent-api:local and binds the API to 127.0.0.1:8088.

Verify

curl -s http://127.0.0.1:8088/health
# → {"status":"ok"}

curl -s http://127.0.0.1:8088/v1/models | jq '.data[].id'

curl -s http://127.0.0.1:8088/v1/chat/completions \
-H 'authorization: Bearer local-open-agent-api' \
-H 'content-type: application/json' \
-d '{
"model": "gpt-5.6-terra",
"messages": [{"role":"user","content":"Say hi in five words."}]
}' | jq .

What Compose mounts

Host / volumeContainerNotes
${HOME}/.codex/home/codex/.codexRead-only
${HOME}/.gemini/home/codex/.geminiWritable (OAuth refresh)
${HOME}/.claude/home/codex/.claudeCLI home; auth token still comes from env
agent-queue-locks/var/lib/open-agent-api/agent-locksShared agent-queue locks

We deliberately don’t bind-mount ~/.claude.json — host CLI atomic renames leave a stale inode inside the container.

Environment worth knowing

Defaults live in docker-compose.yml. The ones people bump most often:

VariableDefault / role
GEMINI_AUTH_PATH/home/codex/.gemini/antigravity_oauth_creds.json
CODEX_AGENT_QUEUE_ENABLEDtrue
CODEX_AGENT_MAX_ACTIVE4 (compose; binary default is 2)
CODEX_AGENT_MAX_ACTIVE_PER_KEY1
CODEX_AGENT_QUEUE_KEY_MODEcursor
CLAUDE_CODE_OAUTH_TOKENFrom host .env (optional)
CODEX_CHAT_API_PORTHost port mapping (default 8088)

Put secrets in a local .env (gitignored), not in committed files.

Cursor / public HTTPS

Cursor won’t accept localhost for BYOK (Access to private networks is forbidden). Use the ngrok overlay:

NGROK_AUTHTOKEN=... docker compose -f docker-compose.yml -f docker-compose.ngrok.yml up -d

Cursor base URL: https://YOUR_SUBDOMAIN.ngrok-free.dev/v1 — never http://127.0.0.1:8088/v1.

Step-by-step: Cursor BYOK + ngrok.

Logs and stop

docker compose logs -f api
docker compose down