> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crucihil.io/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Tools Reference

> Complete parameter and return value reference for all 18 CruciHiL MCP tools

## Rig management

### `list_rigs`

List all registered rigs with connection status.

**Parameters:** None

**Returns:**

```json theme={null}
[
  {
    "name": "bench_01",
    "id": "uuid-...",
    "connected": true,
    "last_seen_at": 1748948400.0,
    "version": "0.15.0",
    "created_at": 1748000000.0,
    "extra_meta": { "platform": "orin_nx", "can_interfaces": ["can0", "can1"] }
  }
]
```

***

### `get_rig_config`

Get connectivity status and hardware summary for one rig.

**Parameters:**

<ParamField path="rig_name" type="string" required>
  Exact name of the rig as registered in the control plane.
</ParamField>

**Returns:**

```json theme={null}
{
  "rig_name": "bench_01",
  "rig_id": "uuid-...",
  "connected": true,
  "last_seen_at": 1748948400.0,
  "version": "0.15.0",
  "created_at": 1748000000.0,
  "hardware_summary": {
    "platform": "orin_nx",
    "can_interfaces": ["can0", "can1"],
    "eth_interfaces": ["eth1"]
  }
}
```

***

### `register_rig`

Register a new rig and return its API key.

<Warning>
  The API key is shown ONCE and cannot be retrieved again. Save it immediately.
</Warning>

**Parameters:**

<ParamField path="rig_name" type="string" required>
  Unique name for the rig. Letters, numbers, hyphens (e.g. `orin-bench-01`).
</ParamField>

**Returns:**

```json theme={null}
{
  "rig_name": "orin-bench-01",
  "rig_id": "uuid-...",
  "role": "admin",
  "api_key": "chk_xxxxxxxxxxxxxxxx",
  "next_steps": [
    "Save the api_key — it will not be shown again.",
    "On the bench machine, generate the rig TOML:",
    "  crucihil discover --describe 'your hardware'",
    "Start the agent:",
    "  export CRUCIHIL_API_KEY=chk_xxxxxxxxxxxxxxxx",
    "  export CRUCIHIL_BASE_URL=<your server URL>",
    "  crucihil agent --rig rigs/orin-bench-01.toml"
  ]
}
```

***

## Test runs

### `list_runs`

List recent test runs, optionally filtered by rig.

**Parameters:**

<ParamField path="rig_name" type="string">
  Filter to runs from this rig. Pass `null` for all rigs.
</ParamField>

<ParamField path="limit" type="integer" default="20">
  Maximum number of runs to return. Max 500.
</ParamField>

**Returns:**

```json theme={null}
[
  {
    "run_id": "uuid-...",
    "suite_name": "engine_validation",
    "status": "completed",
    "total": 5,
    "passed": 4,
    "failed": 1,
    "blocked": 0,
    "errored": 0,
    "skipped": 0,
    "started_at": 1748948400.0,
    "completed_at": 1748948421.3
  }
]
```

***

### `get_run_summary`

Get a full summary of one run including pass rate and duration.

**Parameters:**

<ParamField path="run_id" type="string" required>
  UUID of the run.
</ParamField>

**Returns:**

```json theme={null}
{
  "run_id": "uuid-...",
  "rig_id": "uuid-...",
  "suite_name": "engine_validation",
  "status": "completed",
  "started_at": 1748948400.0,
  "completed_at": 1748948421.3,
  "duration_s": 21.3,
  "total": 5,
  "passed": 4,
  "failed": 1,
  "blocked": 0,
  "errored": 0,
  "skipped": 0,
  "pass_rate": 0.8,
  "triggered_by": "CI"
}
```

***

### `run_test_suite`

Create a queued run and push it to the connected agent.

**Parameters:**

<ParamField path="rig_name" type="string" required>
  Name of the rig to run tests on.
</ParamField>

<ParamField path="suite_path" type="string" required>
  Path to the YAML suite manifest as known to the agent (e.g. `tests/suites/engine_validation.yaml`).
</ParamField>

<ParamField path="tags" type="list[string]">
  Optional tag filter — only tests matching at least one tag are run.
</ParamField>

<ParamField path="suite_type" type="string">
  Optional suite type filter (e.g. `smoke`, `regression`).
</ParamField>

**Returns:** Run record with `run_id` for polling.

***

### `cancel_run`

Cancel a running test suite.

**Parameters:**

<ParamField path="run_id" type="string" required>
  UUID of the run to cancel. Only `running` runs can be cancelled.
</ParamField>

**Returns:**

```json theme={null}
{
  "detail": "cancellation requested",
  "run_id": "uuid-..."
}
```

***

## Result inspection

### `get_results`

List test results for a run.

**Parameters:**

<ParamField path="run_id" type="string" required>
  UUID of the run.
</ParamField>

<ParamField path="status" type="string">
  Filter by status: `pass`, `fail`, `blocked`, `error`, or `skip`.
</ParamField>

**Returns:**

```json theme={null}
[
  {
    "test_id": "engine_startup",
    "run_id": "uuid-...",
    "suite_name": "engine_validation",
    "status": "pass",
    "duration": 0.012,
    "started_at": 1748948400.1,
    "completed_at": 1748948400.112
  }
]
```

***

### `get_signal_trace`

Extract signal samples for a specific signal across the most recent tests in a run.

Searches up to 5 test results. Returns up to 100 samples per test.

**Parameters:**

<ParamField path="run_id" type="string" required>
  UUID of the run.
</ParamField>

<ParamField path="signal_name" type="string" required>
  Signal name as stored in test results (e.g. `EngineData.RPM`).
</ParamField>

**Returns:**

```json theme={null}
{
  "run_id": "uuid-...",
  "signal_name": "EngineData.RPM",
  "found": true,
  "tests": [
    {
      "test_id": "engine_startup",
      "samples": [
        {"t": 0.0, "value": 0.0},
        {"t": 0.1, "value": 450.0},
        {"t": 0.2, "value": 820.0}
      ],
      "total_samples": 3,
      "truncated": false
    }
  ],
  "note": null
}
```

***

### `describe_failure`

Get complete failure context for one test in one run. This is the primary tool for AI failure analysis — it returns everything needed for root-cause analysis in a single call.

Combines: run metadata, error messages, log lines, signal traces (up to 5 signals, 100 samples each).

**Parameters:**

<ParamField path="run_id" type="string" required>
  UUID of the run.
</ParamField>

<ParamField path="test_id" type="string" required>
  Test ID as declared in the YAML manifest.
</ParamField>

**Returns:**

```json theme={null}
{
  "run_id": "uuid-...",
  "test_id": "brake_response",
  "suite_name": "engine_validation",
  "rig_id": "uuid-...",
  "triggered_by": "CI",
  "started_at": 1748948410.0,
  "completed_at": 1748948411.2,
  "duration_s": 1.2,
  "run_started_at": 1748948400.0,
  "status": "fail",
  "errors": ["Expected BrakeStatus.Pressure >= 75.0, got 0.0"],
  "error_count": 1,
  "logs": [],
  "log_count": 0,
  "captured_signals": ["BrakeStatus.Pressure", "EngineData.RPM"],
  "signal_traces": {
    "BrakeStatus.Pressure": [
      {"t": 0.0, "value": 0.0},
      {"t": 0.1, "value": 0.0},
      {"t": 1.2, "value": 0.0}
    ]
  },
  "signal_note": null,
  "pass_rate_in_run": 0.6,
  "run_status": "completed",
  "total_failures_in_run": 2
}
```

***

## Signal and suite introspection

### `list_signals`

Parse a DBC file and return metadata for every signal.

**Parameters:**

<ParamField path="dbc_path" type="string" required>
  Path to the `.dbc` file, relative to the working directory when the MCP server was started.
</ParamField>

**Returns:**

```json theme={null}
{
  "dbc_path": "defs/vehicle_can.dbc",
  "message_count": 8,
  "signal_count": 24,
  "signals": [
    {
      "signal_name": "RPM",
      "message_name": "EngineData",
      "message_id": "0x100",
      "bit_length": 16,
      "factor": 0.25,
      "offset": 0.0,
      "min_val": 0.0,
      "max_val": 8000.0,
      "unit": "rpm",
      "interface": "CAN",
      "choices": null
    }
  ]
}
```

***

### `list_tests`

Parse a YAML suite manifest and return metadata for every test.

**Parameters:**

<ParamField path="suite_path" type="string" required>
  Path to the YAML manifest (e.g. `tests/suites/engine_validation.yaml`).
</ParamField>

**Returns:**

```json theme={null}
{
  "suite_name": "engine_validation",
  "description": "Engine ECU validation suite",
  "version": "1.0.0",
  "suite_path": "tests/suites/engine_validation.yaml",
  "test_count": 5,
  "enabled_count": 4,
  "tests": [
    {
      "id": "engine_startup",
      "name": "ECU reaches idle RPM after ignition",
      "enabled": true,
      "skip_reason": null,
      "priority": "critical",
      "tags": ["engine", "startup"],
      "suite_types": ["smoke", "regression"],
      "hw_variants": ["Virtual_Sim"],
      "timeout": 5.0,
      "depends_on": [],
      "requirements": ["REQ-ENG-001"],
      "ticket": null
    }
  ]
}
```

***

## AI-assisted tools

### `generate_test_suite`

Scaffold a YAML manifest and Python stubs, optionally with AI-generated assertions.

**Parameters:**

<ParamField path="suite_name" type="string" required>
  Snake-case suite name (e.g. `brake_validation`).
</ParamField>

<ParamField path="description" type="string" required>
  One-sentence description of what the suite validates.
</ParamField>

<ParamField path="rig_name" type="string" default="&#x22;Virtual_Sim&#x22;">
  Hardware variant to target.
</ParamField>

<ParamField path="output_dir" type="string" default="&#x22;tests/suites&#x22;">
  Directory to write both files.
</ParamField>

<ParamField path="context_items" type="list[string]">
  Manual context: signal names, fault scenarios, integration flows, sensor feeds.
</ParamField>

<ParamField path="rig_toml_path" type="string">
  Rig TOML — auto-extracts ECU names, power rails, GPIO presence.
</ParamField>

<ParamField path="dbc_path" type="string">
  DBC file — auto-extracts all `MessageName.SignalName` pairs.
</ParamField>

<ParamField path="ai_provider" type="string">
  Provider override: `anthropic`, `openai`, `gemini`.
</ParamField>

**Returns:**

```json theme={null}
{
  "suite_name": "brake_validation",
  "yaml_path": "tests/suites/brake_validation.yaml",
  "py_path": "tests/suites/brake_validation.py",
  "module_path": "tests.suites.brake_validation",
  "auto_context_count": 26,
  "context_items_used": [...],
  "next_steps": [...]
}
```

***

### `analyze_component`

Extract the signal interface contract of a C/C++ software component.

Requires `pip install 'crucihil[analyze]'`.

**Parameters:**

<ParamField path="source_path" type="string" required>
  Path to a `.c`/`.cpp`/`.h` file or a directory of source files.
</ParamField>

<ParamField path="component_name" type="string" required>
  Label for this component in the output (e.g. `BrakeController`).
</ParamField>

<ParamField path="dbc_paths" type="list[string]">
  One or more DBC file paths. Merged with TOML-discovered DBCs.
</ParamField>

<ParamField path="rig_toml_path" type="string">
  Rig TOML — auto-discovers DBCs from `[rig.definitions]`, infers interface type from key name.
</ParamField>

<ParamField path="dependencies" type="list[string]">
  Shim header directories or SWC paths to parse alongside the primary source.
</ParamField>

<ParamField path="ai_provider" type="string">
  Provider override: `anthropic`, `openai`, `gemini`.
</ParamField>

**Returns:**

```json theme={null}
{
  "component": "BrakeController",
  "files_analyzed": 7,
  "identifiers_extracted": 87,
  "signal_corpus_size": 26,
  "inputs": [
    {
      "signal": "BrakeDemand.Value",
      "dbc": "/path/to/chassis.dbc",
      "interface": "ETH",
      "matched_identifier": "Rte_Read_BC_BrakeDemandVal",
      "confidence": 0.95,
      "review_required": false
    }
  ],
  "outputs": [...],
  "unmatched_identifiers": [...],
  "confidence_summary": { "high": 5, "medium": 0, "low": 0 },
  "review_required_count": 0
}
```

***

## Authoring and verification

### `author_component`

Author a self-verified test suite from component source code. Chains: analyze (signal contract with evidence chains) → generate → baseline gate (must run green on the rig, with AI repair rounds) → write. Broken AI output never reaches disk — a deterministic static generator is the guaranteed fallback.

Runs entirely on the machine hosting the MCP server (source code and rig TOML are local paths). Writes the suite files into `output_dir`.

**Parameters:**

<ParamField path="source_path" type="string" required>
  Component source file or directory (local path).
</ParamField>

<ParamField path="component_name" type="string" required>
  Component label (e.g. `BrakeController`).
</ParamField>

<ParamField path="rig_toml_path" type="string" default="&#x22;rigs/virtual.toml&#x22;">
  Rig the baseline gate runs against (virtual by default).
</ParamField>

<ParamField path="dbc_paths" type="list[string]">
  DBC file paths for the signal corpus.
</ParamField>

<ParamField path="repo_root" type="string">
  Firmware repo root — enables cross-component port-graph resolution (shared-memory indirection).
</ParamField>

<ParamField path="output_dir" type="string" default="&#x22;tests/suites&#x22;">
  Where the promoted suite is written.
</ParamField>

<ParamField path="suite_name" type="string">
  Suite name (default: `<component>_contract`).
</ParamField>

<ParamField path="framework" type="string" default="&#x22;crucihil&#x22;">
  Output format: `crucihil` (native YAML+Python), `pytest`, or `robot`.
</ParamField>

<ParamField path="ai_provider" type="string">
  Provider override: `anthropic`, `openai`, `gemini` (auto-detected from env vars if omitted).
</ParamField>

<ParamField path="max_repair_rounds" type="integer" default="2">
  AI repair rounds before the static fallback.
</ParamField>

**Returns:**

```json theme={null}
{
  "suite_name": "brake_controller_contract",
  "framework": "crucihil",
  "yaml_path": "tests/suites/brake_controller_contract.yaml",
  "py_path": "tests/suites/brake_controller_contract.py",
  "contract_path": "contracts/BrakeController.json",
  "generator": "ai",
  "test_functions": ["test_brake_demand_response", "..."],
  "review_tests": [],
  "baseline": { "total": 5, "passed": 5 },
  "repair_attempts": 0
}
```

On failure, returns `{"error": "...", "stage": "analyze" | "generate" | "baseline" | "write"}`.

***

### `verify_suite`

Mutation-verify a test suite and return its strength report. Runs the suite once as a baseline, then once per mutation. Outcome per test: `caught` (test failed — good), `missed` (test stayed green while the behavior was broken — vacuous), `wrong_reason` (test went blocked/error instead of failing). A suite score of `1.0` means every planned mutation was caught.

Works on native CruciHiL suites and on existing pytest / Robot Framework suites with zero rewrites.

**Parameters:**

<ParamField path="suite_path" type="string" required>
  Native YAML manifest, or a pytest/Robot test tree when `framework` is given. A YAML manifest with a `framework:` field routes automatically.
</ParamField>

<ParamField path="rig_toml_path" type="string" default="&#x22;rigs/virtual.toml&#x22;">
  Rig the verification runs against.
</ParamField>

<ParamField path="framework" type="string">
  `pytest` | `robot` to verify a foreign suite unchanged; omit for native (or manifest-declared).
</ParamField>

<ParamField path="contract_path" type="string">
  Contract artifact (`contracts/<component>.json`) — sharpens the mutation plan with the component's real outputs.
</ParamField>

<ParamField path="max_runs" type="integer" default="20">
  Cap on mutation runs (priority-ordered).
</ParamField>

<ParamField path="report_path" type="string">
  Also save the full report JSON here (readable later via `get_strength_report`).
</ParamField>

**Returns:**

```json theme={null}
{
  "suite_name": "brake_controller_contract",
  "rig": "Virtual_Sim",
  "generated_at": "2026-07-05T12:00:00+00:00",
  "suite_score": 1.0,
  "per_test": {
    "brake_demand_response": {
      "caught": 3, "missed": 0, "wrong_reason": 0,
      "planned": 3, "score": 1.0
    }
  },
  "results": [
    {
      "test_id": "brake_demand_response",
      "mutation": {
        "mutation_type": "dead_dut",
        "label": "DUT silent — all output messages stopped",
        "params": {}
      },
      "outcome": "caught",
      "evidence": "Expected BrakeStatus.Pressure >= 75.0, got timeout",
      "baseline_status": "pass",
      "mutated_status": "fail"
    }
  ],
  "unverifiable": {},
  "planned_mutations": [...],
  "report_path": "reports/strength.json"
}
```

`report_path` appears only when it was requested. On failure, returns `{"error": "..."}`.

***

### `get_strength_report`

Read a previously saved mutation strength report JSON.

**Parameters:**

<ParamField path="report_path" type="string" required>
  Path passed to `verify_suite`'s `report_path` (or `crucihil verify --report`).
</ParamField>

**Returns:** The saved strength report (same shape as `verify_suite`), or `{"error": "..."}` if the file is missing or not valid JSON.

***

### `detect_coverage_gaps`

Find what a component's tests never exercised (coverage gaps). Compares the component contract (which signals the component touches) against the signal traces recorded by a run's tests. Reports signals never tested at all and value regions never reached ("never tested BrakePressure > 80% of range"), each with a proposed gap test whose description can be passed straight to `generate_test_suite`.

**Parameters:**

<ParamField path="run_id" type="string" required>
  The run whose recorded traces to analyze.
</ParamField>

<ParamField path="contract_path" type="string" required>
  Contract artifact (`contracts/<component>.json`).
</ParamField>

<ParamField path="dbc_paths" type="list[string]">
  DBCs for signal ranges (defaults to the DBCs the contract entries reference).
</ParamField>

**Returns:**

```json theme={null}
{
  "component": "BrakeController",
  "contract_signals": 4,
  "traced_tests": ["brake_demand_response"],
  "signals": {
    "BrakeStatus.Pressure": {
      "dbc_min": 0.0,
      "dbc_max": 100.0,
      "observed_min": 0.0,
      "observed_max": 60.0,
      "tested_by": ["brake_demand_response"]
    }
  },
  "gaps": [
    {
      "signal": "BrakeStatus.Pressure",
      "kind": "upper_range",
      "detail": "never tested BrakeStatus.Pressure > 60.0 — the top 40% of its DBC range [0.0, 100.0] is unexercised",
      "threshold": 60.0
    }
  ],
  "proposed_tests": [
    {
      "signal": "BrakeStatus.Pressure",
      "value": 100.0,
      "description": "Set BrakeStatus.Pressure to 100.0 and verify the component's response — ...",
      "generate_test_suite_args": { "suite_name": "gap_brakestatus_pressure", "description": "..." }
    }
  ],
  "run_id": "uuid-..."
}
```

Gap `kind` is one of `untested`, `upper_range`, `lower_range`. On failure, returns `{"error": "..."}`.

## See also

* [MCP Overview — connecting AI clients](/mcp/overview)
* [AI Features Overview](/ai-features/overview)
* [analyze\_component deep dive](/ai-features/analyze)
