tinysa-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tinysa-mcpscan 500k to 25M and list the strongest peaks"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tinySA MCP and CLI
A standalone, headless Python USB driver shared by a command-line tool and an MCP server. No TinySA Saver, Qt, or GUI is required. Designed for scripting and agent-controlled measurements on macOS, Linux, and Windows. Automated and hardware verification procedures are described in VALIDATION.md. Console guide translates the firmware's command list into routine measurement operations.
Install
Python 3.11+ and uv are required for the development setup:
git clone https://github.com/ikatkov/tinysa-mcp.git
cd tinysa-mcp
uv sync --locked
uv run tinysa ports
uv run tinysa infoFor a command available outside the project directory:
uv tool install .
tinysa --helpAlternatively, python3 -m venv .venv and .venv/bin/python -m pip install -e .
install the runtime without uv. The Python API is TinySA(USBTransport(port));
always call close() in a finally block.
Related MCP server: Instrument MCP Server
USB preparation
Select analyzer/input mode on the tinySA, set CONFIG → CONNECTION → USB if present, and connect a data-capable cable. Close TinySA Saver, NanoVNA Saver, serial terminals, and other clients. Only one process should use the instrument. Serial baud rate is 115200 (USB CDC generally ignores it).
Auto-detection actively tries USB serial ports: products named tinySA first, then
devices with STM32 USB ID 0483:5740, then other USB serial endpoints. It sends an
empty prompt request and info, accepting the first instrument that identifies as
tinySA. Busy, silent, and unrelated devices are closed and skipped. Each prompt and
identity probe has a deadline of at most two seconds. Bluetooth and built-in console
ports are skipped. If nothing matches, the error lists attempted ports and why each
failed. If multiple tinySAs are attached, choose one explicitly instead of relying
on the deterministic first match.
To override detection, use tinysa --port PORT info with a port returned by
tinysa ports, or set TINYSA_PORT. An explicit port is verified and never falls
back to another device. The account needs permission to open the serial device.
Discovery opens no serial device.
On macOS, these answer different questions:
system_profiler SPUSBDataType # all USB devices and bus topology
tinysa ports # serial endpoints and candidate identities
python3 -m serial.tools.list_ports -v # pyserial's serial inventoryMeasure and script
Global options (--port, --json, timeouts) go before the subcommand:
# Save the current actual/displayed trace to CSV + metadata, with an ASCII chart.
tinysa capture
tinysa capture --output measurements.csv --width 120
# Set bandwidth explicitly (Hz API, kHz console command).
tinysa configure --rbw 10k --attenuation auto --unit dbm
# New scan, not a snapshot. Firmware leaves the instrument paused by default.
tinysa --scan-timeout 120 scan --start 500k --stop 25M --points 450
tinysa resume
# Resume the configured display sweep immediately after a fresh acquisition.
tinysa scan --start 1M --stop 10M --points 100 --resume-after
# Complete measurement and artifact paths as JSON; no chart on stdout.
tinysa --json capture --no-chart > measurement.json
# CSV to stdout for pipelines; no metadata file is created for stdout export.
tinysa capture --output - > spectrum.csv
# Repeated snapshots: one CSV + metadata per acquisition; NDJSON with --json.
tinysa --json record --count 10 --interval 2 --directory readings > captures.ndjson
tinysa record --count 0 --interval 1 # until Ctrl-C
# A completed fresh scan for every record (interval is a minimum, not a sampling rate).
tinysa --json record --fresh --start 500k --stop 25M --points 450 --count 10 --interval 2
# Strongest sampled local maxima, optionally enforce frequency separation.
tinysa --json peaks --limit 10 --min-level -90 --min-separation 100k
tinysa status
tinysa console-helpEach saved CSV has exactly frequency_hz,level_dbm followed by all sampled points.
Its .json sidecar records schema version, source, device/firmware identity, UTC
start/end times, settings readback, state effects, and a peak summary. Default files
are timestamped in ./readings; TINYSA_EXPORT_DIR or --directory changes this.
Existing CSV and metadata files are protected. Timestamps describe host acquisition
and transfer times; individual sample timestamps are not provided by the USB protocol.
The ASCII chart bins samples to terminal columns and preserves each bin's minimum
and maximum. Narrow spurs remain visible; screen geometry cannot be reproduced exactly
at terminal resolution. The CSV retains all samples. Zero span uses sample order on
the horizontal axis, not calibrated time. Use --no-chart, --width, and --height.
With --json --chart or --output - --chart, the chart goes to stderr.
Exit status: 0 success, 1 measurement/connection/file error, 2 argument syntax
error, 130 Ctrl-C. With --json, runtime errors have an error field. Successful
single commands produce one JSON object; record produces one per capture. Parser
errors still use argparse's stderr. No retries on a failed scan.
Use with an AI agent
The server uses the official MCP Python SDK and stdio transport. After uv tool install .,
make tinysa-mcp available on the MCP client's PATH. For clients with a JSON
mcpServers configuration:
{
"mcpServers": {
"tinysa": {
"command": "tinysa-mcp",
"args": []
}
}
}USB detection is automatic unless --port or TINYSA_PORT specifies a device.
Exports default to readings under the server's working directory; choose the
destination at runtime with --export-dir or TINYSA_EXPORT_DIR.
If the client cannot find the command, configure its PATH or supply the executable
location in that client's configuration. tinysa serve is equivalent. USB opens
lazily on the first instrument tool, so discovery works when no instrument is attached.
The server retains the connection until disconnect_device or shutdown. Diagnostics
go to stderr; stdout is reserved for MCP. There is no network listener or GUI.
For Codex, register the installed command with:
codex mcp add tinysa -- tinysa-mcp
codex mcp get tinysaIn the Codex configuration, set tool_timeout_sec = 180.0 in [mcp_servers.tinysa]
to allow the server's 120-second scan deadline plus readout overhead.
For Claude Code, register it for your user account across projects:
claude mcp add --scope user --transport stdio tinysa -- tinysa-mcp
claude mcp get tinysaUse /mcp in Claude Code to inspect the connection. Client registrations and export
destinations belong in each user's configuration rather than in the repository.
Tools:
Tool | Purpose / effects |
| Serial inventory; no USB open |
| Verified model and firmware identity |
| Current state and raw settings readback |
| Current trace; temporarily pauses and restores running state |
| Fresh scan; replaces trace and leaves paused unless |
| Explicit RBW/attenuation/dBm changes and readback |
| Snapshot plus sampled local maxima |
| Explicit display control |
| Release the serial connection |
| Commands actually available on the attached firmware |
capture_spectrum and scan_spectrum support save=true, an optional simple .csv
filename, and include_points=false for compact results. File names stay within
the configured export directory. Tools return structured JSON plus MCP text content.
Read tinysa://guide before measurement; tinysa://export-directory shows the artifact
directory. Measurement tools declare state changes in MCP annotations.
Acquisition tool results also include ten sampled local maxima from that exact capture,
so an agent can discuss peaks without taking a second measurement.
Example agent request: “Identify the tinySA, read its settings, capture the current trace and save it, then report the five strongest sampled peaks with frequencies.”
Expert raw console access is opt-in: start the server with --allow-raw to expose
execute_console_command, or use tinysa command --allow-raw 'rbw 10'. Arbitrary
commands can alter calibration, persistent settings, and generator output. Binary
commands (capture, scanraw, sd_read) and reset are excluded from this text tool.
Measurement semantics and limits
A snapshot reads
frequenciesand actualdata 2while paused, then restores the earlier running state. It does not initiate a new scan. It requires firmware withstatus. A previously paused display remains paused. Pausing can interrupt an ongoing sweep; the displayed trace can contain samples from different sweep passes. Use a fresh scan when a complete acquisition matters. Frequent snapshot polling can keep interrupting the display; userecord --freshfor repeated completed acquisitions.A scan uses
scan START STOP POINTS 3. Frequencies and actual levels arrive in one response, including the legacy zero imaginary component on some firmware. The old point count is restored afterwards. Resume the display before a subsequent snapshot if the scan used a different point count. Display settings and frequency arrays are not a full transactional instrument-state snapshot. Within a connected driver session, snapshots after a different-point-count scan are refused until the sweep is resumed. Across independent CLI invocations, the driver cannot know earlier console operations; resume explicitly before capture.Data follows the selected display unit. This API requires dBm and rejects other units instead of mislabelling them.
configure --unit dbmchanges the display explicitly. Input/analyzer mode is selected by the user, not changed automatically.Existing trace processing (average, max hold, etc.) can affect data; raw
calcreadback accompanies every capture. A fresh scan does not reset this processing.Basic allows up to 290 scan points; Ultra family up to 450. Frequencies accept integer Hz up to a validation ceiling of 12 GHz; usable ranges depend on the actual model, input mode, firmware, and RF front end. This ceiling is not a claim that every instrument supports 12 GHz.
RBW requests are Hz; the console accepts kHz. Firmware chooses available filters; read actual bandwidth from
rbw_reply/rbw_after_reply. Some settings take effect at the next sweep. Query replies are retained verbatim for firmware differences.Peak finding uses local sampled maxima, plateaus, and frequency separation. It does not interpolate frequencies, compute integrated power, or identify the origin of spurs. A reported peak can be at a scan edge.
USB reliability and troubleshooting
The transport reads until a complete ch> prompt, even if split across packets or
without a newline. Compound operations share one lock. POSIX exclusive opens prevent
cooperating clients from sharing the port; close already-running GUIs yourself.
Replies have a 1 MiB bound and a finite deadline. Ordinary timeout is 5 seconds;
fresh scan timeout defaults to 120 seconds and accepts up to 3600. A timeout closes
the connection; the instrument may still be scanning and its state is then unknown.
Wait for completion and reconnect rather than immediately starting another scan.
Malformed values (including the older firmware's -:.000000e+01 formatter bug),
non-finite values, length mismatches, and incorrect endpoints are reported as errors.
Values are never guessed or silently repaired. If a device is silent, check physical
USB connection mode and cable, then power cycle. Narrow RBW and repeated/long sweeps
can require much more time than a simple settings query.
Development
uv sync --locked
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv buildUnit tests use a fragmented fake serial device. The stdio MCP test launches a real server process against a pseudo-terminal instrument, exercising initialization, tool schemas, structured measurements, error delivery, resources, and shutdown. No hardware is required for tests.
uv run python examples/client.py demonstrates a real MCP client capturing and
exporting the current trace. uv run python examples/measure.py demonstrates the
direct Python API. uv run python tools/verify_hardware.py performs opt-in hardware
verification with one fresh scan and restores the earlier running/paused state.
The implementation was written independently after reviewing the
experimental tinySA_mcp project, the
official USB interface,
Ultra console examples,
and firmware source. It avoids a mandatory
Tkinter GUI and arbitrary short sleeps for reply framing. Those firmware commands
vary by release; console-help and settings readback describe the attached instrument.
Available Tools
11 toolscapture_spectrumB
Snapshot current actual dBm trace; briefly pause and restore previous running state.
Does not guarantee a fresh scan. save writes CSV and metadata to the export directory.
| Name | Required | Description | Default |
|---|---|---|---|
| save | No | ||
| filename | No | ||
| include_points | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond the annotations by disclosing real side effects: it 'briefly pause[s] and restore[s] previous running state' and, when save is set, writes CSV and metadata to the export directory. This is consistent with readOnlyHint=false and destructiveHint=false and gives the agent useful operational context the annotations do not.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core action front-loaded and no filler. The indentation/line-break artifact adds minor noise but nothing substantive is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be described, and annotations cover the safety profile. However, the description leaves the filename and include_points parameters unexplained and never explicitly routes to scan_spectrum, so it is adequate but with clear gaps for a 3-parameter instrument tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for all three parameters, so the description must carry the burden. It explains save's file-output behavior but says nothing about filename (format, location, default naming) or include_points, leaving two of three parameters undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Snapshot current actual dBm trace,' which is concrete and distinct from a scan. The line 'Does not guarantee a fresh scan' implicitly separates it from scan_spectrum, but it never names the sibling, so differentiation is inferential rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Does not guarantee a fresh scan' tells the agent what this tool is not, hinting that scan_spectrum is the choice when freshness matters, but it never states that alternative or the condition that selects it. Usage is implied rather than prescribed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
configure_measurementA
Explicitly set bandwidth in Hz, attenuation in dB, or dBm display units; read back settings.
Firmware rounds bandwidth to available filters. None leaves a setting unchanged. Auto and explicit value are mutually exclusive. Changes are not rolled back on error.
| Name | Required | Description | Default |
|---|---|---|---|
| rbw_hz | No | Requested resolution bandwidth in Hz | |
| rbw_auto | No | ||
| unit_dbm | No | ||
| attenuation_db | No | ||
| attenuation_auto | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and destructiveHint=false, so the mutation/safety profile is covered. The description adds valuable behavior beyond that: firmware rounds bandwidth to available filters, and changes are not rolled back on error, which warns the agent about partial-failure state. It does not state required permissions or idempotency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads what is set, then layers three short constraint sentences with zero filler. Every sentence carries operative information (rounding, null semantics, mutual exclusion, error behavior).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no prose. For a 5-parameter, zero-required setter, the description covers the failure mode, rounding side effect, and the auto/explicit interaction an agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 20% (only rbw_hz is documented), so the description must compensate and largely does: it explains the null/'None' semantics and the mutual exclusivity between auto and explicit values, which is the key trap for rbw_auto vs rbw_hz and attenuation_auto vs attenuation_db. The unit_dbm boolean and attenuation_auto flag are still explained only by their names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (explicitly set) and the exact resources it acts on (bandwidth in Hz, attenuation in dB, dBm display units), plus a read-back capability. It is clearly distinguishable from read-only siblings like get_status or scan_spectrum, though it never names an alternative directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides real usage rules for the parameters ('None leaves a setting unchanged', 'Auto and explicit value are mutually exclusive'), which governs correct invocation. However it offers no guidance on when to pick this tool over siblings such as get_device_info or capture_spectrum, so tool-selection guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnect_deviceA
Release USB; the next device tool reconnects. Does not change the current sweep state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare it is not read-only and not destructive, which is somewhat surprising for a 'disconnect' action; the description resolves this by explaining the disconnect is recoverable (next device tool reconnects) and explicitly scopes the side effect ('does not change the current sweep state'). This is meaningful behavioral context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short clauses with zero filler, and the core action ('Release USB') is front-loaded before the recovery caveat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and with no parameters the definition is nearly complete. The only gap is a lack of explicit when-to-use routing relative to the many sibling device tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the schema carries no semantics to supplement; the baseline for a 0-parameter tool applies. Nothing in the description is needed or missing here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Release USB') and clarifies the mechanism by which the device comes back ('the next device tool reconnects'). This distinguishes it from siblings like list_devices or get_device_info, though it never explicitly says what the device is, relying on context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The mention that the next device tool reconnects implies the disconnect is temporary and safe to call, which gives an agent usable context. However, it never states when to prefer disconnecting versus simply not using the device, nor names any alternative sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_spectrum_peaksB
Snapshot current trace and find strongest sampled local maxima; temporarily pauses readout.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| min_level_dbm | No | ||
| min_separation_hz | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations give readOnlyHint=false but do not explain why. The description closes that gap by disclosing 'temporarily pauses readout', which tells the agent this has a transient side effect on the instrument and is not a pure read. It stops short of saying when readout resumes or whether the pause is bounded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the action front-loaded and the side effect appended, with no filler. It is appropriately sized, though the appended clause could be expanded slightly without harming flow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and the pausing behavior is disclosed. However, with zero parameter documentation and no usage guidance against a crowded sibling set, the definition is only minimally sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and the description names no parameter (limit, min_level_dbm, min_separation_hz). 'Strongest' and 'sampled' only loosely gesture at level filtering and the limit, leaving all three parameters' meaning to be guessed from their names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (find) and resource (spectrum peaks), plus the scope of 'snapshot current trace' and 'strongest sampled local maxima'. This distinguishes it reasonably from capture_spectrum/scan_spectrum, though it never explicitly names those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no routing to alternatives like capture_spectrum or scan_spectrum. The agent must infer from context alone when peaks should be found versus a raw capture taken.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_console_helpARead-only
Read the connected firmware's actual supported console commands.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The word 'actual' adds a genuine nuance, signaling this queries live firmware rather than a static command list, but no auth, timing, or failure behavior is described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the key qualifier ('actual supported') front-loaded and no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and with no parameters the schema burden is minimal. The description is sufficient for this simple read tool, though a hint about what the returned command list is useful for would round it out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (read) and resource (the connected firmware's supported console commands), which is clearly distinct from siblings like get_status, get_device_info, or list_devices. It does not explicitly name a sibling it is not, so it falls short of the 5 bar for sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: call this to discover which console commands the attached firmware actually supports. There is no explicit when-to-use/when-not-to-use guidance and no alternatives are named, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_device_infoBRead-only
Connect lazily, verify tinySA identity, and report firmware and maximum scan points.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds one genuine behavioral trait not in the annotations – it connects 'lazily' and performs an identity check – but says nothing about failure modes if the identity check fails or what happens if no device is attached.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence with no filler, and the connection step is front-loaded before the reported fields. It is appropriately sized for a no-argument tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not enumerate return values; it still names the key reported fields (firmware, maximum scan points). Combined with annotations covering safety, the definition is complete enough for the agent to call it correctly, with only failure behavior left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to clarify beyond what the schema already conveys. Baseline 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete verb chain and resource: connect to the device, verify its identity, and report firmware and max scan points. That is far more specific than the name alone, but it does not explicitly distinguish itself from siblings like get_status or list_devices, which an agent must disambiguate on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance and no mention of alternatives. Given siblings such as get_status and list_devices, the agent gets no signal about which one to pick for device inspection; usage is only implied by the phrase 'verify tinySA identity'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statusARead-only
Read sweep state, bandwidth, attenuation, display units, and processing settings.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety and locality profile is fully covered. The description adds which measurement/processing domains are reported, which is modest added value beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that names the verb first and then lists the returned domains. No filler, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and an output schema present, return values need not be spelled out. The description covers what the call reports and is safe to invoke from the annotations, so it is complete for the agent's decision.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate and the baseline is 4. The description correctly implies a parameterless read that scopes itself to the connected device.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Read) and resource (status) and enumerates the exact state it returns: sweep state, bandwidth, attenuation, display units, processing settings. It does not explicitly differentiate itself from the sibling get_device_info, which is the closest overlap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no exclusions, and no mention of alternatives such as get_device_info or list_devices. The agent must infer the boundary between generic device info and this sweep/measurement status from the field list alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesARead-only
List serial ports and USB candidates. Does not connect; STM32 IDs can also be NanoVNAs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavioral context beyond that: it does not establish a connection, and device IDs are ambiguous because STM32 identifiers can also be NanoVNAs, which affects how results should be interpreted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler; the core action is front-loaded and the caveat follows immediately. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description covers the non-obvious parts: no connection is opened and device IDs are not reliably typed. The only minor gap is not stating that this is the entry point preceding device-specific calls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so per the baseline there is nothing for the description to compensate for. The description adds no argument detail because none is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: enumerating serial ports and USB candidates, which cleanly separates it from siblings like get_device_info or get_status. It stops short of naming those siblings explicitly, so an agent must infer the boundary rather than being told.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Does not connect' implies this is a safe discovery step to run before connect/get_device_info, which is useful implied guidance. However, there is no explicit statement of when to choose this tool over get_device_info or get_status, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pause_sweepA
Pause the displayed sweep explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-destructive, closed-world operation, so the safety profile is covered. The description adds the scope qualifier 'displayed sweep', but says nothing about whether the pause is reversible (only implied by the sibling resume_sweep) or what state the sweep is left in.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the action front-loaded and no wasted words. Sized appropriately for a zero-argument operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters, an output schema present, and annotations covering the safety profile, the description only needs to convey the action, which it does. The missing piece is any hint about the pause/resume pairing that an agent would need to sequence calls correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. There is nothing for the description to disambiguate about inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (pause) and resource (the displayed sweep), so an agent can tell what it does without opening the schema. It does not explicitly differentiate itself from the sibling resume_sweep, though the verb makes the distinction obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to pause versus when to let the sweep continue, nor any mention of the counterpart resume_sweep or preconditions such as a sweep needing to be running. Usage must be inferred entirely from the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_sweepA
Resume the instrument's configured display sweep (including frequency array restoration).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a state-changing but non-destructive, non-open-world operation, so the safety profile is covered. The description adds one genuinely useful behavioral detail beyond the annotations — that resuming also restores the frequency array — but omits whether the call fails when no sweep is paused and how it interacts with an in-progress capture or measurement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with the verb and resource first and the parenthetical detail last. Nothing is wasted and nothing essential is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be described, and the annotations cover the safety profile, so the description is nearly sufficient for a zero-argument tool. The one gap is the precondition (a paused sweep) that determines whether the call will succeed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics to explain; the empty schema is fully self-consistent with the description. Baseline 4 applies since the description cannot add parameter meaning where none exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Resume') and a specific resource ('the instrument's configured display sweep'), which is enough to distinguish it from the sibling pause_sweep by polarity alone. It stops short of explicitly naming pause_sweep as its counterpart, so it earns a 4 rather than a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the inverse of pause_sweep, but the description never says it should be called only when a sweep is paused, nor what happens if the sweep was never paused or the device is disconnected. No alternatives or preconditions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_spectrumA
Acquire a new dBm spectrum with paired frequencies/levels; default leaves device paused.
Endpoints are integer Hz. Basic <=290 points, Ultra <=450. resume_after restarts the
configured display sweep. No automatic change to input mode, RBW, or processing.
| Name | Required | Description | Default |
|---|---|---|---|
| save | No | ||
| points | No | Number of sampled points; Basic maximum 290 | |
| stop_hz | Yes | Stop frequency in integer Hz | |
| filename | No | ||
| start_hz | Yes | Start frequency in integer Hz | |
| resume_after | No | ||
| include_points | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only, non-destructive, closed-world operation, and the description adds real value beyond that: the device is left paused by default, resume_after restarts the display sweep, and input mode/RBW/processing are deliberately untouched. It does not state permissions or what happens on failure, but the side-effect profile is well disclosed for a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, each carrying distinct operational information, with the core acquisition behavior front-loaded. No filler or repetition of the schema, though the sentence fragments are slightly clipped.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the sweep/pause behavior is covered. The gaps are the undocumented save/filename/include_points parameters and the absence of any routing guidance against the closely named sibling capture_spectrum.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is only 43%, so the description must compensate; it usefully clarifies the points cap (Basic <=290, Ultra <=450) and the resume_after semantics, and confirms endpoints are integer Hz. It says nothing about save, filename, or include_points, leaving three of seven parameters with no explanation anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: acquiring a new dBm spectrum with paired frequencies/levels. It is clear what the tool returns, though it never distinguishes itself from the sibling capture_spectrum, which an agent could easily confuse it with.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage through behavior notes ('default leaves device paused', 'resume_after restarts the configured display sweep'), which tells the agent when to pass resume_after. However, there is no explicit statement of when to prefer this over capture_spectrum or configure_measurement, and no prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.1.0- First observed
capture_spectrum - First observed
configure_measurement - First observed
disconnect_device - First observed
find_spectrum_peaks - First observed
get_console_help - First observed
get_device_info - First observed
get_status - First observed
list_devices - First observed
pause_sweep - First observed
resume_sweep - First observed
scan_spectrum
TDQS
Scored across 11 tools
The sweep-control pair (pause_sweep/resume_sweep) and lifecycle tools (list_devices/get_device_info/disconnect_device) are clearly distinct. However, capture_spectrum, scan_spectrum, and find_spectrum_peaks all deal with trace acquisition and could be confused, though the descriptions do clarify snapshot vs. fresh scan vs. peak analysis.
All tools use consistent snake_case verb_noun or verb patterns (list_devices, get_status, configure_measurement, scan_spectrum). No mixed conventions or vague single-word verbs.
11 tools is well-scoped for a device-control server, covering connection, status, configuration, acquisition, and sweep control without redundancy.
The surface covers the full device lifecycle: list, connect/info, disconnect, status, configuration, acquisition, pause/resume, and console help. Minor gaps exist (configuration is limited to bandwidth/attenuation/units with no broader settings, and saving is folded into capture_spectrum rather than a dedicated export tool).
Maintenance
Related MCP Connectors
CVE lookups (NVD) and dependency-manifest audits (OSV) for AI agents. No API keys.
CVE lookups (NVD) and dependency-manifest audits (OSV) for AI agents. No API keys.
AI agent infrastructure for discovery, authorization, execution, identity, and signed receipts.
Machine-readable utilities and datasets for AI agents.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables AI agents to control Copper Mountain Vector Network Analyzers over TCP/IP SCPI, offering 45 tools for sweep configuration, calibration, measurement, and Touchstone export.492AGPL 3.0
- AlicenseCqualityBmaintenanceEnables natural language control of test instruments like spectrum analyzers and power supplies via SCPI commands, with auto-discovery and multi-instrument session support.1001MIT
- AlicenseNot gradedqualityBmaintenanceEnables LLMs to control a PicoScope 5000A USB oscilloscope for signal generation, block capture, measurements, and frequency response sweeps.1MIT
- AlicenseBqualityBmaintenanceEnables AI agents to process RF signals, perform spectral analysis, and execute radar DSP primitives such as Range-Doppler processing and CFAR detection, supporting both file-based and live SDR capture.14MIT