Gateway
Centralized API gateway for Model Context Protocol (MCP) servers with auth, routing, and analytics
Installation
npx mcp-gatewayAsk AI about Gateway
Powered by Claude Β· Grounded in docs
I know everything about Gateway. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP Gateway
A centralized API gateway for Model Context Protocol (MCP) servers. MCP Gateway enables LLM clients to connect to multiple MCP servers through a single endpoint with unified authentication, session management, and rate limiting.
Features
- Namespace-based routing: Route requests to different MCP servers based on namespace
- API key authentication: Secure access with configurable API keys and namespace restrictions
- Tool filtering: Allow or deny specific tools per namespace
- Request logging: Track all MCP requests with DuckDB for analytics
- Analytics API: Query usage statistics, tool popularity, and time series data
- SSE streaming support: Full support for Server-Sent Events for streaming responses
Quick Start
Prerequisites
- Go 1.21 or later
- DuckDB (embedded, no separate installation required)
Installation
# Clone the repository
git clone https://github.com/sekoudoumbouya/mcp-gateway.git
cd mcp-gateway
# Install dependencies
go mod download
# Build the gateway
go build -o mcp-gateway ./cmd/gateway
Running the Gateway
# Start with default config
./mcp-gateway
# Start with custom config file
./mcp-gateway -config /path/to/config.yaml
The gateway will start on http://localhost:8080 by default.
Configuration
Create a config.yaml file:
server:
host: "0.0.0.0"
port: 8080
database:
path: "gateway.duckdb"
# Namespace to MCP server mappings
namespaces:
filesystem:
url: "http://localhost:3001/mcp"
description: "Filesystem operations"
# Optional: restrict which tools are allowed
allowed_tools:
- "read_file"
- "list_directory"
search:
url: "http://localhost:3002/mcp"
description: "Web search and browsing"
database:
url: "http://localhost:3003/mcp"
description: "Database operations"
# Authentication
auth:
enabled: true
api_keys:
"dev-key-12345":
user_id: "developer"
description: "Development key"
# Empty namespaces = access to all
"prod-key-67890":
user_id: "production"
namespaces:
- "filesystem"
- "database"
"search-only":
user_id: "search-user"
namespaces:
- "search"
# Rate limiting
rate_limit:
enabled: true
requests_per_minute: 100
burst_size: 10
Environment Variables
Override configuration with environment variables:
| Variable | Description |
|---|---|
GATEWAY_HOST | Server listen host |
GATEWAY_PORT | Server listen port |
GATEWAY_DB_PATH | DuckDB database path |
Environment variable expansion is also supported in config values:
database:
path: "${DATABASE_PATH}"
API Reference
Health Check
GET /health
Returns gateway health status.
Response:
{
"status": "healthy",
"time": "2024-01-15T10:30:00Z"
}
List Namespaces
GET /namespaces
Returns all configured namespaces.
Response:
{
"namespaces": [
{
"name": "filesystem",
"description": "Filesystem operations"
},
{
"name": "search",
"description": "Web search and browsing"
}
]
}
MCP Endpoint
POST /mcp/:namespace
Authorization: Bearer <api-key>
Content-Type: application/json
Forward JSON-RPC 2.0 requests to the specified namespace's MCP server.
Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [...]
}
}
For streaming responses, add Accept: text/event-stream header.
Analytics API
Get Usage Statistics
GET /analytics/usage?period=7d&group_by=user
Authorization: Bearer <api-key>
Parameters:
period: Time period (e.g.,7d,24h,1h,30m)group_by: Group byuser(default) ortool
Response:
{
"period": "168h0m0s",
"results": [
{
"user_id": "developer",
"namespace": "filesystem",
"request_count": 150,
"error_count": 2,
"avg_latency_ms": 45.5,
"total_request_bytes": 15000,
"total_response_bytes": 75000
}
]
}
Get User Statistics
GET /analytics/usage/:user_id?period=24h
Authorization: Bearer <api-key>
Returns detailed statistics for a specific user.
Get Tool Popularity
GET /analytics/tools?period=7d&limit=20
Authorization: Bearer <api-key>
Response:
{
"period": "168h0m0s",
"tools": [
{
"tool_name": "read_file",
"namespace": "filesystem",
"invocations": 500,
"unique_users": 10,
"avg_latency_ms": 25.3,
"error_rate": 0.02
}
]
}
Get Time Series Data
GET /analytics/timeseries?period=24h&bucket=1h
Authorization: Bearer <api-key>
Response:
{
"period": "24h0m0s",
"bucket": "1h0m0s",
"data": [
{
"timestamp": "2024-01-15T09:00:00Z",
"value": 45
},
{
"timestamp": "2024-01-15T10:00:00Z",
"value": 62
}
]
}
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LLM Clients β
β (Claude, GPT, etc. with MCP config) β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Gateway β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β β Auth β β Router β β Event Logger β β
β β Middleware β β (Namespace) β β (DuckDB) β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββββββββββ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β MCP Handler ββ
β β - HTTP/JSON-RPC proxy ββ
β β - SSE streaming support ββ
β β - Tool filtering ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββΌββββββββββββββββ
βΌ βΌ βΌ
ββββββββββββ ββββββββββββ ββββββββββββ
β MCP β β MCP β β MCP β
β Server 1 β β Server 2 β β Server N β
ββββββββββββ ββββββββββββ ββββββββββββ
Development
Running Tests
# Run all unit tests
go test ./...
# Run with verbose output
go test -v ./...
# Run integration tests
go test -tags=integration ./...
# Run with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
Project Structure
mcp-gateway/
βββ cmd/
β βββ gateway/
β βββ main.go # Application entry point
βββ internal/
β βββ config/
β β βββ config.go # Configuration loading and validation
β β βββ config_test.go
β βββ auth/
β β βββ apikey.go # API key authentication middleware
β β βββ apikey_test.go
β βββ gateway/
β β βββ router.go # Namespace routing
β β βββ router_test.go
β β βββ handler.go # MCP request handler
β β βββ handler_test.go
β βββ db/
β β βββ duckdb.go # Database layer
β β βββ events.go # Event logging
β β βββ db_test.go
β βββ analytics/
β β βββ queries.go # Analytics query service
β β βββ queries_test.go
β βββ api/
β βββ analytics.go # Analytics REST API
β βββ analytics_test.go
βββ testdata/ # Test fixtures
β βββ config_valid.yaml
β βββ config_minimal.yaml
β βββ config_invalid_*.yaml
βββ integration_test.go # Integration tests
βββ config.yaml # Default configuration
βββ go.mod
βββ README.md
Error Codes
The gateway uses JSON-RPC 2.0 error codes:
| Code | Message |
|---|---|
| -32700 | Parse error - Invalid JSON |
| -32600 | Invalid Request - Missing authorization, access denied |
| -32601 | Method not found |
| -32603 | Internal error - Failed to connect to MCP server |
License
MIT License
