Skip to main content

A lightweight proxy server that converts Anthropic Messages API to OpenAI API

Project description

local-openai2anthropic

Python 3.12+ License: Apache 2.0 PyPI

English | 中文

A lightweight proxy that bridges Anthropic and OpenAI ecosystems — run Claude SDK apps on any OpenAI-compatible backend, or use OpenAI clients directly with zero conversion overhead.


Why OA2A

  • Bidirectional Protocol Conversion — Anthropic Messages API ↔ OpenAI Chat Completions API. Run Claude SDK / Claude Code on any OpenAI-compatible backend (vLLM, SGLang, cloud APIs).
  • OpenAI-Native PassthroughPOST /v1/chat/completions forwards requests as-is with zero conversion overhead. All upstream fields preserved.
  • Server-Side Web Search — Built-in Tavily / TongXiao search. Give any model internet access without client-side changes.
  • Interleaved Thinking — Full support for thinking blocks with chat_template_kwargs and reasoning_effort. DeepSeek V4 and other reasoning models work out of the box.
  • Streaming, Tools & Vision — SSE real-time streaming, Claude tool_use conversion, multi-modal image input. Full API surface coverage.
  • Model Name Mapping — Wildcard rules map Anthropic model names to backend models automatically.
  • Daemon + Web Dashboardoa2a start/stop/logs for one-command management. Built-in web UI for request monitoring.

What This Does

Two modes of operation:

Mode Endpoint Use Case
Anthropic Proxy POST /v1/messages Claude SDK / Claude Code apps talking to any OpenAI backend
OpenAI Passthrough POST /v1/chat/completions OpenAI-native clients bypassing conversion entirely

Architecture


Quick Start

pip Install

pip install local-openai2anthropic

First run launches an interactive setup wizard:

oa2a start

Or run in foreground:

oa2a

Docker

docker run -d --name oa2a -p 8080:8080 \
  -e OA2A_OPENAI_API_KEY=your-key \
  -e OA2A_OPENAI_BASE_URL=http://host.docker.internal:8000/v1 \
  dongfangzan/local-openai2anthropic:latest

Usage Example

import anthropic

client = anthropic.Anthropic(base_url="http://localhost:8080", api_key="any")

message = client.messages.create(
    model="your-model",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(message.content[0].text)

Daemon Management

oa2a start              # Start in background
oa2a stop               # Stop background server
oa2a restart            # Restart background server
oa2a status             # Check if running
oa2a logs               # Show recent logs
oa2a logs -f            # Follow logs in real-time

Configuration

Config file: ~/.oa2a/config.toml (auto-created)

Core Settings

Option Required Default Description
openai_api_key Yes API key for the upstream backend
openai_base_url Yes https://api.openai.com/v1 Upstream backend URL
openai_org_id No OpenAI Organization ID
openai_project_id No OpenAI Project ID
host No 0.0.0.0 Server bind address
port No 8080 Server port
api_key No Auth key for this proxy (Bearer token)
request_timeout No 300.0 Upstream request timeout in seconds
log_level No INFO DEBUG, INFO, WARNING, ERROR

Model Name Mapping

Map Anthropic model names to backend model names with wildcard support:

default_model = "kimi-k2.5"

[[model_mapping]]
from = "sonnet"
to = "kimi-k2.5"

[[model_mapping]]
from = "*opus*"
to = "deepseek-v4"

from supports * and ? wildcards. default_model is the fallback when no rule matches.

Web Search

Supports two search providers: Tavily and TongXiao (通晓).

tavily_api_key = "tvly-xxx"
tongxiao_api_key = "xxx"
websearch_provider = "tavily"       # "tavily", "tongxiao", or "both"
websearch_max_uses = 5
tavily_max_results = 5
tongxiao_max_results = 5

CORS

cors_origins = ["*"]
cors_credentials = true
cors_methods = ["*"]
cors_headers = ["*"]

API Endpoints

Anthropic-Compatible

Method Path Description
POST /v1/messages Create a message (streaming via stream: true)
GET /v1/models List available models (proxied)
POST /v1/messages/count_tokens Count tokens (local tiktoken estimation)
GET /health Health check

OpenAI-Native Passthrough

Method Path Description
POST /v1/chat/completions OpenAI-format chat completions (streaming & non-streaming)

The passthrough endpoint forwards requests directly to the upstream — no validation, no conversion, no model mapping. All fields (including chat_template_kwargs, reasoning_effort, etc.) are preserved as-is.


Features

  • Streaming — SSE real-time token streaming in both Anthropic and OpenAI modes
  • Tool Calling — Claude-compatible tool use (tool_use / tool_result) converted to OpenAI function calls
  • Vision — Multi-modal image input via image_url content blocks
  • Thinking / Reasoning — Supports thinking blocks with chat_template_kwargs (vLLM/SGLang) and output_config.effort to reasoning_effort mapping for DeepSeek V4
  • Web Search — Server-side web search via Tavily or TongXiao (通晓), usable with any model
  • Model Mapping — Wildcard-based model name resolution
  • API Auth — Optional Bearer token authentication for the proxy itself
  • Web Dashboard — Built-in web UI at / for monitoring request statistics
  • Daemon Mode — Background service management (start/stop/restart/status/logs)

Using with Claude Code

Docker (Recommended)

The repo includes a docker-compose.yml with both OA2A proxy and Claude Code pre-configured:

cat > .env << 'EOF'
OA2A_OPENAI_API_KEY=your-api-key
OA2A_OPENAI_BASE_URL=http://host.docker.internal:8000/v1
CLAUDE_MODEL=your-model-name
EOF

docker-compose up -d
docker-compose exec claude-code claude --dangerously-skip-permissions

Local Installation

Configure ~/.claude/settings.json:

{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:8080",
    "ANTHROPIC_API_KEY": "any",
    "ANTHROPIC_MODEL": "your-model",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "your-model",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "your-model",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "your-model"
  }
}

Then start the proxy (oa2a start) and launch Claude Code (claude).


Supported Backends

Backend Status
vLLM Fully supported
SGLang Fully supported
Any OpenAI-compatible API Should work

Ollama natively supports the Anthropic API format — point Claude SDK directly to http://localhost:11434/v1, no proxy needed.


Development

git clone https://github.com/dongfangzan/local-openai2anthropic.git
cd local-openai2anthropic
pip install -e ".[dev]"

pytest                           # 445+ tests, >80% coverage

License

Apache License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

local_openai2anthropic-0.6.6.tar.gz (5.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

local_openai2anthropic-0.6.6-py3-none-any.whl (859.0 kB view details)

Uploaded Python 3

File details

Details for the file local_openai2anthropic-0.6.6.tar.gz.

File metadata

  • Download URL: local_openai2anthropic-0.6.6.tar.gz
  • Upload date:
  • Size: 5.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for local_openai2anthropic-0.6.6.tar.gz
Algorithm Hash digest
SHA256 418310713c5217a73928116b246c59e1fb5d25d20acabd29b0f065f75873d666
MD5 9403275397a3972982d106e8d277ea15
BLAKE2b-256 2b5d26f99002fba9d9b1061d6ccabe52c280220843c92ecfdd080b287542f38e

See more details on using hashes here.

Provenance

The following attestation bundles were made for local_openai2anthropic-0.6.6.tar.gz:

Publisher: publish.yml on dongfangzan/local-openai2anthropic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file local_openai2anthropic-0.6.6-py3-none-any.whl.

File metadata

File hashes

Hashes for local_openai2anthropic-0.6.6-py3-none-any.whl
Algorithm Hash digest
SHA256 381f62f92bd172f0749fa991183e949d43078500039acb533d0abe32bc26e133
MD5 7792f733757c6c7895f2f0c8fe328f19
BLAKE2b-256 caa6ca050584700ac82af65dfc6254aeb54cf8b5f843bb40483f08755c1d3b4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for local_openai2anthropic-0.6.6-py3-none-any.whl:

Publisher: publish.yml on dongfangzan/local-openai2anthropic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page