Skip to main content
Glama

claudiscope šŸ”¬

Give Claude a pair of probes.

claudiscope is a small MCP server that lets Claude (or you!) talk to your oscilloscope over SCPI. Ask it to measure a signal, change the timebase, or take a screenshot, and it does the fiddling so you don't have to hunt through menus with a greasy thumb.

Built and tested on a Rohde & Schwarz RTB2004. It's a plain SCPI passthrough, so other SCPI scopes should work, but nobody has tried, and I'm not going to pretend otherwise.

āš ļø Heads up: Claude (and you via this software) can change your scope's settings. Don't hand it the keys while the scope is hooked up to something you'd cry about. Read the safety section first.


What you get

  • Tool mode: claudiscope serve runs an MCP server, and Claude drives the scope from a normal chat.

  • Text mode: claudiscope shell is a plain SCPI prompt for when you'd rather type the commands yourself.

  • Auto-detect: it remembers the last address that worked and tries it first, then whatever VISA can see.

  • Guardrails: file, firmware and power commands are blocked, and disruptive ones like *RST need your OK.


Related MCP server: Rigol DHO824 MCP Server

Before you install anything

You need three things:

  1. Python 3.10+

  2. A VISA library so Python can talk to the hardware:

    • Windows: install R&S VISA or NI-VISA. Either works. R&S VISA is the one this was tested with.

    • Linux: no installer needed. pyvisa-py (below) does the job.

  3. A way to reach the scope, either Ethernet or USB (see Connecting the scope).

Claude Desktop (Windows/Mac) or Claude Code (anywhere) is needed to actually chat with it.


Installing

Windows

Clone or download this repo, open a terminal in the folder that contains pyproject.toml, and run:

python -m pip install -e .
python -m claudiscope doctor

doctor checks that everything is wired up. If it prints your VISA backend and no red flags, carry on.

Prefer pipx?

pipx install git+https://github.com/w1nston269/claudiscope

Microsoft Store Python users: the claudiscope command often isn't on your PATH. Use python -m claudiscope <command> everywhere instead. It does exactly the same thing.

Linux

Modern Debian/Ubuntu won't let you pip install into the system Python (the externally-managed-environment error), so use a virtual environment:

sudo apt install python3-venv     # only if the next line complains
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
pip install pyvisa-py psutil zeroconf
claudiscope doctor

You'll need to run source .venv/bin/activate in each new terminal before claudiscope works.

Version gotcha

mcp is pinned below 2.0, because 2.x renamed FastMCP and broke the imports. If you ever see No module named 'mcp.server.fastmcp', run:

python -m pip install "mcp<2"

Updating

claudiscope update            # or: python -m claudiscope update
claudiscope update --check    # just see what's new
  • Installed from a git checkout (pip install -e .): it does a git pull --ff-only and refreshes the install. If you've got local edits that clash with GitHub, it stops and tells you instead of doing anything rude.

  • Installed with pipx or pip from GitHub: it reinstalls from the repo. (pipx upgrade claudiscope also works.)

Restart Claude afterwards. Fully quit and reopen Claude Desktop, or start a new Claude Code session. A running server keeps the old code until you do, which is a fun way to spend ten minutes debugging a bug you already fixed.


Connecting the scope

Option A: Ethernet (the tested one)

This is the easy route because it skips USB driver drama entirely.

  1. Plug the scope into your router or straight into your laptop.

  2. Find its IP in the scope's network/LAN settings (menu names vary by firmware).

  3. Check the laptop can reach it:

    ping <scope-ip>
  4. Try the shell:

    claudiscope shell -r TCPIP0::<scope-ip>::INSTR

    You should see an *IDN? reply starting with Rohde&Schwarz,RTB2004,....

Direct cable, no router? DHCP has nothing to hand out addresses, so either set static IPs on both ends in the same subnet (say scope 192.168.0.10, laptop 192.168.0.11, mask 255.255.255.0), or on Windows use Internet Connection Sharing, which puts everything on 192.168.137.x.

Timeouts? Try the raw socket form of the address instead (check your scope's manual for the port, 5025 is common):

TCPIP0::<scope-ip>::5025::SOCKET

LAN scopes often don't show up in scans. That's normal. Give it the address once and it remembers.

Option B: USB

Use the scope's rear USB device port (usually Type B), not the front ports. Those are for memory sticks and will ignore you.

  • Windows: with R&S VISA or NI-VISA installed, the drivers come along for the ride. The scope should show up under "USB Test and Measurement Devices" in Device Manager. Then run claudiscope scan.

  • Linux: you'll need pyusb, libusb, and probably a udev rule so your user is allowed to open the device. This route is fiddlier and less tested, so Ethernet is the easier choice.

  • Make sure the scope's USB device mode is set to test-and-measurement (USBTMC), not a virtual COM port. The menu wording varies.

A USB resource string looks like USB0::0x0AAD::0x01D6::<serial>::INSTR. Trust what claudiscope scan prints rather than my example.


The commands

Command

What it does

claudiscope doctor

Checks Python, the mcp and pyvisa versions, your VISA backend, visible instruments, and the saved address. Run this first when something's broken.

claudiscope scan

Tries the saved address, then anything VISA can see, and prints the first scope that answers *IDN?.

claudiscope shell

Interactive SCPI prompt. Add -r <resource> to pick an address, otherwise it auto-detects. Lines ending in ? are queries, and everything else is a write followed by an error-queue check. quit exits.

claudiscope update

Updates to the latest version from GitHub. Add --check to just list what's new without installing. Restart Claude afterwards.

claudiscope serve

Starts the MCP server. You don't normally run this yourself, since Claude launches it. Run it by hand only to check it starts (it sits there quietly, and that's correct).

Everything above also works as python -m claudiscope <command>, and claudiscope --version tells you what you're running.


Hooking it up to Claude

Claude Desktop (Windows / Mac)

Open Settings → Developer → Edit Config and add:

{
  "mcpServers": {
    "claudiscope": {
      "command": "C:\\full\\path\\to\\python.exe",
      "args": ["-m", "claudiscope", "serve"]
    }
  }
}

Get the real path from the terminal where doctor works:

python -c "import sys; print(sys.executable)"

Use the full path with doubled backslashes. Desktop launches servers with its own environment, and a bare python may find a different Python than the one you installed into. Then fully quit Claude Desktop from the system tray and reopen it.

Check Settings → Developer: claudiscope should say running. Start a new chat and look for the tools in the message box (the icon is under "Search and tools" or behind the "+", depending on your version). If in doubt, type "Connect to the scope."

Claude Code

claude mcp add claudiscope -- python -m claudiscope serve
claude mcp list

On Linux, point at the virtualenv's Python so the server can see its packages:

claude mcp add claudiscope -- /path/to/claudiscope/.venv/bin/python -m claudiscope serve

What Claude can do with it

Tool

Purpose

connect

Connects (auto-detect, or pass an address) and returns the scope's *IDN?.

status

Am I connected, and to what?

scan

Lists candidate addresses.

scpi_query

Sends a SCPI query (must end in ?).

scpi_write

Sends a SCPI command, then reports the scope's error queue so Claude can correct itself.

get_screenshot

Grabs the display as an image. Claude sees it, and every capture is also saved to ~/claudiscope-screenshots/ with a timestamp (optional name goes in the filename). Chat windows usually don't show tool images inline, so with open_viewer=True it also pops the file up in your default image viewer. Ask for "take a screenshot and open it".

Try: "Connect to the scope, measure Vpp and frequency on channel 1, then take a screenshot."

Claude knows a fair amount of SCPI from memory but can get vendor-specific syntax slightly wrong. The error queue usually lets it fix itself, and attaching your scope's programming manual to the chat helps a lot.


Safety (because we both know how this goes)

Two tiers, applied to everything Claude sends:

  • Blocked: anything under MMEM (file operations), firmware commands, reboot and shutdown. Claude will tell you to run these yourself in the shell.

  • Needs your OK: *RST, *RCL, *SAV, and presets. They wipe your carefully dialed-in settings, so Claude has to ask first.

The list is a starting point, not gospel. Tighten it against your scope's manual in src/claudiscope/safety.py. And Claude Desktop asks before running tools by default, so think twice before clicking "always allow".


Troubleshooting

Symptom

Likely cause

Could not locate a VISA implementation

No VISA library. Install R&S VISA / NI-VISA (Windows) or pyvisa-py (Linux).

list_resources() comes back empty

Normal for LAN scopes. Give it the address. For USB, check the cable, Device Manager and USBTMC mode.

No module named claudiscope in the Desktop log

Desktop launched a different Python. Use the full path in the config.

No module named 'mcp.server.fastmcp'

You have mcp 2.x. python -m pip install "mcp<2".

Server "disconnected" in Desktop

Read %APPDATA%\Claude\logs\mcp-server-claudiscope.log. The last traceback names the culprit.

Timeouts

ping the scope. Check nothing else has a session open to it and the link hasn't dropped.


Project layout

src/claudiscope/
ā”œā”€ā”€ cli.py          # serve / shell / scan / doctor
ā”œā”€ā”€ connection.py   # VISA session, error queue, truncation of huge replies
ā”œā”€ā”€ safety.py       # blocked / confirm tiers
ā”œā”€ā”€ discovery.py    # saved address + VISA scan (config lives in ~/.claudiscope.json)
ā”œā”€ā”€ server.py       # builds the MCP server
ā”œā”€ā”€ shell.py        # the text-mode prompt
ā”œā”€ā”€ update.py       # `claudiscope update`
└── tools/          # one file per group of MCP tools

Each file in tools/ exposes a register(mcp, conn) function, so adding a tool means adding a file.


Status and honesty corner

  • Tested: RTB2004 over Ethernet with R&S VISA on Windows, including screenshots.

  • Untested: USB, other scopes, and most of the Linux path.

  • Not yet: waveform capture (raw data would swamp Claude's context, so it needs a summarizing tool first).

PRs and bug reports welcome, especially "it works on my Rigol" and "it exploded on my Tektronix."

Not affiliated with Rohde & Schwarz or Anthropic. Provided as-is. If it factory-resets your scope at a bad moment, that's on both of us.

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables LLMs like Claude to interact with PicoScope oscilloscopes for signal acquisition, measurement, and analysis. Supports device management, data capture, triggering, and signal generation through natural language commands.
    24
    6
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables control and querying of Rigol DHO824 oscilloscopes, allowing users to capture waveforms, take screenshots, and interact with oscilloscope settings through natural language.
    50 PyPI
    3
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables remote control of LeCroy oscilloscopes via SCPI commands over LAN to perform waveform capture, screenshots, measurements, channel configuration, and triggering through natural language. Supports multiple LeCroy models including WaveSurfer, HDO, WaveRunner, and WavePro series with automatic model detection.
    48
    11
    AGPL 3.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to directly control NI oscilloscopes (e.g., PXIe-5160/5164/5110) through the Model Context Protocol, including waveform acquisition, measurement, and configuration.
    MIT