Skip to content

Repository files navigation

gateii

A minimal, self-hosted proxy for the Anthropic Claude API. Runs on any Docker host. No cloud, no signup, no SaaS.

Claude Code / your app
        │
        ▼
  gateii :8888   ←  token tracking · rate limiting · monitoring
        │
        ▼
  api.anthropic.com

Why gateii exists

You're paying for Claude and have no idea what's actually happening. Either your team shares one API key with no visibility, or every user has their own and finance reviews a spreadsheet of charges no one can attribute. If you're on the Max plan and occasionally hit the wall, you have no data on where it went.

Problem gateii answer
No visibility into token usage Per-user, per-model counters in a Grafana dashboard
Sharing one API key is risky Per-user proxy keys pinned to their own provider + credential
Don't want another SaaS Self-hosted, stateless, three Docker containers, no external deps
Claude Max plan (OAuth) passthrough mode — your token forwarded as-is, no server key
Accidental runaway spend Per-user daily limits, auto-block until midnight UTC
Cost discussions without data Historical metrics in Prometheus, cost estimates from providers.json

Unlike managed observability tools, gateii runs locally, stores nothing on third-party infrastructure, and keeps your Anthropic key where you already put it (in your .env or your OAuth session).

Quickstart

git clone https://github.com/bmmmm/gateii
cd gateii
cp .env.example .env

# Optional: alias the CLI so `gateii <subcommand>` works from anywhere
echo "alias gateii='$(pwd)/scripts/gateii'" >> ~/.zshrc && source ~/.zshrc

# Start the stack
gateii up

# Point Claude Code at the proxy
gateii switch local-proxy

# Optional: remind yourself when a Claude Code session is NOT routed through gateii
gateii hook install

# Open the dashboard
open http://localhost:3001

The gateii hook install step registers a UserPromptSubmit hook in ~/.claude/settings.json that warns (up to 3× per session) when ANTHROPIC_BASE_URL is not pointed at this gateii. It is opt-in on purpose — it only makes sense once you actively route Claude Code through gateii. Remove it with gateii hook uninstall. If you manage ~/.claude/settings.json via dotfiles, mirror the entry there too.

Full walkthrough: Getting started.

Docs

Page What's in it
Getting started Install prerequisites, first start, boot after reboot
CLI reference All gateii <subcommand> options
Modes passthrough vs apikey, when to use each
Routing local-proxy / remote-proxy / direct, safe dev workflow, emergency rescue
Monitoring What the Grafana dashboard shows, metrics exposed
Configuration All .env variables, providers.json pricing
Plugins console (web UI) and git-tracking
Local agents (omlx) Route simple tasks (commits, summaries, …) to a local Apple-Silicon LLM
Providers Adding a new upstream provider
Architecture Three containers, shared dicts, why no Redis
Key files Component map — which module does what
Testing Suite layout, running the tests, CI parity
Security Admin API hardening, secrets hygiene, network exposure
keys.json schema Structured key storage (apikey mode)
Bootstrap handshake Self-provisioning keys over HMAC
Admin API HTTP endpoint reference

Also: Pre-up hooks — how to run platform-specific setup (Colima, podman, …) before docker compose up.

Stack at a glance

Container Image Port Role
gateii-proxy openresty/openresty:alpine 8888 nginx + LuaJIT proxy + metrics
gateii-prometheus prom/prometheus 9090 metrics storage
gateii-grafana grafana/grafana 3001 dashboard
gateii-git-tracking alpine (plugin) — git activity metrics (optional)

All state lives in nginx shared memory. Prometheus stores the time series — so the proxy itself is effectively stateless between restarts. See architecture.md.

License

GPL-3.0

About

Minimal self-hosted LLM API proxy — OpenResty + Prometheus + Grafana

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages