What vouchfx-mcp is¶
vouchfx-mcp is a local stdio Model Context Protocol server for
AI coding agents. It wraps the packaged vouchfx engine —
a compiler and runner for declarative .e2e.yaml integration-test suites that prove a distributed .NET
system end-to-end, across a REST call, a Kafka event, a database mutation and an outbound webhook — so
an agent can validate, run and diagnose a suite directly, without shelling out to vouchfx and parsing
its console output by hand.
It does not build or embed the engine. It spawns the published vouchfx command-line tool as a
subprocess for suite runs and for the live step-type catalogue (vouchfx list --json), and
vendors byte-exact copies of the engine's JSON Schema and documentation for offline suite validation
and doc search — see Install & registration and the engine pin below.
The eighteen tools, at a glance¶
| Tool | What it does |
|---|---|
validate_suite |
Validates an .e2e.yaml suite from a file or inline YAML against the engine's JSON Schema and ten semantic rules (eleven codes, one reserved) at a chosen validation level (schema, semantic, or full), without running it. |
normalize_suite |
Returns a suite's canonical text and its full validation result to the HOST. Normalization is opt-in (comment loss is permanent, and the result says so via commentsDropped); without it, returns the validation result wrapped with null. The canonical text is proved to re-parse to the same document before it is returned — otherwise normalizedYaml is null with a normalizationRefused reason. The server never writes; the host decides whether and where to write the returned text. |
list_step_types |
Lists every step type the pinned engine supports, grouped by family. |
describe_step_type |
Returns one step type's full required/optional field contract. |
search_docs |
Free-text search over the vendored language reference and recipe library. |
plan_coverage |
Deterministic, read-only coverage-and-gap analysis over a declared suite set and an optional event history (Planner). |
scaffold_suite |
Generates a machine-drafted, schema-valid .e2e.yaml skeleton from structured step types, ids, and an environment outline (Generator). |
run_suite |
Runs a suite through the installed vouchfx CLI and reports its taxonomy-faithful verdict. |
explain_run |
Diagnoses a completed run purely by reading its JSON Lines event stream — never re-running anything. |
diagnose_run |
Healer: same taxonomy diagnosis as explain_run, plus two proposal kinds — Fail review patches and EnvironmentError/Inconclusive scoped spec-edit proposals (never auto-applied). |
explain_diagnostic |
Looks up one catalogued VFX-D-####/VFX-E-#### code and returns its title, explanation, common causes, and fixes. |
get_schema |
Returns the composed JSON Schema — the whole document or one addressable section — as a schema document or markdown digest. |
get_run_events |
Pages a completed run's raw JSON Lines events exactly as the engine wrote them — filtered by event type and step before paging, with an opaque cursor. For hosts building their own timeline instead of consuming explain_run's summary. |
get_run_status |
Returns one run's current lifecycle state from the persisted run registry — status, verdict, timestamps, the suites it covered, its events file, and its labels. |
cancel_run |
Asks an in-flight run to stop, through exactly the graceful-stop mechanism run_suite already uses. A cancelled run is Inconclusive, never Fail. |
list_runs |
Pages the run registry newest first, filtered by label and/or start time, with the same opaque cursor contract get_run_events uses. |
get_step_timeline |
Returns one step's complete RETRY attempt timeline from a finished run. explain_run shrinks its own attempt arrays under response-size pressure; this tool never shortens the list, dropping per-attempt evidence text instead. |
get_run_artifacts |
Reports what a finished run left behind — its event-stream artefact and the environment resources the run's own events named. Honestly partial: every result carries partial: true and a gaps array naming each field this build cannot populate and why. |
The full field-level contract, result shape and notable behaviours for each tool are on the tool & resource reference page.
Documentation resources¶
Alongside the eighteen tools, the server advertises two static MCP resources — the generated
vouchfx language reference and the vouchfx recipes library, each the byte-exact vendored copy of
the pinned engine commit's own Markdown documentation — plus a templated diagnostic catalogue
resource family (vouchfx-docs:///errors/{code}) covering every code explain_diagnostic can explain.
An agent can read any of them directly as a resource, or reach the vendored-document content indirectly
through search_docs. See Resources for all three.
Planner workflow (plan → scaffold → validate → run)¶
For a team with a suite folder and a pile of run history but no mechanical way to see what to test
next, plan_coverage (Spec D / M3 Planner) answers "what should I test next?" deterministically:
- Host calls
plan_coveragewith the declared suite path (and, optionally, the event historyrun_suitewrites). A call that finds gaps is a successful result — gaps are the data this tool exists to surface, never an error. - The host picks a gap finding and passes its
suggestedTypes[0]/suggestedStepIdunchanged intoscaffold_suite's ownsteps[].type/steps[].id— no re-derivation needed. - Continue the Generator path below: fill semantics,
validate_suite,run_suite.
plan_coverage never writes a suite file, never calls a model, and never invokes git — see
plan_coverage for the full finding-kind list and threshold
overrides.
Generator workflow (scaffold → validate → run)¶
Authoring is the adoption bottleneck: free-text goals live only in the host LLM (Claude Code, an
MCP-capable IDE, etc.). This server never hosts a model and never accepts free text on
scaffold_suite. The deterministic path is:
- Host LLM turns a free-text goal into structured step types and ids (using
list_step_types/describe_step_typefor catalogue grounding — Spec A). - Host calls
scaffold_suitewith structured args only (steps, optional services/dependencies). - Host LLM (or human) fills semantics in the returned YAML skeleton (paths, queries, expects).
- Host calls
validate_suite, thenrun_suite.
Scaffold output is schema-valid with placeholders, marked as machine-drafted (provenance
comments); a human must review before trust. Secrets appear only as ${secret:…} references, never
literals. See scaffold_suite. Humans are not expected to
maintain a parallel JSON-intent product as primary UX — intent JSON is an engine CLI transport detail.
Healer workflow (run → explain/diagnose → human applies)¶
After a suite run fails or is unclear, authors and MCP hosts use the Healer path (M2):
- Host calls
run_suite(events file path returned). - Host calls
explain_runand/ordiagnose_runon that events path (or omits the path to default to the most recent finished run in the registry, which spans server restarts when launched with--workspace). diagnose_runreturns two kinds of review-only proposals: - Fail steps: patch proposals (stepId,rationale, unified-diff stylepatch) for genuine product failures with observation evidence. - EnvironmentError/Inconclusive: scoped spec-edit proposals (stepIdor null,scopeone of environment/timeouts/match/capture,rationale, YAML fragmentsuggestedEdit) when the reason classifier assigned a structured reason to the outcome. The host LLM may refine wording; this server never auto-applies, never writes the suite file, and never hosts a model.- A human (or host under human review) applies any accepted change, then re-validates and re-runs.
Proposal scoping: Fail steps get review patch proposals only. EnvironmentError/Inconclusive get scoped spec-edit proposals only (never suite-rewrite patches for Fail). EnvironmentError additionally returns infrastructure guidance (image pull, health, provision) alongside (not instead of) spec-edit proposals. Inconclusive may include guidance but gets proposals only when the reason classifier assigned a kind. Free text belongs only in the host conversation — not as a diagnose tool parameter. See diagnose_run.
Status: early prerelease¶
This project is being built spec-first: features land against approved specs in a spec → build → review loop, one requirement at a time. As things stand:
- All eighteen tools, both vendored-document resources, and the diagnostic catalogue resource are real, fully functional implementations — not stubs. The server is feature-complete for its current scope.
validate_suite,search_docs, andexplain_diagnosticwork from embedded vendored/catalogue content and keep working when thevouchfxCLI is not installed.get_schema(CLI-optional) serves the embedded composed schema offline and optionally cross-verifies it against a running CLI when one matchingENGINE_PINis present, reporting any divergence as a diagnostic on the still-successful result.list_step_typesanddescribe_step_typeload the live shape-level catalogue from the pinned engine viavouchfx list --json(required/optional fields, capture support, family intent). They require a CLI that implements Spec A (engine-schema-and-catalogue-export) and fail fast rather than returning type keys alone without field metadata.plan_coveragerequires a CLI that implements the M3 Planner (vouchfx plan --json). The currentENGINE_PIN(v1.0.0-rc.4) implements it. MCP CI tests use a fake CLI so they stay green regardless of what CLI (if any) is installed on the runner.scaffold_suiterequires a CLI that implements Spec B (vouchfx scaffold --intent). The currentENGINE_PIN(v1.0.0-rc.4) implements it. MCP CI tests use a fake CLI so they stay green regardless of what CLI (if any) is installed on the runner.run_suitespawns thevouchfxCLI (and, through it, Docker).explain_run,diagnose_run,get_run_events,get_step_timelineandget_run_artifactsonly ever read a local events file — never re-run anything.get_run_statusandlist_runsread only the run registry, so they need neither an events file nor a CLI, and none of the seven ever takes the workspace run lock — they are safe to call while a run is in flight.get_run_artifactsis deliberately partial while the engine exposes no artifacts directory: it returns what the run registry and the run's own event stream hold, marks every resultpartial: true, and names each missing field in agapsarray rather than leaving an empty array to be interpreted.cancel_runneeds no CLI either, but is not read-only: it stops an in-flight run through exactly the graceful mechanismrun_suiteuses. Cancellation reaches only runs held by the server process you are calling — a run held by another server process against the same workspace is refused by name (VFX-E-1507) rather than silently reported as cancelled, because there is no IPC channel through the file lock that serialises them. Asynchronous (wait: false) execution, which would make this a full detached-run workflow rather than a way to manage a blocking one, awaits upstream ask U4.- The
Vouchfx.Mcppackage is built as adotnet tool(PackAsTool, commandvouchfx-mcp) but has not yet had a tagged release published to NuGet.org — what remains is the first tagged release. Expect rough edges; see Install & registration for what that means in practice today.
The engine pin¶
This server never builds the vouchfx engine from source. It is currently pinned to
v1.0.0-rc.4 (commit be12ebd126fdf03dcea9eade7bcec3afbcba001b) — recorded in this repository's
ENGINE_PIN file, which explains
exactly what each field pins, how the vendored schema and documentation stay drift-gated against it, and
how the pin is advanced over time. run_suite, list_step_types, describe_step_type, plan_coverage,
and scaffold_suite refuse to use a mismatched or missing CLI — a mismatch is always a structured result,
never silent behavioural drift; see Troubleshooting.
Minimum engine for the live catalogue¶
Shape-level catalogue tools need Spec A on the installed engine: vouchfx schema and a rich
vouchfx list --json document where every entry carries requiredFields, optionalFields,
captureSupported, and familyIntent. Engines that only emit thin type/family/provider keys are
rejected with an explicit error (EDGE-004). Advance ENGINE_PIN to a published build that includes
that export when it is available; this server does not invent field metadata from a thin list.
Minimum engine for plan_coverage (Planner)¶
plan_coverage needs the M3 Planner on the installed engine: vouchfx plan <path> [--events
<path>] --json. ENGINE_PIN (v1.0.0-rc.4) implements it. If a LOCALLY installed CLI still lacks that
subcommand (predates the pin), the tool returns a clear CLI-unavailable error rather than inventing a
report locally (CLI and MCP must not drift) — advancing ENGINE_PIN further in future remains a
release step, never a silent in-server fallback.
Minimum engine for scaffold (Generator)¶
scaffold_suite needs Spec B on the installed engine: vouchfx scaffold --intent <file|->.
ENGINE_PIN (v1.0.0-rc.4) implements it. If a LOCALLY installed CLI still lacks that subcommand
(predates the pin), the tool returns a clear CLI-unavailable error rather than inventing YAML locally
(CLI and MCP must not drift) — advancing ENGINE_PIN further in future remains a release step, never
a silent in-server fallback.
Secret hygiene¶
vouchfx-mcp never resolves ${secret:...} references itself, and never reads or echoes its own
process environment into a tool result, progress notification, or resource. The vouchfx engine remains
the sole redaction authority: the --events JSON Lines fields run_suite and explain_run relay are
already redacted at source, and this server passes them through untouched. The vouchfx CLI child
process inherits this server's environment unmodified, which is what lets a suite's own
${secret:env/...} reference resolve inside the engine — this server never builds or reads that
environment for any other purpose.
Where to go next¶
- Install & registration — get the tool on your machine and registered with your MCP client.
- Tool & resource reference — the full contract for every tool and resource.
- Troubleshooting — the CLI pin, Docker, and timeout scenarios you are most likely to hit.