Skip to main content
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.

Connecting an agent

Point any MCP-compatible client at the box:
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.

What the agent sees

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

Resources

Tools

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.

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.
1

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.
2

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.
3

Plan

Call plan_firmware_test(...) to get a phased plan with API references and document pointers per step.
4

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.)
5

Analyse & iterate

Review the CLI output, adjust the script, and re-run it with lager python.

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: the box’s purpose, MCU, subsystems, and references to schematics and datasheets.
See Authoring DUT Context for the full guide.