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/
Metadata
Release files for rosetta-llm 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rosetta_llm-0.2.2.tar.gz | 244.1 kB | Without provenance | Details for rosetta_llm-0.2.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rosetta_llm-0.2.2-py3-none-any.whl | Python 3 | none | any | Details for rosetta_llm-0.2.2-py3-none-any.whl |
Total release size: 295.4 kB
Release files / rosetta_llm-0.2.2.tar.gz
| Download URL | rosetta_llm-0.2.2.tar.gz |
|---|---|
| Size | 244.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e17964ca7301a3ba33deaa9296e435e9baf0c5f1f549255cfd3413aa5dd58563
|
|
BLAKE2b-256 checksum How to use checksums |
aab1f27a7c5e775784619a25327b48597c40eb89405576194f23c97e0567f48c
|
| 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.2-py3-none-any.whl
| Download URL | rosetta_llm-0.2.2-py3-none-any.whl |
|---|---|
| Size | 51.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
77f0ad69067c2b4b7a844bec96e5b2b1bc425bf147a858e5c970293f078ca185
|
|
BLAKE2b-256 checksum How to use checksums |
57ecff3c9fc8a0b6da5036a2a51190d6040da3cbd3db979ffec6556aaaadd7bc
|
| 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}
|
Security for rosetta-llm 0.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.