Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

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
}
resources
{
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
list_portsA

List serial ports (USB metadata included) plus the always-available mock:echo loopback.

openA

Open a serial port session. If device names a workspace device, its profile supplies transport defaults and framing; explicit arguments override. port may be omitted when the device profile declares a selector (vid/pid/serial_number/product) — exactly one live match is required. replay:<capture path> (relative to the workspace) replays a recorded .obcap. Returns a session_id.

closeB

Close a session and release the port.

readA

Cursor-based framed read: returns frames received since your previous read (waits up to timeout_ms for the first frame). Reports dropped_bytes if the buffer overflowed.

sendB

Write raw bytes (audited). Provide exactly one of hex ('01 A0 FF') or text (control chars as-is, e.g. "AT\r\n").

requestB

Send bytes and await the response (audited). match decides when the response is complete: {length:N} | {delimiter:"..."} | {idle_ms:N}; default is a 50 ms idle gap.

run_commandA

Execute a named command from devices//commands/ with typed params: builds the frame, awaits the response and classifies the outcome (normal | exception | silence | timeout | checksum_error | malformed) against the command's declared expect (audited; an unmet expectation is an error carrying the full result JSON). Give session_id for an open session, or port to open an ephemeral one with the device's profile transport — port may be omitted when the profile declares a selector, and accepts replay:. Commands with risk=danger additionally require acknowledge_risk=true.

run_workflowA

Execute a workflow from devices//workflows/: its steps run in order on one session (step params override command defaults); the first failing step skips the rest, then every finally step is attempted regardless. Returns {ok, steps, finally, skipped}; ok=false is an error carrying the full result JSON. Workflow risk is the maximum of its commands' risk — danger requires acknowledge_risk=true. Session resolution is the same as run_command (session_id, port, or profile selector).

schemaA

The authoritative JSON Schema (or, with example=true, an annotated YAML example) of the openbaud knowledge formats — profile, command, workflow. Call this before writing or modifying any YAML under devices/: it is generated from the exact types that parse those files and includes the semantic rules the schema grammar cannot express.

capture_startA

Start lossless timestamped capture of all rx/tx on a session into captures/*.obcap (JSONL). Returns the workspace-relative path (captures/ — pass it verbatim to capture_frames, session_timeline, or replay:) plus abs_path.

capture_stopA

Stop the active capture on a session; returns stats plus the workspace-relative path (captures/ — directly usable with capture_frames, session_timeline, and replay:) and abs_path.

session_timelineA

Lay a recorded capture out as a session timeline: rx/tx byte density folded into buckets, plus the capture session's audited operations (commands, raw writes, workflow steps, denials) as events. Reads captures/.obcap and .openbaud/audit.jsonl — no hardware. The result declares view:{kind:"timeline"}, so its full_result path (or the result itself) renders via show_result.

capture_framesA

Re-frame a recorded capture's byte stream: tx and rx each run through a deframer and come back as timestamped frames, paginated by cursor/max_frames. Framing comes from the explicit framing object or the named device's profile — one of the two is required, nothing is assumed. Idle-gap framing is driven by the recorded timestamps, so boundaries match what a live session would have produced. Reads captures/.obcap — no hardware. The result declares view:{kind:"capture"} for show_result.

diagnose_frameA

Diagnose one raw frame, pure computation — no hardware, no audit entry. Every checksum algorithm x value encoding is verified at the default tail position (checksum_matrix); each row's at is the byte offset where the stored checksum starts (frame_len - stored_len; stored_len is the algorithm's byte count for raw, twice that for ascii_hex), and a row whose algorithm cannot apply to this frame carries only kind/encoding/error, no at. With expected:{device,command} the command's response.parse is also attempted at byte offsets -2..=+2 (parse_attempts) to expose off-by-N framing — parsed: true only means the bytes are structurally decodable at that offset; the offsets are mutually exclusive hypotheses, so judge which (if any) is the real alignment yourself. The result declares view:{kind:"diagnostics"} for show_result.

session_statsA

Live counters for open sessions: port, framing, opened_ms, buffered/dropped bytes, chunks seen, rx/tx byte totals, last_rx_ms, the transport settings the port was opened with, the active capture (path and live counters), and the session error when the port died. Pass session_id for one session; default is all.

stream_pollA

Per-consumer incremental frame poll on an open session — a private cursor with its own deframer, fully independent of read (the two never steal frames from each other). Call with session_id to create a subscription: the result carries its subscription_id plus any frames already buffered. Call with that subscription_id to fetch what arrived since; frames carry a monotonic per-subscription seq, and next_seq is the seq the next frame will get. since_seq acknowledges delivery: frames with seq < since_seq are released — ack with the last delivered frame's seq + 1, not next_seq (next_seq can run ahead of a max_frames-capped page, and acknowledging frames never delivered is a loud error). Each page also stops at max_inline_bytes of rendered payload (default 4096, metered as each frame's hex length + text length; page_bytes reports the page's actual total) — whole frames only, in seq order; a first frame alone beyond the budget is still delivered, alone, with oversized_frame: true, so delivery always makes progress. Omit since_seq and the unacknowledged frames are redelivered unchanged (idempotent re-read, so a lost response costs nothing). A consumer that lags loses the oldest retained frames beyond 1024, counted cumulatively in dropped_frames; a subscription the session's byte buffer overflowed past counts the gaps in dropped_chunks — never silently. close: true releases the subscription (result carries closed: true). At most 8 subscriptions per session; ones idle beyond 120 s are swept by later stream_poll calls, and closing the session releases them all. Every result folds in the session's live counters as stats. Returns immediately with whatever is available — never waits; a poll with nothing left to deliver on a dead port errors loudly instead of looking healthy. Optionally pass parse: {device, command} when CREATING a subscription (never on a follow-up poll — that is a loud error) to parse every frame server-side with that workspace command's response.parse: each frame then carries parsed (the field values) or parse_error (the per-frame reason; one bad frame never stops the stream), parsed once at arrival so redelivery repeats the identical outcome, and every result echoes parse: {device, command} plus the command's units (same semantics as run_command). A device or command that does not exist, or a command without a response.parse block, fails subscription creation loudly.

ask_portA

Ask the user which serial port to use, on hosts that can render it (elsewhere the candidate list comes back as text for you to relay). Use it when several ports could plausibly be the device and the choice is the user's to make — not for your own discovery, which is what list_ports is for. This does not touch hardware: the user's choice arrives in your context, and you then call open yourself.

show_resultA

Show a saved tool result to the user, rendered (a polar plot for angular scans, a field table otherwise) on hosts that support it. Pass path from an earlier result's full_result — the viewer then reads the complete payload directly, so the full data never enters your context. A result is charted only when it declares how (the command's view, or an encoding you pass here); otherwise it renders as a field table. Use it when the user would rather see the data than read it.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
Port pickerCandidate serial ports with one-click open (binds to list_ports).
Result viewerSchema-dispatching result viewer: polar radar plot for angular scans, key/value card for everything else (binds to run_command/request/read).

TDQS

A3.9/5.0

Scored across 18 tools

Disambiguation4/5

Descriptions go out of their way to delineate boundaries (send=raw fire-and-forget, request=send+await, run_command=named typed command; read=cursor read, stream_poll=independent per-consumer subscription; ask_port 'not for discovery, that's list_ports'). This is unusually explicit, though three byte-sending tools and two frame-reading tools still require careful reading to pick correctly.

Naming Consistency4/5

Most names are a clean verb_noun or noun_noun pattern (list_ports, run_command, run_workflow, capture_start, session_timeline, diagnose_frame, show_result, stream_poll), and the capture_*/session_* prefixes group cleanly. A handful of bare verbs (open, close, read, send, request) deviate slightly, but the overall scheme stays predictable.

Tool Count4/5

18 tools is slightly heavy but justified by the breadth of a serial-toolkit domain: discovery, session lifecycle, three send modes, capture, re-framing, diagnostics, stats, streaming, plus schema and viewer helpers. Each tool maps to a distinct capability rather than being redundant.

Completeness5/5

The surface covers the full lifecycle: discovery (list_ports), open/close, multiple send/execute modes (send, request, run_command, run_workflow), lossless capture (capture_start/stop) with offline analysis (capture_frames, session_timeline, diagnose_frame), live stats and streaming, plus schema and result rendering. No obvious dead ends for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues