Skip to main content
Glama
baoduy

drunk-mcp-proxy

by baoduy

drunk-mcp-proxy

Quality gate

Docs

A powerful, production-ready dynamic proxy server for the Model Context Protocol (MCP) and LLM APIs, built with Python and FastMCP. This service enables MCP clients and LLM-compatible applications to seamlessly connect to multiple backend MCP servers and LLM providers through a unified, scalable interface with advanced features including authentication, CORS support, and environment-based configuration.

diagram

Related MCP server: mcphub

๐ŸŽฏ Overview

drunk-mcp-proxy acts as a central gateway for both Model Context Protocol (MCP) services and LLM providers, providing:

  • Unified Interface: Single endpoint for multiple backend MCP servers and LLM providers

  • Dynamic Routing: Automatic routing to configured backend services

  • Namespace Isolation: Prevent tool name conflicts with per-server namespaces

  • OpenAPI Integration: Automatic conversion of OpenAPI specs to MCP tools

  • LLM Proxy: Multi-provider LLM API gateway with OpenAI-compatible endpoints

  • Anthropic Compatibility: Proxy Anthropic Messages API requests through OpenAI-compatible backends

  • WebSocket Responses API: Native WebSocket support for OpenAI Responses API streaming

  • Enterprise Authentication: 14+ pluggable auth providers (JWT, OAuth, GitHub, Azure, etc.)

  • Production Ready: Health checks, CORS, structured logging, Docker support

โœจ Key Features

  • ๐Ÿš€ Dynamic Proxy Management: Configure multiple MCP and OpenAPI services via YAML

  • ๐Ÿค– LLM Gateway: Route requests to multiple LLM providers (OpenAI, Ollama, LM Studio, etc.)

  • ๐Ÿ”„ Anthropic API Compatibility: Use Anthropic/Claude clients with any OpenAI-compatible backend

  • ๐Ÿ”Œ WebSocket Responses API: Full WebSocket support for OpenAI Responses API

  • ๐Ÿณ Docker Support: Multi-stage production Docker image with health checks

  • ๐Ÿ” Enterprise Auth: JWT, GitHub, Google, Discord, Azure OAuth, and custom auth providers

  • ๐ŸŒ CORS Ready: Full CORS middleware for web client integration

  • ๐ŸŽจ OpenAPI Support: Convert OpenAPI specs to MCP tools automatically

  • ๐Ÿ” Health Monitoring: Built-in health check endpoint

  • ๐Ÿ“Š Structured Logging: Configurable log levels

  • ๐Ÿ›ก๏ธ JSON Schema Validation: Automatic config validation

๐Ÿš€ Quick Start

Get up and running with drunk-mcp-proxy using the pre-built Docker image from Docker Hub.

Step 1: Prepare Configuration Files

Create a data/ directory with the required configuration files:

mkdir -p data/mcp data/openapi data/skills

data/config.yaml - Unified Configuration

Define authentication, LLM providers, and MCP/OpenAPI services in a single file:

# Authentication configuration (optional)
auth:
  defaultProvider: basic
  basic:
    base_url: null
    token: $API_KEY
  jwt:
    base_url: null
    jwks_uri: "https://login.microsoftonline.com/common/discovery/keys"
    issuer: "https://sts.windows.net/$AZURE_TENANT_ID/"
    audience: "api://your-client-id"

# LLM provider configuration (optional)
llm:
  - enabled: true
    websocket: true
    provider: openai
    base_url: "https://api.openai.com/v1"
    api_key: $OPENAI_API_KEY

# MCP and OpenAPI service configuration
mcp:
  - path: /
    spec_type: mcp
    skill_dir: skills
    mcp_servers:
      my-server:
        enabled: true
        command: npx
        args: ["@playwright/mcp@0.0.64"]
        transport: stdio

  - path: /api
    spec_file: openapi/petstore.yaml
    spec_type: openapi
    base_url: "https://api.example.com"

Note:

  • Bearer auth (defaultProvider: "bearer") is the simplest option for API key authentication, commonly used by API proxies and gateways.

  • Environment variables like $API_KEY or $AZURE_CLIENT_ID are automatically resolved when the config is loaded.

See the samples in the repository for more configuration examples.

Step 2: Prepare Docker Compose

Create a docker-compose.yml file:

services:
  mcp-proxy:
    image: baoduy2412/mcp-proxy:latest
    container_name: mcp-proxy-server
    ports:
      - "${FASTMCP_PORT:-9123}:${FASTMCP_PORT:-9123}"
    volumes:
      - ./data:/drunk-proxy/data
    env_file:
      - .env
    environment:
      - FASTMCP_HOST=0.0.0.0
      - FASTMCP_PORT=${FASTMCP_PORT:-9123}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9123/health"]
      interval: 30s
      timeout: 10s
      retries: 3

Note: The ./data directory is mounted to /drunk-proxy/data in the container. All configuration files should be placed in this directory.

Step 3: Configure Environment & Run

Create a .env file from the sample:

cp .env.sample .env

Edit .env with your settings. Key environment variables:

# Server Configuration
FASTMCP_PORT=9123
FASTMCP_LOG_LEVEL=INFO
FASTMCP_AUTH_ENABLED=false

# Bearer Authentication (API Key)
API_KEY=your-api-key-here

# OAuth Storage (required if using OAuth)
FASTMCP_OAUTH_STORAGE_ENCRYPTION_KEY=your-44-character-encryption-key

# Azure Authentication (if using Azure OAuth)
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
AZURE_TENANT_ID=your-tenant-id

Tip: See .env.sample for the complete list of available environment variables.

Now start the server:

docker-compose up -d

Verify it's running:

curl http://localhost:9123/health

Additional Services (Optional)

The full docker-compose.yml in the repository includes optional services:

  • MCP Inspector - Debug and inspect MCP servers

  • OpenWebUI - Web interface for LLM interactions


๐Ÿ› ๏ธ Local Development

Using Docker (Build from Source)

git clone https://github.com/baoduy/drunk-mcp-proxy.git
cd drunk-mcp-proxy

docker build -t drunk-mcp-proxy .
docker run -d -p 9123:9123 -v $(pwd)/data:/drunk-proxy/data drunk-mcp-proxy

Running Locally

# Setup environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e ".[dev]"

# Run the server
python src/main.py

The server will start on http://0.0.0.0:9123 by default.

๐Ÿ“– Configuration

Configuration Directory Structure

data/
โ”œโ”€โ”€ config.yaml       # Unified configuration (auth, LLM, and MCP/OpenAPI services)
โ”œโ”€โ”€ mcp/              # MCP server specifications (optional, for external spec files)
โ”‚   โ”œโ”€โ”€ stock.mcp.json
โ”‚   โ””โ”€โ”€ wiki.mcp.json
โ”œโ”€โ”€ openapi/          # OpenAPI specifications
โ”‚   โ””โ”€โ”€ petstore.yaml
โ””โ”€โ”€ skills/           # Skill directories (optional)

Configuration (config.yaml)

The proxy uses a unified YAML configuration file to define authentication, LLM providers, and MCP/OpenAPI services:

# Authentication configuration
auth:
  defaultProvider: basic
  basic:
    token: $API_KEY

# MCP service configuration
mcp:
  - path: /stock
    spec_file: mcp/stock.mcp.json
    spec_type: mcp

  - path: /api
    spec_file: openapi/petstore.yaml
    spec_type: openapi
    base_url: "https://api.example.com"
    filters:
      methods: ["GET", "POST"]
      tags: ["public"]

Environment Variables

Key environment variables (see .env.sample for complete list):

Variable

Description

Default

FASTMCP_PORT

Server port

9123

FASTMCP_HOST

Server host

0.0.0.0

FASTMCP_LOG_LEVEL

Log level (DEBUG, INFO, WARNING, ERROR)

INFO

FASTMCP_AUTH_ENABLED

Enable authentication

false

FASTMCP_CONFIG_DIR

Configuration directory

data

FASTMCP_CORS_ALLOW_ORIGINS

CORS allowed origins

*

API_KEY

API key for bearer authentication

-

FASTMCP_OAUTH_STORAGE_ENCRYPTION_KEY

Fernet key for OAuth token encryption

-

See Environment Variables for complete list.

๐Ÿ“š Documentation

For comprehensive documentation, see the Documentation Index.

๐Ÿ—๏ธ Architecture Overview

MCP Client / LLM Client / Anthropic Client
        โ†“ (HTTP/SSE/WebSocket + Authorization)
        โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  drunk-mcp-proxy Server                      โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚ โ”‚ Starlette ASGI Application             โ”‚  โ”‚
โ”‚ โ”‚ โ€ข CORS Middleware                      โ”‚  โ”‚
โ”‚ โ”‚ โ€ข Auth Validation                      โ”‚  โ”‚
โ”‚ โ”‚ โ€ข Rate Limiting                        โ”‚  โ”‚
โ”‚ โ”‚ โ€ข Health Check: /health                โ”‚  โ”‚
โ”‚ โ”‚ โ€ข Root FastMCP Server (/)              โ”‚  โ”‚
โ”‚ โ”‚ โ€ข MCP Sub-services:                    โ”‚  โ”‚
โ”‚ โ”‚   - /stock (MCP)                       โ”‚  โ”‚
โ”‚ โ”‚   - /wiki (MCP)                        โ”‚  โ”‚
โ”‚ โ”‚   - /api (OpenAPI)                     โ”‚  โ”‚
โ”‚ โ”‚ โ€ข LLM Proxy (/api/v1):                โ”‚  โ”‚
โ”‚ โ”‚   - POST /chat/completions             โ”‚  โ”‚
โ”‚ โ”‚   - POST /messages (Anthropic API)     โ”‚  โ”‚
โ”‚ โ”‚   - WS   /responses (WebSocket)        โ”‚  โ”‚
โ”‚ โ”‚   - POST /embeddings                   โ”‚  โ”‚
โ”‚ โ”‚   - POST /images/generations           โ”‚  โ”‚
โ”‚ โ”‚   - POST /audio/transcriptions         โ”‚  โ”‚
โ”‚ โ”‚   - POST /audio/translations           โ”‚  โ”‚
โ”‚ โ”‚   - GET  /models                       โ”‚  โ”‚
โ”‚ โ”‚   - GET  /providers                    โ”‚  โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ†“ โ†“ โ†“
   [Backend MCP/OpenAPI/LLM Services]

See System Architecture for detailed diagrams.

๐Ÿ” Authentication

drunk-mcp-proxy supports 14+ authentication providers:

  • Token-based: Bearer (API Keys), JWT

  • OAuth 2.0: Azure AD, GitHub, Google, Discord, Auth0

  • Enterprise: WorkOS, Scalekit, Descope

  • Custom: Pass-through, Introspection

Bearer Authentication (API Key)

The simplest option for API key authentication, commonly used by API proxies and gateways:

auth:
  defaultProvider: basic
  basic:
    token: $API_KEY

Set the API_KEY environment variable in your .env file.

OAuth 2.0 Authentication (Azure AD Example)

auth:
  defaultProvider: azure
  azure:
    client_id: $AZURE_CLIENT_ID
    client_secret: $AZURE_CLIENT_SECRET
    tenant_id: $AZURE_TENANT_ID

See Authentication Guide for details.

๐Ÿงช Testing

# Run all tests
python -m pytest

# Run specific test file
python -m pytest tests/test_server.py

# Run with coverage
python -m pytest --cov=src --cov-report=html

๐Ÿค– LLM Proxy

When LLM providers are configured, drunk-mcp-proxy exposes a full OpenAI-compatible LLM gateway at /api/v1. All endpoints use the model ID format provider_modelname (e.g., openai_gpt-4o, lms_llama3.2) to route requests to the appropriate backend.

LLM Provider Configuration

Add providers to the llm section of config.yaml:

llm:
  - enabled: true
    websocket: true       # Enable for providers that support native WebSocket Responses API
                          # When false, HTTP Responses API is used as fallback
    provider: openai      # Short provider name used as prefix in model IDs
    base_url: "https://api.openai.com/v1"
    api_key: $OPENAI_API_KEY

  - enabled: true
    websocket: false
    provider: lms         # LM Studio
    base_url: "http://host.docker.internal:1234/v1"

  - enabled: false
    provider: oll         # Ollama
    base_url: "http://host.docker.internal:11434/v1"

Model ID Format

All LLM endpoints expect the model ID to include a provider prefix separated by an underscore:

{provider}_{model_name}

Examples:

  • openai_gpt-4o โ†’ routes to the openai provider, model gpt-4o

  • lms_llama3.2 โ†’ routes to the lms (LM Studio) provider, model llama3.2

  • ort_claude-3-5-sonnet โ†’ routes to the ort (OpenRouter) provider, model claude-3-5-sonnet

Available Endpoints

All endpoints are mounted at /api/v1 (configurable via FASTMCP_LLM_ROUTE_PREFIX):

Method

Endpoint

Description

POST

/api/v1/chat/completions

OpenAI-compatible chat completions

POST

/api/v1/messages

Anthropic Messages API (see below)

WS

/api/v1/responses

OpenAI WebSocket Responses API

POST

/api/v1/embeddings

Text embeddings

POST

/api/v1/images/generations

Image generation

POST

/api/v1/audio/transcriptions

Audio transcription (Whisper)

POST

/api/v1/audio/translations

Audio translation

GET

/api/v1/models

List all available models across providers

GET

/api/v1/providers

List all configured providers

Chat Completions

Standard OpenAI-compatible chat completions:

curl -X POST http://localhost:9123/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "openai_gpt-4o",
    "messages": [{"role": "user", "content": "Hello!"}],
    "stream": false
  }'

Anthropic Messages API Compatibility

The /messages endpoint accepts Anthropic Messages API format and transparently converts to/from the OpenAI format, letting Anthropic/Claude clients use any OpenAI-compatible backend:

curl -X POST http://localhost:9123/api/v1/messages \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "lms_llama3.2",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 1024
  }'

Supported conversions:

  • System prompts (string and block array)

  • Multimodal content (text, base64 images, URL images)

  • Tool use and tool results

  • Streaming SSE events in Anthropic format

  • stop_sequences โ†’ stop, metadata.user_id โ†’ user, finish reason mapping

Use with Claude Code CLI

Point the Claude Code CLI at the proxy to use any backend model with the Anthropic-compatible endpoint:

export ANTHROPIC_BASE_URL=http://localhost:9123/api/v1
export ANTHROPIC_AUTH_TOKEN=YOUR_API_KEY_HERE
claude --model lms_llama3.2

WebSocket Responses API

The /responses WebSocket endpoint provides OpenAI Responses API streaming. Clients connect via WebSocket and exchange JSON messages using the OpenAI Responses API protocol.

Connection URL: ws://localhost:9123/api/v1/responses

Message flow:

  1. Client connects with Authorization: Bearer <token> header

  2. Client sends a response.create event with model: "provider_modelname"

  3. Proxy routes to the configured backend and streams response events back

  4. For providers with websocket: true, native WebSocket is used for lowest latency

  5. For other providers, the HTTP Responses API is used as fallback

const ws = new WebSocket("ws://localhost:9123/api/v1/responses", {
  headers: { "Authorization": "Bearer YOUR_API_KEY" }
});

ws.send(JSON.stringify({
  type: "response.create",
  response: {
    model: "openai_gpt-4o",
    instructions: "You are a helpful assistant.",
    input: [{ type: "message", role: "user", content: "Hello!" }]
  }
}));

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log(data.type, data);  // response.created, response.output_text.delta, response.done, etc.
};

Provider WebSocket support: Set websocket: true in the provider config for providers that natively support the /responses WebSocket endpoint (e.g., OpenAI). For all other providers, the HTTP Responses API is used as a fallback.

Note: The previous_response_id continuation feature is only supported for providers with native WebSocket (websocket: true). Using it with HTTP fallback providers returns an error.

List Models and Providers

# List all models across all configured providers
curl http://localhost:9123/api/v1/models \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by provider
curl "http://localhost:9123/api/v1/models?provider=openai" \
  -H "Authorization: Bearer YOUR_API_KEY"

# List configured providers
curl http://localhost:9123/api/v1/providers \
  -H "Authorization: Bearer YOUR_API_KEY"

๐Ÿค Contributing

Contributions are welcome! Please:

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-feature)

  3. Commit your changes (git commit -m 'Add amazing feature')

  4. Push to the branch (git push origin feature/amazing-feature)

  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ™ Acknowledgments

  • Built with FastMCP framework

  • Powered by Starlette ASGI framework

  • Authentication via FastMCP's pluggable auth system

๐Ÿ“ž Support


Note: For detailed technical documentation, API references, and advanced configuration, please refer to the comprehensive documentation.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Proxy that aggregates multiple MCP servers and presents them as a unified interface, allowing clients to access resources from multiple servers transparently.
    4
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    A unified hub for centrally managing and dynamically orchestrating multiple MCP servers/APIs into separate endpoints with flexible routing strategies.
    547 npm
    2,426
    Apache 2.0
  • A
    license
    B
    quality
    C
    maintenance
    A flexible proxy server that aggregates multiple backend MCP servers into a single interface using STDIO or SSE transports. It supports dynamic server management via an HTTP API and utilizes namespacing to prevent tool conflicts across connected services.
    3
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A universal MCP server that acts as a unified gateway for dynamically connecting and managing multiple MCP servers via a single HTTP endpoint.
    7 npm
    6
    MIT