MCP Eval Runner

Estrutura de teste padronizada para servidores MCP e fluxos de trabalho de agentes

Documentação

MCP Eval Runner

pacote npm mcp-eval-runner

Um harness de testes padronizado para servidores MCP e fluxos de trabalho de agentes. Defina casos de teste como fixtures YAML (etapas → chamadas de ferramentas esperadas → saídas esperadas), execute suítes de regressão diretamente do seu cliente MCP e obtenha resultados de aprovação/reprovação com diffs — sem sair do Claude Code ou Cursor.

Referência de ferramentas | Configuração | Formato de fixture | Contribuição | Solução de problemas | Princípios de design

Principais recursos

  • Fixtures YAML: Casos de teste são arquivos simples no controle de versão — passíveis de diff, revisão e compartilhamento.
  • Dois modos de execução: O modo ao vivo inicia um servidor MCP real e chama ferramentas via stdio; o modo de simulação executa asserções contra expected_output sem um servidor.
  • Asserções combináveis: Combine output_contains, output_not_contains, output_equals, output_matches, schema_match, tool_called e latency_under por etapa.
  • Encadeamento de saída entre etapas: Referencie a saída de uma etapa anterior nas entradas de etapas subsequentes via {{steps.<step_id>.output}}.
  • Relatórios de regressão: Compare a execução atual com qualquer execução anterior e identifique o que mudou.
  • Modo de observação (watch): Reexecuta automaticamente a fixture afetada quando arquivos mudam.
  • Pronto para CI: Inclui uma GitHub Action para executar evals a cada alteração de configuração.

Requisitos

  • Node.js v22.5.0 ou mais recente.
  • npm.

Primeiros passos

Adicione a seguinte configuração ao seu cliente MCP:

{
  "mcpServers": {
    "eval-runner": {
      "command": "npx",
      "args": ["-y", "mcp-eval-runner@latest"]
    }
  }
}

Por padrão, as fixtures de eval são carregadas de ./evals/ no diretório de trabalho atual. Para usar um caminho diferente:

{
  "mcpServers": {
    "eval-runner": {
      "command": "npx",
      "args": ["-y", "mcp-eval-runner@latest", "--fixtures=~/my-project/evals"]
    }
  }
}

Configuração do cliente MCP

Amp · Claude Code · Cline · Cursor · VS Code · Windsurf · Zed

Seu primeiro prompt

Crie um arquivo em evals/smoke.yaml. Use o modo ao vivo (recomendado) incluindo um bloco server:

name: smoke
description: "Verify eval runner itself is working"
server:
  command: node
  args: ["dist/index.js"]
steps:
  - id: list_check
    description: "List available test cases"
    tool: list_cases
    input: {}
    expect:
      output_contains: "smoke"

Em seguida, digite o seguinte no seu cliente MCP:

Run the eval suite.

Seu cliente deve retornar um resultado de aprovação/reprovação para o teste de fumaça (smoke test).

Formato de fixture

Fixtures são arquivos YAML (ou JSON) colocados no diretório de fixtures. Cada arquivo define um caso de teste.

Campos de nível superior

CampoObrigatórioDescrição
nameSimNome exclusivo para o caso de teste
descriptionNãoDescrição legível por humanos
serverNãoConfiguração do servidor — se presente, executa em modo ao vivo; se ausente, executa em modo de simulação
stepsSimMatriz de etapas a executar

Bloco server (modo ao vivo)

server:
  command: node # executable to spawn
  args: ["dist/index.js"] # arguments
  env: # optional environment variables
    MY_VAR: "value"

Quando server está presente, o eval runner inicia o servidor como um processo filho, conecta-se via transporte MCP stdio e chama a ferramenta de cada etapa contra o servidor ao vivo.

Matriz steps

Cada etapa tem os seguintes campos:

CampoObrigatórioDescrição
idSimIdentificador exclusivo dentro da fixture (usado para encadeamento de saída)
toolSimNome da ferramenta MCP a ser chamada
descriptionNãoDescrição legível da etapa
inputNãoMapa chave-valor de argumentos passados para a ferramenta (padrão: {})
expected_outputNãoString literal usada como saída no modo de simulação
expectNãoAsserções avaliadas contra a saída da etapa

Modos de execução

Modo ao vivo — a fixture tem um bloco server:

  • O servidor é iniciado e cada etapa chama a ferramenta nomeada via MCP stdio.
  • As asserções são executadas contra a resposta real da ferramenta.
  • Erros do servidor fazem a etapa (e, por padrão, o caso) falhar imediatamente.

Modo de simulação — sem bloco server:

  • Nenhum servidor é iniciado.
  • A saída de cada etapa é obtida de expected_output (ou string vazia se ausente).
  • As asserções são executadas contra essa saída estática.
  • Útil para autoria e execuções de teste (dry-run) em CI, mas as asserções output_contains sempre falharão se expected_output não estiver definido.

Tipos de asserção

Todas as asserções ficam dentro do bloco expect de uma etapa:

expect:
  output_contains: "substring" # output includes this text
  output_not_contains: "error" # output must NOT include this text
  output_equals: "exact string" # output exactly matches
  output_matches: "regex pattern" # output matches a regular expression
  tool_called: "tool_name" # verifies which tool was called
  latency_under: 500 # latency in ms must be below this threshold
  schema_match: # output (parsed as JSON) matches JSON Schema
    type: object
    required: [id]
    properties:
      id:
        type: number

Todas as asserções em um único bloco expect são avaliadas; a etapa falha se qualquer asserção falhar.

Encadeamento de saída entre etapas

Referencie a saída de uma etapa anterior no input de uma etapa subsequente usando {{steps.<step_id>.output}}:

steps:
  - id: search_step
    tool: search
    input:
      query: "mcp eval runner"
    expected_output: "result: mcp-eval-runner v1.0"
    expect:
      output_contains: "mcp-eval-runner"

  - id: summarize_step
    tool: summarize
    input:
      text: "{{steps.search_step.output}}"
    expected_output: "Summary: mcp-eval-runner v1.0"
    expect:
      output_contains: "Summary"

O encadeamento funciona tanto no modo ao vivo quanto no modo de simulação.

Nota sobre create_test_case

Fixtures criadas com a ferramenta create_test_case não incluem um bloco server. Elas sempre são executadas no modo de simulação. Para usar o modo ao vivo, adicione um bloco server manualmente ao arquivo YAML gerado.

Ferramentas

Execução

  • run_suite — executa todas as fixtures no diretório de fixtures; retorna um resumo de aprovação/reprovação
  • run_case — executa uma única fixture nomeada pelo nome
  • list_cases — enumera as fixtures disponíveis com contagens de etapas e descrições

Autoria

  • create_test_case — cria um novo arquivo de fixture YAML (modo de simulação; sem bloco server)
  • scaffold_fixture — gera uma fixture modelo com etapas de espaço reservado e comentários de asserção pré-preenchidos

Relatórios

  • regression_report — compara o estado atual da fixture com a última execução; identifica regressões e correções
  • compare_results — compara duas execuções específicas pelo ID da execução
  • generate_html_report — gera um relatório HTML de arquivo único para uma execução concluída

Operações

  • evaluate_deployment_gate — portão de CI; falha se a taxa de aprovação recente cair abaixo de um limite configurável
  • discover_fixtures — descobre arquivos de fixture em um ou mais diretórios (respeita FIXTURE_LIBRARY_DIRS)

Configuração

--fixtures / --fixtures-dir

Diretório de onde carregar os arquivos de fixture de eval YAML/JSON.

Tipo: string Padrão: ./evals

--db / --db-path

Caminho para o arquivo de banco de dados SQLite usado para armazenar o histórico de execuções.

Tipo: string Padrão: ~/.mcp/evals.db

--timeout

Tempo máximo em milissegundos para aguardar uma única etapa antes de marcá-la como falha.

Tipo: number Padrão: 30000

--watch

Observa o diretório de fixtures e reexecuta a fixture afetada automaticamente quando os arquivos mudam.

Tipo: boolean Padrão: false

--format

Formato de saída para resultados de eval.

Tipo: string Opções: console, json, html Padrão: console

--concurrency

Número de casos de teste a executar em paralelo.

Tipo: number Padrão: 1

--http-port

Inicia um servidor HTTP nesta porta em vez do transporte stdio.

Tipo: number Padrão: desabilitado (usa stdio)

Passe as flags pela propriedade args na sua configuração JSON:

{
  "mcpServers": {
    "eval-runner": {
      "command": "npx",
      "args": ["-y", "mcp-eval-runner@latest", "--watch", "--timeout=60000"]
    }
  }
}

Princípios de design

  • Sem mocks: Evals em modo ao vivo são executados contra servidores reais. Correção é inegociável.
  • Fixtures são texto: YAML/JSON no controle de versão; sem formatos proprietários ou bancos de dados.
  • Dogfooding em primeiro lugar: A própria fixture de smoke test do eval runner testa o próprio eval runner.

Verificação

Antes de publicar uma nova versão, verifique o servidor com o MCP Inspector para confirmar que todas as ferramentas estão expostas corretamente e que o handshake do protocolo é bem-sucedido.

Interface interativa (abre o navegador):

npm run build && npm run inspect

Modo CLI (scriptado / amigável para CI):

# List all tools
npx @modelcontextprotocol/inspector --cli node dist/index.js --method tools/list

# List resources and prompts
npx @modelcontextprotocol/inspector --cli node dist/index.js --method resources/list
npx @modelcontextprotocol/inspector --cli node dist/index.js --method prompts/list

# Call a tool (example — replace with a relevant read-only tool for this plugin)
npx @modelcontextprotocol/inspector --cli node dist/index.js \
  --method tools/call --tool-name list_cases

# Call a tool with arguments
npx @modelcontextprotocol/inspector --cli node dist/index.js \
  --method tools/call --tool-name run_case --tool-arg name=smoke

Execute antes de publicar para detectar regressões no registro de ferramentas e na inicialização do runtime.

Contribuição

Novos tipos de asserção vão em src/assertions.ts — implemente a interface Assertion e adicione um teste. Testes de integração ficam em tests/ como testes unitários e em evals/ como fixtures de eval.

npm install && npm test

MCP Registry e Marketplace

Este plugin está disponível em:

Pesquise por mcp-eval-runner.