pyvisa-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PYVISA_LIBRARY | No | VISA backend. `@py` = pyvisa-py. Path to `visa.so` / `visa32.dll` for NI/Keysight. `sim.yaml@sim` for pyvisa-sim. | |
| PYVISA_MCP_ALLOW | No | Comma-separated globs of allowed resources, e.g. `TCPIP::*`. | |
| PYVISA_MCP_MEMORY | No | Path to `instruments.json`. Default `~/.local/share/pyvisa-mcp/instruments.json`. `off` disables saving. | ~/.local/share/pyvisa-mcp/instruments.json |
| PYVISA_MCP_BACKEND | No | VISA backend. `@py` = pyvisa-py. Path to `visa.so` / `visa32.dll` for NI/Keysight. `sim.yaml@sim` for pyvisa-sim. | |
| PYVISA_MCP_READONLY | No | `1` to allow queries only. | |
| PYVISA_MCP_TIMEOUT_MS | No | Default I/O timeout (ms). Default `10000`. | 10000 |
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
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_instrumentsA | Discover local VISA resources (USB, GPIB, serial, some LAN). Network oscilloscopes frequently do NOT appear. Open them by IP with open_instrument, or call discover_network_instruments. |
| discover_network_instrumentsA | Browse mDNS for LXI, VXI-11, HiSLIP, and SCPI-raw services. Many scopes do not advertise. Empty result is normal — open by IP instead. |
| open_instrumentA | Open an instrument and optionally query *IDN?. Bare IPs become TCPIP::::INSTR. host:port becomes a raw TCP SOCKET, which is what many LAN scopes want on port 5025 (Rigol DS1000Z: 5555). |
| close_instrumentA | Close one open instrument, or all of them if resource is omitted. |
| identifyB | Query *IDN? and pick a vendor dialect (keysight, tektronix, rigol, ...). |
| learn_instrumentB | Build (or reload) a local brain for this exact *IDN?. Saved under ~/.local/share/pyvisa-mcp/ (or PYVISA_MCP_MEMORY). Next session, learn_instrument returns the same profile, remembered SCPI, and manual text without probing again. Pass deep=true / fetch_manual=true to refresh. |
| list_learned_instrumentsA | Profiles saved from previous learn_instrument calls (this machine). |
| fetch_manualC | Download this model's user/programming guide into the local brain and index it. |
| search_scope_knowledgeA | Search the saved manual, HELP headers, and SCPI that already worked on this box. Call learn_instrument / fetch_manual first. This is how the model reuses what it learned instead of guessing vendor commands. |
| forget_instrumentC | Delete a saved per-scope profile from disk. |
| writeA | Send a SCPI command with no reply (settings, *RST, :RUN, ...). |
| queryB | Send a SCPI query and return the ASCII response. |
| query_binaryA | Read an IEEE binary block. By default returns stats + a short preview. Pass save_path= to keep the full record, or return_values=true for a capped array. For oscilloscope traces prefer scope_capture_waveform / export_waveform. Do not use query() for binary — the terminator byte can appear inside the payload. |
| read_errorsA | Pop SYST:ERR? until the queue is empty. Call this after any failed command. |
| configure_sessionC | Change timeout and terminators on an already-open instrument. |
| suggest_scpiB | Map a natural-language intent to vendor-correct SCPI. Optionally execute it. Uses *IDN? dialect unless you pass dialect=. Prefer this over inventing commands. |
| scope_capture_waveformB | Read a scaled voltage-vs-time trace from one channel. Uses the vendor dialect from *IDN? (or dialect=). Returns downsampled points plus vmin/vmax/vmean/vpp so the payload fits in an MCP tool result. |
| export_waveformA | Fetch a channel trace and write the full record (no downsample) to disk. CSV columns: t_s, v. Use this for archives; scope_capture_waveform is for a short preview in the chat. |
| scope_measureC | Ask the scope's measurement engine for Vpp, frequency, etc. |
| scope_configureB | Set channel scale/offset/coupling, timebase, and/or edge trigger. Only provided fields are sent. Units: volts, seconds. |
| scope_acquireA | Control acquisition: run, stop, single shot, or vendor autoset. Autoset changes vertical/horizontal/trigger; pass confirm=true. |
| scope_screenshotB | Grab the scope display as PNG/BMP/JPEG. Disables the VISA termchar so 0x0A inside the image is not treated as EOF. Fails if the payload is not a real image (no silent 'png' of ASCII junk). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| identify_bench | Walk through discovering and identifying instruments on this machine / LAN. |
| capture_scope_waveform | Capture and describe a waveform from an oscilloscope channel. |
| debug_visa | Troubleshoot timeouts and SCPI errors. |
| measure_signal | Measure a live signal with the scope. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| resource_howto | How to drive instruments through this MCP server. |
| resource_names | VISA resource name syntax, including TCPIP shortcuts. |
| resource_scpi | IEEE 488.2 / SCPI commands every instrument understands. |
| resource_scope | Oscilloscope dialects and high-level tools. |
| resource_open | Currently open instrument sessions. |
| resource_backend | Active VISA backend, allowlist, and read-only flag. |
| resource_learned | Index of instrument brains saved on this machine. |
TDQS
Scored across 22 tools
Tools have largely distinct purposes, with clear boundaries between generic VISA operations and oscilloscope-specific ones. Minor potential overlap exists between identify and learn_instrument, and between query and suggest_scpi (when executing), but descriptions clarify usage.
All tool names use consistent snake_case, with a clear 'scope_' prefix for oscilloscope-specific tools. This predictable pattern aids discoverability and grouping.
22 tools is on the heavy side for the stated domain, slightly exceeding the typical 3-15 range. While many tools earn their place, some could potentially be consolidated (e.g., identify and learn_instrument), making the set borderline.
The surface covers the full lifecycle of instrument control: discovery, connection, identification, learning, SCPI communication, error handling, configuration, and scope-specific operations like waveform capture, measurement, acquisition, and screenshot. No major gaps are apparent for the domain.