Get Started
Point coding tools at one local OpenAI-shaped, Claude-shaped, and Responses endpoint. Use keys and local runtimes first; optionally attach subscription OAuth at your own risk; fail over on 429/401.
Status: CLI + localhost UI at 127.0.0.1:8317. Tagged
v3.1.1
is the current release. Schema stays 1. v3 routes for cost (pea/auto, pea/economy, pea/free, pea/local) and does not substitute a model you named. It includes a live catalog, failover policies, image generations + embeddings (API-key OpenAI-compat when the catalog tags them), and the v2 request engine (attempt budget, stream prelude, cooldowns, client connect helpers). Subscription OAuth (Claude Pro/Max/Team/Enterprise, Codex, Gemini/Antigravity, xAI, Kimi, Meta Muse, Copilot) is ToS/ban risk, so prefer official API keys. Also: API keys + free/local providers (llama.cpp, vLLM, Jan, GPT4All, NIM, Workers AI, SambaNova, Ollama Cloud), OpenCode Go API key, POST /v1/responses (native Codex OAuth passes tools through), honest quota remaining on Health. Requires
Go 1.26+
for go install.
| Path | When | Risk |
|---|---|---|
| API key | Official provider console / AI Studio (anthropic, openai, google/gemini, xai, Groq, โฆ) | Supported. Prefer this. |
| Local / no key | Ollama, LM Studio, llama.cpp, vLLM, Jan, GPT4All, software you already run | Supported. |
| Subscription OAuth | peaproxy auth login --provider โฆ for Claude Pro/Max/Team/Enterprise, ChatGPT/Codex, Gemini/Antigravity, xAI, Kimi, Meta Muse, or GitHub Copilot | ToS/ban risk. At your own risk. Authors not liable. |
| OpenCode Go | Subscribe at opencode.ai/auth | Official API key (adapter: opencode_go). Distinct from Zen. Not OAuth. |
| Qwen consumer OAuth | n/a | Not yet (no CPA flow). Use a Qwen API key with openai_compat. |
| Factory / Droid upstream | n/a | Not yet (no public consumer chat OAuth). Use Droid as a client of PeaProxy. |
Homebrew (macOS / Linux)
Arch (AUR)
Scoop (Windows)
Go install (tagged v3.1.1)
@latest installs the highest release tag (currently v3.1.1). Installs to ~/go/bin/peaproxy; put that directory on PATH. peaproxy -v reports that tag for go install of a release and for release builds. Needs Go 1.26+.
Linux binary (amd64)
Also on the release: linux/darwin/windows amd64 + arm64 (zip on Windows). macOS release and Homebrew cask binaries are Developer ID signed and notarized.
First serve writes ~/.config/peaproxy/config.yaml if missing. Tokens and inline keys go to the OS keychain (encrypted file fallback), not plaintext YAML.
Run
peaproxy --version
peaproxy serve
peaproxy auth login --provider anthropic
# UI + OpenAI/Claude wires at http://127.0.0.1:8317/ (auth is ToS/ban risk)
Localhost UI
Captured from live peaproxy serve plus a local OpenAI-compat mock. No API keys or OAuth tokens appear in the images.
ListModels with pin/rename overlays. image_out is a modality tag on the row.
image_out one-click generate via POST /v1/images/generations (never faked as chat). The lime square is a throwaway mock upstream, not a photoreal generator.
requestLog: true or the Settings / Request log toggle).
ListModels status, cooldown overlay, and provider-reported remaining when known.Features
Live catalog
Models come from live ListModels, with no hand-maintained allowlist. Hide is listing-only; optional pin/rename overlays (UI and peaproxy catalog). Routing is unchanged.
Local wires
OpenAI /v1/chat/completions, Claude /v1/messages (true SSE), and Codex /v1/responses. Native Codex OAuth passes tools through (tools, tool_choice, function-call items); only stream_options is dropped. Other adapters round-trip function tools via chat and do not execute them.
Image generations
POST /v1/images/generations for API-key OpenAI-compat when the catalog tags image_out. Showcase one-click generates. Subscription OAuth adapters refuse clearly; there is no fake chat image path.
Embeddings
POST /v1/embeddings for API-key OpenAI-compat when the catalog tags embeddings. Showcase can try. OAuth / Messages-only adapters refuse clearly; there are no fake vectors.
Honest quota remaining
Health / peaproxy health / GET /admin/health show provider-reported remaining when known (rate-limit headers; OpenRouter GET /key). Unknown remaining is omitted, never invented as 0 or unlimited.
CLI + localhost UI
No macOS / Windows tray, by design. Accounts, Catalog, Showcase, Clients, Health, Request log, and Settings in the browser on loopback. First-run onboarding CTAs; Settings shows bind, LAN, and secret-backend status.
Keys, free, and local
Ollama (local or Cloud), LM Studio, llama.cpp, vLLM, Jan, GPT4All, Groq, Cerebras, Google AI Studio, xAI, Hugging Face, NVIDIA NIM, Cloudflare Workers AI, SambaNova, Anthropic/OpenAI/OpenRouter keys, OpenCode Zen, OpenCode Go (API key, distinct from Zen), custom OpenAI-compat. Presets show env var names, never values.
Subscription OAuth
v3.1.1 includes Claude (Pro/Max/Team/Enterprise), Codex, Gemini/Antigravity, xAI, Kimi, Meta Muse, and GitHub Copilot login. Ban/ToS risk; prefer API keys. See Security.
Failover
429/401/503/529 and retryable rate-limit / overloaded / auth-expired bodies move to the next account; policies round-robin (default), fill-first, and sticky. Cooled accounts are not re-hit (503 + Retry-After). Usage is persisted next to the config as usage.json.
v3 cost routing
On by default. pea/auto, pea/economy, pea/free, and pea/local choose a live model for cost. A model you name is never substituted. Spend ceiling fails closed when spend cannot be measured. Details: docs/V3.md.
Spend ceiling + free-only
optimization.spendCeilingUSD caps spend in a rolling window and fails closed when spend cannot be measured. optimization.freeOnly refuses any deployment that cannot prove a call stays free, including a model you named. Inspect with GET /admin/policy or peaproxy optimization status|explain.
Grouped accounts + 8 paid presets
Accounts UI is grouped. New API-key presets: DeepSeek, Mistral, Z.AI, MiniMax, Together, Fireworks, Alibaba Coding Plan, Cohere. Only Cohere is live-verified; the rest show (not verified) and mean it.
Cursor subscription upstream
cursor_agent runs your Cursor subscription through Cursor's own cursor-agent CLI (ask mode, read-only, no tool calling). POSIX-only. ToS/ban risk.
Carried context + local assistant
pea_search retrieves earlier context, bounded at 4 rounds, for tool-using non-streaming requests only; every round is billed by the provider. The local assistant is off by default and loopback only.
v2 request engine
One attempt budget, stream prelude check, cooldowns, and client connect helpers. Schema stays 1.
Harness presets
peaproxy clients show for Cursor, Claude Code, OpenCode, Pi, Codex, Amp, Continue, Cline (YAML / /v1 polish), and Droid (Factory client preset only, not an upstream), plus clients verify.
CLI
| Command | Purpose |
|---|---|
serve | Listen 127.0.0.1:8317 + UI (writes first-run config) |
--version | Release tag on a release build or go install of a tag; dev for a dirty local build |
auth | Subscription OAuth (--provider anthropic|openai|gemini|xai|kimi|kimi-ai|meta|copilot). Prints a ToS/ban-risk warning. --print-url / --device / --no-browser. Prefer API keys. Qwen and Factory are not yet. OpenCode Go is an API key (--provider opencode-go explains). |
accounts | Configured provider accounts (list / add <preset>) |
models | Live catalog (--filter all|free|paid|local|subscription_oauth) |
catalog | Listing overlays (pin / rename / hide) matching the Catalog UI |
requests | Opt-in inspector (tail when request log is on) |
health | Adapter health / quota remaining / provider-reported remaining when known / cooldowns matching GET /admin/health |
status | Bind / config path / version |
config | path / show / validate (--strict-config exits non-zero on keys this version does not read) / init |
optimization | v3 policy (status / explain <model>) |
completion | Shell completion script (bash / zsh / fish / powershell) |
clients | Harness presets (list / show / verify [--chat]) |
curl -s http://127.0.0.1:8317/v1/models
curl -s http://127.0.0.1:8317/v1/images/generations \
-H 'Content-Type: application/json' \
-d '{"model":"dall-e-3","prompt":"a pea pod icon"}'
curl -s http://127.0.0.1:8317/v1/embeddings \
-H 'Content-Type: application/json' \
-d '{"model":"text-embedding-3-small","input":"hello pea"}'
peaproxy clients show cursor
peaproxy clients show opencode # includes /v1
peaproxy clients show claude-code # does NOT include /v1
peaproxy clients show pi # both wires; cloak off
peaproxy clients show codex # Responses API
peaproxy clients show droid # Factory Droid BYOK client
peaproxy clients verify cursor --chat
HTTP
| Path | Status |
|---|---|
GET /v1/models | Live list; hide/expose affect listing only |
GET /v0/catalog | Rich catalog (tier, modalities, privacy, hidden/routable) |
POST /v1/chat/completions | Stream + non-stream; failover on retryable status/bodies; cooled accounts are not re-hit (503 + Retry-After) |
POST /v1/messages | Native Anthropic SSE or translated OpenAI stream |
POST /v1/responses | Codex / OpenAI Responses (native OAuth passes tools through; else translated via chat) |
POST /v1/images/generations | OpenAI Images API for models tagged image_out; refused (no chat fake) otherwise |
POST /v1/embeddings | OpenAI Embeddings API for models tagged embeddings; refused (no chat fake) otherwise |
GET / | UI: Accounts, Catalog, Showcase, Clients, Health, Request log, Settings |
GET /healthz | Liveness (LAN warning flags; no admin token) |
GET /admin/health | Bind, adapter health, provider-reported remaining when known, account cooldowns (token required off loopback) |
GET /admin/quota | Per-account quota remaining plus the provider honesty matrix (unknown omitted, never invented) |
GET /admin/policy | Resolved v3 optimization switches, spend against the ceiling, whether spend could be measured (unset ceiling is null, never 0) |
Security
Default bind is loopback. Binding 0.0.0.0 requires --allow-lan and a non-empty admin token. Never log secrets; the opt-in request log is redacted. OpenCode Zen free models may train on prompts; see catalog privacy notes. GitHub Models is retired and is not a provider.
Ready to run a local gateway?
PeaProxy is open-source and MIT licensed. v3.1.1 includes subscription OAuth at your own risk. Prefer official API keys.