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

๐ŸŽฏ 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.

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

โ€“Maintainers
โ€“Response time
1dRelease cycle
17Releases (12mo)

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/baoduy/drunk-mcp-proxy'

If you have feedback or need assistance with the MCP directory API, please join our Discord server