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 Passthrough — POST /v1/chat/completions forwards requests as-is with zero conversion overhead. All upstream fields preserved.
  • OpenAI Responses API Bridge — POST /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 Dashboard — oa2a 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.

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.created → response.output_text.delta → response.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

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

Metadata

Release files for local-openai2anthropic 0.7.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for local-openai2anthropic 0.7.3
File Size Uploaded
local_openai2anthropic-0.7.3.tar.gz 5.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for local-openai2anthropic 0.7.3
File Interpreter ABI Platform
local_openai2anthropic-0.7.3-py3-none-any.whl Python 3 none any Details

Total release size: 6.2 MB

Release files / local_openai2anthropic-0.7.3.tar.gz

Download URL local_openai2anthropic-0.7.3.tar.gz
Size 5.4 MB
Tags Source
SHA-256 checksum
How to use checksums
c34843958c32f300bb2e55c0c2149c9b4e36cdc8dd1f28a75edd913105c27461
BLAKE2b-256 checksum
How to use checksums
c5f6e4977ac40c8732b37cb2de0c2290efcfc200fb4607657318b8448db46ae1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.

Transparency log

Release files / local_openai2anthropic-0.7.3-py3-none-any.whl

Download URL local_openai2anthropic-0.7.3-py3-none-any.whl
Size 875.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4f2f5dcce063ea7c1b7c4c82cc3d87ba4ba1d02c191afb483a7e9c3e193c5c9b
BLAKE2b-256 checksum
How to use checksums
692b12ee7de321cca381f380db796ae1d346cbeb376be2596f00e4ef40260347
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.3 This release

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.6

2 release files

0.5.5

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.0

2 release files

0.3.11

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page