Sign inSign up

baoduy2412/mcp-proxy

By baoduy2412

โ€ขUpdated 6 months ago

ReadMe

Image
0

4.1K

baoduy2412/mcp-proxy repository overview

โ 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/[email protected]"]
        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):

VariableDescriptionDefault
FASTMCP_PORTServer port9123
FASTMCP_HOSTServer host0.0.0.0
FASTMCP_LOG_LEVELLog level (DEBUG, INFO, WARNING, ERROR)INFO
FASTMCP_AUTH_ENABLEDEnable authenticationfalse
FASTMCP_CONFIG_DIRConfiguration directorydata
FASTMCP_CORS_ALLOW_ORIGINSCORS allowed origins*
API_KEYAPI key for bearer authentication-
FASTMCP_OAUTH_STORAGE_ENCRYPTION_KEYFernet 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):

MethodEndpointDescription
POST/api/v1/chat/completionsOpenAI-compatible chat completions
POST/api/v1/messagesAnthropic Messages API (see below)
WS/api/v1/responsesOpenAI WebSocket Responses API
POST/api/v1/embeddingsText embeddings
POST/api/v1/images/generationsImage generation
POST/api/v1/audio/transcriptionsAudio transcription (Whisper)
POST/api/v1/audio/translationsAudio translation
GET/api/v1/modelsList all available models across providers
GET/api/v1/providersList 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

โ ๐Ÿ“ž Support


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

Tag summary

Content type

Image

Digest

sha256:3c0530954โ€ฆ

Size

285.7 MB

Last updated

6 months ago

docker pull baoduy2412/mcp-proxy