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.The recommended agent workflow
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.

