Skip to main content
Glama

secure-mcp-proxy

README.md9.33 kB
# secure-mcp-proxy ![GitHub License](https://img.shields.io/github/license/sparfenyuk/mcp-proxy) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mcp-proxy) A secure MCP (Model Context Protocol) proxy that enables switching between server transports with built-in API token authentication. > **Note:** This project is forked from [sparfenyuk/mcp-proxy](https://github.com/sparfenyuk/mcp-proxy) and enhanced with additional security features. - [secure-mcp-proxy](#secure-mcp-proxy) - [About](#about) - [Features](#features) - [Quick Start](#quick-start) - [Installation](#installation) - [Running the Proxy](#running-the-proxy) - [Configuration](#configuration) - [Authentication](#authentication) - [Docker Support](#docker-support) - [Command Line Reference](#command-line-reference) ## About The `mcp-proxy` is a tool that lets you switch between server transports. There are two supported modes: 1. stdio to SSE/StreamableHTTP 2. SSE to stdio ### 1. stdio to SSE/StreamableHTTP Run a proxy server from stdio that connects to a remote SSE server. This mode allows clients like Claude Desktop to communicate to a remote server over SSE even though it is not supported natively. ```mermaid graph LR A["Claude Desktop"] <--> |stdio| B["mcp-proxy"] B <--> |SSE| C["External MCP Server"] style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px ``` ### 2. SSE to stdio Run a proxy server exposing a SSE server that connects to a local stdio server. This allows remote connections to the local stdio server. The `mcp-proxy` opens a port to listen for SSE requests, spawns a local stdio server that handles MCP requests. ```mermaid graph LR A["LLM Client"] <-->|SSE| B["mcp-proxy"] B <-->|stdio| C["Local MCP Server"] style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px ``` ## Features - **Transport switching**: stdio ↔ SSE/StreamableHTTP - **API token authentication**: Secure your MCP servers with Bearer token auth - **CORS support**: Configure allowed origins for web clients - **Multiple servers**: Host multiple named MCP servers simultaneously - **Docker support**: Container-ready with Docker and Docker Compose - **Flexible configuration**: CLI arguments, environment variables, and JSON config files - **Developer friendly**: Built-in token generator and status endpoint ## Quick Start ```bash # CLI Mode (No Auth) uv run python -m secure_mcp_proxy --port 3000 uvx mcp-server-fetch # example # Named Server Mode export MCP_PROXY_API_TOKEN=your-secret-token uv run python -m secure_mcp_proxy --named-server-config servers.json --port 3000 --host 0.0.0.0 ``` ## Installation ### From Source ```bash # Clone the repository git clone https://github.com/your-username/secure-mcp-proxy cd secure-mcp-proxy # Install dependencies with uv (Python package manager) uv sync # Now you can run the proxy using: uv run python -m secure_mcp_proxy ``` ## Running the Proxy ### CLI Mode ```bash # Single server uv run python -m secure_mcp_proxy --port 3000 uvx mcp-server-fetch # Multiple servers uv run python -m secure_mcp_proxy --port 3000 \ --named-server fetch 'uvx mcp-server-fetch' \ --named-server github 'npx -y @modelcontextprotocol/server-github' # Custom host and port uv run python -m secure_mcp_proxy --host 0.0.0.0 --port 8080 uvx mcp-server-fetch # With environment variables and args uv run python -m secure_mcp_proxy --port 3000 -e API_KEY value -- uvx mcp-server-fetch --timeout 30 ``` ### Named Server Mode ```bash export MCP_PROXY_API_TOKEN=token uv run python -m secure_mcp_proxy --named-server-config servers.json --port 3000 --host 0.0.0.0 ``` ### Client Mode (Connect to Remote Server) ```bash # Connect to remote SSE server uv run python -m secure_mcp_proxy http://remote-server.com/sse # With authentication uv run python -m secure_mcp_proxy --headers Authorization 'Bearer remote-token' http://remote-server.com/sse # Using StreamableHTTP transport uv run python -m secure_mcp_proxy --transport streamablehttp http://remote-server.com/mcp ``` ## Configuration ### Environment Variables - `MCP_PROXY_API_TOKEN`: API token for authentication (optional) - `API_ACCESS_TOKEN`: Token for connecting to remote servers (client mode) ### Named Server Configuration File Create a `servers.json` file: ```json { "mcpServers": { "filesystem": { "enabled": true, "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/username/Downloads"], "auth": true, "env": { "CUSTOM_VAR": "value" } }, "fetch": { "enabled": true, "command": "uvx", "args": ["mcp-server-fetch"], "auth": false }, "time": { "enabled": true, "command": "uvx", "args": ["mcp-server-time"] // No "auth" field defaults to false }, "github": { "enabled": false, "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "auth": true, "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "your-github-token" } } } } ``` **Configuration fields:** - `enabled`: Whether to start this server (default: `true`) - `command`: Command to execute - `args`: Command arguments as array - `auth`: Whether authentication is required (default: `false`) - `env`: Environment variables for this server ## Authentication Authentication is controlled by the `MCP_PROXY_API_TOKEN` environment variable. When set, you can configure which servers require authentication on a per-server basis. ### Authentication Modes 1. **No authentication**: When `MCP_PROXY_API_TOKEN` is not set, all endpoints are public 2. **Selective authentication**: When `MCP_PROXY_API_TOKEN` is set, authentication is controlled per-server: - **CLI Mode**: Always public (no authentication required) - **Named Server Mode**: Follow the `auth` field setting (`true` = auth required, `false` or omitted = public) ### Setting Up Authentication ```bash # Option 1: Environment variable export MCP_PROXY_API_TOKEN=your-secret-token # Option 2: .env file echo 'MCP_PROXY_API_TOKEN="your-secret-token"' > .env # Option 3: Inline export MCP_PROXY_API_TOKEN=your-secret-token uv run python -m secure_mcp_proxy --named-server-config servers.json --port 3000 ``` ### Per-Server Authentication You can configure which servers require authentication using the `auth` field in your configuration file: ```json { "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], "auth": true // Requires authentication }, "fetch": { "command": "uvx", "args": ["mcp-server-fetch"], "auth": false // No authentication required }, "time": { "command": "uvx", "args": ["mcp-server-time"] // No "auth" field = defaults to false (no authentication) } } } ``` ### Generate Secure Tokens ```bash # Generate a production-ready token uv run python -m secure_mcp_proxy.token_generator --production # Generate multiple test tokens uv run python -m secure_mcp_proxy.token_generator ``` ## Docker Support ### Basic Docker Usage ```bash # Build custom image with uv cat > Dockerfile << 'EOF' FROM ghcr.io/sparfenyuk/mcp-proxy:latest RUN python3 -m ensurepip && pip install --no-cache-dir uv ENV PATH="/usr/local/bin:$PATH" UV_PYTHON_PREFERENCE=only-system ENTRYPOINT ["mcp-proxy"] EOF docker build -t secure-mcp-proxy . export MCP_PROXY_API_TOKEN=token docker run -e MCP_PROXY_API_TOKEN=$MCP_PROXY_API_TOKEN -p 3000:3000 secure-mcp-proxy \ --pass-environment --port=3000 --host=0.0.0.0 uvx mcp-server-fetch ``` ### Docker Compose ```yaml # docker-compose.yml services: secure-mcp-proxy: build: . ports: - "3000:3000" environment: - MCP_PROXY_API_TOKEN=your-secret-token volumes: - ./servers.json:/app/servers.json command: > --pass-environment --port=3000 --host=0.0.0.0 --named-server-config=/app/servers.json restart: unless-stopped ``` ## Command Line Reference ### Common Options | Option | Description | Example | |--------|-------------|---------| | `--port` | Server port | `--port 3000` | | `--host` | Server host | `--host 0.0.0.0` | | `--named-server-config` | Config file path | `--named-server-config servers.json` | | `--named-server` | Define named server | `--named-server fetch 'uvx mcp-server-fetch'` | | `--allow-origin` | CORS origins | `--allow-origin "*"` | | `--debug` | Enable debug logging | `--debug` | ## Troubleshooting ### Common Issues 1. **ENOENT error**: Use full path to binary in Claude Desktop config 2. **Port already in use**: Change port with `--port` option 3. **401/403 errors**: Check your `MCP_PROXY_API_TOKEN` environment variable 4. **Module not found**: Ensure you're in the correct directory and dependencies are installed ### Debug Mode ```bash # Enable detailed logging uv run python -m secure_mcp_proxy --debug --port 3000 uvx mcp-server-fetch ```

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/gws8820/secure-mcp-proxy'

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