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

# MCP Server Overview

> How AI agents discover hardware and plan tests on a Lager Box via the Model Context Protocol

Every Lager Box runs an **MCP (Model Context Protocol) server** that lets an AI
agent understand the bench, understand the device under test (DUT), and plan
hardware-in-the-loop tests. It runs on-box and is reachable over the box's local
IP.

The MCP server is **read-only**: it describes the bench and DUT but never drives
hardware or runs code. The agent executes tests over a separate channel — the
`lager` CLI.

```
MCP-compatible AI agent
    |  MCP (streamable-http via box IP)     ← discovery + planning (read-only)
    v
Lager MCP Server (on-box, port 8100)
    |  reads /etc/lager bench config (nets, DUT context, instruments)
    v
Bench / DUT metadata

AI agent  ──  lager python path/to/test.py --box <box-ip>  ──▶  Hardware
              (execution happens over the CLI, not MCP)
```

## Connecting an agent

Point any MCP-compatible client at the box:

```json theme={null}
{
  "mcpServers": {
    "lager": {
      "url": "http://<box-ip>:8100/mcp"
    }
  }
}
```

<Note>
  The MCP server is for **discovery and planning** only — it does not run code or
  drive hardware. To **execute** a test, the agent writes a Python file locally and
  runs it with `lager python path/to/test.py --box <box-ip>`, which syncs the
  project to the box and runs it with full project context. Pass the box's **IP
  address** to `--box` — the same IP you connected to the MCP server on. Local box
  names are just client-side aliases, so the IP is the only identifier both sides
  can rely on. To make this concrete, `discover_bench()` echoes the address you
  actually connected on as `box_address` and hands back a ready-to-run
  `lager python … --box <that-address>` command.
</Note>

## What the agent sees

The server exposes two kinds of things: **resources** (read-only context the
agent reads) and **tools** (callable functions).

### Resources

| Resource                            | What it gives the agent                                                                                                                                                                                                                                                       |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lager://dut/overview.md`           | **Read this first.** A narrative briefing: what the box tests, the DUT MCU/peripherals, subsystems, and which documents to fetch.                                                                                                                                             |
| `lager://dut/context`               | The full DUT context as structured JSON.                                                                                                                                                                                                                                      |
| `lager://bench/identity`            | Box ID, hostname, version, and a per-DUT summary (purpose, MCU).                                                                                                                                                                                                              |
| `lager://bench/netlist`             | Every net with type, roles, instrument, and metadata.                                                                                                                                                                                                                         |
| `lager://bench/interfaces`          | Protocol interfaces (SPI, I2C, UART) and their nets.                                                                                                                                                                                                                          |
| `lager://guide/overview`            | What Lager is and what a "net" is.                                                                                                                                                                                                                                            |
| `lager://guide/workflow`            | The recommended orient → discover → plan → write → run loop.                                                                                                                                                                                                                  |
| `lager://guide/rtt-defmt`           | The core firmware-log workflow: streaming RTT and decoding `defmt`. Covers the `dbg.session()` scope, the reconnect-aware RTT reader and self-healing `reset()`/`read_memory()` (so you don't write flash/reset workarounds), and the DA1469x post-flash reconnect exception. |
| `lager://reference/{net_type}`      | The full API reference for one net type as JSON (e.g. `lager://reference/Debug`) — methods, gotchas, and a runnable example snippet.                                                                                                                                          |
| `lager://guide/api-quick-reference` | Compact `lager.Net` API cheat sheet by net type.                                                                                                                                                                                                                              |
| `lager://guide/docs`                | Links to the full hosted docs (`docs.lagerdata.com`) and the `llms.txt` page index for anything not covered on-box.                                                                                                                                                           |

### Tools

| Tool                                                   | Purpose                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `discover_dut()`                                       | One call for orientation: DUT purpose, MCU, peripherals, subsystems, and document references.                                                                                                                                                                                               |
| `discover_bench(net_name?)`                            | Enumerate hardware — nets, plus instruments with their channels, capabilities, and authored specs/ranges. With a net name, return that net's full metadata, capabilities, parent subsystem, and relevant document references (and, if the net is unknown, the list of available net names). |
| `cite_schematic(net_name)`                             | Return just the schematic/datasheet references and page hints relevant to one net.                                                                                                                                                                                                          |
| `plan_firmware_test(firmware_description, test_goals)` | Generate a phased test plan, scoped to relevant nets, with DUT context and document references attached.                                                                                                                                                                                    |
| `assess_suitability(test_type)`                        | Check whether the bench can run a given test type.                                                                                                                                                                                                                                          |
| `get_test_example(query)`                              | Find runnable example scripts by net type, pattern, or keyword.                                                                                                                                                                                                                             |
| `box_manage(action)`                                   | `health` check or `reload` the bench config from disk.                                                                                                                                                                                                                                      |

<Note>
  The tool surface is intentionally read-only. There are no tools that drive
  hardware (set a voltage, toggle a GPIO, flash firmware) or mutate the box. All
  of that lives in the test script the agent writes and runs with `lager python`,
  or in dedicated [CLI commands](/source/reference/cli).
</Note>

### Prompts

The server also registers a few **prompts** — slash-command-style entry points
that steer a client (e.g. Cursor) through the discover → plan → write → run
workflow. They don't do work themselves; each returns an instruction the agent
follows using the tools above.

| Prompt                                      | What it does                                                                                              |
| ------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `write_lager_test(what_to_test)`            | Walks the agent through discovering the bench/DUT, planning, writing a test, and running it over the CLI. |
| `explore_bench()`                           | Orients on what the box is, what it tests, and what it can run.                                           |
| `assess_test_feasibility(test_description)` | Checks whether the bench has the capabilities for a described test.                                       |

## The recommended agent workflow

<Steps>
  <Step title="Orient">
    Read `lager://dut/overview.md` (or call `discover_dut()`) to learn what the
    box tests, the MCU and peripherals, the subsystems, and which documents to
    fetch.
  </Step>

  <Step title="Discover">
    Call `discover_bench()` to enumerate nets, instruments, and capabilities.
    Call `discover_bench(net_name)` for detail on a specific net, including its
    subsystem and the schematic sheet it lives on.
  </Step>

  <Step title="Plan">
    Call `plan_firmware_test(...)` to get a phased plan with API references and
    document pointers per step.
  </Step>

  <Step title="Write & Run">
    Author a Python test file using `from lager import Net, NetType`. Identify
    the box by the IP address you connected to the MCP server on — local box
    names are arbitrary client-side aliases. `--box` accepts a raw IP, so no
    registration is needed: run `lager python path/to/test.py --box <box-ip>`.
    The runnable can also be a **folder** (entrypoint `main.py`), which syncs
    and imports everything in it — handy for shipping reusable helper modules:
    `lager python path/to/test_dir --box <box-ip>`. (Optionally,
    `lager boxes add --name <name> --ip <box-ip>` registers a friendly alias.)
  </Step>

  <Step title="Analyse & iterate">
    Review the CLI output, adjust the script, and re-run it with `lager python`.
  </Step>
</Steps>

## Where context comes from

The quality of everything above depends on the metadata you author once, at
bench setup:

* **Per-net `purpose`** — set in the Net Manager TUI (`lager nets tui`). One
  sentence describing what each wire does on the DUT.
* **DUT context** — set with [`lager box dut`](/source/reference/cli/box-dut):
  the box's purpose, MCU, subsystems, and references to schematics and
  datasheets.

See [Authoring DUT Context](/source/reference/mcp/dut-context) for the full
guide.
