MCP Workflow Orchestration Server

Permite que agentes de IA descubram, criem e executem fluxos de trabalho complexos e de múltiplas etapas definidos em arquivos YAML simples.

Documentação

@cyanheads/workflows-mcp-server

Armazene, consulte e crie playbooks de workflow YAML para agentes de LLM via MCP. STDIO ou Streamable HTTP.

5 Ferramentas

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Visão geral

Uma biblioteca de workflows declarativos para agentes de LLM, apoiada por arquivos YAML locais. Armazene, liste e recupere playbooks nomeados e versionados de múltiplas etapas — cada um uma sequência de chamadas de servidor/ferramenta MCP — para reutilização permanente ou execuções temporárias de uso único. Executa como um processo stdio ou um servidor HTTP Streamable local; um índice em memória é reconstruído automaticamente conforme os arquivos mudam.

Ferramentas

FerramentaDescrição
workflow_listLista todos os workflows permanentes no índice, com filtros opcionais de palavra-chave, categoria e tag.
workflow_getRecupera uma definição completa de workflow por nome, com instruções globais anexadas no início.
workflow_createGrava um novo workflow permanente em YAML na biblioteca.
workflow_create_tempGrava um rascunho de workflow temporário, indexado mas excluído dos resultados de listagem, mantido até ser excluído.
workflow_deleteRemove um workflow permanente ou um rascunho temporário por nome e versão opcional, após o usuário confirmar o alvo resolvido.

Referência de capacidades

workflow_list ferramenta

  • Filtro opcional de palavra-chave query (substring sem diferenciar maiúsculas/minúsculas no nome e na descrição do workflow)
  • Filtro opcional de categoria (correspondência de substring sem diferenciar maiúsculas/minúsculas)
  • Filtro opcional de tag (correspondência AND sem diferenciar maiúsculas/minúsculas — todas as tags listadas devem estar presentes)
  • Os valores dos filtros são aparados de espaços iniciais e finais antes da correspondência; um query ou category em branco não aplica filtro
  • Defina includeTools: true para exibir os pares únicos de server/tool usados nas etapas de cada workflow
  • Workflows temporários são excluídos; os resultados são ordenados por nome e, em seguida, por precedência semver decrescente (uma versão de lançamento antes de suas pré-lançamentos)
  • Resultados vazios ecoam os filtros aplicados com uma dica para ampliar a busca

workflow_get ferramenta

  • Ciente de semver: omita version para obter a correspondência mais alta disponível; especifique uma versão para uma consulta exata
  • Um version que não seja semver válido é rejeitado como argumentos inválidos antes de qualquer consulta; uma grafia tolerada (v1.0.0, espaços ao redor, metadados de build) resolve para sua forma canônica (1.0.0)
  • name é aparado antes da consulta, correspondendo a como as ferramentas de criação o armazenam; um name em branco é rejeitado como argumentos inválidos
  • Retorna a estrutura YAML completa do workflow com todas as etapas e metadados
  • Injeta o conteúdo de global_instructions.md como globalInstructions — aplique-os ao executar o workflow; null quando o arquivo estiver ausente
  • Workflows temporários são acessíveis aqui, mesmo excluídos de workflow_list
  • Placeholders de modelo ({{input.foo}}, {{steps.X.output.Y}}) são retornados literalmente — o servidor nunca os interpola

workflow_create ferramenta

  • Workflow armazenado em categories/<slugified-category>/<slugified-name>-<slugified-version>-<hash>-workflow.yaml, onde <hash> são os primeiros 8 caracteres hexadecimais de SHA-256 sobre name@version — um arquivo por name@version, então múltiplas versões coexistem e chaves cujos slugs coincidem (Deploy / deploy, Café Plan / Caf Plan) nunca compartilham um arquivo
  • Qualquer nome com conteúdo visível é aceito; um sem letras ou dígitos ASCII (por exemplo, Рабочий процесс) usa workflow como a parte do nome em seu nome de arquivo
  • Rejeita se name@version já existir, como workflow permanente ou rascunho temporário — aumente a versão para criar uma nova revisão, ou exclua o rascunho com workflow_delete para armazená-lo permanentemente
  • Criações concorrentes de um name@version produzem um workflow e um already_exists, mesmo entre categorias
  • version é armazenado na forma semver canônica: um v inicial, espaços ao redor e metadados de build são removidos, então v1.0.0+build.5 é armazenado, indexado e recuperado como 1.0.0
  • Rejeita um name, description, author, category ou etapa server/tool apenas com espaços com invalid_input
  • Rejeita um name com mais de 200 caracteres ou um category com mais de 255 caracteres após a slugificação com invalid_input, para que todo nome de arquivo e diretório caiba no limite de 255 bytes
  • O servidor carimba created_date e last_updated_date automaticamente
  • Índice e snapshot reconstruídos após a gravação; o observador do sistema de arquivos também dispara (idempotente, com debounce)
  • Uma falha do sistema de arquivos é relatada como write_failed com o código de erro e a descrição apenas, nunca o caminho absoluto

workflow_create_temp ferramenta

  • Gravar um name@version que já tem um rascunho sobrescreve esse rascunho no lugar: status é "created" para um novo rascunho e "overwritten" para um substituído, e uma sobrescrita mantém o created_date original do rascunho
  • Rejeita um name@version mantido por um workflow permanente com already_exists
  • Armazenado sob temp/ com o mesmo esquema de nome de arquivo, armazenamento canônico de version e rejeição de campos apenas com espaços como workflow_create
  • Indexado e acessível via workflow_get, mas excluído dos resultados de workflow_list; um campo notice informando isso acompanha tanto em structuredContent quanto na saída de texto
  • Rascunhos persistem: um rascunho permanece sob temp/ entre reinicializações até que workflow_delete o remova — nada expira rascunhos ou os limpa
  • Útil para planos de uso único, andaimes ou rascunhos ainda não prontos para a biblioteca permanente

workflow_delete ferramenta

  • Exclui workflows permanentes e rascunhos temporários igualmente; o source da saída ("permanent" ou "temp") indica qual foi removido
  • Ciente de semver: omita version para excluir a correspondência mais alta disponível entre workflows permanentes e rascunhos; especifique uma versão para mirar exatamente uma
  • Mesmas regras de version e name que workflow_get: entrada não-semver é rejeitada antes de qualquer exclusão, uma grafia tolerada mira sua forma canônica e um name com espaços é aparado
  • Pergunta ao usuário primeiro: a chamada retorna um prompt de confirmação nomeando o name@version resolvido, sua origem e seu caminho de arquivo relativo a WORKFLOWS_DIR, e exclui apenas quando o usuário responde confirm: true. Responder false, recusar ou cancelar falha com cancelled e não exclui nada
  • O servidor mantém o registro de cada prompt e entrega ao cliente apenas um id aleatório para ele. Uma resposta deve chegar em até 10 minutos e funciona uma vez; uma resposta a um prompt que o servidor nunca emitiu, já respondido ou emitido há muito tempo falha com confirmation_invalid e não exclui nada
  • O arquivo é excluído apenas se ainda for o que o usuário viu: se o nome resolver para um workflow ou arquivo diferente, ou o conteúdo do arquivo mudou, quando a resposta chega, a chamada falha com target_changed e não exclui nada
  • Precisa de um cliente que possa exibir o prompt (elicitação); um cliente sem isso não pode excluir, e não há como contornar o prompt
  • Irreversível: o arquivo é removido e o workflow não aparece mais em workflow_list ou workflow_get — a menos que outro arquivo escrito manualmente declare o mesmo name@version. Essa cópia então toma seu lugar, e o resultado carrega um notice nomeando seu caminho relativo a WORKFLOWS_DIR
  • Excluir um rascunho libera seu name@version, então workflow_create pode armazená-lo permanentemente
  • Excluir o último workflow em um diretório categories/<slug>/ remove esse diretório esvaziado; um diretório que ainda contém qualquer arquivo permanece

Recursos

Construído sobre @cyanheads/mcp-ts-core: transportes stdio e Streamable HTTP, autenticação plugável (none / jwt / oauth), armazenamento intercambiável (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), registro estruturado com rastreamento OpenTelemetry opcional.

Biblioteca de workflows:

  • Arquivos de workflow YAML validados contra um esquema no momento da indexação; arquivos inválidos (incluindo um name, description, author, category ou etapa server/tool apenas com espaços) são ignorados e registrados, nunca derrubam o servidor
  • Versões indexadas na forma semver canônica — um arquivo escrito como version: v1.0.0 é indexado como name@1.0.0
  • Uma entrada de índice por name@version: um workflow permanente tem precedência sobre um rascunho temporário com a mesma chave (o rascunho é ignorado com um aviso nomeando ambos os arquivos), e dois arquivos de um tipo que compartilham uma chave registram um aviso de duplicata, com o último lido vencendo
  • Índice em memória chaveado por name@version, construído na inicialização a partir de workflows-yaml/categories/ e workflows-yaml/temp/ recursivamente, mantido atualizado por um observador recursivo do sistema de arquivos com debounce em qualquer adição/alteração/remoção
  • O índice lê a identidade de cada workflow do conteúdo de seu arquivo, nunca de seu nome de arquivo, então arquivos nomeados sob qualquer esquema — incluindo o <name>-<version>-workflow.yaml anterior — são listados, recuperados e excluídos como qualquer outro
  • Criações e exclusões são executadas uma de cada vez dentro do servidor, então a verificação de existência de cada uma é mantida até que sua gravação seja concluída
  • Consulta ciente de semver — versão mais recente retornada quando version é omitido
  • Snapshot _index.json gravado em cada reconstrução para ferramentas externas e depuração
  • WORKFLOWS_DIR, GLOBAL_INSTRUCTIONS_PATH e intervalo de debounce configuráveis

Saída amigável ao agente:

  • Saída discriminada — source: "permanent" | "temp" em cada resposta de workflow_get e códigos de reason tipados (not_found, version_not_found, already_exists, cancelled, confirmation_invalid, target_changed, index_unavailable, …) em falhas, para que os chamadores ramifiquem com base em dados em vez de analisar strings de erro
  • Sem ida e volta extra — workflow_get sempre retorna globalInstructions junto com a definição do workflow na mesma resposta
  • Modelagem de resposta — o sinalizador opcional includeTools de workflow_list pré-deriva os pares únicos de server/tool usados por um workflow, e um resultado vazio ecoa os filtros aplicados com uma dica de ampliação em vez de retornar nada

Começando

Nenhuma chave de API necessária. O servidor lê de um diretório local workflows-yaml/ por padrão.

Adicione o seguinte ao seu arquivo de configuração do 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"
      }
    }
  }
}

Ou com npx (sem Bun necessário):

{
  "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"
      }
    }
  }
}

Ou com 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 Streamable HTTP, defina o transporte e inicie o servidor:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp

Workflows de semente

O repositório inclui um diretório workflows-yaml/ com exemplos de workflows organizados sob categories/. Eles estão prontos para uso como ponto de partida. O arquivo workflows-yaml/global_instructions.md contém instruções que o servidor anexa ao início de cada resposta de workflow_get — edite-o para definir orientações globais para seu agente.

Pré-requisitos

  • Bun v1.4.0 ou superior (ou Node.js v24+).
  • Um diretório local contendo arquivos de workflow YAML (ou use a semente workflows-yaml/ incluída).

Instalação

  1. Clone o repositório:
git clone https://github.com/cyanheads/workflows-mcp-server.git
  1. Navegue para o diretório:
cd workflows-mcp-server
  1. Instale as dependências:
bun install
  1. Configure o ambiente:
cp .env.example .env
# edit .env if needed — most settings have defaults

Configuração

VariávelDescriçãoPadrão
WORKFLOWS_DIRCaminho absoluto ou relativo para o diretório raiz dos workflows../workflows-yaml
GLOBAL_INSTRUCTIONS_PATHCaminho para o arquivo markdown de instruções globais. Deriva de WORKFLOWS_DIR quando não definido.<WORKFLOWS_DIR>/global_instructions.md
WATCHER_DEBOUNCE_MSMilissegundos para debounce de eventos de alteração no sistema de arquivos antes de reconstruir o índice.500
MCP_TRANSPORT_TYPETransporte: stdio ou http.stdio
MCP_HTTP_PORTPorta para o servidor HTTP.3010
MCP_SESSION_MODESessões HTTP: auto ou stateful. O prompt de confirmação de workflow_delete precisa de uma sessão ativa, então a inicialização HTTP com stateless falha com um erro de configuração. Ignorado via stdio.stateful, declarado em src/index.ts
MCP_AUTH_MODEModo de autenticação: none, jwt ou oauth.none
MCP_LOG_LEVELNível de log (RFC 5424).info
OTEL_ENABLEDHabilita instrumentação OpenTelemetry (spans, métricas, logs de conclusão).false

Consulte .env.example para a lista completa de sobrescritas opcionais.


Executando o servidor

Desenvolvimento local

  • Compilar e executar:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • Executar verificações e testes:

    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

O Dockerfile usa por padrão transporte HTTP, modo de sessão com estado (obrigatório — veja MCP_SESSION_MODE acima) e registra logs em /var/log/workflows-mcp-server. Dependências de pares do OpenTelemetry são instaladas por padrão — compile com --build-arg OTEL_ENABLED=false para omiti-las.


Estrutura do projeto

DiretórioFinalidade
src/index.tsPonto de entrada do createApp() — registra ferramentas e inicializa o serviço de índice de workflows.
src/config/Análise e validação de variáveis de ambiente específicas do servidor com Zod.
src/mcp-server/tools/Definições de ferramentas (*.tool.ts).
src/services/workflow-index/WorkflowIndexService — análise YAML, construção de índice, observador, consulta semver, auxiliares de escrita.
tests/Testes unitários e de integração espelhando src/.
workflows-yaml/Biblioteca de workflows de exemplo — categories/ para workflows permanentes, temp/ para rascunhos temporários, global_instructions.md para orientação global de agentes.

Guia de desenvolvimento

Consulte CLAUDE.md para diretrizes de desenvolvimento e regras arquiteturais. A versão resumida:

  • Handlers lançam exceções, o framework captura — sem try/catch na lógica de ferramentas
  • Use ctx.log para registro de logs com escopo de requisição
  • Registre novas ferramentas via o barrel em src/mcp-server/tools/definitions/index.ts
  • Operações de sistema de arquivos passam por WorkflowIndexService, não diretamente nos handlers de ferramentas

Contribuindo

Issues são bem-vindas. Execute verificações e testes antes de enviar:

bun run devcheck
bun run test

Licença

Apache-2.0 — veja LICENSE para detalhes.