Rosetta
Multi-format bidirectional translation proxy for LLM APIs. Translates between OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages formats — letting any client SDK talk to any provider regardless of which native API the provider speaks.
Quick Start
uvx (no install required)
# Create your config
mkdir -p ~/.rosetta-llm
cp config.example.jsonc ~/.rosetta-llm/config.json
# Edit ~/.rosetta-llm/config.json with your providers and API keys
# Run instantly
uvx rosetta-llm
Or point to a custom config:
uvx rosetta-llm --config /path/to/config.json
# Equivalent via env var:
ROSETTA_CONFIG=/path/to/config.json uvx rosetta-llm
uv tool install (persistent)
uv tool install rosetta-llm
rosetta-llm --help
rosetta-llm --config ~/my-config.json --port 9999
Docker
docker run -p 7860:7860 \
-v ~/.rosetta-llm/config.json:/app/config.json \
-e ANTHROPIC_API_KEY=sk-ant-... \
-e OPENAI_API_KEY=sk-... \
ghcr.io/lokesh-chimakurthi/rosetta-llm:latest
From source
git clone https://github.com/Lokesh-Chimakurthi/rosetta-llm.git
cd rosetta-llm
uv sync
python -m rosetta
Features
- Three endpoint families:
/v1/chat/completions,/v1/responses,/v1/messages— all with full streaming support - Passthrough fast path: zero-overhead when inbound format matches provider's native format
- Canonical IR translation: lossless cross-format translation including thinking blocks, tool calls, and reasoning
- Claude Code gateway: full model picker integration — non-Anthropic models appear in
/modelviaclaude-code/prefixing - Provider routing:
<provider>/<model>prefix scheme (e.g.,anthropic/claude-opus-4-7) - Bearer-token auth: optional proxy-level API key authentication
- Structured JSON logging: request-scoped with configurable log levels
- Docker support: multi-stage build with
python:3.13-slim
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/messages |
Anthropic Messages |
| POST | /v1/messages/count_tokens |
Local tiktoken token count |
| POST | /v1/chat/completions |
OpenAI Chat Completions |
| POST | /v1/responses |
OpenAI Responses |
| GET | /v1/models |
Merged model list |
| GET | /health |
Liveness check |
| GET | /providers |
Provider status |
Model ID Format
Models are addressed as <provider_key>/<model_name> where provider_key matches a key in your config's providers section.
Examples:
abc/kimi-k2.5— routes to the "abc" provider with model "kimi-k2.5"anthropic/claude-opus-4-7— routes to the "anthropic" provideropenai/gpt-5.4— routes to the "openai" provider
Claude Code Integration
Rosetta is a fully compatible Claude Code LLM gateway. Point Claude Code at Rosetta and all configured providers appear in the /model picker — including non-Anthropic models.
Setup
export ANTHROPIC_BASE_URL=http://localhost:7860
export ANTHROPIC_AUTH_TOKEN=sk-proxy-XXXX # if proxy auth is enabled
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
Or in Claude Code settings (~/.claude/settings.json):
{
"env": {
"ANTHROPIC_BASE_URL": "http://localhost:7860",
"ANTHROPIC_AUTH_TOKEN": "sk-proxy-XXXX",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
}
}
Model picker
On startup, Claude Code queries GET /v1/models with its session headers. Rosetta detects Claude Code (via the X-Claude-Code-Session-Id header) and returns a model list tailored for the picker:
- Models already named
claude-*oranthropic/*pass through unchanged - All other models get a
claude-code/prefix — this ensures they pass Claude Code's built-in model filter (which only shows models starting withclaudeoranthropic)
For example, if your config has an OpenAI provider with gpt-5.4, it appears in the picker as claude-code/openai/gpt-5.4. When selected, Rosetta strips the claude-code/ prefix internally and routes to the correct provider.
Headers forwarded upstream
Rosetta forwards Claude Code's session headers (anthropic-beta, anthropic-version, X-Claude-Code-Session-Id) to every upstream call, preserving prompt caching and feature detection.
Translation Matrix
The proxy automatically translates between formats:
| Client Endpoint | Provider Format | Path |
|---|---|---|
/v1/messages |
anthropic | passthrough |
/v1/messages |
openai_chat | translate via IR |
/v1/messages |
openai_responses | translate via IR |
/v1/chat/completions |
openai_chat | passthrough |
/v1/chat/completions |
anthropic | translate via IR |
/v1/chat/completions |
openai_responses | translate via IR |
/v1/responses |
openai_responses | passthrough |
/v1/responses |
anthropic | translate via IR |
/v1/responses |
openai_chat | translate via IR |
Usage Examples
Anthropic client -> OpenAI-backed model
curl http://localhost:7860/v1/messages \
-H "Authorization: Bearer sk-proxy-XXXX" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.4",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello!"}]
}'
OpenAI client -> Anthropic-backed model
curl http://localhost:7860/v1/chat/completions \
-H "Authorization: Bearer sk-proxy-XXXX" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-opus-4-7",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'
Environment Variables
| Variable | Purpose |
|---|---|
ROSETTA_CONFIG |
Path to config.json (default: ~/.rosetta-llm/config.json) |
| Provider-specific | Set via api_key_env in config (e.g., ANTHROPIC_API_KEY) |
Development
uv sync --group dev
uv run pytest -q
uv run mypy src/
uv run ruff check src/ tests/
Release files for rosetta-llm 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rosetta_llm-0.2.1.tar.gz | 243.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rosetta_llm-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 295.1 kB
Release files / rosetta_llm-0.2.1.tar.gz
| Download URL | rosetta_llm-0.2.1.tar.gz |
|---|---|
| Size | 243.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
08bc0a6fe3641e9e0b4a7ea3de5ffaf8cbbf32a7bb30ebaf0d3859f42fa2b4e8
|
|
BLAKE2b-256 checksum How to use checksums |
f42c3bdbb1d1e157ef247c50b9a3b7a66a21d7ec44834c5364379d43734cdb2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","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}
|
Release files / rosetta_llm-0.2.1-py3-none-any.whl
| Download URL | rosetta_llm-0.2.1-py3-none-any.whl |
|---|---|
| Size | 51.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aed5b4130a827d5097ee2a32e2965eca8bdde3834e3549c0a2edc89d5e7464cb
|
|
BLAKE2b-256 checksum How to use checksums |
c27343f3733bc96ea56065dee188a1060efeeb704ca0e69a3acdd52eb3ae4ad7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","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}
|