MCP Workflow Orchestration Server
Permite que los agentes de IA descubran, creen y ejecuten flujos de trabajo complejos de múltiples pasos definidos en archivos YAML simples.
Documentación
@cyanheads/workflows-mcp-server
Almacena, consulta y crea playbooks de flujos de trabajo YAML para agentes LLM a través de MCP. STDIO o HTTP Streamable.
Resumen
Una biblioteca declarativa de flujos de trabajo para agentes LLM, respaldada por archivos YAML locales. Almacena, lista y recupera playbooks multipaso nombrados y versionados — cada uno una secuencia de llamadas a herramientas/servidores MCP — para reutilización permanente o ejecuciones temporales de un solo uso. Se ejecuta como proceso stdio o como servidor HTTP Streamable local; un índice en memoria se reconstruye automáticamente a medida que los archivos cambian.
Herramientas
| Herramienta | Descripción |
|---|---|
workflow_list | Lista todos los flujos de trabajo permanentes en el índice, con filtros opcionales de palabra clave, categoría y etiqueta. |
workflow_get | Recupera una definición completa de flujo de trabajo por nombre, con instrucciones globales antepuestas. |
workflow_create | Escribe un nuevo flujo de trabajo permanente YAML en la biblioteca. |
workflow_create_temp | Escribe un borrador temporal de flujo de trabajo, indexado pero excluido de los resultados de lista, conservado hasta que se elimine. |
workflow_delete | Elimina un flujo de trabajo permanente o un borrador temporal por nombre y versión opcional, después de que el usuario confirme el objetivo resuelto. |
Referencia de capacidades
workflow_list herramienta
- Filtro opcional de palabra clave
query(subcadena sin distinción de mayúsculas/minúsculas en nombre y descripción del flujo de trabajo) - Filtro opcional de categoría (coincidencia de subcadena sin distinción de mayúsculas/minúsculas)
- Filtro opcional de etiqueta (coincidencia AND sin distinción de mayúsculas/minúsculas — todas las etiquetas listadas deben estar presentes)
- Los valores de filtro se recortan de espacios iniciales y finales antes de la coincidencia; un
queryocategoryen blanco no aplica filtro - Establece
includeTools: truepara mostrar los pares únicosserver/toolutilizados en los pasos de cada flujo de trabajo - Los flujos de trabajo temporales se excluyen; los resultados se ordenan por nombre y luego por precedencia semver descendente (una versión estable antes que sus prereleases)
- Los resultados vacíos reflejan los filtros aplicados con una sugerencia para ampliarlos
workflow_get herramienta
- Consciente de semver: omite
versionpara obtener la coincidencia disponible más alta; especifica una versión para una búsqueda exacta - Un
versionque no es semver válido se rechaza como argumentos inválidos antes de cualquier búsqueda; una ortografía tolerada (v1.0.0, espacios circundantes, metadatos de compilación) se resuelve a su forma canónica (1.0.0) namese recorta antes de la búsqueda, coincidiendo con cómo las herramientas de creación lo almacenan; unnameen blanco se rechaza como argumentos inválidos- Devuelve la estructura YAML completa del flujo de trabajo con todos los pasos y metadatos
- Inyecta el contenido de
global_instructions.mdcomoglobalInstructions— aplícalos al ejecutar el flujo de trabajo;nullcuando el archivo está ausente - Los flujos de trabajo temporales son accesibles aquí aunque estén excluidos de
workflow_list - Los marcadores de posición de plantilla (
{{input.foo}},{{steps.X.output.Y}}) se devuelven textualmente — el servidor nunca los interpola
workflow_create herramienta
- Flujo de trabajo almacenado en
categories/<slugified-category>/<slugified-name>-<slugified-version>-<hash>-workflow.yaml, donde<hash>son los primeros 8 caracteres hexadecimales de SHA-256 sobrename@version— un archivo porname@version, por lo que múltiples versiones coexisten y claves cuyos slugs coinciden (Deploy/deploy,Café Plan/Caf Plan) nunca comparten archivo - Se acepta cualquier nombre con contenido visible; uno sin letras ASCII ni dígitos (p. ej.,
Рабочий процесс) usaworkflowcomo parte del nombre de su archivo - Rechaza si
name@versionya existe, como flujo de trabajo permanente o borrador temporal — incrementa la versión para crear una nueva revisión, o elimina el borrador conworkflow_deletepara almacenarlo permanentemente - Creaciones concurrentes de un
name@versionproducen un flujo de trabajo y unalready_exists, incluso entre categorías versionse almacena en forma semver canónica: unvinicial, espacios circundantes y metadatos de compilación se eliminan, por lo quev1.0.0+build.5se almacena, indexa y recupera como1.0.0- Rechaza un
name,description,author,categoryo pasoserver/toolsolo con espacios coninvalid_input - Rechaza un
namede más de 200 caracteres o uncategoryde más de 255 caracteres después de la slugificación coninvalid_input, para que cada nombre de archivo y directorio quepa en el límite de 255 bytes - El servidor sella
created_dateylast_updated_dateautomáticamente - Índice y snapshot reconstruidos después de la escritura; el observador del sistema de archivos también se activa (idempotente, con debounce)
- Un fallo del sistema de archivos se reporta como
write_failedcon el código de error y la descripción únicamente, nunca la ruta absoluta
workflow_create_temp herramienta
- Escribir un
name@versionque ya tiene un borrador sobrescribe ese borrador en su lugar:statuses"created"para un borrador nuevo y"overwritten"para uno reemplazado, y una sobrescritura conserva elcreated_dateoriginal del borrador - Rechaza un
name@versionretenido por un flujo de trabajo permanente conalready_exists - Almacenado bajo
temp/con el mismo esquema de nombres de archivo, almacenamiento canónico deversiony rechazo de campos solo con espacios queworkflow_create - Indexado y accesible vía
workflow_getpero excluido de los resultados deworkflow_list; un camponoticeque lo indica viaja en ambosstructuredContenty la salida de texto - Los borradores persisten: un borrador permanece bajo
temp/entre reinicios hasta queworkflow_deletelo elimina — nada expira borradores ni los limpia - Útil para planes de un solo uso, andamiaje o borradores aún no listos para la biblioteca permanente
workflow_delete herramienta
- Elimina flujos de trabajo permanentes y borradores temporales por igual; el
sourcede la salida ("permanent"o"temp") indica cuál se eliminó - Consciente de semver: omite
versionpara eliminar la coincidencia disponible más alta entre flujos de trabajo permanentes y borradores; especifica una versión para apuntar a una exacta - Mismas reglas de
versionynamequeworkflow_get: la entrada no semver se rechaza antes de eliminar nada, una ortografía tolerada apunta a su forma canónica, y unnamecon relleno se recorta - Pregunta primero al usuario: la llamada devuelve un aviso de confirmación que nombra el
name@versionresuelto, su fuente y su ruta de archivo relativa aWORKFLOWS_DIR, y elimina solo cuando el usuario respondeconfirm: true. Responderfalse, declinar o cancelar falla concancelledy no elimina nada - El servidor conserva el registro de cada aviso y entrega al cliente solo un id aleatorio para él. Una respuesta debe llegar dentro de 10 minutos y funciona una sola vez; una respuesta a un aviso que el servidor nunca emitió, ya respondido o emitido hace demasiado tiempo falla con
confirmation_invalidy no elimina nada - El archivo se elimina solo si sigue siendo el que el usuario vio: si el nombre se resuelve a un flujo de trabajo o archivo diferente, o el contenido del archivo cambió, para cuando llega la respuesta, la llamada falla con
target_changedy no elimina nada - Necesita un cliente que pueda mostrar el aviso (elicitation); un cliente sin ello no puede eliminar, y no hay forma de evitar el aviso
- Irreversible: el archivo se elimina y el flujo de trabajo ya no aparece en
workflow_listoworkflow_get— a menos que otro archivo escrito a mano declare el mismoname@version. Esa copia entonces toma su lugar, y el resultado lleva unnoticenombrando su ruta relativa aWORKFLOWS_DIR - Eliminar un borrador libera su
name@version, por lo queworkflow_createpuede entonces almacenarlo permanentemente - Eliminar el último flujo de trabajo en un directorio
categories/<slug>/elimina ese directorio vaciado; un directorio que aún contenga cualquier archivo permanece
Características
Construido sobre @cyanheads/mcp-ts-core: transportes stdio y HTTP Streamable, autenticación conectable (none / jwt / oauth), almacenamiento intercambiable (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), registro estructurado con trazado OpenTelemetry opcional.
Biblioteca de flujos de trabajo:
- Archivos de flujo de trabajo YAML validados contra un esquema en tiempo de indexación; archivos inválidos (incluyendo un
name,description,author,categoryo pasoserver/toolsolo con espacios) se omiten y registran, nunca bloquean el servidor - Versiones indexadas en forma semver canónica — un archivo escrito como
version: v1.0.0se indexa comoname@1.0.0 - Una entrada de índice por
name@version: un flujo de trabajo permanente supera a un borrador temporal con la misma clave (el borrador se omite con una advertencia que nombra ambos archivos), y dos archivos de un tipo que comparten una clave registran una advertencia de duplicado, ganando el último leído - Índice en memoria claveado por
name@version, construido al inicio desdeworkflows-yaml/categories/yworkflows-yaml/temp/recursivamente, mantenido fresco por un observador recursivo del sistema de archivos con debounce en cualquier adición/cambio/eliminación - El índice lee la identidad de cada flujo de trabajo de su contenido de archivo, nunca de su nombre de archivo, por lo que archivos nombrados bajo cualquier esquema — incluyendo el
<name>-<version>-workflow.yamlanterior — se listan, recuperan y eliminan como cualquier otro - Las creaciones y eliminaciones se ejecutan una a la vez dentro del servidor, por lo que la verificación de existencia de cada una se mantiene hasta que su escritura aterriza
- Búsqueda consciente de semver — se devuelve la última versión cuando
versionse omite - Snapshot
_index.jsonescrito en cada reconstrucción para herramientas externas y depuración WORKFLOWS_DIR,GLOBAL_INSTRUCTIONS_PATHe intervalo de debounce configurables
Salida amigable para agentes:
- Salida discriminada —
source: "permanent" | "temp"en cada respuestaworkflow_gety códigosreasontipados (not_found,version_not_found,already_exists,cancelled,confirmation_invalid,target_changed,index_unavailable, …) en fallos, para que los llamadores ramifiquen en datos en lugar de analizar cadenas de error - Sin ida y vuelta extra —
workflow_getsiempre devuelveglobalInstructionsjunto con la definición del flujo de trabajo en la misma respuesta - Forma de respuesta — el indicador opcional
includeToolsdeworkflow_listpre-deriva los pares únicosserver/toolutilizados por un flujo de trabajo, y un resultado vacío refleja los filtros aplicados con una sugerencia de ampliación en lugar de devolver nada
Primeros pasos
No se requieren claves API. El servidor lee de un directorio local workflows-yaml/ por defecto.
Agrega lo siguiente a tu archivo de configuración del cliente MCP:
{
"mcpServers": {
"workflows-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/workflows-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"WORKFLOWS_DIR": "/absolute/path/to/your/workflows-yaml"
}
}
}
}
O con npx (sin Bun requerido):
{
"mcpServers": {
"workflows-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/workflows-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"WORKFLOWS_DIR": "/absolute/path/to/your/workflows-yaml"
}
}
}
}
O con Docker:
{
"mcpServers": {
"workflows-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-v", "/absolute/path/to/your/workflows-yaml:/workflows-yaml",
"-e", "WORKFLOWS_DIR=/workflows-yaml",
"ghcr.io/cyanheads/workflows-mcp-server:latest"
]
}
}
}
Para HTTP Streamable, establece el transporte e inicia el servidor:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Flujos de trabajo semilla
El repositorio incluye un directorio workflows-yaml/ con flujos de trabajo de ejemplo organizados bajo categories/. Están listos para usar como punto de partida. El archivo workflows-yaml/global_instructions.md contiene instrucciones que el servidor antepone a cada respuesta workflow_get — edítalo para establecer guía global para tu agente.
Prerrequisitos
- Bun v1.4.0 o superior (o Node.js v24+).
- Un directorio local que contenga archivos de flujo de trabajo YAML (o usa la semilla
workflows-yaml/incluida).
Instalación
- Clona el repositorio:
git clone https://github.com/cyanheads/workflows-mcp-server.git
- Navega al directorio:
cd workflows-mcp-server
- Instala las dependencias:
bun install
- Configura el entorno:
cp .env.example .env
# edit .env if needed — most settings have defaults
Configuración
| Variable | Descripción | Valor por defecto | |:---------|:------------|:--------| | `WORKFLOWS_DIR` | Ruta absoluta o relativa al directorio raíz de los flujos de trabajo. | `./workflows-yaml` | | `GLOBAL_INSTRUCTIONS_PATH` | Ruta al archivo markdown de instrucciones globales. Se deriva de `WORKFLOWS_DIR` cuando no se establece. | `/global_instructions.md` | | `WATCHER_DEBOUNCE_MS` | Milisegundos para debounce de eventos de cambio en el sistema de archivos antes de reconstruir el índice. | `500` | | `MCP_TRANSPORT_TYPE` | Transporte: `stdio` o `http`. | `stdio` | | `MCP_HTTP_PORT` | Puerto para el servidor HTTP. | `3010` | | `MCP_SESSION_MODE` | Sesiones HTTP: `auto` o `stateful`. La solicitud de confirmación de `workflow_delete` necesita una sesión activa, por lo que el inicio HTTP con `stateless` falla con un error de configuración. Se ignora sobre stdio. | `stateful`, declarado en `src/index.ts` | | `MCP_AUTH_MODE` | Modo de autenticación: `none`, `jwt` o `oauth`. | `none` | | `MCP_LOG_LEVEL` | Nivel de registro (RFC 5424). | `info` | | `OTEL_ENABLED` | Habilitar [instrumentación OpenTelemetry](https://github.com/cyanheads/mcp-ts-core/tree/main/docs/telemetry) (spans, métricas, registros de finalización). | `false` |Consulta .env.example para la lista completa de anulaciones opcionales.
Ejecutar el servidor
Desarrollo local
-
Compilar y ejecutar:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
Ejecutar comprobaciones y pruebas:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t workflows-mcp-server .
docker run --rm \
-v /path/to/workflows-yaml:/workflows-yaml \
-e WORKFLOWS_DIR=/workflows-yaml \
-p 3010:3010 \
workflows-mcp-server
El Dockerfile usa por defecto transporte HTTP, modo de sesión con estado (requerido — ver MCP_SESSION_MODE arriba) y registra en /var/log/workflows-mcp-server. Las dependencias opcionales de OpenTelemetry se instalan por defecto — compila con --build-arg OTEL_ENABLED=false para omitirlas.
Estructura del proyecto
| Directorio | Propósito |
|---|---|
src/index.ts | Punto de entrada de createApp() — registra herramientas e inicializa el servicio de índice de flujos de trabajo. |
src/config/ | Análisis y validación de variables de entorno específicas del servidor con Zod. |
src/mcp-server/tools/ | Definiciones de herramientas (*.tool.ts). |
src/services/workflow-index/ | WorkflowIndexService — análisis YAML, construcción de índice, observador, búsqueda semver, ayudantes de escritura. |
tests/ | Pruebas unitarias y de integración que reflejan src/. |
workflows-yaml/ | Biblioteca de flujos de trabajo semilla — categories/ para flujos permanentes, temp/ para borradores temporales, global_instructions.md para guía global de agentes. |
Guía de desarrollo
Consulta CLAUDE.md para pautas de desarrollo y reglas arquitectónicas. La versión corta:
- Los manejadores lanzan excepciones, el framework las captura — sin
try/catchen la lógica de herramientas - Usa
ctx.logpara registro con ámbito de solicitud - Registra nuevas herramientas mediante el barrel en
src/mcp-server/tools/definitions/index.ts - Las operaciones del sistema de archivos pasan por
WorkflowIndexService, no directamente en los manejadores de herramientas
Contribuciones
Las incidencias son bienvenidas. Ejecuta comprobaciones y pruebas antes de enviar:
bun run devcheck
bun run test
Licencia
Apache-2.0 — consulta LICENSE para más detalles.