Symfony AI Mate: darle a la IA los ojos del profiler (y por qué dejó de ser un servidor MCP)
Me pasan un enlace con la pregunta de siempre: "¿esto qué es, para
qué vale y merece la pena?". El enlace es Symfony
AI Mate. Me he leído la documentación, las páginas de integración y
de extensiones, los composer.json de los
paquetes y el resumen de la charla que lo presentó. No lo he instalado
todavía: lo que sigue es lectura con criterio, no un benchmark.
Qué es, en una frase
Mate es un comando, vendor/bin/mate,
que deja a un agente de código (Claude Code, Codex, Copilot, Cursor, el
asistente de JetBrains…) mirar tu aplicación PHP por
dentro: el contenedor de servicios compilado, los perfiles del
profiler de Symfony y los logs de Monolog. Es una herramienta de
desarrollo; la propia documentación insiste en que no es para
producción.
El problema que ataca es real. Un agente lee tu código muy bien, pero no ve la aplicación corriendo. No sabe qué servicio acabó inyectándose de verdad, ni qué consultas lanzó Doctrine en esa petición lenta, ni qué dijo el log a las 10:42. Así que reconstruye el proyecto fichero a fichero, tarda y a veces se inventa el resto. Johannes Wachter (Sulu), que lo presentó en la SymfonyOnline de junio, lo resumía así: "don't give AI more context, give it better context".
Cómo se usa
composer require --dev symfony/ai-mate
vendor/bin/mate init # crea mate/, toca composer.json, AGENTS.md y CLAUDE.md
composer dump-autoload
vendor/bin/mate skills:installA partir de ahí el agente no necesita configuración propia. mate init deja un bloque gestionado en AGENTS.md (y un CLAUDE.md que lo importa) explicando qué
herramientas hay y cuándo usarlas, e instala skills en .agents/skills/ y .claude/skills/. El agente descubre lo que hay y
lo llama como cualquier otro comando:
vendor/bin/mate tools:list
vendor/bin/mate tools:inspect symfony-profiler-list
vendor/bin/mate tools:call symfony-profiler-list --limit=1
vendor/bin/mate resources:read symfony-profiler://profile/<token>/db
vendor/bin/mate tools:call monolog-search --term="timeout" --level=errorSi la aplicación vive en Docker o DDEV, se le dice cómo invocarlo con
el parámetro mate.invocation (por ejemplo
ddev exec vendor/bin/mate), y Mate se
niega a arrancar si la versión de PHP no es la del proyecto. Ese detalle
me gusta: evita el clásico "el agente ejecutó con el PHP equivocado y te
diagnosticó un fantasma".
Qué trae de serie
- Núcleo:
server-info(versión de PHP, sistema, extensiones cargadas). - Puente de Symfony: buscar servicios del contenedor compilado por id, clase o tag; ver el detalle de uno; listar y abrir perfiles del profiler, con los collectors de Doctrine, Mailer y Translation normalizados para que un modelo los entienda.
- Puente de Monolog: buscar en logs (con regex y nivel), buscar por campos de contexto, hacer tail y listar ficheros y canales.
- Comunidad (awesome-mate): extensiones para PHPUnit, PHPStan, Rector y Composer.
Y lo más interesante para quien tenga su propio dominio: escribir herramientas es poner un atributo en un método. Mate saca el esquema de entrada de la firma y del PHPDoc, y eso es lo que ve el agente.
namespace Mate;
use Symfony\AI\Mate\Attribute\MateTool;
final class PedidosAtascados
{
/**
* @param int $minutos Antigüedad mínima del pedido en estado "pendiente"
*/
#[MateTool(name: 'pedidos-atascados', title: 'Pedidos atascados',
description: 'Lista pedidos pendientes más viejos que N minutos')]
public function __invoke(int $minutos = 30): array
{
// consulta de solo lectura a tu base de datos de desarrollo
return [];
}
}También hay #[MateResource] y #[MateResourceTemplate] para exponer datos por
URI.
El giro que más me ha interesado: ya no es un servidor MCP
El repositorio todavía se describe en GitHub como "MCP server", pero desde la versión 0.13 (30 de agosto de 2026) Mate es un CLI a secas. No hay servidor que arrancar, no hay un fichero de configuración por cliente y no hay descripciones de herramientas ocupando permanentemente la ventana de contexto del agente. La documentación lo dice sin rodeos: cualquier agente que sepa ejecutar un comando de shell ya puede usarlo.
Esto no es un detalle de implementación, es una opinión de diseño, y creo que tienen razón. Con MCP, cada herramienta conectada se paga en contexto en cada conversación, la uses o no. Con un CLI más skills que explican cuándo tirar de qué, el agente carga el conocimiento solo cuando lo necesita. Es exactamente la conclusión a la que llegamos por nuestra cuenta montando nuestras propias herramientas: comandos pequeños, bien documentados en un fichero que el agente lee, antes que un zoo de servidores MCP siempre encendidos.
El precio también existe y conviene decirlo: MCP te da esquemas
tipados y permisos por herramienta; un CLI te pide confiar en "este
agente puede ejecutar vendor/bin/mate" en
tu máquina. Para una herramienta de solo lectura en desarrollo es un
buen trato. Para algo que escriba o toque producción, no lo sería.
¿Para qué vale de verdad?
Donde le veo más valor:
- Peticiones lentas y N+1 de Doctrine: el agente abre el perfil, ve las consultas y te señala el bucle. Es el ejemplo estrella de la charla y tiene todo el sentido.
- "¿Por qué no se inyecta este servicio?": preguntarle al contenedor compilado en vez de que el agente adivine leyendo YAML y atributos.
- Triaje de errores: cruzar el perfil de la petición que falló con los logs de ese momento sin copiar y pegar nada.
- Dominio propio: tres o cuatro
#[MateTool]de solo lectura sobre tu base de datos de desarrollo valen más que cualquier explicación larga en un prompt.
Las pegas, sin maquillaje
- Requisitos altos. El núcleo pide PHP 8.2 o
superior. El puente de Symfony pide
symfony/dependency-injection7.3 u 8. Si tu proyecto vive en PHP 7 con Symfony 4 o 5 (el legacy de medio mundo), el puente de Symfony no entra sin actualizar antes. El de Monolog es más amable: Monolog 2 o 3. - Es 0.x y se nota. En la 0.13 acaban de cambiar el modelo entero, de servidor a CLI. Es bueno que se atrevan, pero significa que lo que montes encima puede romperse en la siguiente versión.
- Toca tu repo.
mate initmodificacomposer.jsony escribe enAGENTS.md,CLAUDE.mdy las carpetas de skills. Son bloques gestionados, pero revisa el diff antes de commitear, sobre todo si tu equipo ya tiene esos ficheros cuidados a mano. - Los logs son datos. La documentación habla de redactar cookies, sesión y cabeceras de autenticación en los datos del profiler, pero lo que haya en tus logs de desarrollo (correos, identificadores, lo que sea) acaba en la conversación con el modelo. En desarrollo con datos falsos, bien; con una copia de datos reales, piénsatelo.
- Logs en fichero. El puente de Monolog lee ficheros. Si tus logs salen por stdout hacia un contenedor o un agregador, no los va a ver sin cambiar la configuración.
Veredicto
Útil, sí, y con una idea de fondo mejor que el propio producto.
- Si trabajas en un proyecto Symfony 7.3+ con PHP 8.2+ y ya usas un agente: instálalo. Los puentes de profiler y logs te ahorran copiar y pegar, y el agente deja de adivinar.
- Si tu proyecto es legacy (PHP 7, Symfony 4/5): hoy
no te sirve tal cual. Pero copia el patrón: un par de comandos de solo
lectura bien documentados en
AGENTS.mdy unas skills que digan cuándo usarlos. No hace falta Mate para eso. - Si tienes tu propio framework sobre PHP 8.2+: el
núcleo con
#[MateTool]propias es una forma limpia y estándar de exponer tu dominio a cualquier agente. En teoría encaja en un proyecto como Cohete; no lo he probado todavía.
Lo que más me llevo no es la herramienta, es la decisión: Symfony, que tenía un servidor MCP funcionando, lo ha tirado para quedarse con un CLI y skills, porque el contexto del agente es caro y lo que necesita no es más información, sino la buena en el momento justo. Es la lección correcta.
Comentarios (0)
Sin comentarios todavia. Se el primero!
Deja un comentario