gpu-broker-mcp
gpu-broker-mcp
Un servidor MCP sin estado que intermedia el acceso a cómputo GPU para agentes de IA. Los agentes descubren nodos, reservan capacidad, envían inferencias y consultan resultados a través de cuatro herramientas MCP — sin gestionar claves SSH, IPs de nodos ni APIs de proveedores directamente.
SDK: mcp==2.0.0 (Python SDK v2, mcp.server.MCPServer)
Especificación objetivo: MCP specification revision 2026-07-28
Transporte: Streamable HTTP, modo sin estado (stateless_http=True, json_response=True). Sin sesiones, sin Mcp-Session-Id, sin enrutamiento fijo.
Arquitectura
┌─────────────────────────────────────────────────────────────┐
│ Agent (MCP client) │
│ Calls: list_nodes → reserve_node → dispatch_inference │
│ → get_result (poll) │
└────────────────────────┬────────────────────────────────────┘
│ JSON-RPC over Streamable HTTP
│ (stateless, any replica)
┌────────────────────────▼────────────────────────────────────┐
│ gpu-broker-mcp server │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ HMAC-SHA256 │ │ NodePool ABC │ │
│ │ Handle signing │ │ ├ FakeNodePool │ │
│ │ & validation │ │ └ VastNodePool │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Error taxonomy │ │ JobStore ABC │ │
│ │ (single enum, │ │ └ InMemoryStore │ │
│ │ structured JSON) │ │ (per-replica) │ │
│ └──────────────────┘ └──────────────────┘ │
└────────────────────────┬────────────────────────────────────┘
│ SSH (VastNodePool only)
┌────────────────────────▼────────────────────────────────────┐
│ GPU node (e.g. Vast.ai RTX 3090) │
│ Runs inference workload, returns stdout │
└─────────────────────────────────────────────────────────────┘El broker se ejecuta localmente. Es un cliente de los nodos GPU, no reside en ellos — realiza la firma HMAC limitada por CPU y la serialización JSON, nada que se beneficie de una GPU.
Related MCP server: vibedonate
Por qué handles firmados en lugar de sesiones
El estado de la reserva vive dentro del propio handle: un payload JSON codificado en base64 (ID del nodo, caducidad, ámbito) concatenado con su firma HMAC-SHA256. El secreto proviene de GPU_BROKER_SECRET y el servidor se niega a arrancar si no está definido.
Esto significa que cualquier réplica que comparta el secreto puede validar un handle que nunca emitió. No hay tabla de sesiones, ni cabecera Mcp-Session-Id, ni requisito de enrutamiento fijo. Un balanceador de carga puede enrutar cualquier petición a cualquier réplica. Los handles tienen ámbito (reserve vs task), de modo que un handle de reserva no puede reutilizarse como ID de tarea ni viceversa — el uso indebido devuelve HANDLE_SCOPE_INVALID.
Lo que el JobStore en memoria sí pierde entre réplicas es la consulta del estado de los trabajos: la réplica B no puede indicar el estado de un trabajo enviado a la réplica A. Esto es un requisito de backend compartido (Redis, Postgres), no un defecto del diseño sin estado. La validación de la firma —la parte crítica para la seguridad— es totalmente portable.
Herramientas
Herramienta | Parámetros | Devuelve |
| — | Array JSON de nodos disponibles (id, model, vram, price, load) |
|
| Handle de reserva firmado |
|
|
|
|
|
|
Las firmas de las herramientas son estables entre backends — cambiar FakeNodePool por VastNodePool no altera ninguna interfaz visible para el cliente.
Nota sobre el caché
list_nodes devuelve meta.ttlMs y meta.cacheScope en el resultado de su herramienta. Esto es una convención local — SEP-2549 rige las respuestas de tools/list y resources/list, no los resultados individuales de tools/call. Los clientes que la reconocen pueden almacenar en caché; los que no, simplemente volverán a llamar.
Cabeceras de enrutamiento
El servidor emite las cabeceras Mcp-Method y Mcp-Name para el enrutamiento por puerta de enlace, pero no las aplica en el lado del servidor. El punto de aplicación es el borde (puerta de enlace API, proxy inverso), no el propio broker.
Taxonomía de errores
Todo error de herramienta devuelve JSON estructurado con code, message, retryable y, opcionalmente, retry_after_seconds. Los agentes deben ramificar según code, nunca según message — los mensajes son diagnósticos legibles por humanos y pueden cambiar.
Código | Reintentable | Cuándo se dispara |
| No | La versión de la librería de gestión de NVIDIA no coincide con el driver del host GPU |
| No | Conflicto de versión entre el driver CUDA y la librería en el host GPU |
| Sí | Bloqueo del gestor de paquetes retenido por otro proceso en el host GPU (p. ej., unattended-upgrades) |
| No | Socket del runtime de contenedores inaccesible en el host GPU |
| No | No hay suficiente memoria GPU para la carga de trabajo solicitada |
| Sí | No se puede conectar con el nodo GPU (timeout SSH, conexión rechazada, fallo de DNS) |
| No | El TTL del handle firmado ha expirado |
| No | La firma HMAC no coincide: handle manipulado, secreto incorrecto o handle malformado |
| No | Desajuste del ámbito del handle (p. ej., pasar un handle de tarea donde se espera un handle de reserva) |
| Sí | Fallo de terminación TLS o de la capa de proxy entre el broker y el nodo |
| No | Firma válida, pero el trabajo no está en el almacén de esta réplica (esperable con un almacén en memoria entre réplicas) |
Los errores a nivel de host (de NVML_VERSION_MISMATCH a DOCKER_SOCKET_PERMISSION_DENIED) se mapean a partir de cadenas de stderr de SSH en vast.py:_raise_from_stderr. Los patrones se basan en modos de fallo conocidos de los hosts GPU de Vast.ai, pero aún no se han validado contra cadenas de producción capturadas. La tarea 3 capturará la salida de error literal y refinará los patrones de coincidencia.
Inicio rápido
Modo fake (sin GPU, sin clave API)
export GPU_BROKER_SECRET="any-secret-string"
python src/gpu_broker/server.py
# Server at http://127.0.0.1:8000/mcpModo Vast.ai (GPU real)
export GPU_BROKER_SECRET="any-secret-string"
export VASTAI_API_KEY="your-vast-api-key"
# Find and rent a node
python vast_manage.py search --gpu "RTX 3090" --max-price 0.30
python vast_manage.py rent <offer_id>
python vast_manage.py wait <instance_id>
# Start the broker (auto-detects VASTAI_API_KEY)
python src/gpu_broker/server.py
# When done
python vast_manage.py destroy <instance_id>Ejecución de las pruebas
uv run pytest tests/ -vLas pruebas incluyen:
Round-trip del handle (reserve → dispatch → get_result)
Rechazo de firma manipulada
Rechazo de handle caducado
Rechazo por desajuste de ámbito
JOB_NOT_FOUND para la búsqueda entre réplicas
Prueba de ausencia de estado en subprocesos: arranca tres servidores HTTP reales (A y B comparten un secreto, C tiene uno distinto), lanza una tarea desde A, confirma que A devuelve
pending, B devuelveJOB_NOT_FOUNDy C devuelveHANDLE_SIGNATURE_INVALIDRechazo de arranque sin secreto definido
Round-trip de serialización para cada variante de error
Alcance y limitaciones actuales
Es un prototipo funcional, no un sistema de producción.
FakeNodePool devuelve una lista estática de tres nodos y no envía inferencia real. Útil para probar las interacciones de las herramientas y la mecánica de los handles.
VastNodePool consulta la API de Vast.ai en busca de instancias en ejecución y envía inferencias por SSH. Hace trabajo real, pero no tiene pool de conexiones, lógica de reintentos ni gestión de claves SSH más allá de la predeterminada del sistema.
InMemoryJobStore pierde todo el estado al reiniciarse y no puede compartir el estado de los trabajos entre réplicas. Un despliegue de producción necesita un backend compartido (Redis, Postgres).
Los patrones de la taxonomía de errores para fallos a nivel de host son conjeturas fundamentadas en modos de fallo conocidos. Necesitan validarse contra stderr real capturado de hosts GPU.
No hay autenticación en el propio endpoint MCP — cualquier cliente que pueda alcanzar el puerto HTTP puede invocar las herramientas. En producción se necesita una capa de autenticación delante.
No hay límite de tasa, ni límites de tamaño de petición, ni registro de auditoría.
This server cannot be deployed
Maintenance
Related MCP Connectors
HiveCompute MCP Server — decentralized inference router for AI agents
- mcpOAuthai.agentgates
Confidential compute and inference sold to agents over x402 USDC, plus an agent wallet over MCP.
Prepaid inference for agents over hosted MCP. Chat, image, and video.
Public MCP for agent verification, work discovery and governed interoperability.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for securely discovering, pricing, renting, connecting, and releasing GPU compute instances from AI Galaxy with budget checks and two-phase approval.8MIT
- AlicenseNot gradedqualityBmaintenanceEnables peer-to-peer AI inference donation by exposing MCP tools to check node status and request capacity, with local-first compute sharing, consent, and metering.53 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables Kubernetes-native management of agent/model workloads via MCP tools, including fleet status, workload lifecycle, and boot orchestration for AI workflows.MIT
- AlicenseAqualityAmaintenanceZero-quota GPU orchestration MCP server — lets AI agents discover, provision, and manage GPU compute across multi-datacenter partner nodes (H100/H200/B200) through a single control plane.1222 npmMIT