Route Claude Code through a LiteLLM proxy with automatic API key management via 1Password CLI.
Use this when your team runs a shared LiteLLM gateway and stores API keys in 1Password. The wrapper handles config distribution, per-project key rotation, and keeps developer machines in sync — no manual env vars to manage.
curl -fsSL https://raw.githubusercontent.com/aproorg/claude-wrapper/main/install.js | nodeThe installer:
- Writes a process wrapper to
~/.local/bin/claudethat shadows the real binary - Adds
~/.local/binto your PATH (if not already there) - Prompts for your LiteLLM base URL and 1Password item reference
- Pre-fetches the team configuration
Non-interactive mode: When piped without a TTY (CI, Docker), prompts are skipped and defaults are used silently.
which claude # Should show ~/.local/bin/claude
CLAUDE_DEBUG=1 claude # Shows resolved config- Claude Code installed (Homebrew, npm, or standalone)
- 1Password CLI (
op) with CLI integration enabled - curl and git
This repo ships with defaults for the maintainers' infrastructure. To use it for your own org:
- Fork the repo and update
claude-env.sh:LITELLM_BASE_URL— your LiteLLM gateway URLOP_ACCOUNT— your 1Password team domainOP_ITEM— the 1Password vault path for your API keys
- Update the install URL in your fork's README to point to your raw GitHub URL
- Distribute — team members run your fork's one-liner to install
Individual developers can also override any value via ~/.config/claude/local.env without touching the shared config.
# Clear all caches (API keys + remote config)
claude --clear-cache
# Force refresh config cache only
rm ~/.cache/claude/env-remote.sh
# Re-run installer to update local settings
curl -fsSL https://raw.githubusercontent.com/aproorg/claude-wrapper/main/install.js | node
# Debug mode (shows resolved config + stale cache warnings)
CLAUDE_DEBUG=1 claudeIf you're working on this repo, use a symlink instead of the installed wrapper:
git clone <your-fork-url> ~/claude-wrapper
mkdir -p ~/.local/bin
ln -sf ~/claude-wrapper/claude ~/.local/bin/claude
# Add to your .bashrc / .zshrc if ~/.local/bin isn't already on PATH:
export PATH="$HOME/.local/bin:$PATH"Verify: which claude should show ~/.local/bin/claude.
How it works
The installer writes a process wrapper to ~/.local/bin/claude that shadows the real Claude Code binary. When you run claude, the wrapper:
- Finds the real binary (portable PATH iteration, skipping itself)
- Fetches the latest team config from this repo, validates it against an integrity check, caches it for 5 minutes, falls back to stale cache on network failure
- Sources the config to set
ANTHROPIC_BASE_URL,ANTHROPIC_AUTH_TOKEN, model defaults, and per-project API keys - Optionally sources
~/.config/claude/middleware.shfor custom pre-launch hooks (errors are trapped with actionable messages) execs the real Claude Code with all original arguments
Config override chain: Remote defaults (claude-env.sh) → local overrides (~/.config/claude/local.env) → environment variables. Local values persist across remote config updates — the TTL-based refresh only re-fetches the remote config, never touching your local settings.
Per-project API keys
The wrapper detects the current project from the git remote (or directory name) and looks up a project-specific API key field in your 1Password item. If no project-specific field exists, it falls back to the default API Key field.
1Password item: "op://Vault/your-litellm-item"
├── API Key (default fallback)
├── backend-api (project-specific)
└── customer-portal (project-specific)
Override project detection: CLAUDE_PROJECT=my-project claude
Configuration
| Variable | Default | Description |
|---|---|---|
CLAUDE_ENV_URL |
(this repo) | Override remote config URL |
CLAUDE_ENV_UPDATE_TTL |
300 |
Cache TTL in seconds |
CLAUDE_MODEL |
claude-opus-4-6 |
Override default model |
CLAUDE_PROJECT |
(auto-detected) | Override project name |
CLAUDE_DEBUG |
0 |
Enable debug output |
Files:
| File | Purpose |
|---|---|
~/.local/bin/claude |
Process wrapper (written by installer) |
~/.cache/claude/env-remote.sh |
Cached remote config (auto-refreshed) |
~/.config/claude/local.env |
Your local overrides (never auto-modified) |
~/.config/claude/middleware.sh |
Optional pre-launch hook |
Local config (local.env)
The installer stores your LiteLLM URL and 1Password item in ~/.config/claude/local.env. These values override the remote defaults and are never touched by automatic updates.
# View current settings
cat ~/.config/claude/local.env
# Re-run installer to change values (shows current as defaults)
curl -fsSL https://raw.githubusercontent.com/aproorg/claude-wrapper/main/install.js | nodeThe file uses simple KEY="VALUE" format and has 0600 permissions.
Middleware
Create ~/.config/claude/middleware.sh to run custom shell commands before Claude launches. The file is sourced (not executed), so it can export environment variables, modify PATH, or run setup commands.
# Example: add a custom env var
echo 'export MY_CUSTOM_VAR="hello"' > ~/.config/claude/middleware.sh
# Example: prepend to PATH
echo 'export PATH="/opt/my-tools/bin:$PATH"' > ~/.config/claude/middleware.sh- The file is optional — if missing, nothing happens.
- Errors in middleware are caught and reported with an actionable message (file path + fix instructions).
Windows (PowerShell)
curl -fsSL https://raw.githubusercontent.com/aproorg/claude-wrapper/main/install.js | nodeThe installer:
- Downloads
claudestart.ps1to%LOCALAPPDATA%\claude\bin\ - Creates a
claudestart.cmdshim so it works fromcmd.exetoo - Adds the install directory to your user PATH
- Prompts for your LiteLLM base URL and 1Password item reference
Note: On Windows the command is
claudestart(notclaude) because Windows doesn't support the same binary-shadowing trick used on macOS/Linux.
Get-Command claudestart # Should show the .cmd shim
$env:CLAUDE_DEBUG = "1"; claudestart # Shows resolved config- Claude Code installed (npm global install or standalone)
- 1Password CLI (
op.exe) with CLI integration enabled - PowerShell 5.1+ (ships with Windows 10/11) or PowerShell 7+
- git (for project detection)
# Clear all caches (API keys + remote config)
claudestart --clear-cache
# Force refresh config cache only
Remove-Item "$env:LOCALAPPDATA\claude\env-remote.sh"
# Re-run installer to update local settings
curl -fsSL https://raw.githubusercontent.com/aproorg/claude-wrapper/main/install.js | node
# Debug mode
$env:CLAUDE_DEBUG = "1"; claudestart| File | Purpose |
|---|---|
%LOCALAPPDATA%\claude\bin\claudestart.ps1 |
PowerShell wrapper |
%LOCALAPPDATA%\claude\bin\claudestart.cmd |
CMD shim |
%LOCALAPPDATA%\claude\env-remote.sh |
Cached remote config |
%APPDATA%\claude\local.env |
Your local overrides |
%LOCALAPPDATA%\claude\<project>.key |
Cached API keys (12h TTL) |
If you prefer not to use the installer:
- Run
Set-ExecutionPolicy RemoteSignedin an elevated PowerShell (once) - Clone the repo and copy
claudestart.ps1to a directory on your PATH - Create a
claudestart.cmdnext to it with:@powershell -ExecutionPolicy Bypass -File "%~dp0claudestart.ps1" %*
Follow the macOS/Linux instructions inside your WSL shell — WSL uses the bash wrapper, not the PowerShell one.
Add to your settings.json:
{
"claudeCode.environmentVariables": [
{ "name": "CLAUDE_CODE_SKIP_AUTH_LOGIN", "value": "1" }
],
"claudeCode.claudeProcessWrapper": "claudestart.cmd"
}VSCode integration (macOS/Linux)
Add to your settings.json:
{
"claudeCode.environmentVariables": [
{ "name": "CLAUDE_CODE_SKIP_AUTH_LOGIN", "value": "1" }
],
"claudeCode.claudeProcessWrapper": "/Users/YOU/.local/bin/claude"
}