MCP Gateway
Una puerta de enlace y proxy con múltiples funciones que federan servicios MCP y REST, unificando descubrimiento, autenticación, limitación de velocidad y observabilidad en un único endpoint para clientes de IA.
Documentación
ContextForge
Un registro y proxy de código abierto que federiza MCP, A2A y APIs REST/gRPC con gobernanza centralizada, descubrimiento y observabilidad. Optimiza las llamadas de Agentes y Herramientas, y soporta plugins.

ContextForge es un registro y proxy de código abierto que federiza herramientas, agentes y APIs en un único endpoint limpio para tus clientes de IA. Proporciona gobernanza centralizada, descubrimiento y observabilidad en toda tu infraestructura de IA:
- Puerta de enlace de Herramientas — MCP, REST, traducción gRPC-a-MCP y compresión TOON
- Puerta de enlace de Agentes — Protocolo A2A, enrutamiento de agentes compatible con OpenAI y Anthropic
- Puerta de enlace de API — Límite de velocidad, autenticación, reintentos y proxy inverso para servicios REST
- Extensibilidad mediante Plugins — Más de 40 plugins para transportes, protocolos e integraciones adicionales
- Observabilidad — Trazado OpenTelemetry con Phoenix, Jaeger, Zipkin y otros backends OTLP
Se ejecuta como un servidor MCP totalmente compatible, desplegable mediante PyPI o Docker, y se escala a entornos multi-clúster en Kubernetes con federación y caché respaldadas por Redis.
Tabla de Contenidos
- Descripción General y Objetivos
- Inicio Rápido - PyPI
- Inicio Rápido - Contenedores
- Contenedor de Desarrollo VS Code
- Instalación
- Actualización
- Configuración
- Ejecución
- Despliegue en la Nube
- Referencia de la API
- Pruebas
- Estructura del Proyecto
- Desarrollo
- Solución de Problemas
- Contribuciones
📌 Enlaces Rápidos
| Recurso | Descripción |
|---|---|
| Configuración en 5 Minutos | Comienza rápido — uvx, Docker, Compose o desarrollo local |
| Obtener Ayuda | Opciones de soporte, preguntas frecuentes, canales de la comunidad |
| Guía de Incidencias | Cómo reportar errores, solicitar funciones, contribuir |
| Documentación Completa | Guías completas, tutoriales, referencia de la API |
| Deprecaciones | Rutas de ejecución deprecadas y guía de migración |
Descripción General y Objetivos
ContextForge es un registro y proxy de código abierto que federiza cualquier servidor Model Context Protocol (MCP), servidor A2A o API REST/gRPC, proporcionando gobernanza centralizada, descubrimiento y observabilidad. Optimiza las llamadas de agentes y herramientas, y soporta plugins. Consulta la hoja de ruta del proyecto para más detalles.
Actualmente soporta:
- Federación entre múltiples servicios MCP y REST
- Integración A2A (Agente-a-Agente) para agentes de IA externos (OpenAI, Anthropic, personalizados)
- Traducción gRPC-a-MCP mediante descubrimiento automático de servicios basado en reflexión
- Virtualización de APIs heredadas como herramientas y servidores compatibles con MCP
- Transporte sobre HTTP, JSON-RPC, WebSocket, SSE (con keepalive configurable) y HTTP Streamable; transporte stdio disponible para uso del lado del servidor
- Una interfaz de administración para gestión en tiempo real, configuración y monitoreo de registros (con soporte de despliegue aislado)
- Autenticación integrada, reintentos y límite de velocidad con tokens OAuth por usuario y soporte incondicional del encabezado X-Upstream-Authorization
- Observabilidad OpenTelemetry con Phoenix, Jaeger, Zipkin y otros backends OTLP
- Despliegues escalables mediante Docker o PyPI, caché respaldada por Redis y federación multi-clúster
Para ver una lista de próximas funciones, consulta la Hoja de Ruta de ContextForge
🔌 Capa de Puerta de Enlace con Flexibilidad de Protocolo
- Federiza cualquier servidor MCP o API REST
- Te permite elegir tu versión del protocolo MCP (p. ej.,
2025-11-25) - Expone una interfaz única y unificada para diversos backends
🧩 Virtualización de Servicios REST/gRPC
- Envuelve servicios no-MCP como servidores MCP virtuales
- Registra herramientas, prompts y recursos con configuración mínima
- Traducción gRPC-a-MCP mediante protocolo de reflexión de servidor
- Descubrimiento automático de servicios e introspección de métodos
🔁 Adaptador de Herramientas REST-a-MCP
-
Adapta APIs REST en herramientas con:
- Extracción automática de JSON Schema
- Soporte para encabezados, tokens y autenticación personalizada
- Políticas de reintento, tiempo de espera y límite de velocidad
🧠 Registros Unificados
- Prompts: Plantillas Jinja2, soporte multimodal, reversión/versionado
- Recursos: Acceso basado en URI, detección MIME, caché, actualizaciones SSE
- Herramientas: Nativas o adaptadas, con validación de entrada y controles de concurrencia
📈 Interfaz de Administración, Observabilidad y Experiencia de Desarrollo
- Interfaz de administración construida con HTMX 2.0.3 (incluido) + Alpine.js
- Visor de registros en tiempo real con filtrado, búsqueda y capacidades de exportación
- Autenticación: Básica, JWT o esquemas personalizados
- Registros estructurados, endpoints de salud, métricas
- Más de 7,000 pruebas, objetivos Makefile, recarga en vivo, hooks de pre-commit
🔍 Observabilidad OpenTelemetry
- Trazado independiente del proveedor con soporte del protocolo OpenTelemetry (OTLP)
- Soporte de múltiples backends: Phoenix (enfocado en LLM), Jaeger, Zipkin, Tempo, DataDog, New Relic
- Trazado distribuido a través de puertas de enlace y servicios federados
- Instrumentación automática de herramientas, prompts, recursos y operaciones de la puerta de enlace
- Métricas específicas de LLM: Uso de tokens, costos, rendimiento del modelo
- Cero sobrecarga cuando está deshabilitado con degradación gradual
Consulta la Documentación de Observabilidad para guías de configuración con Phoenix, Jaeger y otros backends.
Inicio Rápido - PyPI
ContextForge está publicado en PyPI como mcp-contextforge-gateway.
⚠️
JWT_SECRET_KEYyAUTH_ENCRYPTION_SECRETson obligatorios en todos los entornos — incluido el desarrollo local. La puerta de enlace no se iniciará sin ellos. Genera secretos reales conpython3 -m mcpgateway.scripts.init_secretsantes de la primera ejecución.
Resumen — comando único usando 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 \
PLATFORM_ADMIN_EMAIL=admin@example.com \
uvx --from mcp-contextforge-gateway mcpgateway --host 0.0.0.0 --port 4444
📋 Requisitos Previos
- Python ≥ 3.11
- curl + jq - solo para el último paso de prueba de humo
1 - Instalar y ejecutar (fácil de copiar y pegar)
# 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 admin@example.com --exp 10080 --secret "$JWT_SECRET_KEY")
curl -s -H "Authorization: Bearer $MCPGATEWAY_BEARER_TOKEN" \
http://127.0.0.1:4444/version | jq
Windows (PowerShell) inicio rápido
# 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 admin@example.com --exp 10080 --secret $Env:JWT_SECRET_KEY
curl -s -H "Authorization: Bearer $Env:MCPGATEWAY_BEARER_TOKEN" `
http://127.0.0.1:4444/version | jq
⚡ Alternativa: uv (más rápido)
# 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...
Más configuración
Copia .env.example a .env y ajusta cualquiera de las configuraciones (o úsalas como variables de entorno).
🚀 Demostración de extremo a extremo (registrar un servidor MCP local)
# 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
Inicio Rápido - Contenedores
Usa la imagen OCI oficial de GHCR con Docker o Podman. Ten en cuenta: Actualmente, arm64 no es compatible en producción. Si estás, por ejemplo, ejecutando en MacOS con chips Apple Silicon (M1, M2, etc.), puedes ejecutar los contenedores usando Rosetta o instalar vía PyPi en su lugar.
🚀 Inicio Rápido - Docker Compose
Importante:
docker compose up -dno construye la imagen de la puerta de enlace localmente por defecto — usa la imagen preconstruida de GHCR. El archivo compose incluye un bloquebuild:como respaldo, pero las construcciones locales requieren un cierre hermético de wheels que solo produce el pipeline de CI. Si ves un error decryptographyo de resolución de dependencias durante la construcción, estás encontrando esto — simplemente extrae la imagen en su lugar (el paso 2 a continuación maneja esto automáticamente).También debes tener un archivo
.envcon secretos reales antes de ejecutardocker compose up -d. La puerta de enlace no se iniciará con valores de marcador de posición.
Obtén un stack completo con PostgreSQL y 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 admin@example.com --exp 10080 --secret "$JWT_SECRET_KEY"
Lo que obtienes:
- 🗄️ PostgreSQL - Base de datos lista para producción con más de 55 tablas
- 🚀 ContextForge - Puerta de enlace con todas las funciones e interfaz de administración
- 📊 Redis - Caché de alto rendimiento y almacenamiento de sesiones
- 🔧 Herramientas de Administración - pgAdmin, Redis Insight para gestión de bases de datos
- 🌐 Proxy Nginx - Proxy inverso con caché en el puerto 8080
Habilitar HTTPS (opcional):
# 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
☸️ Inicio Rápido - Helm (Kubernetes)
Despliega en Kubernetes con funciones de nivel empresarial:
# 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 admin@yourcompany.com --exp 10080 --secret "${JWT_SECRET}"
Nota SSRF: Helm usa por defecto configuraciones SSRF estrictas (
SSRF_ALLOW_PRIVATE_NETWORKS=false). Si registras URLs de herramientas dentro del clúster, permite solo los CIDRs de tu clúster mediantemcpContextForge.config.SSRF_ALLOWED_NETWORKSo, para configuraciones de referencia solo locales, establece temporalmenteSSRF_ALLOW_PRIVATE_NETWORKS=true. Consultadocs/docs/manage/configuration.md#ssrf-protectionydocs/docs/deployment/helm.md.
Funciones Empresariales:
- 🔄 Auto-escalado - HPA con objetivos de CPU/memoria
- 🗄️ Elección de Base de Datos - PostgreSQL (producción), SQLite (desarrollo)
- 📊 Observabilidad - Métricas Prometheus, trazado OpenTelemetry
- 🔒 Seguridad - RBAC, políticas de red, gestión de secretos
- 🚀 Alta Disponibilidad - Despliegues multi-réplica con agrupamiento Redis
- 📈 Monitoreo - Paneles Grafana integrados y alertas
🐳 Docker (Contenedor Único)
# 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 PLATFORM_ADMIN_EMAIL=admin@example.com \
-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 admin@example.com --exp 10080 --secret "${JWT_SECRET_KEY}"
Navega a http://localhost:4444/admin e inicia sesión con PLATFORM_ADMIN_EMAIL / PLATFORM_ADMIN_PASSWORD.
Avanzado: Almacenamiento persistente, red del host, aislado
Persistir base de datos SQLite:
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 PLATFORM_ADMIN_EMAIL=admin@example.com -e PLATFORM_ADMIN_PASSWORD=<strong-password> \
ghcr.io/ibm/mcp-context-forge:latest
Red del host (acceder a servidores MCP locales):
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
Despliegue aislado (sin 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 (compatible con rootless)
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
Avanzado: Almacenamiento persistente, red del host
Persistir 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
Red del host:
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
✏️ Consejos para Docker/Podman
-
Archivos .env - Pon todas las líneas
-e FOO=en un archivo y reemplázalas con--env-file .env. Consulta el .env.example proporcionado como referencia. -
Etiquetas fijadas - Usa una versión explícita (p. ej.
1.0.0-RC-3) en lugar delatestpara construcciones reproducibles. -
Tokens JWT - Genera uno en el contenedor en ejecución (lee el secreto del entorno del contenedor):
docker exec mcpgateway python3 -m mcpgateway.utils.create_jwt_token \ --username admin@example.com --exp 10080 --secret "${JWT_SECRET_KEY}" -
Actualizaciones - Detén, elimina y vuelve a ejecutar con el mismo montaje
-v $(pwd)/data:/data; tu base de datos y configuración permanecen intactas.
🚑 Prueba de humo del contenedor en ejecución
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
Inicio Rápido: Contenedor de Desarrollo VS Code
Clona el repositorio y ábrelo en VS Code—detectará .devcontainer y te pedirá "Reabrir en Contenedor". El contenedor incluye Python 3.11, Docker CLI y todas las dependencias del proyecto.
Para configuración detallada, flujos de trabajo e instrucciones de GitHub Codespaces, consulta Developer Onboarding.
Instalación
make venv install-dev # create .venv + install deps + build Admin UI
make serve # gunicorn on :4444
Nota sobre el workspace de Rust:
- Las crates de Rust propiedad del workspace se encuentran en
crates/y son detectadas por elCargo.tomlraíz mediantecrates/*. - Ejecuta
cargo build,cargo testycargo checkdesde la raíz del repositorio para cubrir el workspace compartido. make venv install-devcrea el.venvraíz, que también es reutilizado por las compilaciones PyO3/maturin del workspace.
Alternativa: UV o 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]"
Configuración del adaptador PostgreSQL
Instala el controlador psycopg para 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)
Formato de la URL de conexión:
DATABASE_URL=postgresql+psycopg://user:password@localhost:5432/mcp
Contenedor rápido de Postgres:
docker run --name mcp-postgres \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_DB=mcp -p 5432:5432 -d postgres
Actualización
Para instrucciones de actualización, guías de migración y procedimientos de reversión, consulta:
- Guía de actualización — Procedimientos generales de actualización
- MIGRATION.md — Cambios importantes e instrucciones de actualización paso a paso
- CHANGELOG.md — Historial de versiones y cambios importantes
Configuración
⚠️ Si falta alguna variable
.envrequerida o es inválida, la puerta de enlace fallará rápidamente al inicio con un error de validación mediante Pydantic.
Copia el .env.example proporcionado a .env y actualiza los valores sensibles de seguridad a continuación.
🔐 Requerido: Configurar antes de iniciar
Estas variables deben configurarse antes de que la puerta de enlace se inicie. No hay valores predeterminados utilizables: la aplicación falla al inicio si faltan o tienen valores de marcador de posición:
| Variable | Descripción | Cómo generar |
|---|---|---|
JWT_SECRET_KEY | Secreto HMAC para firmar JWT (32+ caracteres) | python3 -m mcpgateway.scripts.init_secrets |
AUTH_ENCRYPTION_SECRET | Frase de contraseña para cifrar credenciales almacenadas | python3 -m mcpgateway.scripts.init_secrets |
Estas variables tienen valores predeterminados inseguros y deben cambiarse antes del uso en producción:
| Variable | Descripción | Valor predeterminado |
|---|---|---|
BASIC_AUTH_USER | Nombre de usuario para autenticación HTTP Basic | admin |
BASIC_AUTH_PASSWORD | Contraseña para autenticación HTTP Basic | requerida — sin valor predeterminado; configurar mediante make init-secrets-patch-env |
PLATFORM_ADMIN_EMAIL | Correo electrónico para el usuario administrador de arranque | admin@example.com |
PLATFORM_ADMIN_PASSWORD | Contraseña para el usuario administrador de arranque | requerida — configurar un valor seguro antes de la primera ejecución |
PLATFORM_ADMIN_FULL_NAME | Nombre para mostrar del administrador de arranque | Admin User |
🔒 Valores predeterminados de seguridad (Seguro por defecto)
Estos ajustes están habilitados por defecto por seguridad; solo deshabilítalos por compatibilidad con versiones anteriores:
| Variable | Descripción | Valor predeterminado |
|---|---|---|
REQUIRE_JTI | Requerir la reclamación JTI en los tokens para soporte de revocación | true |
REQUIRE_TOKEN_EXPIRATION | Requerir la reclamación exp en los tokens | true |
PUBLIC_REGISTRATION_ENABLED | Permitir auto-registro público de usuarios | false |
🛡️ Seguridad de contenido
Los límites de tamaño de contenido previenen ataques DoS y aseguran la estabilidad del sistema:
| Variable | Descripción | Valor predeterminado |
|---|---|---|
CONTENT_MAX_RESOURCE_SIZE | Tamaño máximo de contenido de recursos (bytes) | 102400 (100KB) |
CONTENT_MAX_PROMPT_SIZE | Tamaño máximo de plantillas de prompt (bytes) | 10240 (10KB) |
Nota: Los límites de tamaño se aplican solo a operaciones nuevas de creación/actualización. El contenido existente no se valida retroactivamente.
🌐 Seguridad de enrutamiento entre puertas de enlace UAID
Configuración de seguridad UAID
Requisitos de producción:
El enrutamiento UAID entre puertas de enlace requiere configuración de seguridad explícita:
-
Configurar la lista de dominios permitidos:
UAID_ALLOWED_DOMAINS=["gateway1.example.com", "gateway2.example.com"] -
Asegurar la confianza JWT:
- Ambas puertas de enlace deben confiar en el mismo emisor JWT
- Opción A: Secreto compartido (mismo
JWT_SECRET_KEYen todas las puertas de enlace) - Opción B: SSO federado (Google, GitHub, Entra ID)
-
Habilitar la autenticación:
AUTH_REQUIRED=true UAID_FORWARD_AUTH=true
Flujo de autenticación:
Las llamadas entre puertas de enlace reenvían el token de portador del usuario mediante el encabezado Authorization.
Las puertas de enlace remotas validan los tokens a través del middleware de autenticación existente, preservando el contexto RBAC.
Características de seguridad:
- ✅ Valor predeterminado de cierre seguro: la lista de dominios permitidos vacía bloquea todo el enrutamiento entre puertas de enlace
- ✅ Reenvío de token de portador: la autenticación del usuario se preserva entre saltos
- ✅ Rastro de auditoría: la puerta de enlace de origen y el usuario se rastrean en los encabezados
- ✅ Mensajes de error claros: las configuraciones incorrectas se detectan al inicio y en tiempo de ejecución
Solución de problemas:
- Error "UAID_ALLOWED_DOMAINS not configured": Agrega dominios de confianza a la lista permitida en .env
- 401/403 de la puerta de enlace remota: Verifica que ambas puertas de enlace confíen en el mismo emisor JWT
- Advertencia "proceeding without authentication token": Verifica que el middleware de autenticación extraiga el token a
request.state.bearer_token
Para la arquitectura de seguridad detallada, consulta docs/security/uaid-cross-gateway-auth.md.
⚙️ Valores predeterminados del proyecto (Configuración de desarrollo)
Estos valores difieren de los valores predeterminados del código para proporcionar una configuración local/de desarrollo funcional:
| Variable | Descripción | Valor predeterminado |
|---|---|---|
HOST | Dirección de enlace | 0.0.0.0 |
MCPGATEWAY_UI_ENABLED | Habilitar el panel de la interfaz de administración | true |
MCPGATEWAY_ADMIN_API_ENABLED | Habilitar los endpoints de la API de administración | true |
DATABASE_URL | URL de conexión SQLAlchemy | sqlite:///./mcp.db |
SECURE_COOKIES | Configurar false para desarrollo HTTP (no HTTPS) | false |
📚 Referencia completa de configuración
Para la lista completa de más de 300 variables de entorno organizadas por categoría (autenticación, caché, SSO, observabilidad, etc.), consulta la Referencia de configuración.
Ejecución
Referencia rápida
| Comando | Servidor | Puerto | Base de datos | Caso de uso |
|---|---|---|---|---|
make dev | Uvicorn | 8000 | SQLite | Desarrollo (instancia única, recarga automática) |
make serve | Gunicorn | 4444 | SQLite | Nodo único de producción (multi-worker) |
make serve-ssl | Gunicorn | 4444 | SQLite | Nodo único de producción con HTTPS |
make compose-up | Docker Compose + Nginx | 8080 | PostgreSQL + Redis | Pila completa (3 réplicas, balanceo de carga) |
make compose-sso | Docker Compose + Keycloak | 8080 / 8180 | PostgreSQL + Redis | Pruebas SSO locales (perfil Keycloak) |
make testing-up | Docker Compose + Nginx | 8080 | PostgreSQL + Redis | Entorno de pruebas |
Servidor de desarrollo (Uvicorn)
make dev # Uvicorn on :8000 with auto-reload and SQLite
# or
./run.sh --reload --log debug --workers 2
run.shes un envoltorio alrededor deuvicornque carga.env, soporta recarga y pasa argumentos al servidor.
Banderas clave:
| Bandera | Propósito | Ejemplo |
|---|---|---|
-e, --env FILE | cargar archivo de entorno | --env prod.env |
-H, --host | dirección de enlace | --host 127.0.0.1 |
-p, --port | puerto de escucha | --port 8080 |
-w, --workers | workers de gunicorn | --workers 4 |
-r, --reload | recarga automática | --reload |
Servidor de producción (Gunicorn)
make serve # Gunicorn on :4444 with multiple workers
make serve-ssl # Gunicorn behind HTTPS on :4444 (uses ./certs)
Docker Compose (Pila completa)
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
Implementación en la nube
ContextForge se puede implementar en cualquier plataforma de nube importante:
| Plataforma | Guía |
|---|---|
| AWS | Implementación ECS/EKS |
| Azure | Implementación AKS |
| Google Cloud | Cloud Run |
| IBM Cloud | Code Engine |
| Kubernetes | Helm Charts |
| OpenShift | Implementación OpenShift |
Para guías de implementación completas, consulta Documentación de implementación.
Referencia de la API
La documentación interactiva de la API está disponible cuando el servidor está en ejecución:
- Swagger UI — Prueba llamadas a la API directamente en tu navegador
- ReDoc — Explora la referencia completa de endpoints
Autenticación rápida:
# 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 admin@example.com --exp 10080 --secret "$JWT_SECRET_KEY")
# Test API access
curl -H "Authorization: Bearer $TOKEN" http://localhost:4444/health
Para ejemplos completos de curl que cubren todos los endpoints, consulta la Guía de uso de la API.
Pruebas
make test # Run unit tests
make lint # Run all linters
make doctest # Run doctests
make coverage # Generate coverage report
Consulta la Guía de cobertura de doctests para detalles sobre pruebas de documentación.
Estructura del proyecto
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
mcp-servers/ # Sample/test MCP servers (see note below)
Nota: El directorio
mcp-servers/contiene servidores de muestra y prueba no soportados, la mayoría originados de contribuciones de la comunidad, proporcionados solo para fines de demostración y pruebas de integración. Generalmente carecen de gestión de sesiones, estado persistente, multi-tenencia, autenticación y otras preocupaciones de producción. No pasan por el mismo rigor de revisión, pruebas y seguridad que el código central de ContextForge y no deben ejecutarse en producción.Seguridad: Nunca ejecutes servidores MCP no confiables directamente en tu sistema de archivos local. Usa siempre un sandbox, contenedor o microVM (por ejemplo, gVisor, Firecracker) con capacidades restringidas. Ten precaución al registrar cualquier servidor MCP remoto, incluidos servidores de catálogos públicos — realiza tu propia evaluación de seguridad antes de otorgar acceso a tu puerta de enlace.
Para la estructura completa, consulta CONTRIBUTING.md o ejecuta tree -L 2.
Desarrollo
make dev # Dev server with auto-reload (:8000)
make test # Run test suite
make lint # Run all linters
make coverage # Generate coverage report
Ejecuta make para ver todos los objetivos disponibles.
Para flujos de trabajo de desarrollo, consulta:
Solución de problemas
Problemas comunes y soluciones:
| Problema | Solución rápida |
|---|---|
docker compose up falla con cryptography o error de resolución de dependencias | La compilación local requiere un cierre de wheel producido por CI. Ejecuta docker pull ghcr.io/ibm/mcp-context-forge:latest && echo 'IMAGE_LOCAL=ghcr.io/ibm/mcp-context-forge:latest' >> .env y luego reintenta |
docker compose up falla con SecurityConfigurationError: jwt_secret_key | .env falta o tiene marcadores de posición __REPLACE_ME__. Ejecuta cp .env.example .env && python3 -m mcpgateway.scripts.init_secrets --patch-env .env |
docker compose up falla — mcpgateway/nginx-cache acceso de extracción denegado | La imagen de nginx debe compilarse localmente: docker compose build nginx |
make dev — nada en el puerto 8000 | Verifica la terminal para SecurityConfigurationError — ejecuta make ensure-secrets y luego reintenta. En WSL2 usa http://127.0.0.1:8000 no localhost |
| Error de "disk I/O" de SQLite en macOS | Evita directorios sincronizados con iCloud; usa ~/mcp-context-forge/data |
| Puerto 4444 no accesible en WSL2 | Configura la integración WSL en Docker Desktop |
| La puerta de enlace sale inmediatamente | Ejecuta cp .env.example .env && python3 -m mcpgateway.scripts.init_secrets --patch-env .env |
ModuleNotFoundError | Ejecuta make install-dev |
Para guías detalladas de solución de problemas, consulta Documentación de solución de problemas.
Contribuciones
- Haz un fork del repositorio, crea una rama de características.
- Ejecuta
make linty corrige cualquier problema. - Mantén
make testen verde. - Abre un PR con commits firmados (
git commit -s).
Consulta CONTRIBUTING.md para las pautas completas y Guía de problemas #2502 para saber cómo reportar errores, solicitar características y encontrar problemas en los que trabajar.
Registro de cambios
Un registro de cambios completo se puede encontrar aquí: CHANGELOG.md
Licencia
Licenciado bajo la Apache License 2.0 - consulta LICENSE
Autores principales y mantenedores
- Mihai Criveti - Ingeniero distinguido, IA agéntica
Agradecimientos especiales a nuestros contribuyentes por ayudarnos a mejorar ContextForge:
