MCP Gateway

by IBM

ContextForge MCP Gateway 是一款功能丰富的网关和代理,能够联邦 MCP 和 REST 服务——统一发现、认证、速率限制、可观察性、虚拟服务器、多传输协议,以及可选的管理界面,集成在一个简洁的端点中,适用于您的 AI 客户端。它作为完全符合规范的 MCP 服务器运行,可通过 PyPI 或 Docker 部署,并能在 Kubernetes 上扩展到多集群环境,支持 Redis 支持的联邦和缓存。

Developer toolsstdioCommunity

Repository-wide counts · Cached 2026-03-07

Overview

The MCP Gateway MCP server is a publicly available project. Review the upstream repository for installation instructions, supported tools, compatibility, permissions, and current maintenance status.

Configuration

Configuration, transport, authentication, and runtime requirements vary by project. Open the repository before connecting and use the smallest set of credentials and permissions required.

Open the MCP Gateway repository to read the latest documentation.

KEEP EXPLORING

Compare source, connection, and authentication details before choosing an implementation.

View the complete category

模型上下文协议服务器

modelcontextprotocol

Community

一组用于模型上下文协议(MCP)的参考实现,展示了对大型语言模型(LLM)工具和数据源的安全且受控的访问方式。

Context7 Platform - Up-to-date Code Docs For Any Prompt

upstash

Community

Context7 MCP server providing up-to-date, version-specific documentation and code examples for libraries, enabling coding agents to fetch accurate docs and code snippets. Requires an API key for higher rate limits, passed via CONTEXT7_API_KEY header.

Playwright MCP

Microsoft Corporation

Community

A Model Context Protocol (MCP) server that provides browser automation capabilities using Playwright. Enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.

AIHawk

feder-cr

Community

AIHawk is an anti detect browser and web browsing agent, open source, with an MCP server for coding agents: undetected, no captchas, no blocks. It requires an OpenRouter API key for the standalone web UI mode, which can be provided via the --openrouter-key flag or the OPENROUTER_API_KEY environment variable or a .env file in the running directory.

FROM THE SOURCE

Repository README

Build-time snapshot · Retrieved 2026-10-05

View original

ContextForge

An open source registry and proxy that federates MCP, A2A, and REST/gRPC APIs with centralized governance, discovery, and observability. Optimizes Agent & Tool calling, and supports plugins.

ContextForge Banner

Build Python Package  Dependency Review  Tests & Coverage  Lint & Static Analysis

Async License  PyPI  Docker Image 

ContextForge is an open source registry and proxy that federates tools, agents, and APIs into one clean endpoint for your AI clients. It provides centralized governance, discovery, and observability across your AI infrastructure:

  • Tools Gateway — MCP, REST, gRPC-to-MCP translation, and TOON compression
  • Agent Gateway — A2A protocol, OpenAI-compatible and Anthropic agent routing
  • API Gateway — Rate limiting, auth, retries, and reverse proxy for REST services
  • Plugin Extensibility — 40+ plugins for additional transports, protocols, and integrations
  • Observability — OpenTelemetry tracing with Phoenix, Jaeger, Zipkin, and other OTLP backends

It runs as a fully compliant MCP server, deployable via PyPI or Docker, and scales to multi-cluster environments on Kubernetes with Redis-backed federation and caching.

ContextForge

Table of Contents


Resource Description
5-Minute Setup Get started fast — uvx, Docker, Compose, or local dev
Getting Help Support options, FAQ, community channels
Issue Guide How to file bugs, request features, contribute
Full Documentation Complete guides, tutorials, API reference
Deprecations Deprecated runtime paths and migration guidance

Overview & Goals

ContextForge is an open source registry and proxy that federates any Model Context Protocol (MCP) server, A2A server, or REST/gRPC API, providing centralized governance, discovery, and observability. It optimizes agent and tool calling, and supports plugins. See the project roadmap for more details.

It currently supports:

  • Federation across multiple MCP and REST services
  • A2A (Agent-to-Agent) integration for external AI agents (OpenAI, Anthropic, custom)
  • gRPC-to-MCP translation via automatic reflection-based service discovery
  • Virtualization of legacy APIs as MCP-compliant tools and servers
  • Transport over HTTP, JSON-RPC, WebSocket, SSE (with configurable keepalive), and Streamable HTTP; stdio transport available for server-side use
  • An Admin UI for real-time management, configuration, and log monitoring (with airgapped deployment support)
  • Built-in auth, retries, and rate-limiting with user-scoped OAuth tokens and unconditional X-Upstream-Authorization header support
  • OpenTelemetry observability with Phoenix, Jaeger, Zipkin, and other OTLP backends
  • Scalable deployments via Docker or PyPI, Redis-backed caching, and multi-cluster federation

ContextForge Architecture

For a list of upcoming features, check out the ContextForge Roadmap


🔌 Gateway Layer with Protocol Flexibility
  • Federates any MCP server or REST API
  • Lets you choose your MCP protocol version (e.g., 2025-11-25)
  • Exposes a single, unified interface for diverse backends
🧩 Virtualization of REST/gRPC Services
  • Wraps non-MCP services as virtual MCP servers
  • Registers tools, prompts, and resources with minimal configuration
  • gRPC-to-MCP translation via server reflection protocol
  • Automatic service discovery and method introspection
🔁 REST-to-MCP Tool Adapter
  • Adapts REST APIs into tools with:

    • Automatic JSON Schema extraction
    • Support for headers, tokens, and custom auth
    • Retry, timeout, and rate-limit policies
🧠 Unified Registries
  • Prompts: Jinja2 templates, multimodal support, rollback/versioning
  • Resources: URI-based access, MIME detection, caching, SSE updates
  • Tools: Native or adapted, with input validation and concurrency controls
📈 Admin UI, Observability & Dev Experience
  • Admin UI built with HTMX 2.0.3 (bundled) + Alpine.js
  • Real-time log viewer with filtering, search, and export capabilities
  • Auth: Basic, JWT, or custom schemes
  • Structured logs, health endpoints, metrics
  • 7,000+ tests, Makefile targets, live reload, pre-commit hooks
🔍 OpenTelemetry Observability
  • Vendor-agnostic tracing with OpenTelemetry (OTLP) protocol support
  • Multiple backend support: Phoenix (LLM-focused), Jaeger, Zipkin, Tempo, DataDog, New Relic
  • Distributed tracing across federated gateways and services
  • Automatic instrumentation of tools, prompts, resources, and gateway operations
  • LLM-specific metrics: Token usage, costs, model performance
  • Zero-overhead when disabled with graceful degradation

See Observability Documentation for setup guides with Phoenix, Jaeger, and other backends.


Quick Start - PyPI

ContextForge is published on PyPI as mcp-contextforge-gateway.


⚠️ JWT_SECRET_KEY and AUTH_ENCRYPTION_SECRET are required in every environment — including local development. The gateway will not start without them. Generate real secrets with python3 -m mcpgateway.scripts.init_secrets before first run.

TLDR — single command using uv:

# 1️⃣  Generate secure secrets (creates .env.secrets)
python3 -m mcpgateway.scripts.init_secrets

# 2️⃣  Export the generated values
export JWT_SECRET_KEY="$(grep '^JWT_SECRET_KEY=' .env.secrets | cut -d= -f2)"
export AUTH_ENCRYPTION_SECRET="$(grep '^AUTH_ENCRYPTION_SECRET=' .env.secrets | cut -d= -f2)"

# 3️⃣  Start the gateway
JWT_SECRET_KEY="$JWT_SECRET_KEY" \
AUTH_ENCRYPTION_SECRET="$AUTH_ENCRYPTION_SECRET" \
MCPGATEWAY_UI_ENABLED=true \
MCPGATEWAY_ADMIN_API_ENABLED=true \
[email protected] \
uvx --from mcp-contextforge-gateway mcpgateway --host 0.0.0.0 --port 4444
📋 Prerequisites
  • Python ≥ 3.11
  • curl + jq - only for the last smoke-test step

1 - Install & run (copy-paste friendly)

# 1️⃣  Create an isolated env and install from PyPI
mkdir mcpgateway && cd mcpgateway
python3 -m venv .venv && source .venv/bin/activate
pip install --upgrade pip
pip install mcp-contextforge-gateway

# 2️⃣  Download .env.example and generate real secrets
curl -O https://raw.githubusercontent.com/IBM/mcp-context-forge/main/.env.example
cp .env.example .env

# Generate cryptographically secure secrets into .env.secrets
python3 -m mcpgateway.scripts.init_secrets

# Patch the generated secrets into .env (replaces __REPLACE_ME__ placeholders)
python3 -m mcpgateway.scripts.init_secrets --patch-env .env

# 3️⃣  Start the gateway
mcpgateway --host 0.0.0.0 --port 4444 &

# 4️⃣  Generate a bearer token and smoke-test
export JWT_SECRET_KEY=$(grep '^JWT_SECRET_KEY=' .env | cut -d= -f2)
export MCPGATEWAY_BEARER_TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
    --username [email protected] --exp 10080 --secret "$JWT_SECRET_KEY")

curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     http://127.0.0.1:4444/version | jq
Windows (PowerShell) quick-start
# 1️⃣  Isolated env + install from PyPI
mkdir mcpgateway ; cd mcpgateway
python3 -m venv .venv ; .\.venv\Scripts\Activate.ps1
pip install --upgrade pip
pip install mcp-contextforge-gateway

# 2️⃣  Download .env.example and generate real secrets
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/IBM/mcp-context-forge/main/.env.example" -OutFile ".env.example"
Copy-Item .env.example .env

# Generate cryptographically secure secrets into .env.secrets
python3 -m mcpgateway.scripts.init_secrets

# Patch the generated secrets into .env (replaces __REPLACE_ME__ placeholders)
python3 -m mcpgateway.scripts.init_secrets --patch-env .env

# 3️⃣  Launch the gateway
mcpgateway.exe --host 0.0.0.0 --port 4444

# 4️⃣  Bearer token and smoke-test
$Env:JWT_SECRET_KEY = (Get-Content .env | Select-String '^JWT_SECRET_KEY=').ToString().Split('=')[1]
$Env:MCPGATEWAY_BEARER_TOKEN = python3 -m mcpgateway.utils.create_jwt_token `
    --username [email protected] --exp 10080 --secret $Env:JWT_SECRET_KEY

curl -s -H "Authorization: Bearer $Env:MCPGATEWAY_BEARER_TOKEN" `
     http://127.0.0.1:4444/version | jq
⚡ Alternative: uv (faster)
# 1️⃣  Isolated env + install from PyPI using uv
mkdir mcpgateway ; cd mcpgateway
uv venv
.\.venv\Scripts\activate
uv pip install mcp-contextforge-gateway

# Continue with steps 2️⃣-4️⃣ above...
More configuration

Copy .env.example to .env and tweak any of the settings (or use them as env variables).

🚀 End-to-end demo (register a local MCP server)
# 1️⃣  Spin up the sample MCP time server using mcpgateway.translate & docker (replace docker with podman if needed)
python3 -m mcpgateway.translate \
     --stdio "docker run --rm -i ghcr.io/ibm/fast-time-server:latest -transport=stdio" \
     --expose-sse \
     --port 8003

# Or using the official mcp-server-git using uvx:
pip install uv # to install uvx, if not already installed
python3 -m mcpgateway.translate --stdio "uvx mcp-server-git" --expose-sse --port 9000

# NEW: Expose via multiple protocols simultaneously!
python3 -m mcpgateway.translate \
     --stdio "uvx mcp-server-git" \
     --expose-sse \
     --expose-streamable-http \
     --port 9000
# Now accessible via both /sse (SSE) and /mcp (streamable HTTP) endpoints

# 2️⃣  Register it with the gateway
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"name":"fast_time","url":"http://localhost:8003/sse"}' \
     http://localhost:4444/gateways

# 3️⃣  Verify tool catalog
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" http://localhost:4444/tools | jq

# 4️⃣  Create a *virtual server* bundling those tools. Use the ID of tools from the tool catalog (Step #3) and pass them in the associatedTools list.
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"server":{"name":"time_server","description":"Fast time tools","associated_tools":[<ID_OF_TOOLS>]}}' \
     http://localhost:4444/servers | jq

# Example curl
curl -s -X POST -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"server":{"name":"time_server","description":"Fast time tools","associated_tools":["6018ca46d32a4ac6b4c054c13a1726a2"]}}' \
     http://localhost:4444/servers | jq

# 5️⃣  List servers (should now include the UUID of the newly created virtual server)
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" http://localhost:4444/servers | jq

# 6️⃣  Client HTTP endpoint. Inspect it interactively with the MCP Inspector CLI (or use any MCP client)
npx -y @modelcontextprotocol/inspector
# Transport Type: Streamable HTTP, URL: http://localhost:4444/servers/UUID_OF_SERVER_1/mcp,  Header Name: "Authorization", Bearer Token

Quick Start - Containers

Use the official OCI image from GHCR with Docker or Podman. Please note: Currently, arm64 is not supported on production. If you are e.g. running on MacOS with Apple Silicon chips (M1, M2, etc), you can run the containers using Rosetta or install via PyPi instead.

🚀 Quick Start - Docker Compose

Important: docker compose up -d does not build the gateway image locally by default — it uses the pre-built image from GHCR. The compose file includes a build: block as a fallback, but local builds require a hermetic wheel closure that is only produced by the CI pipeline. If you see a cryptography or dependency resolution error during build, you are hitting this — just pull the image instead (step 2 below handles this automatically).

You also must have a .env file with real secrets before running docker compose up -d. The gateway will not start with placeholder values.

Get a full stack running with PostgreSQL and Redis:

# 1️⃣  Clone the repository
git clone https://github.com/IBM/mcp-context-forge.git
cd mcp-context-forge

# 2️⃣  Set up .env with real secrets AND pull the pre-built images
cp .env.example .env
python3 -m mcpgateway.scripts.init_secrets --patch-env .env
# .env now has strong JWT_SECRET_KEY and AUTH_ENCRYPTION_SECRET

# Pull pre-built images from GHCR (avoids local build entirely)
docker pull ghcr.io/ibm/mcp-context-forge:latest
echo 'IMAGE_LOCAL=ghcr.io/ibm/mcp-context-forge:latest' >> .env

# Build only the nginx image (small, local-only, builds in seconds)
docker compose build nginx

# 3️⃣  Start the full stack
docker compose up -d

# 4️⃣  Check status
docker compose ps

# 5️⃣  View logs
docker compose logs -f gateway

# 6️⃣  Access Admin UI: http://localhost:8080/admin
#     Login: PLATFORM_ADMIN_EMAIL / PLATFORM_ADMIN_PASSWORD (from .env)

# 7️⃣  Generate an API token
export JWT_SECRET_KEY=$(grep '^JWT_SECRET_KEY=' .env | cut -d= -f2)
docker compose exec gateway python3 -m mcpgateway.utils.create_jwt_token \
  --username [email protected] --exp 10080 --secret "$JWT_SECRET_KEY"

What you get:

  • 🗄️ PostgreSQL - Production-ready database with 55+ tables
  • 🚀 ContextForge - Full-featured gateway with Admin UI
  • 📊 Redis - High-performance caching and session storage
  • 🔧 Admin Tools - pgAdmin, Redis Insight for database management
  • 🌐 Nginx Proxy - Caching reverse proxy on port 8080

Enable HTTPS (optional):

# Start with TLS enabled (auto-generates self-signed certs)
make compose-tls

# Access via HTTPS: https://localhost:8443/admin

# Or bring your own certificates:
# Unencrypted key:
mkdir -p certs
cp your-cert.pem certs/cert.pem && cp your-key.pem certs/key.pem
make compose-tls

# Passphrase-protected key:
mkdir -p certs
cp your-cert.pem certs/cert.pem && cp your-encrypted-key.pem certs/key-encrypted.pem
echo "KEY_FILE_PASSWORD=your-passphrase" >> .env
make compose-tls

☸️ Quick Start - Helm (Kubernetes)

Deploy to Kubernetes with enterprise-grade features:

# Add Helm repository (when available)
# helm repo add mcp-context-forge https://ibm.github.io/mcp-context-forge
# helm repo update

# For now, use local chart
git clone https://github.com/IBM/mcp-context-forge.git
cd mcp-context-forge/charts/mcp-stack

# Generate secrets first
python3 -m mcpgateway.scripts.init_secrets
JWT_SECRET=$(grep '^JWT_SECRET_KEY=' .env.secrets | cut -d= -f2)
ENC_SECRET=$(grep '^AUTH_ENCRYPTION_SECRET=' .env.secrets | cut -d= -f2)

# Install with PostgreSQL (default)
# IMPORTANT: replace <strong-password> with a real password — do not use 'changeme' in production
helm install mcp-gateway . \
  --set mcpContextForge.secret.PLATFORM_ADMIN_EMAIL=admin@yourcompany.com \
  --set mcpContextForge.secret.PLATFORM_ADMIN_PASSWORD=<strong-password> \
  --set mcpContextForge.secret.BASIC_AUTH_PASSWORD=<strong-password> \
  --set "mcpContextForge.secret.JWT_SECRET_KEY=${JWT_SECRET}" \
  --set "mcpContextForge.secret.AUTH_ENCRYPTION_SECRET=${ENC_SECRET}"

# Check deployment status
kubectl get pods -l app.kubernetes.io/name=mcp-context-forge

# Port forward to access Admin UI
kubectl port-forward svc/mcp-gateway-mcp-context-forge 4444:80
# Access: http://localhost:4444/admin

# Generate API token (reads JWT_SECRET_KEY from the pod's environment)
kubectl exec deployment/mcp-gateway-mcp-context-forge -- \
  python3 -m mcpgateway.utils.create_jwt_token \
  --username [email protected] --exp 10080 --secret "${JWT_SECRET}"

SSRF note: Helm defaults to strict SSRF settings (SSRF_ALLOW_PRIVATE_NETWORKS=false). If you register in-cluster tool URLs, allow only your cluster CIDRs via mcpContextForge.config.SSRF_ALLOWED_NETWORKS or, for local-only benchmark setups, temporarily set SSRF_ALLOW_PRIVATE_NETWORKS=true. See docs/docs/manage/configuration.md#ssrf-protection and docs/docs/deployment/helm.md.

Enterprise Features:

  • 🔄 Auto-scaling - HPA with CPU/memory targets
  • 🗄️ Database Choice - PostgreSQL (prod), SQLite (dev)
  • 📊 Observability - Prometheus metrics, OpenTelemetry tracing
  • 🔒 Security - RBAC, network policies, secret management
  • 🚀 High Availability - Multi-replica deployments with Redis clustering
  • 📈 Monitoring - Built-in Grafana dashboards and alerting

🐳 Docker (Single Container)

# Generate secrets first (creates .env.secrets)
python3 -m mcpgateway.scripts.init_secrets
export JWT_SECRET_KEY="$(grep '^JWT_SECRET_KEY=' .env.secrets | cut -d= -f2)"
export AUTH_ENCRYPTION_SECRET="$(grep '^AUTH_ENCRYPTION_SECRET=' .env.secrets | cut -d= -f2)"

docker run -d --name mcpgateway \
  -p 4444:4444 \
  -e MCPGATEWAY_UI_ENABLED=true \
  -e MCPGATEWAY_ADMIN_API_ENABLED=true \
  -e HOST=0.0.0.0 \
  -e JWT_SECRET_KEY="${JWT_SECRET_KEY}" \
  -e AUTH_ENCRYPTION_SECRET="${AUTH_ENCRYPTION_SECRET}" \
  -e AUTH_REQUIRED=true \
  -e [email protected] \
  -e PLATFORM_ADMIN_PASSWORD=<strong-password> \
  -e PLATFORM_ADMIN_FULL_NAME="Platform Administrator" \
  -e DATABASE_URL=sqlite:///./mcp.db \
  -e SECURE_COOKIES=false \
  ghcr.io/ibm/mcp-context-forge:latest

# Tail logs
docker logs -f mcpgateway

# Generate API token (using the same secret)
docker run --rm -it \
  -e JWT_SECRET_KEY="${JWT_SECRET_KEY}" \
  ghcr.io/ibm/mcp-context-forge:latest \
  python3 -m mcpgateway.utils.create_jwt_token \
  --username [email protected] --exp 10080 --secret "${JWT_SECRET_KEY}"

Browse to http://localhost:4444/admin and login with PLATFORM_ADMIN_EMAIL / PLATFORM_ADMIN_PASSWORD.

Advanced: Persistent storage, host networking, airgapped

Persist SQLite database:

mkdir -p $(pwd)/data && touch $(pwd)/data/mcp.db && chmod 777 $(pwd)/data
docker run -d --name mcpgateway --restart unless-stopped \
  -p 4444:4444 -v $(pwd)/data:/data \
  -e DATABASE_URL=sqlite:////data/mcp.db \
  -e MCPGATEWAY_UI_ENABLED=true -e MCPGATEWAY_ADMIN_API_ENABLED=true \
  -e HOST=0.0.0.0 -e JWT_SECRET_KEY="${JWT_SECRET_KEY}" \
  -e AUTH_ENCRYPTION_SECRET="${AUTH_ENCRYPTION_SECRET}" \
  -e [email protected] -e PLATFORM_ADMIN_PASSWORD=<strong-password> \
  ghcr.io/ibm/mcp-context-forge:latest

Host networking (access local MCP servers):

docker run -d --name mcpgateway --network=host \
  -v $(pwd)/data:/data -e DATABASE_URL=sqlite:////data/mcp.db \
  -e MCPGATEWAY_UI_ENABLED=true -e HOST=0.0.0.0 -e PORT=4444 \
  -e JWT_SECRET_KEY="${JWT_SECRET_KEY}" -e AUTH_ENCRYPTION_SECRET="${AUTH_ENCRYPTION_SECRET}" \
  ghcr.io/ibm/mcp-context-forge:latest

Airgapped deployment (no internet):

docker build -f Containerfile -t mcpgateway:airgapped .
docker run -d --name mcpgateway -p 4444:4444 \
  -e MCPGATEWAY_UI_AIRGAPPED=true -e MCPGATEWAY_UI_ENABLED=true \
  -e HOST=0.0.0.0 -e JWT_SECRET_KEY="${JWT_SECRET_KEY}" \
  -e AUTH_ENCRYPTION_SECRET="${AUTH_ENCRYPTION_SECRET}" \
  mcpgateway:airgapped

🦭 Podman (rootless-friendly)

podman run -d --name mcpgateway \
  -p 4444:4444 -e HOST=0.0.0.0 -e DATABASE_URL=sqlite:///./mcp.db \
  ghcr.io/ibm/mcp-context-forge:1.0.0-RC-3
Advanced: Persistent storage, host networking

Persist SQLite:

mkdir -p $(pwd)/data && chmod 777 $(pwd)/data
podman run -d --name mcpgateway --restart=on-failure \
  -p 4444:4444 -v $(pwd)/data:/data \
  -e DATABASE_URL=sqlite:////data/mcp.db \
  ghcr.io/ibm/mcp-context-forge:1.0.0-RC-3

Host networking:

podman run -d --name mcpgateway --network=host \
  -v $(pwd)/data:/data -e DATABASE_URL=sqlite:////data/mcp.db \
  ghcr.io/ibm/mcp-context-forge:1.0.0-RC-3

✏️ Docker/Podman tips
  • .env files - Put all the -e FOO= lines into a file and replace them with --env-file .env. See the provided .env.example for reference.

  • Pinned tags - Use an explicit version (e.g. 1.0.0-RC-3) instead of latest for reproducible builds.

  • JWT tokens - Generate one in the running container (reads the secret from the container environment):

    docker exec mcpgateway python3 -m mcpgateway.utils.create_jwt_token \
      --username [email protected] --exp 10080 --secret "${JWT_SECRET_KEY}"
    
  • Upgrades - Stop, remove, and rerun with the same -v $(pwd)/data:/data mount; your DB and config stay intact.


🚑 Smoke-test the running container
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     http://localhost:4444/health | jq
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     http://localhost:4444/tools | jq
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
     http://localhost:4444/version | jq

Quick Start: VS Code Dev Container

Clone the repo and open in VS Code—it will detect .devcontainer and prompt to "Reopen in Container". The container includes Python 3.11, Docker CLI, and all project dependencies.

For detailed setup, workflows, and GitHub Codespaces instructions, see Developer Onboarding.


Installation

make venv install-dev      # create .venv + install deps + build Admin UI
make serve                 # gunicorn on :4444

Rust workspace note:

  • Workspace-owned Rust crates live under crates/ and are picked up by the root Cargo.toml via crates/*.
  • Run cargo build, cargo test, and cargo check from the repo root to cover the shared workspace.
  • make venv install-dev creates the root .venv, which is also reused by the workspace's PyO3/maturin builds.
Alternative: UV or pip
# UV (faster)
uv venv && source .venv/bin/activate
uv pip install -e '.[dev]'

# pip
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
PostgreSQL adapter setup

Install the psycopg driver for PostgreSQL:

# Install system dependencies first
# Debian/Ubuntu: sudo apt-get install libpq-dev
# macOS: brew install libpq

uv pip install 'psycopg[binary]'   # dev (pre-built wheels)
# or: uv pip install 'psycopg[c]'  # production (requires compiler)

Connection URL format:

DATABASE_URL=postgresql+psycopg://user:password@localhost:5432/mcp

Quick Postgres container:

docker run --name mcp-postgres \
  -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=mysecretpassword \
  -e POSTGRES_DB=mcp -p 5432:5432 -d postgres

Upgrading

For upgrade instructions, migration guides, and rollback procedures, see:


Configuration

⚠️ If any required .env variable is missing or invalid, the gateway will fail fast at startup with a validation error via Pydantic.

Copy the provided .env.example to .env and update the security-sensitive values below.

🔐 Required: Set Before Starting

These variables must be set before the gateway will start. There are no usable defaults — the application fails at startup if these are missing or placeholder values:

Variable Description How to generate
JWT_SECRET_KEY HMAC secret for signing JWTs (32+ chars) python3 -m mcpgateway.scripts.init_secrets
AUTH_ENCRYPTION_SECRET Passphrase for encrypting stored credentials python3 -m mcpgateway.scripts.init_secrets

These variables have insecure defaults and should be changed before production use:

Variable Description Default
BASIC_AUTH_USER Username for HTTP Basic auth admin
BASIC_AUTH_PASSWORD Password for HTTP Basic auth required — no default; set via make init-secrets-patch-env
PLATFORM_ADMIN_EMAIL Email for bootstrap admin user [email protected]
PLATFORM_ADMIN_PASSWORD Password for bootstrap admin user required — set a strong value before first run
PLATFORM_ADMIN_FULL_NAME Display name for bootstrap admin Admin User

🔒 Security Defaults (Secure by Default)

These settings are enabled by default for security—only disable for backward compatibility:

Variable Description Default
REQUIRE_JTI Require JTI claim in tokens for revocation support true
REQUIRE_TOKEN_EXPIRATION Require exp claim in tokens true
PUBLIC_REGISTRATION_ENABLED Allow public user self-registration false

🛡️ Content Security

Content size limits prevent DoS attacks and ensure system stability:

Variable Description Default
CONTENT_MAX_RESOURCE_SIZE Maximum resource content size (bytes) 102400 (100KB)
CONTENT_MAX_PROMPT_SIZE Maximum prompt template size (bytes) 10240 (10KB)

Note: Size limits apply only to new create/update operations. Existing content is not retroactively validated.

🌐 UAID Cross-Gateway Routing Security

UAID Security Configuration

Production Requirements:

Cross-gateway UAID routing requires explicit security configuration:

  1. Configure Domain Allowlist:

    UAID_ALLOWED_DOMAINS=["gateway1.example.com", "gateway2.example.com"]
    
  2. Ensure JWT Trust:

    • Both gateways must trust the same JWT issuer
    • Option A: Shared secret (same JWT_SECRET_KEY on all gateways)
    • Option B: Federated SSO (Google, GitHub, Entra ID)
  3. Enable Authentication:

    AUTH_REQUIRED=true
    UAID_FORWARD_AUTH=true
    

Authentication Flow:

Cross-gateway calls forward the user's bearer token via the Authorization header. Remote gateways validate tokens through existing auth middleware, preserving RBAC context.

Security Features:

  • ✅ Fail-closed default: Empty allowlist blocks all cross-gateway routing
  • ✅ Bearer token forwarding: User authentication preserved across hops
  • ✅ Audit trail: Source gateway and user tracked in headers
  • ✅ Clear error messages: Misconfigurations caught at startup and runtime

Troubleshooting:

  • "UAID_ALLOWED_DOMAINS not configured" error: Add trusted domains to allowlist in .env
  • 401/403 from remote gateway: Verify both gateways trust same JWT issuer
  • "proceeding without authentication token" warning: Check auth middleware extracts token to request.state.bearer_token

For detailed security architecture, see docs/security/uaid-cross-gateway-auth.md.

⚙️ Project Defaults (Dev Setup)

These values differ from code defaults to provide a working local/dev setup:

Variable Description Default
HOST Bind address 0.0.0.0
MCPGATEWAY_UI_ENABLED Enable Admin UI dashboard true
MCPGATEWAY_ADMIN_API_ENABLED Enable Admin API endpoints true
DATABASE_URL SQLAlchemy connection URL sqlite:///./mcp.db
SECURE_COOKIES Set false for HTTP (non-HTTPS) dev false

📚 Full Configuration Reference

For the complete list of 300+ environment variables organized by category (authentication, caching, SSO, observability, etc.), see the Configuration Reference.


Running

Quick Reference

Command Server Port Database Use Case
make dev Uvicorn 8000 SQLite Development (single instance, auto-reload)
make serve Gunicorn 4444 SQLite Production single-node (multi-worker)
make serve-ssl Gunicorn 4444 SQLite Production single-node with HTTPS
make compose-up Docker Compose + Nginx 8080 PostgreSQL + Redis Full stack (3 replicas, load-balanced)
make compose-sso Docker Compose + Keycloak 8080 / 8180 PostgreSQL + Redis Local SSO testing (Keycloak profile)
make testing-up Docker Compose + Nginx 8080 PostgreSQL + Redis Testing environment

Development Server (Uvicorn)

make dev                 # Uvicorn on :8000 with auto-reload and SQLite
# or
./run.sh --reload --log debug --workers 2

run.sh is a wrapper around uvicorn that loads .env, supports reload, and passes arguments to the server.

Key flags:

Flag Purpose Example
-e, --env FILE load env-file --env prod.env
-H, --host bind address --host 127.0.0.1
-p, --port listen port --port 8080
-w, --workers gunicorn workers --workers 4
-r, --reload auto-reload --reload

Production Server (Gunicorn)

make serve               # Gunicorn on :4444 with multiple workers
make serve-ssl           # Gunicorn behind HTTPS on :4444 (uses ./certs)

Docker Compose (Full Stack)

make compose-up          # Start full stack: PostgreSQL, Redis, 3 gateway replicas, Nginx on :8080
make compose-sso         # Start SSO stack with Keycloak on :8180
make sso-test-login      # Run SSO smoke checks (providers + login URL + test users)
make compose-logs        # Tail logs from all services
make compose-down        # Stop the stack

Manual (Uvicorn)

uvicorn mcpgateway.main:app --host 0.0.0.0 --port 4444 --workers 4

Cloud Deployment

ContextForge can be deployed to any major cloud platform:

Platform Guide
AWS ECS/EKS Deployment
Azure AKS Deployment
Google Cloud Cloud Run
IBM Cloud Code Engine
Kubernetes Helm Charts
OpenShift OpenShift Deployment

For comprehensive deployment guides, see Deployment Documentation.


API Reference

Interactive API documentation is available when the server is running:

  • Swagger UI — Try API calls directly in your browser
  • ReDoc — Browse the complete endpoint reference

Quick Authentication:

# Read JWT_SECRET_KEY from your .env (it must already contain a real secret)
export JWT_SECRET_KEY=$(grep '^JWT_SECRET_KEY=' .env | cut -d= -f2)

# Generate a JWT token
export TOKEN=$(python3 -m mcpgateway.utils.create_jwt_token \
  --username [email protected] --exp 10080 --secret "$JWT_SECRET_KEY")

# Test API access
curl -H "Authorization: Bearer $TOKEN" http://localhost:4444/health

For comprehensive curl examples covering all endpoints, see the API Usage Guide.


Testing

make test            # Run unit tests
make lint            # Run all linters
make doctest         # Run doctests
make coverage        # Generate coverage report

See Doctest Coverage Guide for documentation testing details.


Project Structure

mcpgateway/          # Core FastAPI application
├── main.py          # Entry point
├── config.py        # Pydantic Settings configuration
├── db.py            # SQLAlchemy ORM models
├── schemas.py       # Pydantic validation schemas
├── services/        # Business logic layer (50+ services)
├── routers/         # HTTP endpoint definitions
├── middleware/      # Cross-cutting concerns
└── transports/      # SSE, WebSocket, stdio, streamable HTTP

tests/               # Test suite (7,000+ tests)
docs/docs/           # Full documentation (MkDocs)
charts/              # Kubernetes/Helm charts
plugins/             # Plugin framework and implementations

Security: Never run untrusted MCP servers directly on your local filesystem. Always use a sandbox, container, or microVM (e.g. gVisor, Firecracker) with restricted capabilities. Exercise caution when registering any remote MCP server, including servers from public catalogs — perform your own security evaluation before granting access to your gateway.

For complete structure, see CONTRIBUTING.md or run tree -L 2.


Development

make dev             # Dev server with auto-reload (:8000)
make test            # Run test suite
make lint            # Run all linters
make coverage        # Generate coverage report

Run make to see all available targets.

For development workflows, see:


Troubleshooting

Common issues and solutions:

Issue Quick Fix
docker compose up fails with cryptography or dependency resolution error The local build requires a CI-produced wheel closure. Run docker pull ghcr.io/ibm/mcp-context-forge:latest && echo 'IMAGE_LOCAL=ghcr.io/ibm/mcp-context-forge:latest' >> .env then retry
docker compose up fails with SecurityConfigurationError: jwt_secret_key .env is missing or has __REPLACE_ME__ placeholders. Run cp .env.example .env && python3 -m mcpgateway.scripts.init_secrets --patch-env .env
docker compose up fails — mcpgateway/nginx-cache pull access denied nginx image must be built locally: docker compose build nginx
make dev — nothing on port 8000 Check terminal for SecurityConfigurationError — run make ensure-secrets then retry. On WSL2 use http://127.0.0.1:8000 not localhost
SQLite "disk I/O error" on macOS Avoid iCloud-synced directories; use ~/mcp-context-forge/data
Port 4444 not accessible on WSL2 Configure WSL integration in Docker Desktop
Gateway exits immediately Run cp .env.example .env && python3 -m mcpgateway.scripts.init_secrets --patch-env .env
ModuleNotFoundError Run make install-dev

For detailed troubleshooting guides, see Troubleshooting Documentation.


Contributing

  1. Fork the repo, create a feature branch.
  2. Run make lint and fix any issues.
  3. Keep make test green.
  4. Open a PR with signed commits (git commit -s).

See CONTRIBUTING.md for full guidelines and Issue Guide #2502 for how to file bugs, request features, and find issues to work on.


Changelog

A complete changelog can be found here: CHANGELOG.md

License

Licensed under the Apache License 2.0 - see LICENSE

Core Authors and Maintainers

Special thanks to our contributors for helping us improve ContextForge:

Contributors to the mcp-context-forge repository

Star History and Project Activity

Star History Chart

PyPi Downloads  Stars  Forks  Contributors  Last Commit  Open Issues