Skip to main content
Glama
LeCroy Oscilloscope MCP

LeCroy Oscilloscope MCP

by lucasgerads

lecroy-mcp

MCP server for controlling LeCroy oscilloscopes via SCPI over LAN (VXI-11) or USB.

Demo

Requirements

  • uv installed

  • A LeCroy oscilloscope connected over LAN or USB

Related MCP server: Rigol DHO824 MCP Server

MCP configuration

Add to your MCP client config (e.g. Claude Code's .mcp.json):

{
  "mcpServers": {
    "lecroy-scope": {
      "type": "stdio",
      "command": "uvx",
      "args": ["lecroy-mcp"]
    }
  }
}

uvx will automatically download and run the server — no manual installation needed.

Oscilloscope setup (LAN / VXI-11)

This server communicates over the standard VXI-11 protocol. Before connecting, enable it on the scope:

  1. On the scope, go to Utilities → Utilities Setup ... → Remote

  2. In the Control from section, enable LXI (VXI11)

  3. Note the IP Address shown — you will need it for the connection string

The scope's IP can be assigned via DHCP or configured statically under Utilities → Utility → Remote → Net Connections.

Note: The TCPIP (VICP) option shown in the same panel uses LeCroy's proprietary protocol and is currently not supported by this server. Only LXI (VXI11) is required.

Scope Setup

Connection options

Option 1 — Manual connection

Copy the MCP client config from above as-is and connect from within the Claude session:

  1. scope_scan — auto-detect LeCroy scopes on the local network

  2. scope_list_resources — list all VISA resources (LAN + USB)

  3. scope_connect("TCPIP0::192.168.1.111::inst0::INSTR") — connect directly

Optionally set LECROY_SUBNET to hint the scan range:

{
  "mcpServers": {
    "lecroy-scope": {
      "type": "stdio",
      "command": "uvx",
      "args": ["lecroy-mcp"],
      "env": {
        "LECROY_SUBNET": "192.168.1.0/24"
      }
    }
  }
}

Set LECROY_HOST in the env block and the server auto-connects on startup:

{
  "mcpServers": {
    "lecroy-scope": {
      ...
      "env": {
        "LECROY_HOST": "192.168.1.111"
      }
    }
  }
}

Option 3 — Pre-configure a full resource string (LAN or USB)

Use LECROY_RESOURCE for full control, including USB connections:

{
  "mcpServers": {
    "lecroy-scope": {
      ...
      "env": {
        "LECROY_RESOURCE": "USB0::0x05FF::0x1023::12345::INSTR"
      }
    }
  }
}

Usage

Once connected, you have tools for:

  • Channel setup (scale, offset, coupling, bandwidth limit)

  • Trigger configuration (mode, source, level, edge)

  • Timebase and memory depth

  • Automated measurements (PKPK, FREQ, RMS, RISE, DUTY, etc.)

  • Waveform capture (JSON or CSV)

  • Screenshots

  • Math functions (FFT, INTG, DIFF, etc.)

  • WaveSource built-in generator (WaveSurfer 3000Z and similar)

Supported models

The server detects the connected model and adjusts commands accordingly. Profiles are included for:

  • WaveSurfer 3000Z / 4000HD

  • HDO4000A / HDO6000B / HDO8000A

  • WaveRunner 6000 / 8000

  • WavePro HD

  • MDA800A, SDA

Unknown models fall back to conservative defaults.

Manual installation

If you prefer not to use uvx:

pip install lecroy-mcp

Then use lecroy-mcp as the command in your MCP config instead of uvx lecroy-mcp.

Updating

With uvx, use the @latest tag to force the newest version:

uvx lecroy-mcp@latest

Or update the args in your .mcp.json to always pull the latest:

"args": ["lecroy-mcp@latest"]

With pip:

pip install --upgrade lecroy-mcp

Notes

  • Requires pyvisa-py backend — NI-VISA is currently not supported (breaks screenshot capture)

  • All VISA access is serialized via a threading lock; parallel MCP tool calls are safe

Troubleshooting

Diagnostic messages not appearing in MCP logs

If you are not seeing server log output (e.g. auto-connect status or errors) in your MCP client's log viewer, add PYTHONUNBUFFERED to the env block:

"env": {
  "PYTHONUNBUFFERED": "1"
}

This disables Python's output buffering so log messages are flushed immediately. It is not required for normal operation.

Tested with

Component

Details

Oscilloscope

Teledyne LeCroy WaveSurfer 3024Z

Operating system

Windows 10, Windows 11, Linux Mint

MCP client

Claude Code

This server should also work with other MCP-compatible clients such as OpenAI Codex and Google Gemini Code Assist, and on other operating systems such as macOS. Reports and contributions for additional configurations are welcome.

Disclaimer

Teledyne LeCroy and LeCroy are registered trademarks of Teledyne LeCroy, Inc. This project is an independent open-source tool and is not affiliated with, endorsed by, or sponsored by Teledyne LeCroy, Inc. All product and company names are trademarks or registered trademarks of their respective holders.

Available Tools

48 tools
scope_armA

Arm the trigger (ARM). Start waiting for a trigger event.

Use scope_get_acquisition_status to poll for completion.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_auto_setupB

Run AUTO_SETUP to automatically scale vertical, horizontal and trigger.

The scope will adjust all settings to best display the connected signals.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_beepA

Trigger the oscilloscope audible beeper. Useful for confirming operations.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_calibrateA

Run self-calibration (*CAL?) and return the result status.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_capabilitiesA

Return the detected model profile for the connected oscilloscope.

Shows family name, channel count, bandwidth, ADC resolution, supported coupling values, bandwidth-limit values, memory depth, math channels, and which optional features (invert, unit, SARA) are available.

Connect with scope_connect first; the profile is detected from *IDN?.

Transport: local (reads cached profile set during scope_connect)

Inputs: no named parameters. Returns: result

scope_capture_channelsA

Capture multiple channels atomically and save to a single .npz file.

Use this when you need time-domain signals from multiple channels (plotting, cross-channel analysis, export). For scalar results like peak voltage or frequency, prefer scope_measure — no waveform transfer needed.

If the scope is already stopped (e.g. from a previous capture), arms it first and waits for a fresh acquisition before reading. All channels are read within a single VISA lock hold so the waveforms come from the same snapshot. Always leaves the scope stopped after capture.

Saves to 'waveforms/' with an auto-generated filename, e.g.: waveforms/C3F1_20260329_153042.npz

The .npz file contains arrays: time_s, c3, f1, ... (one per channel). Analog channels use keys like c1, c2; math channels use f1, f2, etc.

Load in Python with: import numpy as np d = np.load('/path/to/file.npz') time_s, c3, f1 = d['time_s'], d['c3'], d['f1']

Args: channels: List of analog channel numbers (e.g. [1, 2]) and/or math channel strings (e.g. ["F1", "F2"]). Mixed lists are supported, e.g. [3, "F1"] captures C3 and the F1 math trace together. max_points: Maximum samples per channel (default 10000, evenly downsampled).

Transport: SCPI (binary WF? DAT1 transfer + INSPECT? WAVEDESC scaling)

Inputs: channels (required), max_points. Returns: result

scope_channel_infoA

Get all current settings for a channel in one call.

Returns vertical scale, offset, coupling, bandwidth limit, invert, trace visibility, unit, and configured probe (from LECROY_PROBE_Cn env var).

Args: channel: Channel number 1–4

Transport: SCPI

Inputs: channel (required). Returns: result

scope_configure_channelA

Configure one or more settings for a channel in a single call.

All parameters except channel are optional — only the provided ones are applied.

Probe attenuation (ATTN) is set automatically from the LECROY_PROBE_Cn environment variable at connect time and cannot be changed here — it reflects the physical probe and is the engineer's responsibility.

Args: channel: Channel number 1–4 vdiv: Vertical scale in V/div, e.g. 0.1 = 100 mV/div, 1.0 = 1 V/div offset: Vertical offset in volts (positive shifts trace down) coupling: D1M (DC 1MΩ), D50 (DC 50Ω), A1M (AC 1MΩ), or GND bwlimit: Bandwidth limit: OFF (full BW), 20MHZ, 200MHZ. High-BW models also support 500MHZ, 1GHZ, etc. Use scope_capabilities to see valid values for the connected scope. invert: True to invert the signal polarity, False for normal trace: True to show the channel trace, False to hide it unit: Vertical unit: V (volts), A (amperes), W (watts), U (user)

Transport: SCPI

Inputs: channel (required), vdiv, offset, coupling, +4 more. Returns: result

scope_configure_triggerA

Configure trigger mode, source, slope, and/or level in a single call.

All parameters are optional — only the provided ones are applied. For complex trigger types (pulse width, window, TV, etc.) use scope_write.

If level is provided without source, it is applied to C1. To set the level on a different channel, always pass source together with level.

Args: mode: Trigger mode: AUTO (free-running), NORM (wait for trigger), SINGLE (one capture then stop), STOP (stop acquisition) source: Trigger source: C1, C2, C3, C4, EX, EX5, or LINE slope: Edge slope: POS (rising), NEG (falling), or EITHER level: Trigger threshold in volts

Transport: SCPI

Inputs: mode, source, slope, level. Returns: result

scope_connectA

Connect to the LeCroy oscilloscope at the given VISA resource address.

Args: resource_string: VISA address, e.g. 'TCPIP0::192.168.1.111::inst0::INSTR'

Returns the IDN string on success.

Transport: local (opens VISA session, then queries *IDN? via SCPI)

Inputs: resource_string (required). Returns: result

scope_connection_statusA

Check whether the server has an active VISA connection and identify the scope.

Transport: local (connection check) + SCPI (*IDN? if connected)

Inputs: no named parameters. Returns: result

scope_cursor_infoA

Query current cursor measurements from the oscilloscope.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_decode_readA

Read decoded serial data from the scope's SerialDecode subsystem.

The scope must already have a serial decode active (configured via its UI or scope_decode_configure_uart). Works with UART/RS-232, I2C, SPI, CAN, and any other protocol supported by the Decode option.

Reads the decoded table row-by-row using the VBS Table API and saves the result to a timestamped .npz file so the raw data is not embedded in the response. The file contains: time_s — float array, timestamp for each decoded frame/byte data — uint8 array, decoded byte values

Returns JSON with the file path and metadata. Load in Python with: import numpy as np d = np.load('/path/to/file.npz') times, data_bytes = d['time_s'], d['data']

Note: row-by-row VBS queries are slow (~0.05 s each). Decodes with hundreds of rows will take 10–20 s. Keep this in mind for large captures.

Args: decoder: Decode slot number — 1 or 2 (default 1)

Transport: VBS (app.SerialDecode.Decode{n}.Out.Result.*)

Inputs: decoder. Returns: result

scope_disconnectA

Disconnect from the oscilloscope. Safe to call even if not connected.

Transport: local

Inputs: no named parameters. Returns: result

scope_force_triggerA

Force an immediate trigger event (FRTR).

Useful when in NORM mode and the signal hasn't triggered yet.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_get_acquisition_statusA

Query the current acquisition and trigger state.

Returns the trigger mode (TRMD?) and internal state register (INR?). INR bit 0 set (value & 1 == 1) means a new waveform was acquired since the last INR read. Note: SAMPLE_STATUS? is not supported on WS3000Z.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_get_dateA

Query the oscilloscope internal date and time.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_get_waveformA

Capture waveform data from a channel and save it as a .npz file.

Use this when you need the time-domain signal (plotting, export, detailed analysis). For scalar results like peak voltage, frequency, or RMS, prefer scope_measure — it is faster and uses all scope points without any transfer.

If the scope is already stopped (e.g. from a previous capture), arms it first and waits for a fresh acquisition before reading. Always leaves the scope stopped after capture so the on-screen waveform matches the file.

Saves to a 'waveforms/' subfolder with an auto-generated filename, e.g.: waveforms/C1_20260329_153042.npz

Returns JSON with the file path and metadata — the raw voltage values are not embedded in the result. Load the file in Python with: import numpy as np d = np.load('/path/to/file.npz') time_s, voltage_v = d['time_s'], d['voltage_v']

Args: channel: Channel number 1–4 max_points: Maximum samples to capture (default 10000, evenly downsampled).

Transport: SCPI (binary WF? DAT1 transfer + INSPECT? WAVEDESC scaling)

Inputs: channel (required), max_points. Returns: result

scope_helpA

Look up LeCroy SCPI documentation by topic.

Call with no argument (or topic="") to see the list of available topics.

Args: topic: One of: overview, channel, timebase, trigger, acquisition, measurement, waveform, math, cursor, screenshot, system. Leave empty to list all topics.

Transport: local

Inputs: topic. Returns: result

scope_identifyA

Query the oscilloscope identification string (*IDN?).

Returns make, model, serial number, and firmware version.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_list_resourcesA

List all VISA instrument resources visible on this computer (LAN and USB).

Use this to find the resource string for scope_connect. A LAN-connected LeCroy typically appears as: TCPIP0::192.168.1.111::inst0::INSTR A USB-connected LeCroy typically appears as: USB0::0x05FF::0x1023::::INSTR

If nothing appears, try scope_scan to search the network directly.

Transport: local

Inputs: no named parameters. Returns: result

scope_math_infoA

Get the definition and display state of a math function.

Args: func: Math function number 1–4

Transport: SCPI

Inputs: func (required). Returns: result

scope_math_zoom_infoA

Read the current horizontal zoom settings for a math trace.

Args: func: Math function number 1–4

Transport: VBS (app.Math.Fn.Zoom.HorCenter, app.Math.Fn.Zoom.HorScale)

Inputs: func (required). Returns: result

scope_measureA

Get a single automated measurement from a channel.

Args: channel: Channel number 1–4 param: One of: MEAN — mean (average) voltage MAX — maximum voltage MIN — minimum voltage PKPK — peak-to-peak voltage FREQ — frequency PERIOD — period RMS — RMS voltage RISE — rise time (10%–90%) FALL — fall time (90%–10%) WIDTH — pulse width (positive) DUTY — duty cycle BASE — base voltage level TOP — top voltage level AMPL — amplitude (top – base) OVSP — overshoot (positive) UNDSP — undershoot PHASE — phase difference DELAY — delay AREA — area under curve

Returns the value with units as reported by the oscilloscope.

Transport: SCPI (PAVA)

Inputs: channel (required), param (required). Returns: result

scope_measure_allA

Get all automated measurements for a channel in one call.

Queries MEAN, MAX, MIN, PKPK, FREQ, PERIOD, RMS, RISE, FALL, WIDTH, DUTY, BASE, TOP, AMPL, OVSP, UNDSP, PHASE, DELAY, AREA.

Args: channel: Channel number 1–4

Transport: SCPI (PAVA)

Inputs: channel (required). Returns: result

scope_queryA

Send any SCPI query command and return the response.

Escape hatch for SCPI commands not covered by dedicated tools. Use dedicated tools whenever one exists — they handle edge cases, model differences, and response parsing correctly. Do NOT use this to send raw VBS strings; use scope_wavesource_* and other VBS-backed tool groups instead.

Args: command: SCPI query string, e.g. 'C1:VDIV?' or 'TRMD?'

Transport: SCPI

Inputs: command (required). Returns: result

scope_recall_waveformA

Recall a waveform from internal memory.

Args: slot: Memory slot 1–4 to recall from dest: Destination, e.g. 'C1' (overlays the recalled waveform on C1)

Transport: SCPI

Inputs: slot (required), dest (required). Returns: result

scope_resetA

Reset the oscilloscope to factory defaults (*RST).

WARNING: This clears all waveforms, measurements and settings.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_save_waveform_csvA

Capture a waveform and save it as a timestamped CSV file ready for post-processing.

Files are always saved to a 'waveforms/' subfolder next to the server with an auto-generated filename, e.g.: waveforms/C1_20260329_153042.csv The full path is returned so you know exactly where the file landed.

The CSV has two columns: time_s and voltage_v. Metadata lines starting with # at the top are ignored by pandas (use comment='#').

Example Python usage: import pandas as pd df = pd.read_csv('waveforms/C1_20260329_153042.csv', comment='#') df.plot(x='time_s', y='voltage_v')

Args: channel: Channel number 1–4 max_points: Maximum samples to save (default 10000).

Transport: SCPI (binary WF? DAT1 transfer + INSPECT? WAVEDESC scaling)

Inputs: channel (required), max_points. Returns: result

scope_scanA

Scan the network for LeCroy oscilloscopes.

More reliable than scope_list_resources for LAN-connected scopes — probes each host directly rather than relying on broadcast discovery.

Scans all hosts in the subnet for port 111 (VXI-11 portmapper) in parallel, then queries *IDN? on responsive hosts and filters for LeCroy instruments.

Args: subnet: CIDR subnet to scan, e.g. '192.168.1.0/24'. Defaults to LECROY_SUBNET env var if set, otherwise auto-detected from the local network interface.

Transport: local (TCP socket probe + SCPI *IDN? per candidate)

Inputs: subnet. Returns: result

scope_screenshotA

Capture the oscilloscope screen and save as a timestamped image file.

Files are always saved to a 'screenshots/' subfolder with an auto-generated filename, e.g.: screenshots/scope_20260329_153042.png The full path is returned so you know exactly where the file landed.

Args: image_format: BMP, JPEG, PNG, or TIFF (default PNG) area: DSOWINDOW (default), GRIDAREAONLY, or FULLSCREEN background: WHITE (default) or BLACK to preserve the dark screen theme

Transport: SCPI (HARDCOPY_SETUP + SCREEN_DUMP, binary read)

Inputs: image_format, area, background. Returns: result

scope_set_cursor_typeA

Set the cursor type.

Args: cursor_type: HREL (relative horizontal), VREL (relative vertical), HREF (absolute horizontal), VREF (absolute vertical), or OFF to disable cursors.

Transport: SCPI

Inputs: cursor_type (required). Returns: result

scope_set_mathA

Define a math waveform function.

Available operators (all MAUI scopes):

Arithmetic: ABS(C1) absolute value INVERT(-C1) negation SQR(C1) square SQRT(C1) square root RECIPROCAL(C1) 1/x RESC(C1) rescale (scale + offset + change units) C1+C2 sum of two channels C1-C2 difference C1*C2 product C1/C2 ratio

Signal processing: FFT(C1) Fast Fourier Transform — use TYPE parameter to select POWERSPECTRUM (dBm), MAGNITUDE, PHASE, REAL, IMAGINARY. WINDOW options: VONHANN, HAMMING, FLATTOP, BLACKMANHARRIS, RECTANGULAR. Example: EQN,"FFT(C1)",TYPE,POWERSPECTRUM,WINDOW,VONHANN INTG(C1) integral DERI(C1) derivative (adjacent-sample subtraction) AVG(C1) averaging — add AVERAGETYPE,SUMMED or CONTINUOUS ERES(C1) enhanced resolution (smoothing, 0.5–3 extra bits)

Envelope / extrema: FLOOR(C1) minimum value at each X over N sweeps ROOF(C1) maximum value at each X over N sweeps

Parameter-based (use a measurement parameter Pn as source): TREND(P1) trend plot of parameter values over time HIST(P1) histogram of parameter values

Display only: ZOOMONLY(C1) zoom display without computation

After setting an FFT, use scope_set_math_zoom to zoom the frequency axis.

Args: func: Math function number 1–4 equation: Math expression string, e.g. 'FFT(C1)' or 'C1+C2'

Transport: SCPI

Inputs: func (required), equation (required). Returns: result

scope_set_math_traceB

Show or hide a math function trace.

Args: func: Math function number 1–4 visible: True to show, False to hide

Transport: SCPI

Inputs: func (required), visible (required). Returns: result

scope_set_math_zoomA

Set the horizontal display zoom for a math trace.

Useful for zooming into a specific frequency range on an FFT trace without changing the FFT computation itself.

Units depend on the math function type:

  • FFT traces: Hz (e.g. center=1250, per_div=250 shows 0–2500 Hz on 10 divs)

  • Time-domain math traces: seconds

Args: func: Math function number 1–4 center: Center value (Hz for FFT, seconds for time-domain math) per_div: Scale per division

Transport: VBS (app.Math.Fn.Zoom.HorCenter, app.Math.Fn.Zoom.HorScale)

Inputs: func (required), center (required), per_div (required). Returns: result

scope_set_memory_sizeA

Set the acquisition memory depth (record length).

Args: size: Memory depth — one of: 500, 1K, 10K, 25K, 50K, 100K, 250K, 500K, 1M, 2.5M, 5M, 10M, 25M. Available sizes are model-dependent; WaveSurfer 3000Z maximum is 10M. Larger = more detail, slower transfer.

Transport: SCPI

Inputs: size (required). Returns: result

scope_set_panel_lockA

Lock or unlock the oscilloscope front-panel controls.

Args: locked: True to lock (prevent accidental adjustment), False to unlock.

Transport: SCPI

Inputs: locked (required). Returns: result

scope_set_tdivA

Set the time base (time per division).

Args: seconds_per_div: Time/div in seconds. Examples: 1e-9 (1 ns), 1e-6 (1 µs), 1e-3 (1 ms), 1.0 (1 s)

Transport: SCPI

Inputs: seconds_per_div (required). Returns: result

scope_set_trigger_delayA

Set the trigger delay (horizontal position offset).

Args: seconds: Delay in seconds. Positive = trigger point moves left, negative = trigger point moves right.

Transport: SCPI

Inputs: seconds (required). Returns: result

scope_setup_measurementsA

Configure the scope's measurement panel (P1–P6) for a channel.

PAVA measurements only return valid values for parameters that are active in one of the six display slots. Call this once after connecting to a channel with a new signal. The scope_measure and scope_measure_all tools will also auto-configure if they detect an invalid result, but calling this explicitly sets up the display panel for that channel.

Args: channel: Channel number 1–4 params: List of up to 6 parameter names to show in the panel. Defaults to ['PKPK', 'FREQ', 'MEAN', 'RMS', 'RISE', 'DUTY']. Valid names: MEAN MAX MIN PKPK FREQ PERIOD RMS RISE FALL WIDTH DUTY BASE TOP AMPL OVSP UNDSP PHASE DELAY AREA

Transport: SCPI (PACU)

Inputs: channel (required), params. Returns: result

scope_stopB

Stop acquisition immediately (STOP).

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_store_waveformB

Store a waveform to internal memory.

Args: source: Waveform to store — 'C1', 'C2', 'C3', 'C4', 'F1'–'F4' slot: Memory slot 1–4

Transport: SCPI

Inputs: source (required), slot (required). Returns: result

scope_timebase_infoA

Get all current timebase settings in one call.

Returns time/div, trigger delay, sample rate, and memory size.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_trigger_infoA

Get all current trigger settings in one call.

Returns trigger mode, source/type configuration, and level per channel.

Transport: SCPI

Inputs: no named parameters. Returns: result

scope_wavesource_configureA

Configure the WaveSource built-in generator in a single call.

All parameters are optional — only the provided ones are applied. Only available on models with has_wavesource=True (e.g. WaveSurfer 3000Z). Check scope_capabilities first.

Args: shape: Waveform shape: Sine, Square, Triangle, Pulse, DC, Noise, Arb. For sawtooth/ramp use Triangle with symmetry=0 or symmetry=100. frequency: Output frequency in Hz, e.g. 1000.0 for 1 kHz amplitude: Peak-to-peak amplitude in Vpp, e.g. 3.3 for 3.3 Vpp offset: DC offset in volts load: Output load: 'HiZ' (high impedance) or '50' (50 Ω termination) duty_cycle: Duty cycle in percent — Square and Pulse shapes only symmetry: Symmetry in percent — Triangle shape only (50 = symmetric)

Transport: VBS (app.WaveSource.*)

Inputs: shape, frequency, amplitude, offset, +3 more. Returns: result

scope_wavesource_enableA

Enable or disable the WaveSource output.

Args: on: True to enable output, False to disable.

Transport: VBS (app.WaveSource.Enable)

Inputs: on (required). Returns: result

scope_wavesource_infoA

Get all current WaveSource generator settings.

Returns shape, frequency, amplitude, offset, load, duty cycle, symmetry, and enabled state.

Only available on models with has_wavesource=True (e.g. WaveSurfer 3000Z). Check scope_capabilities first.

Transport: VBS (app.WaveSource.*)

Inputs: no named parameters. Returns: result

scope_writeA

Send any SCPI write command (no response expected).

Escape hatch for SCPI commands not covered by dedicated tools. Use dedicated tools whenever one exists — they handle edge cases, model differences, and response parsing correctly. Do NOT use this to send raw VBS strings; use scope_wavesource_* and other VBS-backed tool groups instead.

Args: command: SCPI command string, e.g. 'C1:VDIV 0.5' or 'TRIG_MODE AUTO'

Transport: SCPI

Inputs: command (required). Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 48 tools

    Disambiguation5/5

    Each tool targets a distinct operation (e.g., connect, configure_channel, measure, capture_waveform) with clear boundaries. Even similar tools like scope_measure and scope_measure_all are well-differentiated by scope. No ambiguity.

    Naming Consistency5/5

    All tools follow a consistent 'scope_verb_noun' pattern (e.g., scope_connect, scope_configure_channel, scope_set_tdiv). The naming is predictable and uniform across the entire set.

    Tool Count2/5

    48 tools is very high for an MCP server. While the oscilloscope domain is complex, the number exceeds the threshold for 'too many' (25+). Many tools could be consolidated or exposed as parameters of fewer tools.

    Completeness4/5

    The tool set covers nearly all oscilloscope operations: connection, channels, timebase, trigger, measurements, math, cursors, screenshot, wavesource, memory. Minor gaps exist (e.g., no tool to configure serial decode settings, only reading is provided).

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      A
      quality
      C
      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
      7
      -
    • 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.
      54 PyPI
      7
      MIT
    • A
      license
      C
      quality
      B
      maintenance
      Enables natural language control of test instruments like spectrum analyzers and power supplies via SCPI commands, with auto-discovery and multi-instrument session support.
      100
      1
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables remote control of Siglent oscilloscopes via SCPI over TCP/IP, allowing natural language commands for configuration, measurements, and waveform data retrieval.
      -