API gateway for Claude Code with Anthropic API compatibility
Project description
Claude Bridge
API gateway that intercepts Claude Code CLI and exposes it through Anthropic Messages API.
Overview
Claude Bridge wraps the Claude Code CLI (not the SDK) and exposes it through an Anthropic-compatible REST API. It acts as an interceptor, translating HTTP API requests into CLI subprocess calls. Each request is handled as a single, stateless task to Claude Code.
Features
- CLI Interceptor - Wraps Claude Code CLI, not the Python SDK
- Anthropic Messages API compatibility - Drop-in replacement for Anthropic API
- Anthropic SDK compatible - Works seamlessly with the official Anthropic Python SDK
- Streaming support - Server-Sent Events (SSE) for real-time responses
- Stateless architecture - Each request is independent
- No SDK dependency - Direct subprocess calls to
claudeCLI - Full Claude Code capabilities - All CLI features available
Quick Start (No Installation Required)
Run Claude Bridge instantly with uvx (no installation needed):
uvx claude-bridge
This will download, install, and run the server in an isolated environment.
Note:
uvxrequires the package to be published to PyPI. For local development, useuv run claude-bridgeinstead.
Installation
Prerequisites
- Python 3.12+
- uv (recommended) - Fast Python package installer and runner:
pip install uv - Claude CLI - Install from claude.com
- The
claudecommand must be available in your PATH - Authenticate using:
claude setup-token
- The
Option 1: Run with uvx (Recommended - No Installation)
# Run directly without installing
uvx claude-bridge
Option 2: Install Locally
Using uv (recommended):
uv pip install -e .
Or for development:
uv pip install -e ".[dev]"
This will install the claude-bridge CLI command in your virtual environment.
Alternatively, using pip:
pip install -e ".[dev]"
Usage
Start the server
With uvx (no installation required):
uvx claude-bridge
After local installation:
claude-bridge
Or with uv run:
uv run claude-bridge
Or directly with Python:
python main.py
The server will start on http://localhost:8000 by default.
Configuration
Create a .env file in the project root (or use environment variables):
# Application settings
DEBUG=false
HOST=0.0.0.0
PORT=8000
# Claude CLI settings
CLAUDE_CLI_PATH=claude # Path to claude binary
CLAUDE_CWD=/path/to/working/directory
⚠️ File Upload Configuration (Required)
File upload is disabled by default for security. To enable:
1. Configure via .env file OR command-line arguments
Option A: Using .env file (persistent)
# Required for file upload
CLAUDE_ALLOWED_TOOLS_STR=Read
CLAUDE_ALLOWED_DIRECTORIES_STR=/tmp
# Permission mode (required for non-interactive API)
CLAUDE_PERMISSION_MODE=bypassPermissions
Option B: Using CLI arguments (override .env, higher priority)
claude-bridge --allowed-tools Read --allowed-directories /tmp
Note: CLI arguments take precedence over environment variables.
2. Understand Security Implications
What you're allowing:
CLAUDE_ALLOWED_TOOLS_STR=Read- Claude can read files (but not write/execute)CLAUDE_ALLOWED_DIRECTORIES_STR=/tmp- Claude can only access/tmpdirectoryCLAUDE_PERMISSION_MODE=bypassPermissions- No interactive permission prompts (required for API mode)
What is protected:
- ❌ Claude cannot execute code (no Bash tool)
- ❌ Claude cannot modify files (no Write/Edit tools)
- ❌ Claude cannot access other directories (only those you specify)
3. Adjust for Your Environment
macOS/Linux:
CLAUDE_ALLOWED_DIRECTORIES_STR=/tmp
Windows:
CLAUDE_ALLOWED_DIRECTORIES_STR=C:\Temp
Custom temp directory:
CLAUDE_ALLOWED_DIRECTORIES_STR=/var/myapp/temp
Multiple directories (comma-separated):
CLAUDE_ALLOWED_DIRECTORIES_STR=/tmp,/var/app-temp
4. Start Server
After configuring .env or using CLI arguments:
claude-bridge
You should see:
INFO: Claude CLI permissions configured: tools=[Read], directories=[/tmp], mode=bypassPermissions
INFO: File upload is ENABLED
Troubleshooting
Error: "CLAUDE_ALLOWED_TOOLS_STR not configured"
→ Add CLAUDE_ALLOWED_TOOLS_STR=Read to your .env file, OR
→ Use CLI argument: --allowed-tools Read
Error: "contains non-existent directory"
→ Verify the directory exists: ls -la /tmp
Advanced: Using All Permission Arguments
# Enable multiple tools and directories via CLI
claude-bridge \
--allowed-tools "Read,Bash" \
--disallowed-tools "Write,Edit" \
--allowed-directories "/tmp,/var/app-data"
Permission errors in responses → Ensure your temp directory matches where files are created
Example: Upload File
curl -X POST http://localhost:8000/anthropic/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 1024,
"messages": [{
"role": "user",
"content": [{
"type": "text",
"text": "What is in this image?"
}, {
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "iVBORw0KGgoAAAA...base64_image_data..."
}
}]
}]
}'
Authentication
The bridge uses the Claude CLI's existing authentication. Make sure you've authenticated:
# Authenticate Claude CLI
claude setup-token
# Verify it works
claude --version
claude --print "Hello, Claude!"
The bridge will automatically use the CLI's credentials. No need to configure API keys separately!
API Endpoints
POST /anthropic/v1/messages
Create a message using Claude Code.
Supported Model Names:
The bridge automatically maps Anthropic API model names to Claude CLI aliases:
claude-sonnet-4→sonnet(latest Sonnet)claude-opus-4→opus(latest Opus)claude-haiku-4→haiku(latest Haiku)- Or use full model names like
claude-sonnet-4-5-20250929(recommended for stability)
Non-streaming request:
curl -X POST http://localhost:8000/anthropic/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Hello, Claude!"}
]
}'
Streaming request:
curl -X POST http://localhost:8000/anthropic/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 1024,
"stream": true,
"messages": [
{"role": "user", "content": "Count to 10"}
]
}'
With system prompt:
curl -X POST http://localhost:8000/anthropic/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 1024,
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "What is 2+2?"}
]
}'
GET /health
Health check endpoint.
curl http://localhost:8000/health
Using with Anthropic SDK
The bridge is fully compatible with the official Anthropic Python SDK. Simply configure the client with a custom base_url:
import anthropic
client = anthropic.AsyncAnthropic(
api_key="not-needed", # Bridge uses CLI authentication
base_url="http://localhost:8000/anthropic"
)
# Streaming example
async with client.messages.stream(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
) as stream:
async for text in stream.text_stream:
print(text, end="", flush=True)
# Non-streaming example
message = await client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
messages=[{"role": "user", "content": "What is 2+2?"}]
)
print(message.content[0].text)
Note: The bridge does not validate API keys. Authentication is handled by the Claude CLI itself via claude setup-token.
Development
Setup Pre-commit Hooks
This project uses pre-commit hooks for code quality and consistency:
# Install hooks (one-time setup)
pre-commit install
# Run manually on all files (optional)
pre-commit run --all-files
Hooks will automatically run on git commit and include:
- ✅ Code formatting (ruff)
- ✅ Linting (ruff)
- ✅ Type checking (mypy)
- ✅ Security scanning (bandit)
- ✅ File hygiene (trailing whitespace, EOF, etc.)
- ✅ Secret detection (detect-private-key)
Run tests
The project includes comprehensive unit and integration tests:
# Run all tests with coverage
pytest
# Run specific test categories
pytest tests/unit/ # Unit tests only
pytest tests/integration/ # Integration tests only
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/unit/test_adapter.py
# Run without coverage report
pytest --no-cov
# Generate HTML coverage report
pytest --cov-report=html
# Then open htmlcov/index.html in your browser
Test Structure:
tests/unit/- Fast, isolated unit tests for individual componentstests/integration/- Integration tests with mocked external dependenciestests/fixtures/- Sample data for teststests/conftest.py- Shared pytest fixtures
Manual code quality checks
# Linting and formatting
ruff check src/ --fix
ruff format src/
# Type checking
mypy src/
# Security scanning
bandit -c pyproject.toml -r src/
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_bridge-0.0.2.tar.gz.
File metadata
- Download URL: claude_bridge-0.0.2.tar.gz
- Upload date:
- Size: 94.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
724a5ecd02065b700b18945ebe662884125af905cc3a91a9ed789eee0eb3dac6
|
|
| MD5 |
987d0554ebc1b24191fe04490836daad
|
|
| BLAKE2b-256 |
5c930d4cf8117fff6b5593fc77abbcf9528ba4c9021925e329712c9e6b480a55
|
File details
Details for the file claude_bridge-0.0.2-py3-none-any.whl.
File metadata
- Download URL: claude_bridge-0.0.2-py3-none-any.whl
- Upload date:
- Size: 25.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
140ecbfcb6999e95de57905f53ef3094441366038a528ea1c649b99b79dfa4ce
|
|
| MD5 |
0a46382aba8d644676d8d2713eaf8595
|
|
| BLAKE2b-256 |
5cf149a4d1c0ebf522783adf859f04d3ddeed8a5f769f4cde866e3bb7f2408d3
|