vunit-mcp
It is an MCP server that lets an LLM/agent drive a VUnit HDL unit-testing project end to end.
Inspect the project: report server config/simulator availability (
vunit_status), list all tests (vunit_list_tests), and list source files in compile order (vunit_list_files).Build and run: compile all sources (
vunit_compile) and run tests with patterns, threads, clean builds, timeouts, and attribute filters (vunit_run_tests), returning pass/fail summaries and failing test names.Debug failures: re-read the last JUnit report (
vunit_get_report) to see which tests passed/failed, and fetch a single test's log tail with parsed check results (vunit_get_test_log).Analyze waveforms: after running with a waveform format, resolve the recorded waveform file path plus failing-check sim time (
vunit_get_test_waveform) for handoff to a waveform-reading tool.Understand dependencies: get the ordered source files needed to implement a specific test (
vunit_test_dependencies) and export the full project model as JSON (vunit_export_json).No simulator needed for status, listing, report/log/waveform lookup, dependency analysis, or export; only compile/run require a simulator.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vunit-mcplist the tests in the project and run the failing ones"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
vunit-mcp
MCP (stdio) server that lets an LLM/agent drive a VUnit (HDL
unit-testing) project end to end: list tests, compile, run, and inspect
reports, per-test logs, and — for GHDL runs (and NVC on a VUnit with the
headless --wave flag) — record signal waveforms and hand the file path
off to a waveform-reading MCP server.
VUnit has no standalone CLI and VUnit.main() calls sys.exit(), so the
server never runs vunit in-process — it shells out to the project's own
run.py, exactly how a human runs it. The server installs no VUnit at
all: the only VUnit that ever answers a question is the project's own, so
the answers cannot disagree with what the project actually compiles. Even
vunit_test_dependencies ("which files do I need to implement this
test?"), which needs VUnit internal API with no CLI equivalent, runs as a
subprocess under the project's interpreter — see Dependency
probe.
Setup
uv venv .venv
uv pip install -e . # installs vunit-mcp + mcp + pydantic — no vunitVUnit itself belongs to the project, not here. Compile/run also need a
simulator (ghdl, nvc, …) on the PATH of the interpreter that runs
run.py — the project venv, which the server creates and activates for you
(see Project virtualenv).
Waveforms need --wave in the project's VUnit
Headless waveform recording (waveform_format) needs the --wave flag
from upstream PR #1101, which
no released VUnit has yet. Since the server ships no VUnit, whether
waveforms work is decided entirely by what the project installs:
Project's VUnit | GHDL | NVC |
has | vcd, headless | fst, headless |
stock (no | vcd/ghw via the legacy | nothing recorded — the run says so |
vunit_status reports whether the flag is there, and the tool docs tell
the LLM to check it before promising a waveform.
On a VUnit 5.0 prerelease one project-side change applies: VUnit 5 no
longer compiles the HDL builtins by default, so a 4.x-style run.py must
add PROJ.add_vhdl_builtins() after VUnit.from_argv() (VUnit prints the
exact line to add if it is missing).
Related MCP server: squish-mcp
Configuration (env vars)
Variable | Meaning | Default |
| dir containing | server's cwd |
| run script path relative to project dir |
|
| interpreter that runs | the project venv's own python (see below) |
| create a missing project venv with uv ( | enabled |
|
|
|
| max seconds for venv creation + dependency install |
|
| passed through as | VUnit auto-detect |
| default |
|
| max seconds per run/compile |
|
| extra | unset |
| comma-separated patterns (fnmatch globs on file name or project-relative path, or a directory name) of registered files whose content changes must not invalidate the export cache — for generated/volatile files; adding or removing them still does | unset (fingerprint everything) |
Project virtualenv
The project's own virtualenv is always used and activated for every
run.py subprocess — VIRTUAL_ENV set, <venv>/bin first on PATH,
PYTHONHOME cleared, and this server's own venv removed from the
environment — so nested python/pip/console-script lookups made by
run.py itself resolve inside it, not just the top-level interpreter.
Resolution order at startup:
VUNIT_MCP_PYTHON, if set (authoritative; when it points into a venv, that venv is activated too, and nothing is ever created).An existing
<project>/.venv, else<project>/venv.Otherwise one is created with
uv, from whichever of the project's dependency declarations works:uv syncfor apyproject.toml, elseuv venv+uv pip install -r requirements.txt, elseuv venv+uv pip install -r pyproject.toml(a pyproject that only carries tool config falls through torequirements.txtinstead of failing the run).If the project declares no dependencies, or
uvis not installed, the old behavior applies:python3/pythonfromPATH(this server's own venv excluded), andvunit_statusreports why.
Several agents on one code base
vunit_run_tests is serialized by an in-process lock, so one server per agent
removes the only interlock there is. Concurrent run.py invocations share
<project>/vunit_out (compiled libraries, test_output/, junit.xml) and will
clobber each other. Either give each agent its own VUNIT_MCP_OUTPUT_DIR, or —
simpler and fully disjoint — give each agent its own git worktree and start
the server with that worktree as cwd; output dir, venv, export cache and git
index are then separate with no configuration. Venv provisioning is safe
either way: discovery and creation happen under a cross-process lock keyed on
the project path (shared with tsfpga-mcp, which provisions the same venv), so a
server that arrives mid-install waits for the real thing instead of adopting a
virtualenv that has an interpreter but not yet any packages.
MCP client config (Claude Code)
The server has runtime dependencies (mcp, pydantic), so run it with
uvx rather than a raw venv binary — it resolves and installs them into an
isolated environment for you:
{
"mcpServers": {
"vunit": {
"command": "uvx",
"args": ["--from", "/path/to/vunit-mcp", "vunit-mcp"],
"env": {
"VUNIT_MCP_PROJECT_DIR": "/path/to/your/vunit/project"
}
}
}
}--from accepts a local checkout path or a git URL
(--from "vunit-mcp @ git+https://github.com/<owner>/vunit-mcp.git").
A local checkout is installed by content hash, so edits to the server are
picked up automatically; uvx --refresh forces a re-resolve.
VUNIT_MCP_PROJECT_DIR is optional — it defaults to the server's current
working directory — but most MCP hosts launch servers from an arbitrary
directory, so set it explicitly unless you know the host's cwd is the
project.
Or with MCP Inspector for manual testing:
VUNIT_MCP_PROJECT_DIR=/path/to/project npx @modelcontextprotocol/inspector \
uvx --from /path/to/vunit-mcp vunit-mcpSkill
This repo ships an agent skill, skills/vunit-mcp/SKILL.md, that tells the
LLM when and how to use the tools: which tool answers which request,
workflow recipes ("why did test X fail?" → vunit_get_test_log), the
lib.entity[.test_case] test-name format, and the VUNIT_MCP_* configuration.
Install it next to the server so the agent picks it up automatically.
Claude Code
Symlinking keeps the repo checkout as the single source of truth (copy with
cp -r if you prefer a static install):
# personal — available in every project
ln -s /path/to/vunit-mcp/skills/vunit-mcp ~/.claude/skills/vunit-mcp
# or project-local — available only in that project
mkdir -p <your-project>/.claude/skills
ln -s /path/to/vunit-mcp/skills/vunit-mcp <your-project>/.claude/skills/vunit-mcpMaki
Maki loads skills from the same ~/.claude/skills/ directory:
ln -s /path/to/vunit-mcp/skills/vunit-mcp ~/.claude/skills/vunit-mcpTools
Tool | Needs sim | Description |
| no | config, vunit version, simulator availability — call first |
| no | all tests ( |
| no | source files in compile order via |
| yes | compile all sources ( |
| yes | elaborate test benches without running ( |
| yes | run tests (patterns, threads, clean, …); writes JUnit XML; returns pass/fail summary + failing tests. |
| no | answers which tests passed/failed — re-reads the last run's JUnit XML, no re-run, safe to call repeatedly; per-test status + failing-check counts; use it to pick a test before reading its log. |
| no | answers why one test failed — the single test's |
| no | resolves the test's recorded waveform file (requires |
| no | ordered list of source files needed to implement one test (grouped by library, compile order, VUnit built-ins summarized); caches a project model in |
| no | project files, tests, and attributes via |
Export cache
vunit_export_json and vunit_test_dependencies do not re-run
run.py --export-json on every call: the exported model is written to
<project>/.vunit-mcp-cache/export.json together with a fingerprint of its
inputs, and served from that file while the fingerprint matches. The cache
invalidates when:
any registered source file's mtime or size changes, or the file disappears;
run.pyitself changes (covers adding/removing/relocating files);VUNIT_MCP_PYTHON,VUNIT_MCP_SIMULATOR, orVUNIT_MCP_EXTRA_ARGSchange.
Files matching VUNIT_MCP_FINGERPRINT_EXCLUDE (comma-separated fnmatch
globs on file name or project-relative path, or a directory name) are
exempt from the first rule — their mtime/size are not tracked, for
generated or volatile files whose rewrites would churn the cache. Their
name and existence are still tracked, so adding or removing one
invalidates as usual.
To force a fresh export, delete .vunit-mcp-cache/export.json. Dependency
answers are cached additionally, in memory, keyed by export content and
test name.
Dependency probe
Some VUnit questions cannot be answered through the project's own run.py
CLI — e.g. "which files do I need to implement this test?", which needs
VUnit's internal get_implementation_subset. Importing VUnit in the server
would answer it with the wrong VUnit, so instead dependency_probe.py is
executed as a script by the project's interpreter:
<project venv python> dependency_probe.py # request JSON on stdinIt is deliberately self-contained — stdlib + vunit only, never importing
vunit_mcp, since the project venv has vunit-mcp installed nowhere. It
rebuilds a VUnit instance from the cached --export-json model
(libraries and source files registered), calls the internal API, and writes
its reply to <scratch>/result.json rather than stdout, because VUnit logs
to stdout/stderr with no contract that it stays quiet.
That instance is never run through the CLI: the export model lacks the
user's run.py specifics (custom options, test attributes, requirements,
…), so anything that compiles or runs must go through the project's own
run.py.
The scratch dir is <project>/.vunit-mcp-cache/model/<sha256 of export> —
never the project's vunit_out (VUnit would wipe it) and never the
.vunit-mcp-cache root (which holds export.json). VUnit leaves a pickled
project_database there and reloads it next time, which makes it a parse
cache: parsing every source file is the expensive part. That path is
predictable, so a database planted there by a hostile project would be code
execution on pickle.loads; the first probe of each key therefore wipes
any database it did not write itself, and only later probes in the same
server process reuse one.
Log-size policy
Tool output is deliberately bounded so it stays LLM-friendly — raw logs are never dumped in full:
vunit_get_test_logreturns the last 100 lines by default and says so (e.g. "showing last 100 of 3421 lines"); raiselinesfor more. Even an explicit "full" read is capped at ~24 KB (the tail of the file).vunit_compilereturns a 10-line tail on success and an error-line excerpt (error/fatal/failure lines + 2 lines of context) on failure.vunit_elaboratebehaves the same way, but performs a real GHDL elaboration pass (ghdl -e), not just per-file analysis (ghdl -a) — it catches cross-unit errors (port/generic/type mismatches between an entity and its instantiations) thatvunit_compilemisses whenever the mismatched entity isn't exercised by a currently-selected test.All other raw-output fallbacks (failed
run.py, unparseable output) are tail-truncated to 4 000 chars, keeping the end where errors and result lines live.vunit_run_tests/vunit_get_reportreturn the parsed JUnit summary (counts + failing test names) rather than raw output.vunit_export_jsoninlines the JSON only below 8 000 chars; above that it returns counts + file/test name lists.Waveforms are never read or dumped by this server:
vunit_get_test_waveformreturns the recorded file's path (plus the failing check's sim time), and the actual waveform analysis happens in a separate waveform-reading MCP server that receives that path.vunit_list_files/vunit_export_jsonlist project files only; VUnit built-in library sources (installed package files) are summarized as a count, since they are stable and not part of the project.
Development
uv pip install -e ".[dev]"
uv run pytest tests/ # pure parsers — no simulator required
uv run ruff check src/ tests/
uv run mypy src/vunit_mcp/A few tests exercise dependency_probe.py for real and need a VUnit; they
skip unless one is installed. To run them, sync the non-default e2e
dependency group — the only place vunit-hdl appears in this repo:
uv sync --group e2e
uv run pytest tests/Available Tools
9 toolsvunit_compileAIdempotent
Compile all sources in the VUnit project (--compile). Requires a simulator. Safe to re-run.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark idempotentHint=true and readOnlyHint=false; the description adds the simulator requirement and the 'all sources' scope, but does not describe side effects on build artifacts or what happens if the simulator is unavailable. It aligns with idempotency rather than contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences carry the primary action, scope, prerequisite, and safety property with no filler. Useful information is front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless tool with an output schema and safety annotations, the description is largely sufficient. It could be stronger by placing the tool in the VUnit workflow (compile before run_tests) and by noting build-artifact side effects, but nothing essential is missing for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema documents 100% of them (none), so the description does not need parameter-level detail. Baseline for zero params applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the action ('Compile') and the exact scope ('all sources in the VUnit project'), and anchors it to the CLI flag --compile. This is clearly distinct from sibling tools such as list_files, run_tests, and status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear context and prerequisite: the command requires a simulator, and re-running is safe. It does not explicitly contrast with siblings or say when not to use it, but an agent can infer this is the build/pre-step versus run_tests.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_export_jsonARead-only
Export the project model (source files, all tests, attributes) as JSON via --export-json. Attributes carry requirement/traceability data. The export is cached at .vunit-mcp-cache/export.json in the project and re-run only when the project's sources change. Does not require a simulator.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true and openWorldHint=false. The description goes beyond this by revealing non-obvious behavior: the export is cached at .vunit-mcp-cache/export.json and re-run only when project sources change. It also discloses that no simulator is required. These are meaningful behavioral traits not captured in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: purpose and contents, attribute meaning, and caching/no-simulator behavior. There is no redundancy, fluff, or repetition of what the schema or annotations already convey.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only export tool with an output schema, the description is complete. It tells the agent what is exported, that the result is cached and when it is refreshed, and that no simulator is required. Nothing an agent needs to correctly invoke this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description carries no parameter semantics burden. Schema coverage is trivially complete. The baseline for a 0-parameter tool is 4, and the description appropriately omits parameter information that would be irrelevant.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Export the project model (source files, all tests, attributes) as JSON.' It enumerates what is included, mentions the exact CLI flag (--export-json), and even notes that attributes carry requirement/traceability data. This clearly distinguishes it from siblings like vunit_list_tests or vunit_list_files, which only cover subsets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides useful context such as 'Does not require a simulator' and the caching re-run condition, which helps an agent understand when the tool is feasible. However, it never explicitly tells the agent when to choose this tool over alternatives like vunit_list_tests or vunit_list_files, nor names them. The usage guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_get_reportARead-only
Re-read the last run's JUnit report from the output dir (no re-run). Returns per-test status, with the number of failing VUnit checks per test when its log shows any. Pass a failing test name to vunit_get_test_log to see why it failed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this with 'no re-run' and 're-read', making the read-only nature explicit. It adds behavioral details beyond annotations: it reads from the output dir, returns per-test status, and conditionally includes failing-check counts. This is valuable context without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, with the core action front-loaded in the first sentence. The second sentence adds return semantics and a cross-reference to a sibling tool. Every word earns its place; there is no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only tool with an output schema, the description fully covers what the agent needs to know: what it does, what it returns, and how to follow up on failures. The output schema explains return structure, so not describing it here is appropriate. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description has no parameter meanings to add. Per the rubric, 0 params yields a baseline of 4, and the description appropriately focuses on the return value instead of inventing parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states a specific verb and resource: 'Re-read the last run's JUnit report from the output dir'. The phrase 'no re-run' explicitly differentiates it from vunit_run_tests. It also specifies the return content (per-test status and failing checks), leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool (after a run, to inspect results without re-running) and points to the alternative vunit_get_test_log for deeper investigation of a specific failing test. While it doesn't explicitly say 'use this instead of X' for all siblings, the pointer to the log tool and the emphasis on no re-run give sufficient guidance for routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_get_test_logARead-only
Get the log output for one test (the per-test output.txt), which is
how you see WHY a test failed. test_name is the full name from
vunit_list_tests / vunit_get_report. Returns the last 100 lines by
default (failure info appears at the end); pass a larger lines for
more context. When the log contains failing VUnit checks, a
structured "Check results" section is appended after the log.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations mark readOnlyHint=true, the description adds valuable behavioral details: the tool returns the last 100 lines by default, failure info appears at the end, and a structured 'Check results' section is appended when failing checks are present. It also notes the size cap ('~24 KB max') via the parameter description, but the tool description itself conveys the relevant default behavior and appended section. No contradictions with annotations exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: purpose, parameter source, and behavior. It is front-loaded with the core purpose and avoids any fluff. Every sentence adds actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only log retrieval tool with one required parameter and an output schema, the description provides all necessary context: why to use it, how to specify the test, what the default output is, how to get more context, and when an extra structured section appears. Nothing critical is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides descriptions for both parameters (lines and test_name), so the tool description does not need to repeat basic definitions. But it adds contextual meaning by linking test_name to sibling tools ('full name from vunit_list_tests / vunit_get_report') and explaining the rationale for the lines default (failure info at end). The 'Check results' detail is not in the schema, so the description compensates for any gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get the log output for one test', a specific verb and resource, and immediately clarifies its purpose: 'which is how you see WHY a test failed.' This clearly distinguishes it from sibling tools like vunit_list_tests (lists tests) and vunit_get_report (report-level data), making the tool's role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent that test_name comes from vunit_list_tests / vunit_get_report, implying the caller should first obtain a test name from those tools. It also gives concrete usage guidance: the default 100 lines is enough for failure info, increasing lines gives more context. However, it does not explicitly name alternatives or when-not-to-use cases, so it stops short of a fully explicit usage policy.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_list_filesARead-only
List all source files in compile order. Does not require a simulator.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds non-obvious behavioral context: the listing is in compile order and needs no simulator. This goes beyond the schema and annotations, though it doesn't detail output format or failure modes; given the output schema and read-only annotation, this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The core function is stated first, followed by a useful environment note; every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only tool with an output schema, the description covers what the tool does and a key environmental constraint (no simulator needed). Nothing required to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the empty schema fully documents the interface. The baseline for 0 parameters is 4; there is no parameter information the description would need to compensate for.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and identifies the resource ('all source files') plus an ordering property ('in compile order'). It clearly differentiates from the sibling vunit_list_tests, which lists tests rather than source files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Does not require a simulator' gives useful usage context, indicating the tool works without simulator setup. However, it does not explicitly contrast this tool with alternatives like vunit_list_tests or vunit_compile, so when-to-use guidance remains implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_list_testsARead-only
List all test cases (lib.entity[.proc]) the project knows about. Does not require a simulator.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already flags this as a safe read operation. The description adds value by specifying the output format (lib.entity[.proc]) and the notable behavior that a simulator is not required, which is not captured in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. It front-loads the core action and resource, then adds the format and simulator requirement efficiently. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, read-only, zero-parameter tool with an output schema present, the description provides all necessary information: what it lists, in what format, and under what conditions (no simulator). Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema leaves nothing undocumented. The description's mention of the test case format adds context that complements the empty parameter list, satisfying the baseline for no-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'List' with a clear resource 'all test cases' and defines the format (lib.entity[.proc]). This unambiguously distinguishes it from sibling tools like vunit_list_files and vunit_status, which serve different purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clarifies that this tool lists tests the project knows about and explicitly notes that it does not require a simulator. This provides clear context for when it is applicable, though it does not explicitly compare against alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_run_testsA
Run VUnit tests and return a pass/fail summary plus the list of failing tests. Patterns default to ['*'] (run everything). A JUnit XML is always written next to the output dir for vunit_get_report. Requires a simulator.
| Name | Required | Description | Default |
|---|---|---|---|
| input | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations are sparse (readOnlyHint=false, openWorldHint=false), so the description carries the transparency burden. It discloses the always-written JUnit XML, the pattern default, and the simulator requirement—useful behavioral facts. However, it omits other side effects like filesystem changes or potential long-running execution.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no redundancy: the first states the core action and result, the second explains the default patterns, and the third notes the JUnit XML location and simulator requirement. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite many parameters, the description covers the essential operation, its output, a key artifact, and a prerequisite. The output schema exists, so return-value details are handled. A minor gap is not mentioning the compile prerequisite, but the sibling vunit_compile makes that obvious.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Top-level schema description coverage is 0%, so the description must compensate for parameter guidance. It mentions only the test_patterns default and leaves the other eight parameters to the nested schema. This is insufficient given the low coverage signal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb+resource: 'Run VUnit tests', and specifies the outputs: a pass/fail summary and the list of failing tests. It also distinguishes itself from the sibling vunit_get_report by noting the JUnit XML is written for that tool, making the purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides practical context: default test patterns ('*' runs everything), a prerequisite ('Requires a simulator'), and a pointer to vunit_get_report for the report artifact. It does not explicitly state when not to use it, but the 'for vunit_get_report' hint implies the companion flow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_statusARead-only
Report server configuration: project dir, run script, interpreter, VUnit version, and whether a simulator appears available. Call this first when diagnosing setup problems.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description reinforces this by saying 'Report' rather than implying mutation. It adds useful context by stating what configuration items are inspected and candidly notes that simulator availability is only 'appears available,' setting proper expectations about the check's certainty.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence front-loads the tool's exact purpose and report contents, while the second gives a clear usage directive. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a zero-parameter status tool. It covers what the tool reports, when to call it, and the tentative nature of the simulator-availability check. The presence of an output schema means return-value details do not need to be in the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and an empty input schema, so there are no parameter semantics to explain. This matches the baseline for no-parameter tools; the description focuses on output content rather than input handling, which is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Report' and identifies a clear resource: server configuration. It enumerates the exact content (project dir, run script, interpreter, VUnit version, simulator availability), making the tool's purpose unambiguous and distinct from sibling tools that list tests, compile, run, or fetch reports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Call this first when diagnosing setup problems' explicitly states when to invoke the tool. It also implies a sequencing role relative to the sibling tools, providing clear usage guidance without needing to mention every alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vunit_test_dependenciesARead-only
Return the ordered list of source files needed to implement one test case: the files it depends on to elaborate, grouped by library in compile order (VUnit built-in files summarized as a count). Does not compile and needs no simulator.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal read-only behavior; the description adds useful non-obvious details: no compilation occurs, no simulator is needed, and VUnit built-in files are summarized as a count rather than fully enumerated. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences: the first front-loads the returned data and its ordering/grouping, and the second gives the key no-side-effect constraint. Every sentence earns its place with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only dependency query, the description plus schema fully covers what is returned, how it is grouped/ordered, and the fact that no compile or simulator is required. The output schema also exists, so return-value documentation beyond this is not necessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description says 'one test case' but does not explain how test_name selects it or how wildcard patterns behave. The input schema's test_name description already covers full names, wildcards, and ambiguous matches, so the main description provides only marginal semantic addition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb and resource: returning the ordered source-file dependency list for one test case, grouped by library in compile order. It also clearly separates this from compile/run tools by noting it does not compile and needs no simulator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description frames this as a lightweight dependency/elaboration inspection tool and explicitly states no compile or simulator is required, which helps the agent choose it for static dependency questions. It does not name sibling alternatives or give explicit when-not-to-use conditions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.1.0- First observed
vunit_compile - First observed
vunit_export_json - First observed
vunit_get_report - First observed
vunit_get_test_log - First observed
vunit_list_files - First observed
vunit_list_tests - First observed
vunit_run_tests - First observed
vunit_status - First observed
vunit_test_dependencies
TDQS
Scored across 9 tools
Each tool targets a distinct concern: configuration health, test listing, file listing, compilation, running, report retrieval, per-test logs, JSON export, and dependency resolution. There is no meaningful overlap even between get_report and get_test_log because one is the aggregate results summary and the other is the raw output for a single test.
All tools share the vunit_ prefix and mostly follow a verb_noun pattern (list_tests, list_files, run_tests, get_report, get_test_log, export_json). Minor deviations like vunit_status and vunit_compile are still readable and do not create confusion.
Nine tools is well-scoped for a VUnit test project workflow. Each tool covers a distinct step from inspection and compilation through running tests and debugging failures, and none feels redundant or extraneous.
The tool set covers the full practical VUnit workflow: diagnosing setup, discovering tests and files, compiling, running, retrieving aggregate results, inspecting per-test logs, exporting project data, and tracing test dependencies. There are no obvious dead ends that would prevent an agent from completing a typical build-and-debug cycle.
Maintenance
Related MCP Connectors
Read a project's prompts, logs and agents, and send new work to the agent on your own machines.
Provides capabilities that let LLM agents perform a range of infrastructure management tasks.
Agentic CI operations for build inspection, failure diagnosis, and runner troubleshooting.
Create RF signal projects from prompts, inspect graphs, and export IQ data.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables AI assistants to run, list, and analyze Lupa test suites, returning structured JSON results for debugging.49Apache 2.0

squish-mcpofficial
FlicenseAqualityFmaintenanceEnables AI agents to run and create Squish test scripts and test suites and analyze the results.1913-- AlicenseNot gradedqualityBmaintenanceProvides LLMs and AI agents safe, structured, read-only access to verification artifacts for deterministic triage and root-cause analysis. Supports UVM, cocotb, and SystemVerilog verification ecosystems.4Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides LLM clients a safe, structured interface to Intel Quartus Prime 25.1 FPGA flows, enabling linting, simulation, and asynchronous compilation with results returned as concise JSON.GPL 3.0