Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
AGENTIC_HIL_CONFIGNoAbsolute path to the authoritative configuration file. Normally discovered automatically from the platform config directory; this override is only needed when an operator-controlled absolute-path override is required.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
debugger_infoA

Check the debugger backend is installed: runs only --version, at most 10 s; contacts no probe or board. Replaces openocd. Returns backend, executable, version, config_status. Next: debugger_probes_list (probe ids), probe_target (board). Failures: debugger_not_found (missing), timeout; not_supported unless exactly one debugger is configured; permission_denied without allow_probe (config version 1).

debugger_probes_listA

List the probe ids of the in-circuit debuggers or programmers on this host; connects to no board. Replaces st-info. Returns probes, each with a probe_id to set as the debugger entry's probe_id. pyOCD and STM32CubeProgrammer ask their CLI; OpenOCD reads the USB serial inventory, complete false (adapters it cannot read there: not_supported). Failure: probe_discovery_failed.

probe_targetA

Connect the in-circuit debugger or programmer to the board and confirm it answers (target_detected true), with no reset and no flash; reset_target resets. Replaces openocd. Refused with resource_busy while a debug session is open. Failures: adapter_not_found (no probe), target_not_detected (board silent), debugger_not_found (backend missing), timeout (one command over debugger.timeout_s).

artifact_uploadA

Store a firmware image in artifacts.upload_directory and return its artifact_id for flash_firmware or debug_start_session; no board needed. Give image_path, or filename with data_base64, else invalid_argument. Needs allow_upload, else permission_denied. The id is the sha256 of the bytes plus the lowercased extension: same bytes and extension, same id. Unsafe destination: unsafe_configured_path.

flash_firmwareA

Write firmware to the board via the in-circuit debugger or programmer, not st-flash; every call writes it again. Needs allow_flash, else permission_denied. resource_busy: debug_stop_session first; device_busy: held elsewhere. The debugger entry's timeout_s (seconds, 60 unless set) caps each debugger command, else timeout. No bench_run_start needed; capture with reset_after_flash adds boot output.

reset_targetA

Reset the board through the in-circuit debugger or programmer: the firmware restarts, flash is kept. Replaces st-util. Needs allow_reset (else permission_denied). Refused with resource_busy while a debug session is open: debug_stop_session first. To check the board without a reset use probe_target. Failures: reset_failed (reset not confirmed), timeout (one command over debugger.timeout_s).

debug_start_sessionA

Opens a GDB session on an ELF for debug_continue and debug_halt. OpenOCD backend only; others answer not_supported. Needs GDB (debug.gdb_executable or PATH), the debugger entry's scripts and allow_raw_debugger_commands off. Returns the core halted: session (status, stop_reason), log_path. A second start: session_already_active. debug_get_session_status inspects it; debug_stop_session ends it.

debug_stop_sessionA

Ends the debug_start_session session; debug_halt keeps it open. Confirms the core halted, disables resume on detach, ends GDB and the debug server, drops breakpoints, frees flash_firmware and reset_target. OpenOCD backend only; others answer not_supported. Success: safe_state_confirmed true. No session: ok, active false. Unproven: ok false, cleanup_required, hardware_state unknown, quarantined.

debug_get_session_statusA

Reports if the debug_start_session session is open and its status: halted, running, error or cleanup_required. Records new stops, but never halts or resumes the core; debug_halt halts, debug_get_stop_reason reads the last stop. Abnormal stop: ok true, target_ok false, target_error_type. No session: ok, active false, status stopped. OpenOCD only, exactly one debugger configured; else not_supported.

debug_set_breakpointA

Adds a breakpoint in the debug_start_session session (else session_not_active) without resuming the core. Each call adds one and returns its breakpoint id; debug_list_breakpoints lists them. A location without a grant answers permission_denied. An unconfirmed insert answers cleanup_required; call debug_clear_breakpoints. OpenOCD only, exactly one debugger configured; else not_supported.

debug_list_breakpointsA

Lists the breakpoints debug_set_breakpoint added in the debug_start_session session, from the session's own record without asking GDB: breakpoints (id, backend_id, location). Never halts or resumes the core. No session: ok, active false, breakpoints empty. debug_clear_breakpoints removes them and checks GDB. OpenOCD only, exactly one debugger configured; else not_supported.

debug_clear_breakpointsA

Removes every breakpoint GDB holds in the debug_start_session session (else session_not_active), then checks none is left. It neither resumes nor halts the core. It answers cleared (the count) and backend_reconciled true; a second call clears 0. Unconfirmed: ok false, breakpoint_reconciliation_failed; a retry is safe. OpenOCD only, exactly one debugger configured; else not_supported.

debug_continueA

Resumes the core in the debug_start_session session until it stops. Needs allow_debug_execution, else permission_denied. Returns stop_reason, stop (frame): breakpoint_hit is ok; unexpected_breakpoint and target_exception are not. An exception or debugger_error stop is not resumed. No session: session_not_active. OpenOCD only, exactly one debugger configured; else not_supported.

debug_haltA

Halts the core; the session stays open. It needs debug_start_session (else session_not_active) on OpenOCD with exactly one debugger configured, else not_supported. debug_continue resumes. Returns stop_reason halted or a stopped core's recorded stop. If an acknowledged interrupt's stop times out, ok and halt_confirmed are false, target_state unknown, bench quarantined; a confirmed halt can lift it.

debug_get_stop_reasonA

Why the core last stopped: stop_reason (breakpoint_hit, halted, exception), stop (frame). Records a newly arrived stop; never halts or resumes the core. Abnormal stop: ok true, target_ok false, target_error_type. None yet: stop_reason_not_available. Without debug_start_session: session_not_active. Session: debug_get_session_status. OpenOCD only, exactly one debugger configured; else not_supported.

debug_symbol_infoA

Find an allowed symbol's hex address, size_bytes and resolved_from in the ELF. Reads no target memory; for bytes use debug_symbol_value, for Intel HEX debug_dump_symbol_ihex. OpenOCD needs debug_start_session (else session_not_active). pyOCD and STM32CubeProgrammer use the ELF this server last flashed via flash_firmware (else symbol_source_not_available; symbol_source_changed if changed since).

debug_symbol_valueA

Reads a symbol from target memory, like gdb print. debug_symbol_info gives its address, debug_dump_symbol_ihex a file. Returns hex, plus value_unsigned and value_signed at 1, 2, 4 or 8 bytes. OpenOCD needs debug_start_session (else session_not_active); pyOCD and STM32CubeProgrammer, the ELF flash_firmware last wrote (else symbol_source_not_available). Over max_dump_size_bytes: permission_denied.

debug_dump_symbol_ihexA

Read an allowed symbol from target memory and write it as Intel HEX to output_path; returns address, size_bytes and output. Value inline: debug_symbol_value. OpenOCD needs debug_start_session (else session_not_active); pyOCD and STM32CubeProgrammer, the ELF last flashed via flash_firmware (else symbol_source_not_available). Over debug.max_dump_size_bytes: permission_denied.

get_last_reportA

Return the newest stored hardware report, pass or fail, under report. For the last failure diagnosed, even after successes, use classify_last_error. Needs no board; reading changes nothing. After a failure it can be the recovery's reset_target or probe_target (report.tool). ok stays true for a failed report: judge report.ok, report.audit_ok, report.cleanup_required. None yet: report_not_found.

classify_last_errorA

Explain the last hardware failure: error_type names it, likely_causes says what to check, report_path and log_path hold the evidence. Unlike get_last_report, it keeps that failure through later successes. source_tool is the failed tool, or reset_target if a flash's recovery reset failed too. Some refusals, such as allow_flash off, record nothing. Needs no board; no failure yet: report_not_found.

com_ports_listA

List com_ports entries in ports by port_id, which com_session_start takes (not a device path), with session_active. Opens no port. available_com_ports holds host serial ports, or permission_denied unless a configured port may be read, serial_backend_not_available without pyserial, com_port_discovery_failed on an OS error; the call stays ok. Use this instead of picocom or /dev/tty*.

com_session_startA

Open the serial port a com_ports entry names and hold it, with its machine-wide lock, until com_session_stop; a reader buffers what the board sends for com_read. DTR and RTS are driven as configured on open, which can reset a board. device_busy, resource_busy or com_port_busy: another server, process or program has the port. permission_denied: neither reading nor writing is allowed.

com_session_stopA

Close the com_session_start session on port_id: stop its reader, close the port, release its lock. Unread bytes are dropped; the session log at log_path keeps them. Without a session it returns ok with was_active false. If the reader does not end within max(1 s, timeout_s + 0.5 s) of the close, it returns com_port_close_failed and keeps the session registered; call again to retry.

com_writeA

Send bytes over the session com_session_start opened on port_id (else session_not_active); needs the port's allow_write (else permission_denied). At most max_write_bytes encoded bytes, 4096 by default. bytes_written counts the bytes sent; a short write returns serial_write_incomplete. Example: com_session_start port_id "uart0", com_write text "hello\r\n", com_read until "\n", com_session_stop.

com_readA

Read what the board sent on a COM port session from com_session_start (else session_not_active), instead of screen, minicom or picocom. With until, one call waits for a pattern instead of polling. Each byte is returned once, as text and hex. If until is not seen in time, the answer is still ok, with until_matched false and the bytes so far.

can_buses_listA

List every can_buses entry in buses, keyed by bus_id, the name can_session_start, can_send and can_read take. Each shows session_active, listen_only with its listen_only_enforcement, fd, max_frame_data_bytes and max_buffer_frames; a bus with shares adds active_participants. Needs no session and opens no adapter. Use this instead of ip link or candump.

can_session_startA

Open a session on a configured CAN bus for can_send and can_read, until can_session_stop or server exit. Returns session; a repeat call answers already_active: true. Fails can_bus_not_configured, device_busy or resource_busy (bus held), can_adapter_timeout (bridge timeout_s, default 10 s), and on a listen_only bus can_listen_only_unsupported or can_listen_only_unconfirmed.

can_session_stopA

Close the can_session_start session on bus_id when done with the bus; its lease is released. Its adapter closes unless other participants share the bus. A declared run still holds the bus. can_send and can_read then answer session_not_active. With no session open, was_active is false. If the close fails or a bridge is silent for 1 s, it returns can_adapter_close_failed and keeps the session.

can_sendA

Send one CAN frame (CAN FD on an fd: true bus) on the can_session_start session, else session_not_active. Needs the bus allow_write, else permission_denied; a listen_only bus refuses with can_listen_only_mode. A repeat sends again. ok: the adapter accepted it, not that a node ACKed it. can_send_failed sets cleanup_required: it may have gone out. Use this instead of cansend.

can_readA

Read the CAN frames your can_session_start session received into frames, counted by frames_read. Use it instead of candump; to wait for a reply, pass until_id rather than polling. Without a session: session_not_active. Returned frames are consumed; an empty read is still ok. Adapter faults: can_read_failed; after can_adapter_invalid_response, can_session_stop and start again.

bench_run_startA

Declare a run holding the devices a sequence like flash, reset, read needs until bench_run_stop or server exit, no timeout; without one the board is free between calls. All or nothing: a refused start holds none. Other devices fail undeclared_device; a second start, run_already_active; a standing incident, resource_quarantined. A single call, or flash_firmware with capture, needs no run.

bench_run_stopA

End the bench_run_start run and release its devices (released_devices). With no run open it answers run_was_active: false. A COM, CAN or debug session still open keeps its own device: open_leases, still_held_devices. With an incident open it runs the recovery recovery.auto_recover allows (by default reset into halt, then a probe re-read), reported in recovery.

bench_run_statusA

Report whether this server has a run open (run_active), what it declared (declared_devices, run_label) and which devices it holds (held_devices); read it when unsure whether you still hold the bench. In memory only: what another process holds shows in hardware_lease_status.

test_reactor_runA

Run a test plan file (agentic-hil://reference/test-plan) on the board. For calls made one by one, use bench_run_start, whose open run refuses this with run_already_active. permission_denied and device_busy refuse at once, before any step. A failing step gets the recovery recovery.auto_recover allows, reported in recovery. With detach, poll test_reactor_status; test_reactor_stop ends it.

test_reactor_statusA

Follow a detached test_reactor_run by its handle; for a bench_run_start run, use bench_run_status. state goes starting, running, then finished or stopped, or worker_gone if its process died; stop_requested_at dates a test_reactor_stop. Once ended, run_ok is the verdict and canonical_report_path its own report; report_path is a mirror the next run overwrites. Fails run_state_invalid.

test_reactor_stopA

Ask a test plan run to stop by writing a request it reads between steps. It finishes the step it is in (a delay or device wait ends early), closes its devices and writes its report; one still starting ends before any step. Answers at once stop_requested: true, also on a repeat; an ended run answers stop_requested: false. Fails run_state_invalid, or run_worker_gone (its process died).

hardware_recoverA

Clear the standing quarantine that blocks hardware calls. Call it when hardware_lease_status shows incident_stands, rather than deleting state files. It needs allow_recover and touches no hardware. A no-contact reason clears with no argument. Any other reason answers recovery_requires_physical_check: ask the operator, pass their answer verbatim as operator_statement, never invent one.

hardware_lease_statusA

Read who holds this bench, from any process (bench_held, held_devices), and any open incident: blocked, cleanup_reasons, auto_recoverable, quarantine_guidance, next_step. Only incident_stands: true needs hardware_recover; otherwise the next hardware call settles it or stands it down. standing_incidents are other projects' incidents, not yours to clear. Drives no device.

project_config_createA

Generate this workspace's configuration from attached hardware instead of writing one by hand: every permission true except allow_raw_debugger_commands and allow_mass_erase, which it writes false. Never ask for those two to be turned on. Regenerating is the operator's call, not a way to narrow or re-open.

project_config_describeA

List the keys project_config_set may change: writable_keys with current_value and value_schema, locked_keys naming in unlocked_by the permission that opens each. Read it before project_config_set instead of guessing; it needs no permission. writes_blocked_by_open_run is true while this server holds a run or session. Bad YAML answers config_invalid, an unreadable file config_unreadable.

project_config_setA

Write values you choose to named keys of the configuration file. Call it after project_config_describe lists the keys, rather than editing the configuration file. Device keys need allow_config_description_write, permission keys allow_config_permissions_write, else permission_denied. Permissions only narrow: closing allow_config_permissions_write freezes them all at once (permissions_frozen).

project_config_adopt_hardwareA

Fill the configuration keys that still hold placeholders from the attached probe. Call it once a board is attached, so nobody retypes its serial. It may also rename a COM device to its stable name and correct a stale identity_source. It writes only when apply is true, never flashes or erases. A read that leaves the board state unknown may get it reset into halt by recovery (resource_quarantined).

project_config_reload_descriptionA

Re-read target, debuggers, com_ports and can_buses from this workspace's configuration into the running server, never permissions or debug. Call it after project_config_set, project_config_adopt_hardware or a hand edit, rather than a restart. New devices get every permission false; changed grants need a restart (restart_required_for). description_changes lists what moved.

server_upgradeA

Upgrade this installation to the newest release with the uv, pipx or pip that installed it. Use it when the operator asks; it takes no arguments and needs allow_upgrade. Each manager run may take 600 s. running_version stays old until this server restarts. On Windows, ask the operator to run agentic-hil upgrade (upgrade_cli_only_on_host). On failure the operator runs any reinstall_command.

Prompts

Interactive templates invoked by user choice

NameDescription
agentic_hil_embedded_workflowSafe workflow for using Agentic HIL hardware tools from an AI agent.

Resources

Contextual data attached and managed by the client

NameDescription
debugger-backendsWhich of type, executable, probe_id, target_type, interface, interface_cfg, target_cfg, connect_mode and flash_address each of openocd, stlink and pyocd requires, discovers, ignores, or refuses; when probe_id becomes mandatory; when flash_address is needed; which backend can connect under reset; and which of bootstrap discovery's two enumerations answers on a given host, which decides the type and executable a generated entry gets.
errorsEvery error_type that carries a concrete fix, with its meaning, ordered remediation steps, and the wrong fix to avoid. Identical to the remediation a failing result carries inline.
config-schemaThe bundled JSON Schema for the authoritative project configuration: every field, type, enum, default, and per-device permission.
config-shapeWhich sections a configuration has and what each is for, which are required, and a worked Nucleo-F446RE example; then how to change one field-wise over MCP, the two grants that open the description and the permissions halves, which key each grant opens, and what deliberately cannot be done. Value shapes are read from the shipped schema, not restated.
lease-lifecycleWhich device a run locks and for how long, what device_busy and undeclared_device mean, why a crashed run needs no recovery; then lease states, the predicate that decides whether to continue, the auto-recovery branch, and the operator recovery path including --confirm-safe-state, --quarantine-id and --accept-config-change.
platform-pathsWhere the authoritative configuration, state_root and the machine-wide device locks go on Windows and POSIX, which command touches which of them, what is and is not checked about a configured path, and how AGENTIC_HIL_CONFIG plus a chosen state_root bind a project to another location.
target-supportWhich field names the target per backend, known-good values for the Nucleo-F446RE, how pyOCD target types are provided by CMSIS packs, how to find and install the right one and where installed packs live, and what doctor's target_support statuses mean, including why 'undetermined' is not a failure.
test-planWhere a plan lives (.agentic-hil/testconfig.yaml), how test_config_path and workspace_root resolve it, and which refusal each mistake earns; which format version admits which step; every step with the entry it routes to and its required and optional keys; the comparator families with their rules; and two plans that run. Generated from the shipped plan schema, not restated.
test-plan-schemaThe bundled JSON Schema every test plan is validated against: every step, key, type, enum, default, and the x-since-version markers the format's version gate reads.

TDQS

A4.1/5.0

Scored across 44 tools

Disambiguation4/5

The set has several superficially similar status/report tools (debug_get_session_status, debug_get_stop_reason, get_last_report, classify_last_error, bench_run_status, test_reactor_status, hardware_lease_status), but descriptions cross-reference each other explicitly and assign distinct purposes, so an agent can tell them apart. The run-vs-run distinction (bench_run_start vs test_reactor_run) is also carefully delineated. Only minor boundary friction remains among the many 'status' tools.

Naming Consistency4/5

Names are uniformly snake_case with a clear verb_noun pattern and domain prefixes (debug_*, com_*, can_*, bench_run_*, project_config_*). A few names lack a domain prefix (get_last_report, classify_last_error, artifact_upload, server_upgrade) and project_config_reload_description is an awkward phrasing, but overall the convention is predictable.

Tool Count2/5

44 tools is well beyond the 25+ heavy threshold. The domain is genuinely broad (debug, flash, serial, CAN, config, recovery, bench orchestration), but the surface is bloated with many fine-grained session/status/breakpoint tools that could be consolidated. This is a lot of surface for an agent to navigate reliably.

Completeness5/5

Coverage is remarkably thorough: each subsystem has full lifecycle tools (session start/stop, breakpoint set/list/clear, read/write), plus flash, reset, symbol inspection, bench-run orchestration, config describe/set/adopt/create, error classification, and quarantine recovery. No obvious dead ends for the stated hardware-in-the-loop purpose.

Maintenance

ActivityActive
ResponsivenessWithin a week