↓ Ir al contenido
  1. Posts/

Aspire + MCP: cuando tu agente entiende tu infraestructura

Adrián Díaz Cervera
Autor
Adrián Díaz Cervera

En el artículo de Aspire vimos cómo orquestar todos los servicios de tu aplicación con un solo comando y obtener observabilidad gratis con el dashboard. En los comentarios del post, Rubén Gomez nos comentaba cómo era usar Aspire con un MCP — como cerrar un círculo. Eso me dio la idea de este artículo.

Es bien cierto que, aunque usas Aspire, lo arrancas y ves que funciona o que no funciona. Cuando no funciona, había algo bastante tedioso: a tu agente le tienes que ir dando el contexto de lo que tú estás viendo, y seguramente te dirá “igual está pasando esto…”, pero igual no. Este artículo conecta la pieza que nos faltaba: ¿y si el agente pudiera ver lo mismo que tú ves en el dashboard de Aspire?

Esa pieza es MCP (Model Context Protocol), y Aspire lo soporta de forma nativa desde la versión 13.1. En este artículo vamos a ver cómo conectar ambos mundos usando la web de la NetCoreConf como ejemplo real.

El problema: contexto estático vs contexto dinámico
#

Hasta ahora, todo el contexto que le dábamos al agente era estático: el CLAUDE.md con las convenciones del equipo, las specs con los requisitos, el código fuente del proyecto. Está bien, y como vimos en los artículos anteriores, marca una diferencia enorme frente a no darle nada. Pero hay un escenario donde el contexto estático se queda corto: cuando algo falla en tiempo de ejecución.

Imagina este escenario en la web de la NetCoreConf: le dices al agente “el endpoint /api/speakers devuelve 500, ¿qué pasa?”. Con contexto estático, el agente lee el código del handler, mira el DbContext, revisa las migraciones y te propone hipótesis: “quizás la conexión a PostgreSQL está mal configurada”, “puede que falte un Include() en la query”. Son conjeturas razonables, pero son conjeturas.

Ahora imagina que el agente puede hacer lo mismo que harías tú: abrir el dashboard de Aspire, ver la traza del request que falló, leer el log con el stack trace y comprobar si PostgreSQL está healthy. Ya no adivina — diagnostica.

Eso es lo que MCP hace posible. El dashboard de Aspire muestra la información para humanos; MCP la expone para agentes. La misma fuente de datos, dos interfaces.

¿Qué es MCP?
#

MCP (Model Context Protocol) es un protocolo abierto creado por Anthropic que permite a agentes IA conectarse a fuentes de datos externas. No es una API REST ni un SDK — es un contrato estándar para que cualquier agente (Claude, GitHub Copilot, Gemini CLI…) pueda descubrir y usar herramientas que tú expones.

Un MCP server expone tools (funciones que el agente puede invocar) y resources (datos que el agente puede consultar). El agente descubre qué tools están disponibles, entiende sus parámetros gracias a las descripciones, y los invoca cuando lo necesita.

¿Por qué encaja tan bien con Aspire?

  • Aspire ya tiene toda la información centralizada: logs, trazas distribuidas, métricas, estado de recursos, health checks.
  • El dashboard la consume para mostrarla visualmente.
  • MCP la consume para exponerla a agentes.
  • No necesitas construir nada: Aspire incluye un MCP server listo para usar a través del CLI.

El flujo mental es este:

AppHost → Dashboard (para humanos)
       → MCP Server (para agentes)

Ambos consumen la misma información de OpenTelemetry y el orquestador.

Configurando MCP en tu proyecto Aspire
#

Configurar el MCP server de Aspire es sorprendentemente fácil. Si ya tienes el CLI de Aspire instalado (que viene con el workload de .NET), son dos pasos.

1. Inicializar MCP en tu proyecto
#

Desde la raíz de tu proyecto (donde está el AppHost), ejecuta:

aspire agent init

El comando es interactivo: detecta tu entorno de desarrollo (VS Code, Claude Code, GitHub Copilot CLI…) y crea la configuración necesaria. Para Claude Code, genera un archivo .mcp.json en la raíz del proyecto:

{
  "mcpServers": {
    "aspire": {
      "command": "aspire",
      "args": ["mcp", "start"]
    }
  }
}

Eso es todo. No hay API keys, no hay URLs que configurar, no hay puertos que abrir. El MCP server usa transporte STDIO: Claude Code lanza aspire mcp start como un subproceso y se comunica con él directamente. Sin servidor HTTP, sin autenticación.

2. Arrancar el AppHost como siempre
#

dotnet run --project src/NetCoreConf.AppHost

Cuando el AppHost arranca, el MCP server está disponible automáticamente. El agente que uses lo detecta al iniciar la sesión y te muestra las tools disponibles.

¿Y si ya tienes el proyecto configurado?
#

Si vienes del artículo anterior y ya tienes el AppHost de la NetCoreConf funcionando, aspire agent init se encarga de todo. No necesitas modificar el Program.cs del AppHost ni añadir ningún paquete NuGet. El MCP server es una funcionalidad del CLI de Aspire, no del AppHost.

Las tools que expone el MCP server de Aspire
#

Una vez configurado, el agente tiene acceso a estas herramientas de forma automática:

Observabilidad y diagnóstico
#

ToolQué hace
list_resourcesLista todos los recursos (contenedores, proyectos, apps) con su estado, health status, endpoints y comandos disponibles
list_console_logsMuestra los logs de consola de un recurso específico
list_structured_logsLogs estructurados con filtros por recurso, nivel y texto
list_tracesTrazas distribuidas — el equivalente a lo que ves en la pestaña de trazas del dashboard
list_trace_structured_logsLogs asociados a una traza concreta
execute_resource_commandEjecuta comandos sobre recursos: start, stop, restart

Documentación y configuración
#

ToolQué hace
list_integrationsLista los paquetes de integración de Aspire disponibles (Redis, PostgreSQL, RabbitMQ…)
get_integration_docsDocumentación de un paquete de integración específico
list_docsLista todas las páginas de documentación de aspire.dev
search_docsBusca en la documentación de Aspire por palabras clave
get_docRecupera el contenido completo de una página de documentación
doctorDiagnostica problemas del entorno Aspire y verifica la instalación

Multi-AppHost
#

ToolQué hace
list_apphostsLista las conexiones de AppHost detectadas
select_apphostSelecciona qué AppHost usar cuando hay varios corriendo

Lo que más me llamó la atención es que el agente no solo puede leer, también puede actuar: execute_resource_command permite reiniciar un contenedor que se ha quedado colgado o parar un servicio que está consumiendo demasiados recursos. Todo desde la conversación con el agente, sin tocar el terminal.

Ejemplo real: diagnosticando un problema con MCP
#

Aquí es donde la cosa se pone interesante. Vamos a ver un caso real con la web de la NetCoreConf.

El problema
#

El endpoint GET /api/sessions funciona, devuelve datos, pero tarda 3 segundos. Inaceptable para una lista de sesiones de una conferencia.

Sin MCP: el agente propone hipótesis
#

Le digo : “El endpoint /api/sessions tarda 3 segundos, ¿qué puede estar pasando?”

El agente lee el handler, ve la query a Entity Framework, y me propone:

“El handler hace un Include(s => s.Speaker) y un Include(s => s.Track). Si la tabla de sesiones tiene muchos registros, estas cargas eager podrían ser el problema. Te sugiero añadir paginación o usar un Select() con proyección para cargar solo los campos necesarios.”

Es una respuesta razonable. Pero es genérica — podría aplicarse a cualquier endpoint lento con EF Core. No sabe si el cuello de botella está en la query, en la serialización, en la conexión a PostgreSQL o en otra cosa.

Con MCP: el agente diagnostica con datos
#

Le digo lo mismo al agente, pero ahora tiene MCP conectado al AppHost.

Lo que hace el agente internamente:

  1. Invoca list_resources — confirma que PostgreSQL está healthy y la API está corriendo.
  2. Invoca list_traces — busca las trazas recientes del endpoint /api/sessions.
  3. Inspecciona la traza — ve que la query SQL tarda 45ms (bien), pero la serialización de la respuesta tarda 2.8 segundos.
  4. Invoca list_structured_logs filtrando por la API — encuentra un warning: "Serializing 847 sessions with full Speaker and Track navigation properties".

Con estos datos, el agente me dice:

“El problema no está en la query — tarda 45ms. El cuello de botella está en la serialización: estás devolviendo 847 sesiones con todas las propiedades de navegación de Speaker y Track incluidas. El serializador está recorriendo el grafo completo de objetos. La solución es un Select() con proyección a un DTO que solo incluya los campos que el frontend necesita.”

Y me propone el fix:

public sealed class GetSessionsHandler(AppDbContext db)
    : IQueryHandler<GetSessionsQuery, IReadOnlyList<SessionSummaryDto>>
{
    public async Task<IReadOnlyList<SessionSummaryDto>> Handle(
        GetSessionsQuery query, CancellationToken ct)
    {
        return await db.Sessions
            .Select(s => new SessionSummaryDto(
                s.Id,
                s.Title,
                s.Description,
                s.StartTime,
                s.EndTime,
                s.Speaker.Name,
                s.Track.Name))
            .ToListAsync(ct);
    }
}

Después del fix, el agente puede verificar que funciona invocando list_traces de nuevo y confirmando que el endpoint ahora responde en 120ms.

debuggin agente

Ese es el cambio: el agente no adivina, diagnostica. Y lo hace usando exactamente las mismas herramientas que tú usarías en el dashboard, pero sin que tú tengas que navegar por las pestañas.

Aspire como hub: Dashboard + MCP + Tests
#

Con MCP integrado, Aspire se convierte en el centro de toda la experiencia de desarrollo. Déjame ponerlo en perspectiva con lo que hemos ido construyendo en los artículos anteriores:

┌─────────────────────────────────────────────────┐
│                   AppHost                        │
│                                                  │
│  PostgreSQL ──┐                                  │
│  API .NET ────┤── Dashboard (humanos)            │
│  React/Vite ──┘── MCP Server (agentes)           │
│                   Tests de integración           │
│                                                  │
│  Un solo lugar define tu topología completa      │
└─────────────────────────────────────────────────┘

Y conectando con la serie de IA, el agente ahora tiene el ciclo completo:

PiezaQué aportaArtículo
CLAUDE.mdContexto estático: cómo trabaja el equipoAdoptar IA en el desarrollo
SkillsVerificación automática del código generadoSkills
SpecsRequisitos sin ambigüedadSpec Driven Development
MCP + AspireContexto dinámico en tiempo realEste artículo

El agente sabe cómo trabaja el equipo, sabe qué tiene que implementar, sabe verificar que lo hizo bien, y ahora sabe qué está pasando en la aplicación en tiempo real.

MCP en el flujo de desarrollo diario
#

Más allá del ejemplo de diagnóstico, MCP cambia varios flujos del día a día:

Debugging asistido
#

El caso más obvio. En lugar de abrir el dashboard, buscar el recurso, filtrar los logs, encontrar la traza y analizar los spans manualmente, le dices al agente "¿por qué falla el endpoint X?" y él hace todo eso por ti. Para errores obvios (una excepción con stack trace claro), te ahorra tiempo. Para errores sutiles (una traza que muestra latencia inesperada en un span concreto), te ahorra mucho más porque el agente puede correlacionar la traza con el código del handler en el mismo contexto.

Validación post-implementación
#

Después de que el agente implementa un cambio (o tú mismo lo haces), puedes pedirle que verifique el impacto:

“Acabo de cambiar la query de sesiones a una proyección. ¿Puedes verificar que el endpoint responde más rápido?”

El agente invoca list_traces, compara los tiempos antes y después, y te confirma si el cambio tuvo efecto. Sin salir de la conversación, sin abrir el navegador.

Onboarding
#

Una persona nueva entra al equipo, clona el repo, ejecuta dotnet run --project src/NetCoreConf.AppHost y tiene todo corriendo. Ahora, además del dashboard para explorar visualmente, puede preguntarle al agente:

"¿Cuántos servicios tiene esta aplicación y cómo se conectan entre sí?"

El agente invoca list_resources y le da un mapa del sistema basado en datos reales, no en documentación que puede estar desactualizada.

Monitorización durante desarrollo
#

Mientras trabajas en una feature, puedes tener al agente vigilando:

“Avísame si algún health check pasa a unhealthy mientras trabajo en este cambio.”

No es un sustituto de un sistema de monitorización real, pero para desarrollo local, donde los problemas suelen ser “se me olvidó levantar PostgreSQL” o “el frontend no conecta con la API porque cambié un puerto”, es más que suficiente.

Lo que MCP NO resuelve (y está bien así)
#

Hay que dejar claras las limitaciones:

  • MCP no reemplaza al debugger. Para poner un breakpoint en una línea concreta e inspeccionar el estado de una variable, sigues necesitando tu IDE. MCP te da la visión de helicóptero; el debugger te da el microscopio.

  • Esto es para desarrollo local. El MCP server de Aspire conecta con tu AppHost corriendo en tu máquina. No es una herramienta de monitorización de producción — para eso tienes Application Insights, Datadog, Grafana o lo que uses.

  • La calidad depende de tu instrumentación. MCP expone lo que OpenTelemetry captura. Si tu servicio loggea "Error occurred" sin contexto, el agente tampoco puede hacer magia. Si tienes logs estructurados con correlation IDs y trazas bien instrumentadas, MCP brilla. Si no, es un espejo de tus propias carencias.

  • No todos los agentes soportan MCP igual. Claude Code tiene soporte nativo y robusto. GitHub Copilot lo soporta a través de su integración con el CLI. Otros agentes están en diferentes niveles de madurez. El protocolo es estándar y abierto, pero las implementaciones varían.

Conclusión
#

En el primer artículo de Aspire dije que “el dashboard es la joya oculta”. Ahora diría que MCP es lo que convierte esa joya en una herramienta de equipo: no solo para quien mira la pantalla, sino para el agente que trabaja a tu lado.

Aspire resolvió el problema de “funciona en mi máquina” para los humanos del equipo: un comando y todo arranca. MCP extiende esa misma solución a los agentes IA. El agente ya no trabaja a ciegas sobre código estático — puede ver el estado real de los servicios, leer las trazas de un error y consultar datos de dominio, exactamente como lo haría cualquier miembro del equipo con acceso al dashboard.

La combinación de ambos cierra un ciclo que empezamos hace meses: contexto estático con CLAUDE.md para que el agente entienda las convenciones, specs para que sepa qué implementar, skills para que verifique lo que ha hecho, y ahora contexto dinámico con MCP para que vea lo que está pasando. El agente pasa de proponer hipótesis a diagnosticar con datos.

Lo que más valoro es que no te pide nada a cambio: el MCP server del CLI no modifica tu código, y si mañana decides que no lo necesitas, borras el .mcp.json y ya. Aspire sigue sumando sin restar.

Pero el MCP server de Aspire solo expone observabilidad — lo que ve el dashboard. ¿Y si el agente también pudiera consultar datos de tu dominio? Buscar speakers, detectar conflictos de horario, validar reglas de negocio… todo reutilizando la lógica que ya tienes en tu capa de Application.