Skip to main content

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.
  • OpenAI Responses API BridgePOST /v1/responses accepts the Responses API format and translates to /v1/chat/completions for backends that only implement chat completions. Lets Responses SDK clients talk to any vLLM/SGLang backend.
  • 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

Three 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
Responses Bridge POST /v1/responses OpenAI Responses SDK clients talking to chat-completions-only backends

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.

OpenAI Responses API Bridge

Method Path Description
POST /v1/responses OpenAI Responses-format request, translated to chat/completions upstream

Accepts the Responses API request shape (input, instructions, reasoning.effort, tools of type function, max_output_tokens, …) and translates it to a /v1/chat/completions call against the upstream backend. The upstream chat completion is translated back into a Responses Response object. Both streaming and non-streaming modes are supported — streaming emits the full Responses SSE event sequence (response.createdresponse.output_text.deltaresponse.completed).

Server-side web search: when the request includes a web_search / web_search_preview tool and a search provider is configured (Tavily or 通晓/TongXiao), the proxy runs the search loop locally. The web_search tool is exposed to the model as a function tool, executed via the configured provider when called, and the results are fed back so the model can answer with up-to-date information. The Responses output includes one web_search_call item per executed search. Configure search the same way as for the Anthropic path:

tavily_api_key = "tvly-xxx"
# or
tongxiao_api_key = "xxx"
websearch_provider = "tavily"       # "tavily", "tongxiao", or "both"
websearch_max_uses = 5
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8080/v1", api_key="any")
resp = client.responses.create(
    model="your-model",
    input="Hello!",
    instructions="Be concise",
)
print(resp.output_text)

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

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.7.3.tar.gz (5.4 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.7.3-py3-none-any.whl (875.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: local_openai2anthropic-0.7.3.tar.gz
  • Upload date:
  • Size: 5.4 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.7.3.tar.gz
Algorithm Hash digest
SHA256 c34843958c32f300bb2e55c0c2149c9b4e36cdc8dd1f28a75edd913105c27461
MD5 5459ef71ec01426dc26b560ac8189609
BLAKE2b-256 c5f6e4977ac40c8732b37cb2de0c2290efcfc200fb4607657318b8448db46ae1

See more details on using hashes here.

Provenance

The following attestation bundles were made for local_openai2anthropic-0.7.3.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.7.3-py3-none-any.whl.

File metadata

File hashes

Hashes for local_openai2anthropic-0.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 4f2f5dcce063ea7c1b7c4c82cc3d87ba4ba1d02c191afb483a7e9c3e193c5c9b
MD5 3554f835627b57266b0a88cee44cd3c4
BLAKE2b-256 692b12ee7de321cca381f380db796ae1d346cbeb376be2596f00e4ef40260347

See more details on using hashes here.

Provenance

The following attestation bundles were made for local_openai2anthropic-0.7.3-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.

Release history Release notifications | RSS feed

This release

0.7.3 This release

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.7

2 files

0.6.6

2 files

0.6.5

2 files

0.6.4

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.9

2 files

0.5.8

2 files

0.5.7

2 files

0.5.6

2 files

0.5.5

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.0

2 files

0.3.11

2 files

0.3.10

2 files

0.3.9

2 files

0.3.8

2 files

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

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