Skip to content

Getting Started

This tutorial walks you through installing mcpyvisa, configuring a backend, and discovering the instruments it can reach. By the end, you will have a working MCP server that an LLM can use to talk to your test equipment.

Before starting, make sure you have:

  • A supported instrument connection — any of the following:
    • An AR488 adapter (ESP32 with AR488 firmware) connected via USB or WiFi to GPIB instruments
    • A USB-TMC instrument connected directly to your computer
    • A LAN/VXI-11 instrument on your network
    • NI-VISA or Keysight IO Libraries installed for system VISA resources
  • Python 3.11+ with uv installed
  • Claude Code (or another MCP-compatible client)
  1. Quickest: run directly from PyPI

    If you just want to use mcpyvisa without cloning the source, uvx will fetch and run it in an isolated environment:

    Terminal window
    uvx mcpyvisa

    This downloads mcpyvisa, installs its dependencies, and starts the MCP server. Press Ctrl+C to stop it. You will configure it properly in the next step.

  2. Alternative: install from source

    If you want to modify mcpyvisa or run from a local checkout:

    Terminal window
    git clone https://git.supported.systems/warehack.ing/mcgpib.git
    cd mcgpib
    uv sync
    uv run mcpyvisa

mcpyvisa reads its configuration from a TOML file. It searches these locations in order:

  1. The path in the $MCPYVISA_CONFIG environment variable
  2. ./mcpyvisa.toml in the current directory
  3. ~/.config/mcpyvisa/config.toml in your home directory

Create a configuration file for your setup. The examples below show the most common backend types.

Create ~/.config/mcpyvisa/config.toml:

~/.config/mcpyvisa/config.toml
[server]
log_level = "INFO"
auto_discover = true
auto_identify = true
[[backend]]
name = "bench-a"
type = "ar488"
transport = "serial"
port = "/dev/ttyUSB0"
baudrate = 115200
auto_discover = true
auto_identify = true
read_timeout_ms = 3000
inter_command_delay_ms = 10
[instruments.dmm]
resource = "GPIB0::22::INSTR"
backend = "bench-a"
[instruments.psu]
resource = "GPIB0::5::INSTR"
backend = "bench-a"

Each field:

FieldPurpose
nameA unique identifier you choose for this backend. Used in connect_backend and disconnect_backend.
type"ar488" for AR488/Prologix GPIB adapters.
transport"serial" for USB connections.
portThe serial port path. On Linux this is typically /dev/ttyUSB0 or /dev/ttyACM0. On macOS, look for /dev/cu.usbserial-*.
baudrateMust match the AR488 firmware setting. The default is 115200.
auto_discoverWhen true, mcpyvisa discovers instruments on the bus immediately after connecting.
auto_identifyWhen true, sends *IDN? to each discovered listener during discovery.
read_timeout_msHow long to wait for an instrument response before timing out (milliseconds).
inter_command_delay_msPause between consecutive commands. Prevents ESP32 voltage dips under rapid bus activity.

The [instruments.*] sections define aliases. Instead of typing GPIB0::22::INSTR in every tool call, you can just say "dmm".

Register mcpyvisa as an MCP server so Claude Code can discover and call its tools.

Terminal window
claude mcp add mcpyvisa -- uvx mcpyvisa

If your config file is not in one of the default search paths, point mcpyvisa to it with the environment variable:

Terminal window
MCPYVISA_CONFIG=/path/to/mcpyvisa.toml claude mcp add mcpyvisa -- uvx mcpyvisa

With mcpyvisa registered, start a Claude Code session and walk through the connection. Here is what a typical first conversation looks like.

  1. Connect to the backend

    Ask Claude to connect, or call the tool directly:

    > Connect to my backend "bench-a"

    Claude calls connect_backend("bench-a"). The server initializes the pyvisa ResourceManager for that backend, opens the transport, and reads the adapter firmware version (for AR488 backends). If auto_discover is enabled, it also discovers instruments reachable through the backend.

    You should see a response like:

    Connected to bench-a (ar488, serial)
    Firmware: AR488 GPIB controller 0.05.99
    Discovered 3 instrument(s):
    GPIB0::1::INSTR — HEWLETT-PACKARD 34401A
    GPIB0::5::INSTR — KEITHLEY INSTRUMENTS INC. 2000 (alias: dmm)
    GPIB0::22::INSTR — Agilent Technologies E3631A (alias: psu)

    Instruments that match a configured alias show their alias name in parentheses.

  2. Discover instruments manually (optional)

    If auto_discover was disabled in your config, or if you have added instruments since connecting, discover explicitly:

    > Discover instruments on bench-a

    Claude calls discover_instruments("bench-a"). For AR488 backends, this sends ++findlstn to poll every GPIB address from 1 to 30, then sends *IDN? to each listener. For other backends, it queries the ResourceManager for available resources.

    Discovered 3 instrument(s) on bench-a:
    GPIB0::1::INSTR — HEWLETT-PACKARD 34401A (S/N: 3146A02377)
    GPIB0::5::INSTR — KEITHLEY INSTRUMENTS INC. 2000 (S/N: 1234567)
    GPIB0::22::INSTR — Agilent Technologies E3631A (S/N: MY12345678)
  3. Identify a specific instrument

    To get detailed identification for a single instrument, use its alias or VISA resource string:

    > Identify the instrument "dmm"

    Claude calls instrument_identify("dmm"):

    dmm (GPIB0::5::INSTR on bench-a):
    Manufacturer: KEITHLEY INSTRUMENTS INC.
    Model: 2000
    Serial: 1234567
    Firmware: A04 /A02
    Raw: KEITHLEY INSTRUMENTS INC.,2000,1234567,A04 /A02

    You can also use the full VISA resource string: instrument_identify("GPIB0::5::INSTR").

Your backend is connected and your instruments are discovered. You are ready to start taking measurements.