Saltar a contenido

ADR 010: Módulo IO (apirest, webhooks, MCP)

Estado

Aceptado — 2026-06 · Diseño de ingeniería (implementación parcial: solo apirest)

Relacionado con ADR 001, ADR 006 (MCP como submódulo), contexto-proyecto.md (taxonomía Dependiente).

Contexto

La pizarra de arquitectura clasifica como Dependiente todo lo que no es dominio de negocio. La capa IO agrupa constructores y middleware de entrada/salida y transformación de datos: cómo llegan peticiones (REST, MCP), cómo salen eventos (webhooks) y cómo se exponen capacidades REST a agentes sin duplicar lógica.

Hoy la lógica está dispersa en cortex_framework/api/, tenant/ y diseño MCP en ADR 006 sin paquete unificado.

Decisión

Ubicación

Módulo interno cortex_framework.io — siempre cargado, no desactivable vía CORTEX_ENABLED_PLUGINS.

flowchart TB
  subgraph io [cortex_framework.io - Dependiente]
    REST[apirest]
    WH[webhooks]
    MCP[mcp]
    BR[apirest2mcp]
  end
  subgraph consumers [Consumidores]
    UI["@cortex/panel-core PanelApiClient"]
    AG[Agente IA]
    EXT[Sistemas externos]
  end
  subgraph plugins [Independiente - cortex_plugin_*]
    PLG[handlers REST y register_mcp_tools]
  end
  UI --> REST
  AG --> MCP
  MCP --> BR
  BR --> REST
  REST --> PLG
  WH --> EXT
  PLG --> WH

Leyenda: Capa IO del framework (Dependiente). Actores: SPA y agentes entran por REST/MCP; plugins registran routers y tools; webhooks notifican externos. Estado: apirest parcialmente implementado; webhooks, MCP y apirest2mcp en diseño.

Submódulos

Submódulo Responsabilidad Estado
apirest FastAPI /api/v1, ensamblado de routers de plugins, guards (require_plugin_enabled, tenant, auth) Parcial — framework/cortex_framework/api/app.py
webhooks Registro de suscripciones, firma HMAC, reintentos, entrega de eventos de dominio hacia URLs externas Diseño
mcp Servidor MCP HTTP, McpToolRegistry, hook register_mcp_tools (ver ADR 006) Diseño
apirest2mcp Generación/adaptación de tools MCP desde contratos OpenAPI o handlers REST existentes — sin duplicar reglas de negocio Diseño

Reglas

  1. Los plugins Independiente exponen negocio vía api_router() y opcionalmente register_mcp_tools; no implementan servidor HTTP propio.
  2. Los handlers MCP invocan la misma capa de servicio que los endpoints REST del plugin (regla de oro ADR 006).
  3. webhooks emite eventos después de operaciones exitosas en plugins; la configuración de endpoints vive en framework/tenant, no en cada plugin por separado.
  4. apirest2mcp es preferible a escribir handlers MCP a mano cuando el contrato REST ya está estable.

Integración con auth y tenant

  • apirest y mcp pasan por ADR 005 (oauth2-server / IdP externo opcional) y TenantMiddleware.
  • Rutas públicas compartidas: health, ready, docs, OpenAPI, discovery OAuth (modo interno).

Fuera de alcance fase 1

  • GraphQL u otros transports.
  • Cola de mensajes distinta de Redis para webhooks (ADR 009 evalúa backing store).
  • MCP stdio en producción (solo dev local).

Consecuencias

  • Positivas: frontera clara entre plataforma IO y plugins de negocio; un solo lugar para middleware transversal.
  • Negativas: refactor de api/ hacia io/apirest/ cuando se implemente el paquete nominal.

Referencias

  • ADR 006
  • framework/cortex_framework/api/app.py
  • framework/cortex_framework/api/routes.py