Skip to main content
Glama
Deathwalker-47

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`.