Turn locally authenticated CLI tools into an OpenAI-compatible REST API.
Log in to a CLI tool once. ShellGate proxies any HTTP client through it — no separate API keys, no extra billing accounts.
Your App → POST /v1/chat/completions → ShellGate → codex exec "..."
(N8N, LangChain, any OpenAI SDK) → kimi --print "..."
→ claude -p "..."
↑
your CLI logins
Requests route automatically based on model name — use Codex, Kimi, and Claude simultaneously from the same endpoint.
| Provider | CLI | Model prefix | Auth | Status |
|---|---|---|---|---|
| OpenAI Codex | codex |
gpt-* |
codex login |
✅ Supported |
| Kimi CLI | kimi |
kimi-* |
kimi login |
✅ Supported |
| Claude Code | claude |
claude-* |
claude login (OAuth) |
✅ Supported |
| Antigravity CLI | agy |
— | — | 🔜 Planned |
One-line (Linux/macOS):
curl -fsSL https://raw.githubusercontent.com/DutaKey/ShellGate/main/install.sh | shFrom source:
git clone https://github.com/DutaKey/ShellGate
cd ShellGate && make buildshellgate setupWalks through config creation, provider login, API key generation, and server start in one flow.
# 1. Create config (~/.shellgate/config.toml)
shellgate init
# 2. Log in to CLI providers
shellgate login codex
shellgate login kimi
shellgate login claude
# 3. Start the server
shellgate serve -d # background
# or
shellgate serve # foreground
# 4. Create an API key
shellgate keysUse http://localhost:8080/v1 as your OpenAI base URL.
ShellGate routes each request to the right provider based on model name:
| Model | Provider |
|---|---|
gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex, gpt-5.2 |
Codex CLI |
kimi-code/kimi-for-coding |
Kimi CLI |
claude-opus-4-7, claude-sonnet-4-6, claude-haiku-4-5 |
Claude Code CLI |
All providers are always active — no config switch needed.
shellgate setup Guided first-time setup wizard
shellgate init Create config file interactively
shellgate login <provider> Authenticate a CLI provider (codex, kimi, claude)
shellgate serve Start the API server (foreground)
shellgate serve -d Start in background
shellgate stop Stop background server
shellgate restart Restart background server
shellgate status Show server status + provider auth status
shellgate logs View last 50 log lines
shellgate logs -f Follow log output (tail -f style)
shellgate keys Interactive key manager (arrow keys)
shellgate keys create <name> Create API key (scriptable)
shellgate keys list List all keys
shellgate keys revoke <id> Revoke a key
Flags:
-c, --config string config file (default ~/.shellgate/config.toml)
Drop-in replacement for the OpenAI API.
| Method | Path | Description |
|---|---|---|
POST |
/v1/chat/completions |
Chat completions (streaming + non-streaming) |
POST |
/v1/responses |
Responses API (N8N AI Agent, LangChain) |
GET |
/v1/models |
List available models (all providers) |
GET |
/v1/models/:id |
Get model by ID |
GET |
/health |
Health check |
POST |
/admin/keys |
Create API key |
GET |
/admin/keys |
List API keys |
DELETE |
/admin/keys/:id |
Revoke API key |
curl — Codex:
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer <your-key>" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.4","messages":[{"role":"user","content":"hello"}]}'curl — Kimi:
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer <your-key>" \
-H "Content-Type: application/json" \
-d '{"model":"kimi-code/kimi-for-coding","messages":[{"role":"user","content":"hello"}]}'curl — Claude:
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer <your-key>" \
-H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"hello"}]}'Python (OpenAI SDK):
from openai import OpenAI
client = OpenAI(
api_key="<your-shellgate-key>",
base_url="http://localhost:8080/v1"
)
# route to Claude
response = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "hello"}]
)
# route to Codex
response = client.chat.completions.create(
model="gpt-5.4",
messages=[{"role": "user", "content": "hello"}]
)N8N: OpenAI node or AI Agent node → set Base URL to http://<host>:8080/v1.
LangChain / other frameworks: Any client that supports custom OpenAI base URL works.
Config lives at ~/.shellgate/config.toml by default.
[server]
host = "0.0.0.0"
port = 8080
read_timeout = "30s"
write_timeout = "120s"
[auth]
admin_secret = "" # required — protects /admin/* endpoints
keys_file = "~/.shellgate/keys.json"
[executor]
codex_binary = "codex"
default_sandbox = "read-only" # read-only | workspace-write | danger-full-access
timeout = "120s"
kimi_binary = "kimi"
claude_binary = "claude"
working_dir = "" # override working dir for all CLI tools
[logging]
level = "info" # debug | info | warn | error
format = "json" # json | textEnvironment variable overrides:
| Variable | Config field |
|---|---|
SHELLGATE_PORT |
server.port |
SHELLGATE_ADMIN_SECRET |
auth.admin_secret |
SHELLGATE_KEYS_FILE |
auth.keys_file |
SHELLGATE_EXECUTOR_CODEX_BINARY |
executor.codex_binary |
SHELLGATE_EXECUTOR_KIMI_BINARY |
executor.kimi_binary |
SHELLGATE_EXECUTOR_CLAUDE_BINARY |
executor.claude_binary |
SHELLGATE_LOG_LEVEL |
logging.level |
docker run -d \
-p 8080:8080 \
-v $HOME/.shellgate:/root/.shellgate \
-v $HOME/.codex:/root/.codex:ro \
-v $HOME/.kimi:/root/.kimi:ro \
-v $HOME/.claude:/root/.claude:ro \
-e SHELLGATE_ADMIN_SECRET=your-secret \
ghcr.io/dutakey/shellgate:latestMIT