Skip to main content

MCP server and skill for AI-controlled oscilloscopes.

Project description

scopebench-mcp

MCP server + skill for AI-controlled oscilloscopes.

scopebench-mcp is a focused framework that lets AI agents connect to an oscilloscope, configure it, acquire waveform data, save visual captures, and return structured evidence through MCP tools. The first target is the RIGOL DHO800 series, starting from the DHO804D we have already tested.

中文简介:scopebench-mcp 是一个让 AI agent 安全、稳定地使用示波器的 MCP server + Agent Skill 项目。它负责连接示波器、配置通道/时基/触发、采集波形和屏幕证据,并把结果以结构化 JSON 和文件路径返回给 AI。第一版聚焦 RIGOL DHO800 系列,已用 DHO804D 做过验证。

Language: English first, with Chinese notes for users and project context. See docs/project_brief_zh.md for the Chinese project brief.

语言说明:README 以英文为主,同时保留中文摘要和中文文档入口;完整中文项目总纲见 docs/project_brief_zh.md

Current Focus

  • Vendor: RIGOL
  • Initial family: DHO800 / DHO900 style SCPI scopes
  • Verified device: RIGOL DHO804D
  • First transports:
    • USB VISA / USBTMC
    • LAN TCP SCPI, verified on DHO804D for direct static Ethernet after USB-assisted LAN apply
  • Agent interface:
    • MCP server for real hardware access
    • Skill instructions for safe and effective AI usage

This project is intentionally scoped to oscilloscopes. Power supplies, meters, logic analyzers, and full circuit-debugging workflows are out of scope for the first version.

Why MCP + Skill

MCP is the execution layer. It owns hardware access, SCPI transport, settings, waveform acquisition, and file outputs.

The skill is the operating guide for the AI. It explains when to use screen waveform versus memory waveform, how to choose conservative defaults, how to avoid reading huge captures into chat, and how to summarize waveform evidence.

The intended flow is:

AI agent
  -> scopebench-mcp skill: how to use the tools well
  -> scopebench-mcp MCP server: actual tool calls
  -> oscilloscope over USB or LAN

Repository Layout

docs/            Public project notes, roadmap, hardware notes, and vendor reference links
src/scopebench_mcp/   Driver, transport, capture, and MCP server code
skill/scopebench-mcp/ Codex/AI skill draft
examples/        Example command flows and capture reports
captures/        Local waveform data, metadata, and screen/preview images, ignored by git
scripts/         Temporary dev/test helper scripts

Client And Platform Compatibility

The stdio MCP server can be configured in Codex, Cursor, Claude Code, Qoder, and CodeBuddy. The canonical SKILL.md content is also portable to clients that support Agent Skills, but each client uses its own discovery directory.

The currently verified USB transport is Windows-only because it uses visa64.dll. LAN TCP SCPI is the intended macOS/Linux path, but macOS hardware validation has not yet been completed. See docs/client_platform_compatibility.md for the client matrix and exact boundaries.

Quickstart

中文快速说明:

  • 安装包名是 scopebench-mcp,不要安装 PyPI 上无关的 scope-mcp
  • Python import 包名是 scopebench_mcp
  • CLI 命令是 scopebench-mcp
  • Skill 名称和 MCP server 名称也是 scopebench-mcp
  • 使用硬件前,用户仍然负责探头接地、电压范围、隔离和上电安全确认;AI 只负责仪器控制、数据读取和分析。

Install

The public Python distribution name is scopebench-mcp. The earlier working name scope-mcp is used by an unrelated project on PyPI, so do not run pip install scope-mcp for this project.

Install the wheel from the matching GitHub Release bundle into a dedicated virtual environment:

py -m venv .venv
.venv\Scripts\python -m pip install ".\scopebench_mcp-0.3.1-py3-none-any.whl[mcp]"

For optional LAN WebControl panel capture, install the WebControl extra and a browser:

.venv\Scripts\python -m pip install ".\scopebench_mcp-0.3.1-py3-none-any.whl[mcp,webcontrol]"
.venv\Scripts\playwright install chromium

The wheel contains the same canonical Agent Skill as the repository. Export it to the exact Skill directory recognized by your client; the destination must not already exist:

.venv\Scripts\scopebench-mcp-skill "C:\path\to\client-skills\scopebench-mcp"

Restart the client or open a fresh conversation after registering the MCP server and Skill. See docs/client_platform_compatibility.md for the supported client directories and INSTALL.md for the complete end-user flow.

A complete release bundle contains:

scopebench-mcp-v0.3.1/
  scopebench_mcp-0.3.1-py3-none-any.whl
  skill/scopebench-mcp/SKILL.md
  INSTALL.md
  SHA256SUMS

For source development, install the project in editable mode:

python -m pip install -e ".[mcp]"

Include the WebControl extra when browser-rendered panel capture is needed:

python -m pip install -e ".[mcp,webcontrol]"
playwright install chromium

Playwright-managed browser revisions are version-specific. Run the install command from the same Python environment that launches scopebench-mcp; a Chromium download made by another virtual environment may not match. Alternatively use an installed supported browser by passing browser_channel="msedge" or browser_channel="chrome".

Windows users may instead use an installed Microsoft Edge browser by passing browser_channel="msedge".

Run the no-hardware tests:

python -m unittest discover -s tests

Start The MCP Server

Run the MCP server:

scopebench-mcp

On Windows, editable installs usually place scopebench-mcp.exe in a Python Scripts directory. If your MCP client cannot find scopebench-mcp, add that Scripts directory to PATH or use the full path in the MCP client config.

Minimal MCP client config:

{
  "mcpServers": {
    "scopebench-mcp": {
      "command": "scopebench-mcp",
      "args": []
    }
  }
}

See examples/mcp_client_config.json for a Windows note and a full-path variant.

USB/VISA Smoke Test

For the verified DHO804D path, connect the PC to the rear USB DEVICE port and confirm your VISA runtime can see the instrument:

python src\scopebench_mcp\drivers\rigol_dho804d_visa.py list
python src\scopebench_mcp\drivers\rigol_dho804d_visa.py idn

Expected verified identity:

RIGOL TECHNOLOGIES,DHO804D,YOUR_SCOPE_SERIAL,00.01.05

The compatibility CLI keeps the same default behavior and also accepts an optional serial check:

python src\scopebench_mcp\drivers\rigol_dho804d_visa.py --serial YOUR_SCOPE_SERIAL idn

Common MCP Tool Flow

The initial MCP tools are:

  • scope_list
  • scope_webcontrol_status
  • scope_webcontrol_capture
  • scope_webcontrol_input
  • scope_identify
  • scope_status
  • scope_network_status
  • scope_configure_channel
  • scope_configure_timebase
  • scope_configure_trigger
  • scope_configure_pulse_trigger
  • scope_configure_acquisition
  • scope_measure
  • scope_measure_statistics
  • scope_measure_timing
  • scope_cursor_measure
  • scope_configure_lan_static
  • scope_autoscale
  • scope_control
  • scope_capture_single
  • scope_capture_pulse
  • scope_acquire_screen
  • scope_acquire_memory
  • scope_screenshot

For USB/VISA targets, scope_list returns parsed resource metadata when available, including vendor ID, product ID, and USB serial. The MCP tools accept an optional serial argument. When serial is provided, the resource string is used only as the address and *IDN? is used as the final identity check. If multiple matching USB scopes are connected and neither resource nor serial is provided, the MCP layer asks for an explicit target instead of silently selecting one.

For LAN targets, scope_webcontrol_status(host="<scope_ip>") performs a read-only, bounded HTTP GET / probe of the oscilloscope-provided WebControl page. It reports HTTP reachability separately from RIGOL/WebControl page detection. It does not open control WebSockets or send pointer/touch input.

scope_webcontrol_capture(host="<scope_ip>") opens the discovered control.html page in a headless browser, waits for a decoded H.264 keyframe, captures only the 1024 x 600 remote-panel canvas, and saves remote_panel.png plus metadata.json. It does not run autoset or change trigger/acquisition state; the image reflects the scope's current display.

scope_webcontrol_input(...) sends exactly one click, touch tap, or drag to panel pixel coordinates. It requires confirm_input=True and a non-empty expected_effect, rejects coordinates outside the detected canvas, and saves before_panel.png, after_panel.png, and metadata.json. Raw coordinates are model-, firmware-, and layout-dependent. Prefer SCPI for normal control and use SCPI readback after UI input whenever practical.

Typical workflow:

  1. scope_list
  2. scope_identify(serial="...")
  3. scope_network_status(serial="...", verify_lan=True) when Ethernet is connected but its address is unknown; switch to LAN only when the returned identity matches.
  4. scope_status(channel=1, serial="...")
  5. For a safe low-voltage bench signal covered by the current session authorization, scope_autoscale(confirm_physical_setup=True, serial="..."), then inspect its returned status. Otherwise configure deliberately with the next three tools.
  6. scope_configure_channel(channel=1, probe_ratio=10, scale_v_per_div=0.1, coupling="DC", offset_v=-0.2, serial="...")
  7. scope_configure_timebase(scale_s_per_div=0.001, offset_s=0.002, serial="...")
  8. scope_configure_trigger(source_channel=1, level_v=0.14, slope="positive", serial="...")
  9. scope_configure_pulse_trigger(condition="greater_than", source_channel=1, polarity="positive", width_s=3e-6, level_v=0.14, serial="...") when an abnormal pulse width is the event of interest. Use lower_width_s and upper_width_s only with condition="between".
  10. scope_measure(channels=[1, 2], measurements=["frequency", "vpp", "rms"], serial="...") for concise independent values from multiple channels; keep channel=1 for the original single-channel response.
  11. scope_measure_statistics(action="start", channel=1, measurement="vpp", sample_count=1000, serial="..."), followed later by action="read", for a bounded instrument-side min/max/average/stddev/count snapshot. Use reset and stop explicitly.
  12. scope_measure_timing(source_channel_a=1, source_channel_b=2, measurements=["rr_delay", "rr_phase"], serial="...") for instrument-side edge delay and phase.
  13. scope_cursor_measure(mode="manual", axis="time", source_channel=1, cursor_a=-0.0005, cursor_b=0.0005, settle_s=0.5, serial="...") for explicit cursor positions and structured deltas after the display calculation settles.
  14. scope_autoscale(confirm_physical_setup=True, serial="...") may also be used later to reset the display starting point when the current session authorization covers it.
  15. scope_control(action="run" | "stop" | "single", wait_s=0.5, serial="...") when acquisition state needs to be explicit.
  16. scope_capture_single(channel=1, points=1000, trigger_timeout_s=10, run_after_capture=True, serial="...") when one event from the currently configured trigger must be captured with bounded waiting and evidence. Pass channels=[1, 2] instead when multiple displayed channels must come from that same frozen event.
  17. scope_capture_pulse(condition="greater_than", source_channel=1, width_s=3e-6, level_v=0.14, points=1000, trigger_timeout_s=10, serial="...") to configure pulse-width trigger and arm the same bounded SINGLE state machine in one connection. Add explicit memory_points, memory_max_points, and chunk/duration/disk limits only when the same stopped event needs deeper RAW evidence. The pulse trigger remains configured afterward.
  18. scope_screenshot(serial="...", screenshot_method="display_png") for a quick visual check.
  19. scope_acquire_screen(channel=1, points=1000, serial="...", screenshot_method="display_png") for waveform evidence.
  20. scope_acquire_memory(channel=1, points=250000, chunk_points=100000, max_points=250000, stop_before_capture=True, serial="...") only when stopped memory detail is needed and stopping acquisition is acceptable.

The callable scope_measure schema enumerates its canonical measurement names: frequency, freq, period, vpp, vmax, max, vmin, min, mean, average, rms, duty, positive_duty, negative_duty, rise_time, and fall_time. Use these names rather than guessing longer aliases such as minimum or maximum.

For scope_acquire_screen and the screen-waveform portion of SINGLE capture, points is a requested upper bound. DHO800 NORMAL waveform reads support at most 1000 points, so the driver bounds the SCPI read window to 1000 without discarding the original request. Compare requested_points with the returned points or multi-channel alignment.points; saved CSV files always contain the actual device payload without padding.

scope_measure_statistics never waits for sample_count acquisitions inside one MCP call. start configures one measurement, enables statistics, and resets history globally; read immediately returns current, minimum, maximum, average, standard deviation, and accumulated count; reset also clears all active statistics; stop disables the statistics display. The state is global to the instrument, so coordinate with other front-panel or remote users.

Capture tools save large evidence to files and return paths plus concise JSON. When an offset is supplied, the channel and timebase configuration tools return structured requested and actual position readback. Treat the device readback as authoritative because valid ranges depend on scale and acquisition state. scope_capture_single leaves the instrument stopped after a successful event by default. Set run_after_capture=True only when acquisition should be restored; the tool polls and reports the resulting non-STOP readback. A trigger timeout sends :STOP, saves no waveform, and leaves the instrument stopped. When channels is supplied, it must contain at least two unique displayed analog channels. The tool arms only once, reads each channel while the scope remains stopped, and verifies common point count and horizontal sampling. The shared evidence directory contains metadata.json, an optional screen.png, and per-channel chN/waveform.csv plus chN/preview.png files. A normal screen waveform report contains:

  • metadata.json
  • waveform.csv
  • preview.png
  • screen.png when direct oscilloscope screenshot capture succeeds

scope_screenshot is screen-only and does not write waveform CSV data.

scope_acquire_memory queries the available record depth, reads RAW stopped memory through contiguous bounded chunks, and incrementally writes CSV plus a small min/max-envelope preview. It returns only summary metadata and paths. The operation has independent point, wall-clock, and disk-use limits. A failed later chunk leaves progress metadata and the completed CSV prefix on disk. It defaults to a 100k point soft limit and refuses larger captures unless the caller explicitly raises max_points, with a current hard cap of 1M points. USB/LAN multi-chunk parity is the gate before that public cap is raised.

LAN Status

LAN TCP SCPI is implemented as a manual host/port transport. On the verified DHO804D, direct static Ethernet works with raw TCP SCPI on port 5555 after LAN settings are written and :LAN:APPLy is sent. Port 5025 refused connections on the tested instrument.

The recommended DHO804D bring-up path is:

  1. Use USB/VISA as the known-good control channel.
  2. Call scope_network_status(serial="...", verify_lan=True) to read the existing IP, mask, gateway, mode, and MAC without changing settings.
  3. If its LAN verification is reachable and the serial matches, use the returned host with transport="lan" and port 5555.
  4. Only when a network change is actually required, call scope_configure_lan_static(..., confirm_network_change=True) with the intended static IP, mask, gateway, and optional DNS, then repeat the read-only status/identity check.
  5. For troubleshooting, validate the intended host interface with bound ping or ARP/neighbor evidence; do not treat an open port alone as instrument identity.

After LAN reachability is established, optionally call:

scope_webcontrol_status(host="<scope_ip>", web_port=80)
scope_webcontrol_capture(host="<scope_ip>", web_port=80)
scope_webcontrol_input(host="<scope_ip>", action="tap", x=772, y=105,
                       expected_effect="Close the visible menu",
                       confirm_input=True)

The status tool only discovers the instrument-provided HTTP interface. The capture tool receives the browser video canvas but sends no pointer/touch input. The input tool is a separately gated operation that records visual evidence but does not treat image differences as proof of semantic success.

On Windows, unbound socket-connect results can be misleading when VPN, proxy, or tunnel adapters are active. Bind probes to the Ethernet source address or check ARP/MAC reachability before treating a LAN result as real.

Existing Assets Imported

  • src/scopebench_mcp/drivers/rigol_dho804d_visa.py Existing Windows VISA helper that can list instruments, query *IDN?, read status, apply a basic CH1 setup, and capture screen waveform data.

  • docs/rigol_dho804d_scope_notes.md Field notes from the initial DHO804D validation, including USB/VISA behavior, Ultra Sigma notes, tested resource string, and practical reading strategy.

MVP Definition

The first public version should make these operations easy for an AI agent:

  • Discover a connected RIGOL scope.
  • Identify model, serial, firmware, and transport.
  • Read status for channel, timebase, trigger, acquisition, and waveform settings.
  • Configure channel scale, offset, coupling, probe ratio, and display.
  • Configure timebase and trigger.
  • Read concise instrument-side measurements such as frequency, Vpp, mean, RMS, and duty cycle.
  • Run autoscale as an explicitly confirmed starting point, then read back the resulting settings.
  • Explicitly run, stop, or single-shot acquisition and read back status.
  • Acquire a small screen waveform and return summary statistics plus saved data, local preview, and real screen image files when supported.
  • Optionally acquire bounded stopped memory waveform evidence without returning raw arrays in chat/tool output.
  • Return all results as structured JSON suitable for an AI agent.

Non-Goals For v0

  • Full multi-vendor abstraction.
  • GUI application.
  • Automatic circuit diagnosis.
  • Controlling power supplies, meters, or logic analyzers.
  • Solving physical wiring or electrical safety automatically.

Safety Position

The AI can control the oscilloscope and analyze data, but the user remains responsible for physical probing, grounding, voltage range, isolation, and powering hardware. At the first hardware access in each agent/MCP session, the workflow should give one concise safety reminder and confirm the physical setup and authorized test scope. That authorization remains valid for the approved workflow; prompt again only after a session restart or a material change in wiring, probes, voltage/isolation risk, network configuration, or intended remote-panel action. High-voltage and non-isolated work always requires explicit scope-specific confirmation.

Status

This is an early standalone project seed created from the initial DHO804D validation work. USB/VISA is verified on one DHO804D for identity, status, configuration tools, screen waveform capture, and direct screen image capture. LAN TCP support is verified on that DHO804D for direct static Ethernet with raw SCPI on port 5555 after USB-assisted LAN configuration and :LAN:APPLy.

This project is not affiliated with RIGOL. RIGOL is a trademark of its owner.

Project Memory

The current project intent, planning, verified assets, and future direction are captured in:

  • docs/README.md for the documentation index.
  • docs/project_brief_zh.md for the Chinese project brief.
  • docs/roadmap.md for implementation order.
  • docs/development_plan.md for technical decisions and implementation tasks.
  • docs/mcp_tool_design.md for the MCP tool draft.
  • docs/client_platform_compatibility.md for MCP client, skill, and host-platform support.
  • docs/open_source_release_strategy.md for the private-development/public-release policy and Apache-2.0 decision.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scopebench_mcp-0.3.1.tar.gz (151.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scopebench_mcp-0.3.1-py3-none-any.whl (68.8 kB view details)

Uploaded Python 3

File details

Details for the file scopebench_mcp-0.3.1.tar.gz.

File metadata

  • Download URL: scopebench_mcp-0.3.1.tar.gz
  • Upload date:
  • Size: 151.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for scopebench_mcp-0.3.1.tar.gz
Algorithm Hash digest
SHA256 29ca9a977cc6f46d60c10fca38aa1c6d40e7abd380eb3dc38541b6baa22ba869
MD5 6cca11879372acee6750feec4c680d46
BLAKE2b-256 e7bb1c726a2cdc828ac5bcf280c0f5a37636fdc0a4b9d93045a007cb25b1cf90

See more details on using hashes here.

File details

Details for the file scopebench_mcp-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: scopebench_mcp-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 68.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for scopebench_mcp-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 535c264906357349134e6968bc3ab5c597919ed94237493c30b1b30dc6719422
MD5 a0d5d73b093fa43b4857a48ac85cba93
BLAKE2b-256 99dadb635399a54cbdd43c65cc1aa5534f4d0d0a92f1b6249d4a2ed246b60c28

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page