OpenAI-Compatible MCP Gateway
README.md
# OpenAI-Compatible MCP Gateway
Local Python MCP server that exposes fixed MCP tools for `gpt`, `claude`, and `gemini`, while still calling any OpenAI-style `chat/completions` backend underneath.
That means each target can be configured independently:
- its own API base URL
- its own API key or API key env var
- its own default model
- its own headers, query params, and endpoint paths
So if you want:
- `gpt` -> OpenAI directly
- `claude` -> OpenRouter
- `gemini` -> Electron Hub
you can do that cleanly with one section per target.
## Tools
The server exposes:
- `provider_status`
- `list_gpt_models`
- `list_claude_models`
- `list_gemini_models`
- `chat_gpt`
- `chat_claude`
- `chat_gemini`
- `simple_gpt_chat`
- `simple_claude_chat`
- `simple_gemini_chat`
## Configuration
By default the server reads `config/providers.toml`.
The repository only includes a safe example file at `config/providers.example.toml`.
Create your local `config/providers.toml` from that example and keep your real keys there.
Override the config path with:
```powershell
$env:OPENAI_COMPAT_MCP_CONFIG="C:\path\to\providers.toml"
```
The file is intentionally fixed-shape. No arbitrary provider registry.
```toml
[server]
name = "OpenAI-Compatible MCP Gateway"
timeout_seconds = 60
[gpt]
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
model = "gpt-4.1-mini"
[claude]
base_url = "https://api.anthropic.com/v1/openai"
api_key_env = "ANTHROPIC_API_KEY"
model = "claude-sonnet-4-5"
[gemini]
base_url = "https://generativelanguage.googleapis.com/v1beta/openai"
api_key_env = "GEMINI_API_KEY"
model = "gemini-2.5-flash"
```
Bootstrap your local config with:
```powershell
Copy-Item config\\providers.example.toml config\\providers.toml
```
Each of `gpt`, `claude`, and `gemini` supports:
- `base_url`
- `model`
- `api_key_env`
- `api_key`
- `chat_completions_path`
- `models_path`
- `api_key_header`
- `api_key_prefix`
- `api_key_query_name`
- `headers`
- `query`
- `default_body`
- `timeout_seconds`
- `enabled`
## Example alternate routing
If you want all three targets to go through OpenRouter or another OpenAI-compatible hub, keep the sections separate and just point them to different models:
```toml
[gpt]
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
model = "openai/gpt-4.1-mini"
headers = { "HTTP-Referer" = "https://example.com", "X-Title" = "Local MCP Gateway" }
[claude]
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
model = "anthropic/claude-sonnet-4"
headers = { "HTTP-Referer" = "https://example.com", "X-Title" = "Local MCP Gateway" }
[gemini]
base_url = "https://openrouter.ai/api/v1"
api_key_env = "OPENROUTER_API_KEY"
model = "google/gemini-2.5-flash"
headers = { "HTTP-Referer" = "https://example.com", "X-Title" = "Local MCP Gateway" }
```
## Install
```powershell
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e .[dev]
```
## Run
For stdio MCP:
```powershell
openai-compat-mcp
```
For streamable HTTP:
```powershell
$env:OPENAI_COMPAT_MCP_TRANSPORT="streamable-http"
openai-compat-mcp
```
## Optional Remote Bearer Auth
If you expose the server over HTTP, you can require an app-level bearer token.
Set:
```powershell
$env:OPENAI_COMPAT_MCP_BEARER_TOKEN="replace-this-with-a-long-random-token"
```
Optional but recommended for remote/public-facing setups:
```powershell
$env:OPENAI_COMPAT_MCP_PUBLIC_BASE_URL="https://your-domain.example.com"
```
Behavior:
- `stdio` mode is unaffected
- HTTP MCP requests must send `Authorization: Bearer <your-token>`
- `provider_status` reports whether remote bearer auth is enabled
## Example MCP client config
```json
{
"mcpServers": {
"openai-compat-gateway": {
"command": "C:\\Users\\anuji\\Documents\\codex\\.venv\\Scripts\\openai-compat-mcp.exe",
"env": {
"OPENAI_COMPAT_MCP_CONFIG": "C:\\Users\\anuji\\Documents\\codex\\config\\providers.toml",
"OPENAI_API_KEY": "sk-...",
"ANTHROPIC_API_KEY": "sk-ant-...",
"GEMINI_API_KEY": "..."
}
}
}
}
```
## Notes
- The gateway uses direct HTTP requests, not vendor SDKs.
- Requests are non-streaming `chat/completions`.
- `list_*_models` depends on the configured backend exposing `GET /models`.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues