OpenAI API Compatible Gateway for Claude Agent SDK
Warning
This project is intended for personal use only. It is designed to help individual developers integrate Claude models into their local development workflow via an OpenAI-compatible interface.
- Do not use this project to provide services to third parties or for commercial purposes
- Do not redistribute or resell access to Claude models through this gateway
- Users are responsible for complying with Anthropic's Terms of Service and all applicable laws and regulations
The authors assume no liability for any misuse of this software.
ChimeraGate is a lightweight local HTTP server that provides complete OpenAI API compatibility, but routes all requests to the Claude Agent SDK. It can replace the OpenAI API directly—just change the baseURL and you can use Claude subscription models through normal API calls.
- Full OpenAI API Compatibility - Compatible with any client that supports OpenAI's Chat Completions API
- Multi-Model Support - Access Claude Sonnet, Opus, and Haiku models through familiar model identifiers
- Streaming & Non-Streaming - Support for both response modes with Server-Sent Events (SSE)
- Bearer Token Authentication - Secure API access with configurable API keys
- Automatic Format Conversion - Bidirectional conversion between OpenAI and Claude message formats
- Debug Logging - Comprehensive logging for development and troubleshooting
- Lightweight & Fast - Built on Hono framework (~15KB) for minimal overhead
- Node.js 18+
- npm or yarn
- Claude subscription (Pro or Max, configured for Claude Agent SDK)
# Clone the repository
git clone https://github.com/yourusername/ChimeraGate.git
cd ChimeraGate
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Edit .env with your settings
# Build the project
npm run build
# Start the server
npm startnpm run devThe server will start with hot reload enabled:
╔═══════════════════════════════════════════════════════════╗
║ CHIMERA GATE ║
║ OpenAI API Compatible Gateway for Claude ║
╠═══════════════════════════════════════════════════════════╣
║ Server: http://localhost:3721 ║
║ Debug: ON ║
╠═══════════════════════════════════════════════════════════╣
║ Endpoints: ║
║ GET /v1/models - List available models ║
║ POST /v1/chat/completions - Chat completion API ║
║ POST /v1/completions - Legacy completion API ║
╚═══════════════════════════════════════════════════════════╝
Create a .env file in the project root:
# Server port (default: 3000)
CHIMERA_PORT=3721
# API authentication key (default: chimera-key-123)
CHIMERA_API_KEY=your-secure-api-key
# Default model when not specified in request (default: claude-sonnet-4-5)
CHIMERA_DEFAULT_MODEL=claude-sonnet-4-5
# Enable debug logging (default: false)
CHIMERA_DEBUG=true| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/ |
Service info |
GET |
/v1/models |
List available models |
POST |
/v1/chat/completions |
Chat completion (primary) |
POST |
/v1/completions |
Legacy completion |
| Model ID | Claude Model |
|---|---|
claude-sonnet-4-5 |
Claude Sonnet 4.5 (default) |
claude-opus-4-5 |
Claude Opus 4.5 |
claude-haiku-4-5 |
Claude Haiku 4.5 |
POST /v1/chat/completions
Authorization: Bearer <API_KEY>
Content-Type: application/jsonRequest Body:
{
"model": "claude-opus-4-5",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
],
"temperature": 0.7,
"max_tokens": 2000,
"stream": false
}Supported Parameters:
| Parameter | Type | Description |
|---|---|---|
model |
string | Model ID (optional, uses default if omitted) |
messages |
array | Array of message objects (required) |
temperature |
number | Sampling temperature 0.0-2.0 (optional) |
max_tokens |
number | Maximum response length (optional) |
stream |
boolean | Enable SSE streaming (optional) |
Response:
{
"id": "chatcmpl-abc123...",
"object": "chat.completion",
"created": 1702310400,
"model": "claude-opus-4-5",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "The capital of France is Paris."
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 10,
"total_tokens": 34
}
}# List models
curl -X GET http://localhost:3721/v1/models \
-H "Authorization: Bearer chimera-key-123"
# Chat completion
curl -X POST http://localhost:3721/v1/chat/completions \
-H "Authorization: Bearer chimera-key-123" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-5",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 100
}'
# Streaming
curl -X POST http://localhost:3721/v1/chat/completions \
-H "Authorization: Bearer chimera-key-123" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "Tell me a story"}],
"stream": true
}'from openai import OpenAI
client = OpenAI(
base_url="http://localhost:3721/v1",
api_key="chimera-key-123"
)
# Non-streaming
response = client.chat.completions.create(
model="claude-opus-4-5",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is 2+2?"}
],
max_tokens=500
)
print(response.choices[0].message.content)
# Streaming
stream = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Write a poem"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'http://localhost:3721/v1',
apiKey: 'chimera-key-123',
});
const response = await client.chat.completions.create({
model: 'claude-opus-4-5',
messages: [{ role: 'user', content: 'Hello!' }],
});
console.log(response.choices[0].message.content);┌─────────────────────────────────────────────────────────────┐
│ Client Application │
│ (Any OpenAI-compatible client) │
└─────────────────────────┬───────────────────────────────────┘
│ HTTP Request (OpenAI format)
▼
┌─────────────────────────────────────────────────────────────┐
│ ChimeraGate │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Hono Server │ │
│ ├───────────────────────────────────────────────────────┤ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │ │
│ │ │ Auth │ │ Routes │ │ Converters │ │ │
│ │ │ Middleware │──│ /v1/* │──│ OpenAI↔Claude│ │ │
│ │ └─────────────┘ └─────────────┘ └──────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Claude Agent SDK │ │ │
│ │ │ Service │ │ │
│ │ └─────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Claude Agent SDK │
│ (Anthropic API) │
└─────────────────────────────────────────────────────────────┘
ChimeraGate/
├── src/
│ ├── index.ts # Application entry point
│ ├── config.ts # Configuration & model mappings
│ ├── types/
│ │ └── openai.ts # OpenAI-compatible type definitions
│ ├── middleware/
│ │ └── auth.ts # Bearer token authentication
│ ├── routes/
│ │ ├── models.ts # GET /v1/models
│ │ ├── chat.ts # POST /v1/chat/completions
│ │ └── completions.ts # POST /v1/completions
│ ├── services/
│ │ └── claudeAgent.ts # Claude Agent SDK wrapper
│ └── converters/
│ └── index.ts # Format conversion utilities
├── package.json
├── tsconfig.json
├── .env
└── .gitignore
All errors follow OpenAI's error response format:
{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}| Error Type | Description |
|---|---|
authentication_error |
Invalid or missing API key |
invalid_request_error |
Malformed request, missing fields, invalid model |
api_error |
Internal server errors |
- Runtime: Node.js (ES modules)
- Framework: Hono - Lightweight, fast web framework
- Language: TypeScript 5.7
- Claude SDK: @anthropic-ai/claude-code
- Function calling / Tool use support
- Vision API support (image inputs)
- Conversation history persistence
- Rate limiting and metrics
- Response caching layer
- Docker deployment
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project's source code is licensed under the MIT License - see the LICENSE file for details.
Note: This project depends on @anthropic-ai/claude-code, which is proprietary software owned by Anthropic PBC. Use of Claude Code is subject to Anthropic's Commercial Terms of Service.
- Anthropic for Claude and the Agent SDK
- Hono for the excellent web framework
- The OpenAI community for the API specification
ChimeraGate - Bridging the gap between OpenAI compatibility and Claude's capabilities.
