Agentic HIL
Develop firmware on the real board behind a debug probe: flash, reset, UART and CAN, policy-gated.
Connector by agentic-hil · GitHub account verified by the MCP Registry
Install
Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.
npx agentmarket install connector/agentic-hil-agentic-hil
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: testing, debugging
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this server can do and what it asks for, from its tool list and install config. Checked Oct 25, 2026.
- Tools
- 18 read · 18 write · 3 delete · 9 not yet classified
- Secrets
- None asked for
- Install scripts
- Not scanned yet
- Runs as
- Python package
Tools by what they do 48
Read from the source code; the running server may list different tools.
Read 18 · Look things up without changing anything.
can_buses_listcan_readcan_session_startclassify_last_errorcom_ports_listcom_readdebug_dump_symbol_ihexdebug_get_session_statusdebug_get_stop_reasondebug_list_breakpointsdebug_symbol_infodebug_symbol_value
Show 6 more tools
debugger_infodebugger_probes_listget_last_reporthardware_lease_statuspower_supply_statusproject_config_describe
Write 18 · Create, change, send or run things.
artifact_uploadbench_run_startbench_run_statusbench_run_stopcom_session_startcom_session_stopcom_writedebug_set_breakpointdebug_start_sessiondebug_stop_sessionflash_firmwarepower_supply_set
Show 6 more tools
project_config_adopt_hardwareproject_config_createproject_config_setserver_upgradetest_reactor_runtest_reactor_stop
Delete 3 · Delete, drop, revoke or wipe things.
debug_clear_breakpointshardware_recoverreset_target
Not yet classified 9 · We could not tell from the name and description.
can_sendcan_session_stopdebug_continuedebug_haltpower_supply_cyclepower_supply_outputprobe_targetproject_config_reload_descriptiontest_reactor_status
Tools (48)
Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].
artifact_uploadStore 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.
bench_run_startDeclare 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_statusReport 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.
bench_run_stopEnd 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`.
can_buses_listList 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_readRead 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.
can_sendSend 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_session_startOpen 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_stopClose 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.
classify_last_errorExplain the last hardware failure. Unlike get_last_report, the failure survives later successes. Returns error_type (its code), likely_causes (what to check), report_path and log_path (evidence). source_tool is the failed tool, or reset_target if a flash's recovery reset failed too. Flash refusals by allow_flash or allow_mass_erase record nothing. Needs no board; no failure yet: report_not_found.
com_ports_listList `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 ports, or `permission_denied` on version 1 unless a configured port may be read, `serial_backend_not_available` without pyserial, `com_port_discovery_failed` on OS errors; the call stays ok. Use this instead of picocom or /dev/tty*.
com_readRead 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.
com_session_startOpen 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_stopClose 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_writeSend 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.
Show 33 more tools
debug_clear_breakpointsRemoves 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. GDB server only, exactly one debugger configured; else not_supported.
debug_continueResumes 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. GDB server only, exactly one debugger configured; else not_supported.
debug_dump_symbol_ihexRead a 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 use an open session, else the ELF flash_firmware last wrote (else symbol_source_not_available). Over debug.max_dump_size_bytes: permission_denied.
debug_get_session_statusReports if the debug_start_session session is open and its status: halted, running, error or cleanup_required. Records new stops; 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. GDB server only, exactly one debugger configured; else not_supported.
debug_get_stop_reasonReads why the core last stopped: stop_reason (breakpoint_hit, halted, exception), stop (frame). Records a new 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. GDB server only, exactly one debugger configured; else not_supported.
debug_haltHalts the core; the session stays open. Needs debug_start_session (else session_not_active) on a GDB server, exactly one debugger configured, else not_supported. 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, quarantined; a confirmed halt lifts it unless the session is in error.
debug_list_breakpointsLists the breakpoints from the debug_start_session session's own record without asking GDB: breakpoints (id, backend_id, location), status, and cleanup_required, quarantined and hardware_state when cleanup is unconfirmed. Never halts or resumes the core. No session: ok, active false. debug_clear_breakpoints removes them. GDB server only, exactly one debugger configured; else not_supported.
debug_set_breakpointAdds 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. GDB server only, exactly one debugger configured; else not_supported.
debug_start_sessionOpens a GDB session on an ELF for debug_continue and debug_halt. OpenOCD, pyOCD or ST-LINK_gdbserver; else not_supported. Needs GDB (debug.gdb_executable or PATH), the debugger's executable 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_sessionEnds the debug_start_session session; debug_halt keeps it open. Confirms core halted, disables resume on detach, ends GDB and debug server, drops breakpoints, frees flash_firmware and reset_target. OpenOCD, pyOCD or ST-LINK_gdbserver only; else not_supported. Success: safe_state_confirmed true. No session: ok, active false. Unproven: ok false, cleanup_required, hardware_state unknown, quarantined.
debug_symbol_infoFind a 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 an open session, else the ELF flash_firmware last wrote (else symbol_source_not_available; symbol_source_changed if changed since).
debug_symbol_valueReads a symbol from target memory, like gdb print. Address: debug_symbol_info; file: debug_dump_symbol_ihex. Returns hex plus value_unsigned and value_signed at 1/2/4/8 bytes. OpenOCD needs debug_start_session (else session_not_active); pyOCD and STM32CubeProgrammer use an open session, else flash_firmware's last ELF (else symbol_source_not_available). Over max_dump_size_bytes: permission_denied.
debugger_infoCheck 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_listList 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.
flash_firmwareWrite 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.
get_last_reportReturn 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.
hardware_lease_statusRead 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.
hardware_recoverClear 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.
power_supply_cyclePower-cycle the board on one supply channel: output off, wait `off_s`, output on, each state read back. Needs `allow_output`. The stored set points are held to the effective limits and the protection is armed at them first. A type that cannot read its output state is refused before contact (`not_supported`). Every call cycles the board again.
power_supply_outputSwitch one supply channel's output on or off and read the state back. Needs `allow_output`. Before switching on, the stored set points are held to the effective limits and the protection is armed at them. A type that cannot read its output state is refused before contact (`not_supported`). Switching to the state already held changes nothing.
power_supply_setSet the voltage, the current or both on one supply channel. Needs `allow_set`. Refused before contact when the configuration sets no limit for the channel, or a value is above its effective limit (`power_supply_limit_exceeded`). Arms the supply's protection at the limits first, writes, and reads every value back exactly (`power_supply_readback_mismatch`). Does not switch the output.
power_supply_statusRead a configured bench power supply: per channel its set points, measured voltage and current, output state, protection and effective limits, each exact or null where the type cannot read it. Writes nothing and needs no grant. `missing_limits` and `writes_refused_reason` say why writes on a channel would be refused. A unit other than the configured one fails `power_supply_identity_mismatch`.
probe_targetConnect 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).
project_config_adopt_hardwareFill 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_createGenerate 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_describeList 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_reload_descriptionRe-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.
project_config_setWrite 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).
reset_targetReset 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).
server_upgradeUpgrade 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.
test_reactor_runRun 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_statusFollow 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_stopAsk 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).
Signals
- Stars
- 20
- Forks
- 1
- Open issues
- 30
- Weekly downloads
- 1,515
- Last commit
- Oct 24, 2026 (4 days ago)
- Last release
- Oct 6, 2026 (22 days ago)
- Last package publish
- Oct 6, 2026 (22 days ago)
From GitHub (fetched Oct 24, 2026) and the package registry.
Details
- Registry name
io.github.agentic-hil/agentic-hil- Version
- 0.24.0
- Auth
- No auth
- Packages
- pypi agentic-hil
- License
- Apache-2.0
- Repository
- github.com/agentic-hil/agentic-hil
- First seen
- Oct 24, 2026
- Last checked
- Oct 25, 2026
Cite this page
Agentic HIL MCP server. Agent Mart. https://agentmart.dev/connectors/agentic-hil-agentic-hil (last updated 2026-10-25)