symfony-command-ui: tus comandos Symfony son tu MCP server


14 de abril de 2026

El problema que todos tenemos

Si trabajas con Symfony, tienes comandos de consola. Muchos. app:users:sync, app:payments:process, app:cache:warmup… Son la columna vertebral de tu aplicacion: encapsulan logica de negocio, se ejecutan en cron, los usas para debuggear, para migraciones, para todo.

Y sin embargo, ejecutarlos es un rollo:

Y ahora, en la era agentica, hay un segundo problema: como le dices a un agente de IA que ejecute tus comandos? Los LLMs son buenos entendiendo JSON, haciendo HTTP, procesando streams. Pero no pueden hacer SSH a tu pod.

La solucion: un bundle que los expone a todos

symfony-command-ui es un bundle de Symfony que he publicado hoy. Hace una cosa simple:

Convierte tus comandos de consola en una UI web con terminal streaming Y en una API JSON que cualquier agente de IA puede usar.

composer require pascualmg/symfony-command-ui

Tres lineas de YAML y tienes un dashboard con todos tus comandos, auto-descubiertos, con formularios generados automaticamente desde tu InputDefinition.

Como funciona

La arquitectura es simple:

  1. El bundle ejecuta php bin/console list --format=json para descubrir los comandos disponibles
  2. Filtra por una whitelist que tu configuras (seguridad)
  3. Traduce cada InputOption y InputArgument a un formulario web (checkboxes, dropdowns, text inputs)
  4. Cuando pulsas Run, ejecuta el comando via Symfony\Component\Process y te streama el output en tiempo real como NDJSON

Cada comando se renderiza como una card independiente con su propio formulario y su propia terminal. Los outputs persisten: puedes ejecutar Stats mientras Generate JWT mantiene su resultado.

La parte interesante: interfaz dual

Aqui es donde se pone bueno. El bundle expone dos interfaces con los mismos endpoints:

Para humanos: el dashboard web

Un Web Component (<symfony-command>) con Shadow DOM, zero dependencias, que descubre los comandos al montar y renderiza todo automaticamente. No hay npm, no hay webpack, no hay build step. Un unico fichero JS que el bundle sirve como asset.

CSS customizable via custom properties. Dark theme por defecto. Theming completo si quieres.

Para agentes: la API JSON

Dos endpoints:

Cualquier agente que hable HTTP puede:

  1. Descubrir que operaciones existen en tu app
  2. Entender sus parametros (sin documentacion extra – salen del InputDefinition de Symfony)
  3. Ejecutarlas y observar el resultado en tiempo real

Es un MCP server gratis. Sin instalar nada especial. Sin protocolo custom. Solo HTTP + JSON.

Un ejemplo real: Claude operando una app

Imagina que tienes un e-commerce con estos comandos:

allowed_commands:
    - app:orders:pending
    - app:orders:process
    - app:inventory:check
    - app:reports:daily

Un agente de IA (Claude, GPT, tu propio agente) puede hacer:

Tu: "Hay pedidos pendientes de mas de 500 euros?"

Agente: /llama GET commands, encuentra app:orders:pending /llama POST execute con {"command":"app:orders:pending","options":{"–min-amount":500,"–json":true}}

"Si, hay 3 pedidos pendientes por encima de 500 euros: #4521 (720 euros), #4523 (1100 euros), #4529 (550 euros). Quieres que los procese?"

Tu: "Primero con dry-run"

Agente: /llama POST execute con {"command":"app:orders:process","options":{"–ids":"4521,4523,4529","–dry-run":true}}

"Dry run completado. Los 3 se procesarian correctamente. Total: 2370 euros. Ejecuto en real?"

Todo esto funciona porque tus comandos de Symfony ya encapsulan la logica. El bundle solo la expone.

El patron: logica en comandos, interfaz como adaptador

Si haces DDD o hexagonal, tus comandos de Symfony son adaptadores CLI que llaman a use cases del dominio. Este bundle anade un segundo adaptador (HTTP) al mismo use case, sin tocar una linea de tu logica de negocio.

                    ┌──────────────┐
      bin/console──►│              │
                    │  Use Case    │
symfony-command-ui──►│  (dominio)   │
      (HTTP+NDJSON) │              │
                    └──────────────┘

No importa si llegas por CLI o por HTTP: el mismo codigo se ejecuta. El bundle solo se encarga del transporte.

Detalles tecnicos

Instalacion en 4 pasos

# 1. Instalar
composer require pascualmg/symfony-command-ui

# 2. El bundle se auto-registra en bundles.php

# 3. Importar rutas
# config/routes/symfony_command_ui.yaml
# symfony_command_ui:
#     resource: '@SymfonyCommandUIBundle/Resources/config/routes.php'
#     prefix: /symfony-console

# 4. Configurar whitelist
# config/packages/symfony_command_ui.yaml
# symfony_command_ui:
#     allowed_commands:
#         - app:mi:comando
#         - app:otro:comando

Abrir https://tu-app.com/symfony-console y listo.

El origen

Esto surgio de un problema real: teniamos un microservicio de identity con 6 comandos de consola para gestionar colectivos (una feature B2B para un partner). Necesitabamos una UI para que el equipo pudiera ejecutarlos sin SSH, y al mismo tiempo queriamos que los agentes de IA pudieran operar el flujo programaticamente.

En vez de hacer un dashboard ad-hoc, extraje la logica generica en un bundle reutilizable. El prototipo funciono en una tarde. La lib se publico al dia siguiente. Hoy esta en Packagist.

Links

Comparte este post:

Es tu post

Estas seguro? Esto no se puede deshacer.

Comentarios (0)

Sin comentarios todavia. Se el primero!

Deja un comentario