CLI for managing a personal LiteLLM proxy with OAuth provider auth, a web gateway, local inference servers, and search.
curl -fsSL https://raw.githubusercontent.com/0xxmemo/litellmctl/main/install.sh | bashWorks on macOS and Ubuntu/Debian. Safe to re-run.
For AWS deployments see docs/aws.md. One GitHub Actions
pipeline provisions an ARM Graviton EC2 instance, user-data runs
install.sh the same way a laptop does, and subsequent deploys are a
git pull && litellmctl restart one-liner executed via SSM. No Docker,
no image builds. Caddy fronts the gateway for auto-HTTPS; an in-UI
admin PTY replaces SSH for ops like running the wizard or logging into
OAuth providers.
source ~/.zshrc # or ~/.bashrc
litellmctl wizard # generate config.yaml (providers, tiers, fallbacks)
litellmctl install # local servers, gateway, search
litellmctl start # start proxy (auto-starts on boot)litellmctl start [--port N] Start proxy (background, auto-start on boot)
litellmctl stop Stop proxy
litellmctl restart Restart proxy
litellmctl logs Tail proxy logs
litellmctl proxy [--port N] Start proxy in foreground (debug)
litellmctl status Auth + proxy + gateway + local servers
litellmctl auth chatgpt Login to ChatGPT / Codex (PKCE)
litellmctl auth gemini Login to Gemini CLI (PKCE)
litellmctl auth qwen Login to Qwen Portal (device-code)
litellmctl auth kimi Login to Kimi Code (device-code)
litellmctl auth status Show token expiry info
litellmctl auth refresh <p> Refresh token for a provider
litellmctl auth export [p...] Copy credentials as transfer script
litellmctl auth import Read credentials from stdin
All services (proxy | gateway | searxng | protonmail | embedding | transcription) are managed with the same four verbs:
litellmctl start [features...] Start one or more features (multi-select if omitted)
litellmctl stop [features...] Stop
litellmctl restart [features...] Restart
litellmctl status [feature] Show status for one feature (default: all)
litellmctl logs [feature] Tail logs for one feature (default: proxy)
litellmctl users List all gateway users
litellmctl set-role <email> <role> Set a user's role (guest/user/admin)
litellmctl routes List all gateway API endpoints
litellmctl api <cmd...> Call any gateway endpoint (see below)
litellmctl migrate-from-mongo One-shot migration of legacy MongoDB → SQLite
Every gateway endpoint is callable using path segments as commands — no HTTP methods, URLs, or auth needed (the CLI uses a localhost-only bypass secret):
litellmctl api health
litellmctl api stats user
litellmctl api admin users
litellmctl api models extended
litellmctl api search q=hello
litellmctl api admin approve -d '{"email":"user@example.com"}'
litellmctl api admin litellm-config -d '{"router_settings":{"num_retries":5}}'
litellmctl api keys delete abc123Method is auto-inferred (GET by default, write method when -d or key=val given, delete/create/update action words).
Tab completion discovers commands from route source files (works offline):
litellmctl api <TAB> # health, stats, admin, keys, ...
litellmctl api stats <TAB> # user, requests, ...Use litellmctl routes to see all endpoints with descriptions.
litellmctl wizard Interactive config.yaml generator
litellmctl install [flags] Install / rebuild components
litellmctl update [flags] git pull (parent + submodule), reinstall fork, restart proxy
litellmctl init-env Detect auth files and update .env
litellmctl toggle-claude Toggle Claude Code between direct API and proxy
litellmctl setup-completions Add litellmctl alias + tab completion to shell
--skip-restart Reinstall but don't restart the proxy
--force Reinstall + restart even if no commits were pulled
update is the right command after git pull-ing the fork on a server: it
pulls the parent repo and the litellm/ submodule, syncs the submodule
pointer, drops stale __pycache__ directories, reinstalls the editable
fork (pip install -e litellm[proxy] --no-deps), then restarts the proxy.
Plain litellmctl restart proxy does not reinstall — if a non-editable
copy of litellm is shadowing the submodule, restart alone won't pick up
fork changes.
--with-local / --without-local Ollama + faster-whisper
--with-embedding / --without-embedding Ollama embedding server
--with-transcription / --without-transcription faster-whisper-server
--with-searxng / --without-searxng SearXNG search server
--with-gateway / --without-gateway Web UI + API gateway
--with-protonmail / --without-protonmail Hydroxide SMTP bridge for OTP emails
ProtonMail is a feature like any other — use the unified verbs:
litellmctl start protonmail Start hydroxide SMTP bridge
litellmctl stop protonmail Stop
litellmctl restart protonmail Restart
litellmctl status protonmail Show bridge status
litellmctl auth protonmail Authenticate hydroxide with ProtonMail
litellmctl uninstall [target] Remove components
Targets: service, embedding, transcription, searxng, gateway, protonmail
If you installed when litellmctl set up PostgreSQL (or you still have DATABASE_URL / related keys in .env), run this once to stop the proxy service and strip DB-related environment variables from .env. It does not drop PostgreSQL databases.
Works on macOS (LaunchAgent com.litellm.proxy) and Linux (systemd user unit litellm-proxy), and cleans nohup + .proxy.pid if used.
~/.litellm/bin/uninstall-legacy-db
# Custom install path: LITELLM_HOME=/path/to/.litellm ~/.litellm/bin/uninstall-legacy-dbThen start the proxy again: litellmctl start.
A full web UI and authenticated API layer on top of LiteLLM:
- Dashboard with usage stats, model breakdown, daily charts
- API key management (create, revoke, rename)
- User management with role-based access (admin/user/guest)
- Model overrides per user
- Config editor for live config.yaml changes
- Search via SearXNG proxy
- Health monitoring with feature detection
Default port: 14041. Override with GATEWAY_PORT in .env.
litellmctl api GET /api/health{
"status": "ok",
"uptime": 42.3,
"features": {
"search": true,
"embedding": true,
"transcription": false,
"proton": true,
"database": true
}
}Privacy-respecting metasearch, accessible via gateway or directly:
# Via CLI (recommended)
litellmctl api GET "/api/search?q=AI+news"
# Direct SearXNG API
curl "http://localhost:8888/search?q=your+query&format=json"Embedding (Ollama) and transcription (faster-whisper-server):
litellmctl local status # check reachability
litellmctl install --with-local # set up both# Source machine — copies self-contained bash script to clipboard
litellmctl auth export chatgpt kimi
# Target machine — paste the script (no litellmctl required)litellmctl auth detects headless environments and prints the OAuth URL.
SSH-tunnel the callback port for automatic capture:
ssh -L 8085:localhost:8085 server # Gemini
ssh -L 1455:localhost:1455 server # ChatGPT~/.litellm/
├── bin/litellmctl CLI entry point
├── bin/lib/ Python CLI package
├── gateway/ Bun-based web gateway + API
│ ├── routes/ TypeScript route handlers (parsed by CLI for commands)
│ ├── routes/ TypeScript route handlers
│ └── src/ React frontend
├── templates/ Provider YAML templates for wizard
├── litellm/ Git submodule (LiteLLM fork)
├── config.yaml Proxy model routing config
├── searxng/ SearXNG settings
└── .env API keys and env vars (git-ignored)
cd ~/.litellm/bin
python3 -m pytest # all tests
python3 -m pytest tests/test_auth_core.py # specific module