Skip to main content
Glama

English | Deutsch | Español | Français | 日本語 | 한국어 | Русский | 简体中文 | 繁體中文

ChannelTerm

Debug your board with AI. Stay in the same terminal.

ChannelTerm lets you and your AI client share a live serial or SSH terminal. Read the same device output, follow AI terminal commands, and take turns operating the board. It runs on Windows, Linux, and macOS and connects external AI clients through MCP.

Use GDB to let AI set breakpoints, step through Linux programs, and inspect variables. Connect the serial port on Windows and run GDB in WSL2, or keep the shared console open while GDB uses the board's Ethernet connection. Choose a debugging setup.

For short boot windows, let the Host interrupt U-Boot and verify the prompt. Export a diagnostic ZIP with optional raw bytes when investigating failures. U-Boot and diagnostic workflow.

Why ChannelTerm?

Keep your terminal open while the AI works with the same device connection:

                         +---- Human terminal
                         |
Serial device ---- Session
                         |
                         +---- AI / MCP client

Each client reads independently, so an AI reader does not consume the output you are watching. ChannelTerm displays AI terminal writes in your attachment; external debugger output has its own visibility rules.

Related MCP server: sbl-probe

What It Enables

  • Share the console: human CLI and AI/MCP clients use one serial or SSH Session.

  • Follow the work: see AI terminal commands alongside the device's output.

  • Debug Linux programs: use managed GDB, a serial bridge, or GDB over the network.

  • Move files: transfer over a shared serial Session with SHA-256 checks, or use dedicated SFTP/SCP connections.

  • Start with one attachment: channelterm attach can create the local shared Host automatically.

Installation

Download the archive for your operating system and architecture from Releases and verify it against that release's SHA256SUMS. Extract it, then run .\channelterm.exe install on Windows or ./channelterm install on Linux/macOS from the extracted directory. Prebuilt binaries do not require Go.

Building from source requires Go 1.26 or newer. Use a currently supported patched Go toolchain, then build the native executable from the repository root:

git clone https://github.com/akira-init1/ChannelTerm.git
cd ChannelTerm
go build ./cmd/channelterm
./channelterm install

install copies the running binary into the current user's standard program location, creates the channelterm and cterm commands, adds that location to the user PATH only when necessary, and initializes a missing minimal configuration. Open a new terminal when it reports a PATH change. channelterm uninstall removes the installer-owned commands and PATH change while preserving user data; channelterm uninstall --purge requires explicit confirmation before deleting configuration, device state, and the local HTTP credential.

Supported desktop targets are Windows, Linux, and macOS on amd64/arm64. See Build and install from source, the exact install / uninstall contract, and configuration locations. Repository checks and cross-build scripts are covered by Building and testing.

Quick Start: One Command, One Terminal

List detected serial devices, saved profiles, and Sessions from the default HTTP Host when it is available:

channelterm list

A running Host is optional. When it is unavailable, list reports MCP as offline and still shows local devices and profiles.

See the CLI reference for the complete option contract.

If an AI client should join the Session, configure a supported client once before attaching:

channelterm init --mcp

Choose HTTP, or press Enter for the HTTP default. The configuration includes the local Bearer credential. Reload the AI client if it does not pick up configuration changes immediately.

Then run the command for the current platform:

# Windows
channelterm attach COM8 --baud 115200 --label board

# Linux
channelterm attach /dev/ttyUSB0 --baud 115200 --label board

# macOS
channelterm attach /dev/cu.usbserial-110 --baud 115200 --label board

That single attach command opens the serial device and attaches the current terminal. When no compatible Host is already running at the default endpoint, it also starts a temporary local HTTP MCP Session Host automatically. Typical startup output is:

Shared Session created: SER-1 (0123456789abcdef0123456789abcdef)
[ChannelTerm] Temporary Session Host started; it and all shared Sessions stop when this attachment exits. Run 'channelterm mcp --transport http' separately for a persistent Host.

No separate MCP-server terminal is required for this quick path. While the attachment remains open, a configured HTTP MCP client can use http://127.0.0.1:37099/mcp and operate the same SER-1. The temporary Host and every Session it owns stop when the creating attachment exits; use a persistent Host only when Sessions must outlive that terminal.

--label board is an optional display name, not an identifier. Use SER-1 or the opaque Session ID when another client needs to refer to the Session.

Common workflows

Goal

Command

Open a shared serial Session and auto-start a temporary Host

channelterm attach COM8 --baud 115200

Configure a supported AI client for the shared HTTP Host

channelterm init --mcp

Keep the Host and Sessions alive independently

channelterm mcp --transport http

List or join an existing Session

channelterm list --kind session then channelterm attach SER-1

Open a private serial connection with no MCP sharing

channelterm attach COM8 --private --baud 115200

Watch structured Session activity

channelterm events SER-1

Open the guided file-transfer menu in the current shared attachment

Press Ctrl+], then press f

Send or receive through a shared Session

channelterm file send firmware.bin --session SER-1 or channelterm file receive /tmp/log.txt ./log.txt --session SER-1

A persistent Host is a separate long-running process. After it reports MCP Streamable HTTP listening on http://127.0.0.1:37099/mcp, other shells and configured AI clients can create or join Sessions. Silence after the readiness line is normal; stop the Host with Ctrl+C when all of its Sessions should close.

During ordinary terminal use, outside a file transfer or debugger takeover:

Ctrl+C      Send 0x03 to the remote terminal
Ctrl+] q    Leave this CLI; an attachment-owned temporary Host also stops
Ctrl+] ?    Show local escape help

See the CLI reference for all local controls and the MCP workflow for client setup and AI-created Sessions.

For reusable workflow guidance, install the bundled cterm-serial-debug Agent Skill in an Agent Skills-compatible client. channelterm init --mcp configures MCP clients but does not install the Skill.

The HTTP server requires a per-user Bearer token and defaults to a loopback-only listener. Built-in CLI clients use the local token automatically. It can also listen on a trusted LAN; remote clients must use the Host's reachable address and send the same token through the Authorization header. Do not expose the endpoint without TLS and separate network access controls.

A Shared Terminal in Practice

An attached CLI renders an Agent command as a local AI activity block. terminal_exec keeps that command out of an idle Bash prompt's history; the lines after the block are still the device's raw terminal output, and the human can type again when the short command lease is released:

root@board:~#

──────── AI ────────
[18:52:31] >> echo agent-check
────────────────────
agent-check
root@board:~# echo human-still-here
human-still-here
root@board:~#

The exact command output depends on the connected device. The AI block is local presentation derived from structured Session events; it is not inserted into the device byte stream or stored terminal output. Raw keys and interactive programs still use terminal_write and retain the device's normal history behavior.

Shared SSH shell

Connect using an authorized private key (encrypted keys prompt for a passphrase) or enter your login password when prompted. Passwords and key passphrases are not saved. For an unknown server, verify its displayed fingerprint and enter yes to save its public key in ~/.ssh/known_hosts; changed keys are rejected. Prompts require an interactive terminal:

# Terminal 1: open the shell; then run uname -a at its prompt.
channelterm ssh user@192.168.1.50

# Terminal 2: observe and use the same shell.
channelterm attach SSH-1

Keep the first command running: exiting it closes this Host and its Sessions. The default local sharing port must be free; use --listen and the printed attach endpoint for a separate Host. See the SSH workflow for key paths, host verification, ports, and current limits.

Files over SSH

Use SFTP for file transfer and remote file management, or legacy SCP for compatible POSIX servers:

channelterm sftp user@192.168.1.50 ls /tmp
channelterm sftp user@192.168.1.50 put ./firmware.bin /tmp/firmware.bin
channelterm sftp user@192.168.1.50 get /tmp/log.txt ./log.txt
channelterm scp user@192.168.1.50 put ./release /tmp/release --recursive

These commands use the same key/password authentication and host verification as SSH, with a dedicated connection independent of terminal Sessions. Replacing existing files requires --overwrite. See file transfer for directory semantics, cancellation, and protocol limits.

Transfers over shared terminal Sessions use a small Linux-shell protocol. Dedicated SSH file connections use SFTP or legacy SCP.

Files over a shared Session

That shared serial Session can also transfer regular files and directories without an AI client or a separately installed board-side transfer agent. In an active shared attach, press Ctrl+] and then f to open the guided send/receive menu. Directories use standard tar and acknowledged, cancellation-friendly chunks; the same operations are available as commands:

channelterm file send firmware.bin --session SER-1
channelterm file receive /tmp/log.txt ./log.txt --session SER-1
channelterm file send ./build/release /tmp/release --session SER-1
channelterm file receive /var/log/myapp ./myapp --session SER-1

Transfers require an idle Linux shell with the utilities listed in the file-transfer workflow. They verify SHA-256 and select a new name instead of overwriting an existing destination. During a transfer, Ctrl+C in a shared attachment asks for cancellation; other writers remain blocked until cleanup releases the lease.

Remote debugging with GDB

Choose how the debugger reaches your Linux program. Each path needs tools and symbols compatible with the target.

Path

GDB connection

Console / Session during debugging

Serial bridge

Workstation GDB → ChannelTerm → board serial port; Windows + WSL2 example below

Reserved for GDB until restored

Serial console + TCP

Workstation GDB → board network interface; WSL2, Linux, Windows, or macOS with compatible GDB

Available for independent shell/log work

Managed GDB/MI

MCP tools control GDB; Host, shell, tools, and ELF must share one native Linux environment

The selected Session is reserved during debugging

Serial GDB bridge: Windows + WSL2

Windows connects the serial port; WSL2 runs GDB; the AI coordinates remote debugging. The Windows ChannelTerm Host keeps the COM port and shared Session open. A target-compatible GDB in WSL2 connects through the Linux channelterm rsp-client helper and the authenticated TLS/TCP bridge to the board's Linux gdbserver.

flowchart LR
    AI["AI client"]
    Human["Human terminal"]
    subgraph Windows
        Host["ChannelTerm Host"]
        COM["COM port"]
        Host <--> COM
    end
    subgraph WSL2["WSL2 / Linux"]
        GDB["Target-compatible GDB"]
        Helper["Linux channelterm rsp-client"]
        GDB <--> Helper
    end
    Board["Linux board / gdbserver"]
    AI -->|"MCP: prepare and manage"| Host
    AI -->|"Process tool: GDB commands"| GDB
    Human ---|"attach / AI reports"| Host
    Helper <-->|"TLS/TCP"| Host
    COM <-->|"Serial RSP"| Board

Keep your Windows serial driver and Linux toolchain: the serial device stays on Windows, and the board needs no network GDB port.

  1. On Windows, configure the AI client with channelterm init --mcp (HTTP), then open the board, for example channelterm attach COM8 --baud 115200. Use the board's confirmed serial settings and keep the owning Host running.

  2. Following the bridge preparation steps, save the TTY state, prepare a compatible gdbserver --once stdio on the board, and call debug_bridge_start through MCP. The AI also needs a process execution tool to run GDB in WSL2.

  3. In WSL2, use Linux ChannelTerm and target-compatible GDB with the matching ELF. Save the private connection descriptor as bridge.json in WSL's filesystem (chmod 600). The WSL2 guide covers networking and paths. Replace the descriptor path below:

(gdb) target remote | channelterm rsp-client --connection /home/EXAMPLE/private/bridge.json
(gdb) break main
(gdb) continue
(gdb) next
(gdb) backtrace
(gdb) detach
  1. On Windows, use channelterm gdb-list or channelterm gdb-list --json to see bridge ports and states. After GDB detach, confirm the board has returned to its shell and call debug_bridge_restore with the saved TTY state to resume shared terminal use.

For this serial bridge, AI can publish actual commands and observations through debug_bridge_report so you can follow them in the attached terminal. Entries are labelled AI reports, not a complete automatic GDB transcript.

Shared serial console + GDB over Ethernet

Keep the serial console available for shared logs and shell work while GDB uses the network. The serial Host and GDB can be on the same computer or different computers; choose each environment's serial driver and target toolchain independently.

flowchart LR
    AI["AI client"]
    Human["Human terminal"]
    Host["ChannelTerm Host"]
    GDB["Workstation GDB: WSL2 / Linux / Windows / macOS"]
    subgraph Board["Linux board"]
        Console["Serial shell / logs"]
        Server["gdbserver"]
    end
    Human ---|"attach"| Host
    AI -->|"MCP"| Host
    AI -->|"Process tool: GDB commands"| GDB
    Host <-->|"Serial"| Console
    GDB <-->|"TCP / Ethernet"| Server

Keep gdbserver running independently of the interactive serial shell if you want to continue issuing shell commands. Load the matching ELF in workstation GDB, then connect over a restricted network as below (replace TARGET_IP and the port). See the serial-console + TCP workflow for target startup, application I/O, and SSH tunnelling.

(gdb) target remote TARGET_IP:2345

This TCP path uses gdbserver directly, without rsp-client or debug_bridge_*. Human and AI see the shared serial activity; external GDB commands/results remain in the debugger's own output and are not automatically mirrored into the serial attachment.

Managed GDB/MI and the external bridge have real GDB/gdbserver coverage on Linux PTYs in CI. See the full workflow for setup, compatibility, SSH alternatives, and recovery.

How It Works

Human CLI -----+
               +--> Session Host --> Session <--> Channel <--> Serial / SSH endpoint
AI via MCP ----+                         |
                                        +-- retained output, activity, events
                                        `-- serialized writes

The Session Host owns connections and Session lifetimes. A Serial or SSH Transport establishes a protocol-neutral Channel; Session reads that Channel, retains bounded output, activity, and events in memory, and serializes writes. CLI and MCP adapters reuse the same Core behavior. Presentation such as highlighting and the AI activity block stays outside stored terminal data.

Readers have independent cursors. Raw writes are serialized but do not coordinate shell commands; application leases temporarily block other writers during command execution, transfers, and debugging. See shared Sessions for ownership and concurrency.

Shared references such as SER-1 are valid only within the owning Host process. Stopping that Host closes its Sessions. A secondary attachment can leave independently. Exiting the attachment that owns a temporary Host, or the SSH command that created its Host, also closes that Host and its Sessions. See the architecture overview for the layer boundaries.

Configuration

config.toml contains user-owned serial profiles and connection policy. state.json is ChannelTerm-managed device identity state. http-auth-token is the secret used to authenticate MCP HTTP clients; do not share or commit it.

# Save and reuse a serial profile.
channelterm serial --port COM8 --baud 115200 --save board
channelterm serial --profile board

# Select a different config.toml for this operation.
channelterm serial --config ./channelterm.toml --profile board

Common options are --profile, --save, --config, --port, and --baud; the MCP Host also accepts --connection-policy ask|auto|deny. --config changes only the selected config.toml, not the default state.json or http-auth-token. See Serial profiles and the configuration reference for complete fields, precedence, validation, and persistence behavior.

Documentation

For exact command flags and defaults, the running program's --help output is authoritative.

Roadmap

Serial and SSH PTY shells are implemented Transports; dedicated SFTP and legacy SCP file clients are also available. Arbitrary SSH exec, Telnet, and stronger multi-writer coordination remain future directions rather than implemented features or release commitments.

ChannelTerm does not currently implement JTAG/OpenOCD, virtual serial devices, a built-in AI, or multi-agent orchestration.

License

ChannelTerm is licensed under the Apache License 2.0.

Available Tools

40 tools
debug_bridge_closeClose External GDB Bridge and SessionA
DestructiveIdempotent

Close the external RSP bridge AND its serial Session. Does not detach, kill a target, or claim shell restoration. Use debug_bridge_restore after externally ending RSP if the Session should be preserved. Idempotent.

Inputs: owner (required), bridge_id (required). Returns: status

debug_bridge_listList External GDB Bridge PortsA
Read-only

List all unfinished external GDB bridges in this Host with bound addresses, ports, Session references, targets, and states. Includes disconnected/recovering bridges until finalization; excludes closed/failed/restored history. Read-only: no heartbeat renewal, target I/O, management owner, or connection secrets. Uses Host access authorization without a per-bridge owner. Does not scan OS ports or other Hosts.

Returns: bridges

debug_bridge_renewRenew External GDB BridgeA

Renew the external RSP bridge's management heartbeat and internal lease, including while listening or disconnected. Current authenticated rsp-client connections renew automatically. The 60-second grace and 24-hour absolute maximum cannot be resurrected. Expiry closes the serial Session without claiming target restoration.

Inputs: owner (required), bridge_id (required). Returns: status

debug_bridge_reportReport External GDB Activity from CodexA
Idempotent

Report actual externally executed GDB commands, results, or observed states as Codex reports, not a complete GDB audit. Publishes only independent Session events visible in attach/events; never executes commands, forwards RSP, verifies target state, or renews the heartbeat. Omit raw RSP and secrets. Reporting failure must not interrupt GDB: continue debugging; renewal is independent of reporting. Sequence increases per bridge (gaps allowed); retry only the latest identical report.

Inputs: kind (required), text (required), owner (required), sequence (required), +1 more. Returns: sequence, bridge_id

debug_bridge_restoreVerify Terminal Restoration after RSPA
DestructiveIdempotent

After external GDB disconnects and the target returns to its shell, explicitly confirm readiness and supply the pre-debug stty -g value. Applies and reads back that value, then verifies a fresh shell marker before releasing the lease. Never injects RSP detach. Failure or ten-second timeout closes the Session.

Inputs: owner (required), bridge_id (required), tty_state (required), confirm_shell_ready (required). Returns: status

debug_bridge_startOpen External GDB BridgeA
DestructiveIdempotent

Bridge an already prepared serial Session to one authorized external GDB via pinned TLS/TCP. Does not start or control GDB/gdbserver or probe RSP. Target readiness cannot be inferred from silence: explicit acknowledgement is required after preparing the target. Returns a secret connection descriptor for channelterm rsp-client. Defaults to loopback; a specific non-loopback bind requires allowed_peer. Reuse owner/request_id and all parameters exactly for retries. Current rsp-client connections maintain the management lease automatically, even without RSP traffic. Renew every 30 seconds before connecting, after disconnect, or with legacy helpers. All bridges have a 24-hour maximum lifetime. Use debug_bridge_report for actual externally executed commands, results, and observed states (Codex reports, not a complete audit).

Inputs: owner (required), request_id (required), session_id (required), acknowledge_unverified_target (required), +3 more. Returns: status, connection

debug_bridge_statusRead External GDB Bridge StatusA
Read-only

Read external RSP bridge status without renewing its heartbeat or disclosing connection secrets. Disconnected retains exclusive ownership and does not mean the target or shell has recovered.

Inputs: owner (required), bridge_id (required). Returns: status

debug_commandControl GDBA
DestructiveIdempotent

Execute one supported GDB action, or renew the 60-second debug heartbeat. Reuse request_id and parameters unchanged after a lost response. Execution is asynchronous: consume debug_events for stops. Raw MI/console and multi-inferior control are unavailable.

Inputs: owner (required), action (required), debug_id (required), request_id (required), +1 more. Returns: record

debug_eventsRead Debug EventsA

Wait for ordered MI records and lifecycle events after a debug cursor; renews the client heartbeat. A stale cursor is an error, never silently skipped. Invalid UTF-8 MI values use explicit base64 objects.

Inputs: owner (required), cursor (required), debug_id (required), timeout_ms. Returns: next, events, status

debug_startStart User-Space DebuggingA
DestructiveIdempotent

Start native Linux user-space GDB/MI on an idle Bash Session using an exclusive managed lease. ChannelTerm, GDB, gdbserver, and ELF must share one Linux environment. PID omitted launches with isolated I/O; attach rejects controlling terminals, pipes, sockets, or shared character devices. Single inferior, multithreaded, all-stop only. Reuse owner and request_id unchanged to retry.

Inputs: elf (required), owner (required), request_id (required), session_id (required), +4 more. Returns: status

debug_stopEnd User-Space DebuggingA
DestructiveIdempotent

End debugging, detach by default, wait for protocol completion, restore original terminal modes and confirm the shell with a unique harmless probe. terminate is allowed only for launched processes. Recovery failure closes the Session and returns an error. Safe to retry.

Inputs: owner (required), debug_id (required), terminate. Returns: status

terminal_acquire_leaseAcquire Session LeaseA

Acquire one exclusive Session lease. Readers continue normally; other writers fail until release.

Inputs: type (required), owner (required), session_id (required). Returns: type, state, created_at, expires_at, +2 more

terminal_begin_file_transfer_cancelBegin File Transfer CancellationB

Begin cancellation confirmation only when a file-transfer lease is active on the Session.

Inputs: session_id (required). Returns: state, active, request_id

terminal_closeClose Terminal SessionA
Destructive

Close the shared terminal Session for every attached client and release its transport; use terminal_session_detach to record only one client's departure without closing it.

Inputs: session_id (required). Returns: closed, session_id, session_ref

terminal_enter_ubootEnter U-BootA
Destructive

Interrupt one U-Boot countdown on an existing serial Session and confirm entry using Host-side raw-byte matching. No skill installation is required.

Select: use terminal_list_sessions if the intended Session is unknown. If current evidence already establishes an idle U-Boot prompt, use terminal_write for authorized commands, not this entry tool or Bash-only terminal_exec. An old buffered prompt alone does not establish current state.

Prepare: inspect boot output with terminal_read (hex/base64 for non-UTF-8 bytes), supplied firmware configuration, or settings verified for this board and firmware. Select the literal markers and exact interrupt bytes from that evidence. An explicit any-key prompt permits a space; a generic countdown does not identify the required key or string. If a required setting is unknown, ask the user only for that missing detail before calling; reuse known answers. Do not guess or cycle through keys. The tool does not discover settings or ask questions during execution.

Run: stay within the user's authorized hardware action; an explicit request to enter U-Boot need not be reconfirmed. Choose wait_reset for manual reset, or reboot only from a verified idle Bash prompt with an explicit command. Before calling, save the terminal_session_events cursor; in another request observe the matching OPERATION_STATE ready event before manual reset. Prepare before resetting rather than relying on model round trips during the countdown. The Host manages its lease and sends the interrupt at most once.

Verify: only status entered confirms a fresh line-bound prompt after countdown; bytes_written alone does not. Check isError and structuredContent.result for partial evidence. boot_started means boot proceeded; timeout means entry was not confirmed, not that the key was wrong. On failure report evidence; do not automatically change keys or reboot again. Cancellation releases ownership without recovery keys or closing a healthy Session; a submitted reboot cannot be undone.

Limits: a silent countdown or firmware-disabled interruption is not handled by this flow; request firmware details instead of inventing a trigger. There is no dedicated password/credential-protection workflow; do not solicit secrets in chat or treat tool arguments as protected credential storage.

Inputs: mode (required), session_id (required), prompt_pattern (required), countdown_pattern (required), +5 more. Returns: status, dropped, elapsed_ms, output_end, +10 more

terminal_execExecute Terminal CommandA
Destructive

Execute one non-interactive command through an idle Bash prompt without adding it to Bash history; use terminal_write for raw keys or interactive programs. Never use this at a U-Boot prompt: use terminal_write for U-Boot commands, or terminal_enter_uboot to interrupt a fresh boot countdown.

Inputs: command (required), session_id (required), timeout_ms. Returns: exit_code, command_id, output_end, session_id, +1 more

terminal_export_diagnosticsExport Session DiagnosticsA

Export a bounded ZIP snapshot of retained Session evidence. include_raw=true explicitly includes sensitive terminal/output/write bytes. Default exports metadata only. Returns ID, size and SHA256; download with terminal_read_diagnostic. Host memory retains at most four archives for 15 minutes, evicting oldest first. No filesystem path is exposed.

Inputs: session_id (required), include_raw. Returns: size, sha256, expires_at, diagnostic_id

terminal_file_transfer_checkpointCheck File Transfer ControlC
Read-only

Check a file-transfer lease at a safe block boundary, waiting while cancellation confirmation is pending.

Inputs: owner (required), session_id (required). Returns: action

terminal_get_connection_decisionGet Connection DecisionA
Read-only

Evaluate the configured response to a discovered endpoint. After an appeared device event, call this before terminal_open_serial: action ask requires user approval, connect permits client-controlled opening, deny requires no action, and none requires no action. This tool never opens a session.

Inputs: endpoint (required), transport (required). Returns: action, policy, reason, present, +5 more

terminal_list_devicesList Discovered DevicesA
Read-only

List currently present devices detected by ChannelTerm without opening them or creating sessions.

Returns: devices

terminal_list_serial_portsList Serial PortsA
Read-only

List serial ports currently detected by the operating system without opening them.

Returns: ports

terminal_list_sessionsList Terminal SessionsA
Read-only

List active terminal sessions and their lifecycle states.

Returns: sessions

terminal_open_serialOpen Serial SessionA
Destructive

Open a serial terminal session from a profile and optional connection overrides. When opening after device discovery, call this only after user approval or a terminal_get_connection_decision action of connect; explicit user-requested connections remain allowed.

Inputs: baud, port, save, wake, +7 more. Returns: reused, session_id, session_ref

terminal_readRead Terminal OutputA
Read-only

Read retained terminal output immediately when cursor is omitted; use terminal_wait to wait for new bytes after a known cursor. For U-Boot entry, use this to inspect evidence and prepare terminal_enter_uboot; let that Host-side tool interrupt the countdown rather than polling and sending keys from the client. Retained prompts alone do not establish current device state.

Inputs: session_id (required), cursor, encoding, max_bytes, +1 more. Returns: data, next, dropped, encoding, +1 more

terminal_read_activityRead Session ActivityA
Read-only

Read retained Session activity immediately when cursor is omitted; use terminal_wait_activity to wait for events after a known activity cursor.

Inputs: session_id (required), cursor, max_events, timeout_ms. Returns: next, events, dropped

terminal_read_device_eventsRead Device EventsA
Read-only

Read retained device appearance and disappearance events immediately when cursor is omitted; use terminal_wait_device_event to wait after a known cursor. After an appeared event, call terminal_get_connection_decision before opening a serial session.

Inputs: cursor, max_events, timeout_ms. Returns: next, events, dropped

terminal_read_diagnosticDownload Diagnostic ArchiveA
Read-only

Read up to 65536 ZIP bytes by diagnostic_id and archive byte offset as base64. This offset is not a Session cursor. Download before expiry/eviction; verify the exported SHA256.

Inputs: offset (required), diagnostic_id (required), max_bytes. Returns: eof, data, next, size, +3 more

terminal_release_leaseRelease Session LeaseA
DestructiveIdempotent

Release an exclusive Session lease owned by this operation.

Inputs: owner (required), session_id (required). Returns: released

terminal_renew_leaseRenew Session LeaseA

Renew an exclusive Session lease owned by this operation before it expires.

Inputs: owner (required), session_id (required). Returns: type, state, created_at, expires_at, +2 more

terminal_report_file_transferReport File Transfer EventA

Publish a file-transfer status event only for the caller-owned active file-transfer lease, without writing terminal output.

Inputs: type (required), owner (required), session_id (required), transfer_id (required), +2 more. Returns: published

terminal_resolve_file_transfer_cancelResolve File Transfer CancellationA
Destructive

Resolve a file-transfer cancellation confirmation; false resumes and true waits for safe cleanup and lease release.

Inputs: cancel (required), request_id (required), session_id (required). Returns: state, total, percent, transferred

terminal_session_attachAttach to Terminal SessionA

Record one client attachment on the Session event stream without acquiring a lease or writing terminal bytes.

Inputs: session_id (required), actor. Returns: attached

terminal_session_detachDetach from Terminal SessionA

Record one client detachment on the Session event stream without closing it for other clients; use terminal_close only to close the shared Session for everyone.

Inputs: session_id (required), actor. Returns: detached

terminal_session_eventsRead Session EventsA
Read-only

Read retained structured Session events, or wait for events after an event cursor. Events never include terminal output bytes.

Inputs: session_id (required), cursor, max_events, timeout_ms. Returns: next, events, dropped

terminal_waitWait for Terminal OutputA
Read-only

Wait only for terminal output bytes after a known cursor; use terminal_read without cursor for an immediate snapshot. This does not return file-transfer status; use terminal_wait_file_transfer for transfer completion or cancellation.

Inputs: cursor (required), session_id (required), encoding, max_bytes, +1 more. Returns: data, next, dropped, encoding, +1 more

terminal_wait_activityWait for Session ActivityA
Read-only

Wait for Session activity events after a known cursor; use terminal_read_activity without cursor for an immediate snapshot.

Inputs: cursor (required), session_id (required), max_events, timeout_ms. Returns: next, events, dropped

terminal_wait_device_eventWait for Device EventA
Read-only

Wait for a device appearance or disappearance event after a known cursor; use terminal_read_device_events without cursor for an immediate snapshot. After appeared, call terminal_get_connection_decision before terminal_open_serial.

Inputs: cursor (required), max_events, timeout_ms. Returns: next, events, dropped

terminal_wait_file_transferWait for File Transfer ResultA
Read-only

Wait for one transfer_id after an event cursor until the transfer completes, is cancelled, or fails and its file-transfer lease has been released. Completed transfers include source_path, requested_path, resolved_path, renamed, and optional sha256; use resolved_path as the saved file path. Use this instead of terminal_wait for file-transfer outcomes.

Inputs: cursor (required), session_id (required), transfer_id (required), max_events, +1 more. Returns: next, event, state, sha256, +7 more

terminal_writeWrite Raw Terminal InputA
Destructive

Write raw UTF-8, hexadecimal, or base64 bytes for keys or interactive programs; shell lines follow target history, so use terminal_exec at an idle Bash prompt. Use this for authorized commands at a verified idle U-Boot prompt; use terminal_enter_uboot for countdown interruption. Do not send an empty Enter merely to probe U-Boot: it may repeat the previous command. For files/ELFs use CLI channelterm file send/receive with --session and the owning --endpoint, then terminal_wait_file_transfer. Do not construct Base64/heredoc uploads with this tool. Run the CLI where the local file and Host are accessible; if unavailable, report the limitation.

Inputs: data (required), session_id (required), actor, encoding. Returns: bytes_written

terminal_write_leasedWrite Leased Terminal InputA
Destructive

Write raw bytes through an active Session lease owned by a managed multi-step operation; normal terminal input must use terminal_write.

Inputs: data (required), owner (required), session_id (required), actor, +1 more. Returns: bytes_written

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 40 tools

    Disambiguation3/5

    Descriptions are unusually explicit about boundaries and cross-reference the correct sibling tool, which rescues much of the set. However, there are several near-parallel families — terminal_read vs terminal_wait, terminal_read_activity vs terminal_wait_activity, terminal_read_device_events vs terminal_wait_device_event, terminal_session_events, terminal_read_diagnostic — plus terminal_write vs terminal_write_leased vs terminal_exec, and terminal_acquire_lease vs terminal_renew_lease vs terminal_release_lease, giving real misselection risk across 40 tools.

    Naming Consistency4/5

    Consistent snake_case with predictable terminal_ / debug_ / debug_bridge_ prefixes that map to sub-domains, which is a sensible convention at this scale. Minor variance in element ordering (some verb-first like terminal_get_connection_decision and terminal_list_serial_ports, others noun-first like terminal_session_events, terminal_file_transfer_checkpoint) keeps it from a perfect score.

    Tool Count2/5

    40 tools is well past the point of easy selection for an agent, and a substantial share are structural duplicates (paired immediate-read / wait variants) or lease bookkeeping rather than distinct capabilities. The domain is genuinely complex (serial sessions, U-Boot entry, GDB bridge, file transfer, diagnostics), but that breadth is used to justify a surface that is too large.

    Completeness4/5

    Lifecycle coverage is strong: session open/close/attach/detach, lease acquire/renew/release, read/write, device discovery and events, U-Boot entry, native debug start/stop/command/events, debug bridge start/status/renew/report/restore/close, plus file-transfer checkpoint/cancel and diagnostics export/download. Gaps are minor and documented — no tool to create or edit serial profiles (terminal_open_serial assumes one), and file upload/download is pushed to the CLI rather than the tool surface.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      D
      maintenance
      A headless MCP server that enables AI tools (like Claude Code) to read and analyze serial logs from embedded boards (ESP32, STM32) for firmware debugging, with read-only tools for log retrieval and a built-in web viewer.
      6
      1
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Serial communication and protocol analysis MCP server that gives AI coding assistants direct access to serial ports for reading, writing, decoding, and capturing embedded device output.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables humans and AI agents to collaboratively control serial ports via MCP tools or Web UI, with real-time data sharing across all participants.
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      An MCP server that lets AI coding agents drive the full STM32 development loop—code generation, build, flash, debug, serial monitoring, and fault diagnosis—end to end via CubeIDE, CubeMX, CubeProgrammer, OpenOCD, and GDB.
      1
      MIT