SCPI MCP
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SCPI MCP Set the power supply to 5V and measure the output with the multimeter."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SCPI MCP
An MCP server that puts benchtop test equipment within reach of an agentic coding harness. Point Claude Code, Codex or any other MCP client at it and ask it to go investigate a circuit.
It exposes four instruments as 76 typed tools, plus a raw SCPI passthrough for everything the wrappers do not cover:
Device key | Instrument |
| Arbitrary waveform generator |
| Multimeter |
| Oscilloscope |
| Power supply |
Anything that speaks SCPI over a socket should work. SCPI is a text protocol standardized in 1990, which turns out to suit this well: instruments that already take commands as strings do not need much of an adapter to take them from a model.
Why it is useful
The oscilloscope can hand back screenshots. That matters more than it sounds, because a lot of what a scope tells you is a shape rather than a number, and a model that can look at the trace reasons about it the way a person would instead of working from whichever measurements someone thought to request in advance.
The useful range runs from "set a rising edge trigger at 2.5 volts on channel 2", which just saves a menu dive, up to handing over a misbehaving circuit and letting the model drive all four instruments to work out why.
Related MCP server: rigol-oscilloscope-mcp
Requirements
Python 3.10 or newer
Instruments reachable over the network, listening for raw SCPI (port 5025 on nearly everything)
Install
git clone https://github.com/colingimenez/SCPI_MCP.git
cd SCPI_MCP
uv syncConfiguration
Instrument addresses come from the environment, so nothing needs editing in source. Set only the ones you have.
Variable | Default |
|
|
|
|
|
|
|
|
|
|
Use it from an MCP client
{
"mcpServers": {
"scpi": {
"command": "uv",
"args": ["--directory", "/path/to/SCPI_MCP", "run", "main.py"],
"env": {
"SCPI_OSC_HOST": "192.0.2.10",
"SCPI_PSU_HOST": "192.0.2.11"
}
}
}
}A note on safety
Raw SCPI has no authentication of any kind. Anything that can reach port 5025 on an instrument can drive it, and this server does nothing to change that. Put your bench on a network you trust.
The tools will also happily turn a power supply on, change its voltage, and reset an instrument to factory defaults, because that is the point. Be aware that a model driving this is driving real hardware with real things wired to it.
Known specifics
Oscilloscope screenshot capture is written against the Siglent SDS1202X-E, which streams a raw image with no length header and no terminator. Other scopes implement this differently and may need their own path.
License
MIT.
Available Tools
76 toolsarb_disable_burstA
Disable burst mode on a waveform generator channel.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
arb_disable_modulationB
Disable all modulation on a waveform generator channel.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
arb_disable_sweepA
Disable frequency sweep on a waveform generator channel.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
arb_get_basic_waveformB
Query the current basic waveform parameters of a waveform generator channel.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
arb_get_outputA
Query whether a waveform generator channel output is on or off.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
arb_set_amB
Enable AM modulation on the waveform generator.
Args: channel: Channel number (1 or 2). depth: Modulation depth in percent. frequency: Modulation frequency in Hz.
Inputs: depth (required), channel (required), frequency (required). Returns: result
arb_set_amplitudeA
Set the output amplitude in Vpp on the waveform generator.
Args: channel: Channel number (1 or 2). amplitude: Amplitude in Vpp.
Inputs: channel (required), amplitude (required). Returns: result
arb_set_burstB
Enable burst mode on the waveform generator.
Args: channel: Channel number (1 or 2). cycles: Number of burst cycles. period: Burst period in seconds.
Inputs: cycles (required), period (required), channel (required). Returns: result
arb_set_duty_cycleA
Set the duty cycle (%) for square/pulse waveforms on the waveform generator.
Args: channel: Channel number (1 or 2). duty: Duty cycle percentage.
Inputs: duty (required), channel (required). Returns: result
arb_set_fmA
Enable FM modulation on the waveform generator.
Args: channel: Channel number (1 or 2). deviation: Frequency deviation in Hz. frequency: Modulation frequency in Hz.
Inputs: channel (required), deviation (required), frequency (required). Returns: result
arb_set_frequencyA
Set the output frequency in Hz on the waveform generator.
Args: channel: Channel number (1 or 2). frequency: Frequency in Hz.
Inputs: channel (required), frequency (required). Returns: result
arb_set_offsetC
Set the DC offset in volts on the waveform generator.
Args: channel: Channel number (1 or 2). offset: Offset in volts.
Inputs: offset (required), channel (required). Returns: result
arb_set_outputA
Enable or disable the output of a waveform generator channel.
Args: channel: Channel number (1 or 2). state: True to enable, False to disable.
Inputs: state (required), channel (required). Returns: result
arb_set_output_loadA
Set the output load impedance on the waveform generator.
Args: channel: Channel number (1 or 2). load: 'HZ' for high-impedance or a numeric value in ohms (e.g. '50').
Inputs: load (required), channel (required). Returns: result
arb_set_phaseA
Set the phase in degrees on the waveform generator.
Args: channel: Channel number (1 or 2). phase: Phase in degrees.
Inputs: phase (required), channel (required). Returns: result
arb_set_pmA
Enable PM (phase) modulation on the waveform generator.
Args: channel: Channel number (1 or 2). deviation: Phase deviation in degrees. frequency: Modulation frequency in Hz.
Inputs: channel (required), deviation (required), frequency (required). Returns: result
arb_set_polarityA
Set the output polarity on the waveform generator.
Args: channel: Channel number (1 or 2). polarity: 'NOR' for normal, 'INVT' for inverted.
Inputs: channel (required), polarity (required). Returns: result
arb_set_sweepA
Enable frequency sweep on the waveform generator.
Args: channel: Channel number (1 or 2). start_freq: Start frequency in Hz. stop_freq: Stop frequency in Hz. time: Sweep time in seconds.
Inputs: time (required), channel (required), stop_freq (required), start_freq (required). Returns: result
arb_set_waveformA
Set the basic waveform type on the waveform generator.
Args: channel: Channel number (1 or 2). waveform: Waveform type – SINE, SQUARE, RAMP, PULSE, NOISE, ARB, or DC.
Inputs: channel (required), waveform (required). Returns: result
dmm_clear_statisticsA
Clear accumulated statistics on the multimeter.
Inputs: no named parameters. Returns: result
dmm_disable_statisticsA
Disable statistics calculation on the multimeter.
Inputs: no named parameters. Returns: result
dmm_enable_statisticsA
Enable statistics calculation on the multimeter.
Inputs: no named parameters. Returns: result
dmm_fetchA
Fetch the last measurement from the multimeter without triggering a new one.
Inputs: no named parameters. Returns: result
dmm_get_functionA
Query the current measurement function on the multimeter.
Inputs: no named parameters. Returns: result
dmm_get_rangeA
Query the current measurement range on the multimeter.
Inputs: no named parameters. Returns: result
dmm_get_statisticsA
Query statistics (average, min, max, stddev) from the multimeter.
Inputs: no named parameters. Returns: result
dmm_measureB
Configure and take a single measurement on the multimeter.
Args: function: One of VOLT:DC, VOLT:AC, CURR:DC, CURR:AC, RES, FRES, FREQ, PER.
Inputs: function (required). Returns: result
dmm_readA
Take a new measurement reading from the multimeter (triggers and reads).
Inputs: no named parameters. Returns: result
dmm_set_auto_rangeA
Enable or disable auto-range on the multimeter.
Args: enable: True to enable, False to disable.
Inputs: enable (required). Returns: result
dmm_set_functionA
Set the measurement function on the multimeter.
Args: function: One of VOLT:DC, VOLT:AC, CURR:DC, CURR:AC, RES, FRES, FREQ, PER, CONT, DIOD, CAP.
Inputs: function (required). Returns: result
dmm_set_nplcA
Set the integration time in number of power line cycles on the multimeter.
Args: nplc: NPLC value (e.g. 0.02, 0.2, 1, 10, 100).
Inputs: nplc (required). Returns: result
dmm_set_rangeA
Set the measurement range on the multimeter.
Args: value: Range value (e.g. 10 for 10V range).
Inputs: value (required). Returns: result
dmm_set_resolutionC
Set the measurement resolution on the multimeter.
Args: resolution: Resolution value.
Inputs: resolution (required). Returns: result
dmm_set_trigger_sourceA
Set the trigger source on the multimeter.
Args: source: One of IMM, BUS, EXT.
Inputs: source (required). Returns: result
dmm_triggerB
Send a software trigger to the multimeter.
Inputs: no named parameters. Returns: result
get_errorA
Read the latest error from the device error queue.
Args: device: Device key – one of 'arb', 'dmm', 'osc', 'psu'.
Inputs: device (required). Returns: result
identifyA
Query the identification string of a device.
Args: device: Device key – one of 'arb', 'dmm', 'osc', 'psu'.
Inputs: device (required). Returns: result
osc_auto_setupB
Run auto-setup on the oscilloscope.
Inputs: no named parameters. Returns: result
osc_force_triggerB
Force a trigger event on the oscilloscope.
Inputs: no named parameters. Returns: result
osc_get_channel_infoA
Query full channel setup info from the oscilloscope.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
osc_get_timebaseA
Query the current timebase setting on the oscilloscope.
Inputs: no named parameters. Returns: result
osc_measureA
Measure a waveform parameter on the oscilloscope.
Args: channel: Channel number (1 or 2). parameter: One of PKPK, MAX, MIN, AMPL, TOP, BASE, MEAN, RMS, FREQ, PER, RISE, FALL, DUTY, WID, NWID, DELAY, OVSP, OVSH.
Inputs: channel (required), parameter (required). Returns: result
osc_runA
Start acquisition (set trigger mode to AUTO) on the oscilloscope.
Inputs: no named parameters. Returns: result
osc_screenshotA
Capture a screenshot from the oscilloscope. Returns base64-encoded PNG data.
Inputs: no named parameters. Returns: result
osc_set_acquire_modeB
Set the acquisition mode on the oscilloscope.
Args: mode: One of SAMPLING, PEAK_DETECT, AVERAGE.
Inputs: mode (required). Returns: result
osc_set_average_countA
Set the number of averages when in average acquisition mode.
Args: count: Number of averages (power of 2, e.g. 4, 16, 64, 256).
Inputs: count (required). Returns: result
osc_set_channel_couplingA
Set the coupling mode of an oscilloscope channel.
Args: channel: Channel number (1 or 2). coupling: One of AC, DC, GND.
Inputs: channel (required), coupling (required). Returns: result
osc_set_channel_offsetA
Set the vertical offset of an oscilloscope channel.
Args: channel: Channel number (1 or 2). offset: Offset in volts.
Inputs: offset (required), channel (required). Returns: result
osc_set_channel_scaleA
Set the vertical scale (V/div) of an oscilloscope channel.
Args: channel: Channel number (1 or 2). scale: Volts per division.
Inputs: scale (required), channel (required). Returns: result
osc_set_channel_stateA
Enable or disable a channel trace on the oscilloscope.
Args: channel: Channel number (1 or 2). state: True to enable, False to disable.
Inputs: state (required), channel (required). Returns: result
osc_set_memory_sizeA
Set the acquisition memory depth on the oscilloscope.
Args: size: Memory size, e.g. '7K', '70K', '700K', '7M', '14M'.
Inputs: size (required). Returns: result
osc_set_probe_attenuationA
Set the probe attenuation factor on an oscilloscope channel.
Args: channel: Channel number (1 or 2). attenuation: Attenuation factor (e.g. 1, 10, 100).
Inputs: channel (required), attenuation (required). Returns: result
osc_set_timebaseA
Set the horizontal timebase (s/div) on the oscilloscope.
Args: scale: Time per division in seconds.
Inputs: scale (required). Returns: result
osc_set_trigger_levelA
Set the trigger level in volts on the oscilloscope.
Args: level: Trigger level in volts.
Inputs: level (required). Returns: result
osc_set_trigger_modeC
Set the trigger mode on the oscilloscope.
Args: mode: One of AUTO, NORM, SINGLE, STOP.
Inputs: mode (required). Returns: result
osc_set_trigger_slopeA
Set the trigger slope on the oscilloscope.
Args: slope: 'POS' for rising edge, 'NEG' for falling edge.
Inputs: slope (required). Returns: result
osc_set_trigger_sourceA
Set the trigger source channel on the oscilloscope.
Args: channel: Channel number (1 or 2).
Inputs: channel (required). Returns: result
osc_singleA
Set the oscilloscope to single-trigger mode.
Inputs: no named parameters. Returns: result
osc_stopB
Stop acquisition on the oscilloscope.
Inputs: no named parameters. Returns: result
psu_get_currentA
Query the set current limit on a power supply channel.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_get_outputA
Query whether a power supply channel output is on or off.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_get_statusB
Query the system status register of the power supply (channel modes, output states).
Inputs: no named parameters. Returns: result
psu_get_voltageA
Query the set voltage on a power supply channel.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_measure_currentA
Measure the actual output current on a power supply channel.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_measure_powerA
Measure the actual output power on a power supply channel.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_measure_voltageA
Measure the actual output voltage on a power supply channel.
Args: channel: Channel number (1, 2, or 3).
Inputs: channel (required). Returns: result
psu_recallB
Recall a saved preset on the power supply.
Args: preset: Preset number (1–5).
Inputs: preset (required). Returns: result
psu_saveA
Save the current settings to a preset on the power supply.
Args: preset: Preset number (1–5).
Inputs: preset (required). Returns: result
psu_set_currentA
Set the output current limit on a power supply channel.
Args: channel: Channel number (1, 2, or 3). current: Current in amps.
Inputs: channel (required), current (required). Returns: result
psu_set_modeA
Set the channel tracking mode on the power supply.
Args: mode: One of INDEPENDENT, SERIES, PARALLEL.
Inputs: mode (required). Returns: result
psu_set_ocpA
Set the over-current protection threshold on a power supply channel.
Args: channel: Channel number (1 or 2). current: OCP threshold in amps.
Inputs: channel (required), current (required). Returns: result
psu_set_outputA
Enable or disable the output of a power supply channel.
Args: channel: Channel number (1, 2, or 3). state: True to enable, False to disable.
Inputs: state (required), channel (required). Returns: result
psu_set_ovpA
Set the over-voltage protection threshold on a power supply channel.
Args: channel: Channel number (1 or 2). voltage: OVP threshold in volts.
Inputs: channel (required), voltage (required). Returns: result
psu_set_voltageB
Set the output voltage on a power supply channel.
Args: channel: Channel number (1, 2, or 3). voltage: Voltage in volts.
Inputs: channel (required), voltage (required). Returns: result
resetA
Reset a device to factory defaults.
Args: device: Device key – one of 'arb', 'dmm', 'osc', 'psu'.
Inputs: device (required). Returns: result
send_raw_scpiB
Send an arbitrary SCPI command to a device. If the command ends with '?', the response is returned.
Args: device: Device key – one of 'arb', 'dmm', 'osc', 'psu'. command: The raw SCPI command string.
Inputs: device (required), command (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 76 tools
Device-specific prefixes (arb_, dmm_, osc_, psu_) cleanly separate tools by instrument, and most tools target a unique parameter. A few pairs like dmm_read vs dmm_measure and psu_get_voltage vs psu_measure_voltage have overlapping semantics, though descriptions clarify the distinction.
Most tools follow a consistent device_verb_noun pattern (e.g., arb_set_frequency, psu_measure_current), making the set highly predictable. Minor deviations such as osc_screenshot, psu_recall, and arb_get_basic_waveform break the strict pattern but are still understandable.
76 tools is a high number, but the server covers four independent instruments with 15-22 tools each, matching the device-specific scope. The count feels heavy for an agent to sort through, though naming conventions and prefix grouping mitigate the burden.
The surface covers the vast majority of operations needed for the four instruments: waveform generation, DMM measurement and statistics, oscilloscope triggering/measurement, and PSU output/protection. The most notable gap is lack of oscilloscope waveform data acquisition (raw trace points), which agents may need for signal analysis.
Related MCP Connectors
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Email inboxes, webhooks, mock APIs, 2FA codes, approvals and 170 tools for AI agents.
Context and control for any AI. Agent identity, scoped access, and proof across tools.
Capture, inspect, send and assert on webhooks and inbound email from your coding agent.
Related MCP Servers
- AlicenseCqualityBmaintenanceEnables natural language control of test instruments like spectrum analyzers and power supplies via SCPI commands, with auto-discovery and multi-instrument session support.1001MIT
- AlicenseAqualityBmaintenanceEnables LLMs to control RIGOL oscilloscopes over SCPI via LAN or USB, including configuring channels/timebase/trigger, taking measurements, capturing waveforms and screenshots, decoding serial protocols, running FFT analysis, and controlling the built-in AFG.38MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to connect to and control Siglent oscilloscopes and power supplies over SCPI/TCP using typed tool calls with input validation, safety controls, and built-in observability.1Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables unified discovery, query, and control of laboratory instruments (power supplies, oscilloscopes, signal generators, multimeters) via VISA/SCPI, with device-specific libraries and an MCP server exposing 19 tools for natural language interaction.-