siglent-sds-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., "@siglent-sds-mcp Setup and capture 2 Mbps UART waveform on channel 1"
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.
siglent-sds-mcp
MCP server for controlling a SIGLENT SDS824X HD oscilloscope via SCPI over raw TCP.
Project status: SDS824X HD hardware-tested alpha. Core measurement-driven auto setup is functional on real hardware.
Quick start
# Install
python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
# Test
pytest -q
# Run MCP server (stdio, for AI client config)
python -m siglent_sds_mcp.server
# Quick connectivity probe
python examples/tcp_idn_test.py <scope-ip>Related MCP server: niscope-mcp
Auto setup — one-command screen setup
The main feature: point at an unknown signal and let the scope measurement engine find usable VDIV / OFST / TDIV settings. The command also saves a screenshot artifact from the final setup path.
# Backwards-compatible CLI name; internally uses measurement-driven auto setup
python examples/auto_find_waveform_tcp.py <scope-ip> --channels C1 C2 C3 C4
# With signal-type hint for better trigger slope policy
python examples/auto_find_waveform_tcp.py <scope-ip> --signal-hint uart
# Direct TTL wiring / 1X probe
python examples/auto_find_waveform_tcp.py <scope-ip> \
--channels C1 \
--signal-hint clock \
--probe 1
# Weak periodic signal policy
python examples/auto_find_waveform_tcp.py <scope-ip> \
--channels C1 \
--signal-hint clock \
--noise-floor 0.05 \
--min-signal-vpp 0.005
# Restart acquisition after capture only when explicitly requested
python examples/auto_find_waveform_tcp.py <scope-ip> --restart-after-captureDefault behavior: leave_stopped=true. The tool intentionally leaves the scope stopped on the final visible frame. The return object includes screen_hold, final_panel_state, measurements, final_settings, probe_steps, screenshot, and compatibility_parameters.
Compatibility note: coarse_timebase, initial_vdiv, max_points, and refine_attempts are accepted by the historical auto_find_waveform API so older MCP/CLI callers do not break. The current measurement-driven adapter path owns the actual scanning and refinement logic, so those compatibility fields are reported in JSON but are not directly used by the measurement path.
Waveform capture modes
get_waveform_tcp defaults to capture_mode="immediate".
STOP -> WF? DAT2This intentionally skips WFSU. SDS824X HD field debugging showed that sending WFSU SP,1,NP,0,FP,0 after STOP can refresh/replace the stopped frame before WF? DAT2, which loses intermittent UART/RS485 bursts and often returns an IDLE frame instead.
For stable/repetitive signals only, callers may request the legacy configured path:
STOP -> WFSU SP,1,NP,0,FP,0 -> WF? DAT2Use it through MCP by setting:
{
"capture_mode": "configured"
}The metadata records capture.mode, capture.wfsu_sent, decode.dt_source, parsed.trdl_s, parsed.effective_start_s, parsed.effective_end_s, and warnings when fallback timing is used.
UART decoding
analyze_uart_csv_file now performs real UART 8N1 byte decoding instead of only reporting edge timing. It detects falling-edge start bits, samples 8 data bits LSB-first, validates the stop bit, and returns decoded bytes:
{
"decoded_hex": "48 69",
"decoded_ascii": "Hi",
"frames": [
{"byte_hex": "0x48", "stop_ok": true, "framing_ok": true}
]
}Thresholding is histogram-based when two voltage levels are visible, with min/max midpoint fallback. This is more robust for small-amplitude UART such as high=5.2 V and low=4.95 V, where simple min/max Vpp rules are too brittle.
Architecture
MCP client (AI)
│ MCP tool calls (stdio)
▼
server.py — FastMCP tools, auto-reconnect
│
▼
sds_tcp_adapter.py — SDS800X HD command adapter
│ channel / acquisition / trigger / measure / screenshot /
│ waveform capture (WAVEDESC adaptive decode + envelope decimation) /
│ measurement-driven auto_setup
▼
waveform_capture.py — immediate/configured WF? DAT2 capture modes
│ immediate mode preserves stopped frames by skipping WFSU
▼
tcp_transport.py — RawTcpTransport
│ socket-level SCPI, IEEE 488.2 binary block parser,
│ thread-safe (RLock), pre-query socket flush
▼
auto_setup.py — compatibility wrapper for historical auto_find_waveform API
SIGLENT SDS824X HD oscilloscope (LAN port 5025)Command verification pipeline
candidate → official-doc → tested → implemented → safe-toolTracked in docs/sds824x-hd-command-matrix.md. Do NOT expose an untested command as a default MCP tool.
Key design decisions
Measurement-driven auto setup
SDS800XHDTcpAdapter.auto_setup() uses scope measurements (PKPK, MEAN, FREQ, PER, MAX, MIN) to select display settings. This avoids relying on a separate offline CSV analyzer for first-pass screen setup.
Weak periodic signal policy
noise_floor_v is treated as the strong-signal threshold. A lower-amplitude signal can still be accepted when the scope reports a valid FREQ or PER and PKPK >= min_signal_vpp. This handles real field observations such as a stable 7.89 kHz signal with only about 22.5 mV peak-to-peak.
WAVEDESC adaptive decode
WF? DAT2 returns 8-bit signed bytes. Voltage decode queries WF? DESC for the WAVEDESC descriptor and uses the descriptor-derived codes_per_div with current panel VDIV? / OFST? for decoding.
Timebase and dt policy
DAT2 timing should use WAVEDESC HORIZ_INTERVAL whenever available. SARA? is recorded as metadata and only used as a fallback. Metadata warnings are emitted when dt_source falls back to SARA or TDIV because UART/protocol decoding can be wrong if the fallback does not match the DAT2 memory interval.
Min/max envelope decimation
When max_points < raw sample count, each bucket outputs min + max voltages instead of naive stride-sampling. Preserves glitches/spikes stride would miss.
ARM/STOP behaviour
get_waveform_tcp immediate mode freezes the current frame with STOP and reads DAT2 directly. This is the default for intermittent signals. The older WFSU path is available only through capture_mode="configured".
Trigger level policy
C?:TRLV <level> is a known issue on SDS824X HD firmware 4.8.12.1.1.6.5. Display-oriented auto setup does not depend on this command by default. set_trigger_level=true must be requested explicitly.
Project structure
src/siglent_sds_mcp/
server.py — MCP tools, auto-reconnect, FastMCP
sds_tcp_adapter.py — Command adapter, WAVEDESC decode, envelope, auto_setup
waveform_capture.py — WF? DAT2 capture modes, immediate skips WFSU
tcp_transport.py — Raw TCP socket, lock, binary block parser
auto_setup.py — Compatibility wrapper for auto_find_waveform API
uart_analyzer.py — Offline UART CSV analyzer and 8N1 byte decoder
rs485_analyzer.py — RS485 differential pair analyzer
modbus_timing.py — Modbus RTU timing calculator
report.py — Markdown field report generator
artifacts.py — Timestamped artifact paths, JSON writer
transport.py — PyVISA fallback (legacy, not wired into MCP)
scope_driver.py — SiglentSDSDriver with safety gate (legacy)
docs/
architecture.md — Layered design, UART capture reference
sds824x-hd-command-matrix.md — Per-command verification status
sds824x-hd-knowledge-base.md — Instrument-specific knowledge
verification-workflow.md — Hardware verification procedure
tests/ — pytest, parser tests, TCP transport tests, auto setup helper tests
examples/ — auto_find_waveform_tcp, TCP IDN probe, waveform/RS485 captureSafety model
Allowed | Blocked |
|
|
Channel/timebase/trigger setup | Firmware update |
Measurement query | Network config changes |
Screenshot/waveform fetch | File deletion/formatting |
Offline waveform analysis | Arbitrary SCPI writes |
Raw SCPI writes are NOT exposed as MCP tools. safe_scpi_query_tcp only accepts ?-suffixed commands.
Test coverage
pytest -qKey test areas:
test_unit_parsing.py—_parse_voltage,_parse_time,_parse_sample_ratetest_wavedesc.py/test_wavedesc_parser.py— synthetic WAVEDESC decode, ASCII prefix handlingtest_tcp_binary_prefix.py—query_binaryIEEE 488.2 / BMP prefix skippingtest_auto_setup.py—_pick_vdiv,_pick_tdiv, measurement parser and SCPI number formattingtest_auto_find_compat.py— weak periodic detection, screen hold, screenshot artifact, compatibility parameterstest_waveform_capture_modes.py— immediate mode skips WFSU; configured mode sends WFSU with warningtest_uart_decoder.py— UART 8N1 byte decoding, hex/ascii output, low-Vpp thresholdingtest_tcp_transport_parser.py— socketpair binary block parsing
Target device
SIGLENT SDS824X HD / SDS800X HD family
SCPI over raw TCP, port 5025
Firmware verified: 4.8.12.1.1.6.5
Reference
MagnusJohansson/siglent-sds-mcp— upstream SIGLENT SDS MCP reference (SDS1104X-E class)
Available Tools
20 toolsanalyze_rs485_pair_csv_fileC
Analyze two CSV waveforms as RS485 A/B and compute Vdiff = VA - VB.
Inputs: csv_a_path (required), csv_b_path (required), baudrate, threshold_v. Returns: object
analyze_uart_csv_fileC
Analyze a two-column UART waveform CSV: time_s, voltage_v.
Inputs: csv_path (required), baudrate. Returns: object
auto_find_waveform_tcpD
Backwards-compatible multi-channel auto setup entry point.
Inputs: probe, channels, max_points, signal_hint, +7 more. Returns: object
auto_setup_tcpC
Auto setup one channel and leave the waveform visible by default.
Inputs: probe, channel, settle_s, signal_hint, +4 more. Returns: object
capture_uart_2mbps_tcpC
One-shot candidate workflow for 2 Mbps UART capture and CSV analysis.
Inputs: channel, max_points, logic_level. Returns: object
capture_uart_auto_tcpA
Capture UART waveform and auto-decode with full self-calibration.
Features
P1: VDIV/OFST auto-ranging from live MAX/MIN measurement.
P2: Baud-rate auto-detection from run-length statistics (baudrate=0).
P3: Noise-trigger retry: re-ARMs when PKPK < min_pkpk_v.
P4: TDIV auto-calculated to fit max_bytes at the given/detected baud rate.
P5: cpd sanity-check: re-derives codes-per-div when WAVEDESC value is off.
Parameters
channel: Oscilloscope channel (default C1). baudrate: Nominal baud rate. 0 = auto-detect. probe_attn: Probe attenuation factor (1 or 10). max_bytes: Estimated maximum message length in bytes (for TDIV sizing). timeout_s: Seconds to wait for a valid trigger. max_trigger_attempts: Re-ARM attempts before giving up. min_pkpk_v: Minimum PKPK (V) to accept a trigger as genuine.
Inputs: channel, baudrate, max_bytes, timeout_s, +3 more. Returns: object
configure_acquisition_tcpD
Configure acquisition/timebase/trigger using SDS-style candidate commands.
Inputs: command, timebase, trigger_mode, trigger_delay, +3 more. Returns: object
configure_channel_tcpC
Configure a channel using SDS-style TCP SCPI candidate commands.
Inputs: vdiv, probe, trace, offset, +3 more. Returns: object
connect_tcpC
Connect to the oscilloscope through raw TCP SCPI socket.
Inputs: host (required), port, timeout_s, header_off. Returns: object
disconnect_tcpA
Disconnect the current raw TCP oscilloscope session.
Inputs: no named parameters. Returns: object
generate_reportB
Generate a Markdown field report from captured artifacts and JSON summaries.
Inputs: notes, title, scenario, scope_idn, +7 more. Returns: object
get_acquisition_status_tcpA
Query acquisition state, timebase, sample rate and trigger status.
Inputs: no named parameters. Returns: object
get_channel_tcpB
Query a channel configuration through the TCP adapter.
Inputs: channel. Returns: object
get_waveform_tcpC
Download waveform data and save CSV.
capture_mode="immediate" skips WFSU and reads WF? DAT2 from the current stopped frame. Use capture_mode="configured" only for stable/repetitive signals where WFSU-selected waveform memory is desired.
Inputs: channel, csv_path, max_points, capture_mode, +2 more. Returns: object
identify_tcpB
Query *IDN? through the connected raw TCP session.
Inputs: no named parameters. Returns: object
measure_tcpD
Take a measurement using SDS-style candidate commands.
Inputs: channel, parameter. Returns: object
modbus_rtu_timingA
Calculate Modbus RTU character time and silence intervals.
Inputs: parity, baudrate, data_bits, stop_bits. Returns: object
project_statusC
Return implementation status and verification boundary.
Inputs: no named parameters. Returns: object
safe_scpi_query_tcpA
Send a read-only SCPI query ending in '?' through raw TCP.
Inputs: command (required). Returns: object
screenshot_tcpC
Capture a screen image through candidate SCDP command.
Inputs: output_path, include_base64. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 20 tools
Most tools have clear, distinct purposes, but there is some overlap between auto_setup_tcp and auto_find_waveform_tcp, and between the two UART capture tools. However, detailed descriptions help differentiate them, so confusion is limited.
The '_tcp' suffix is consistently used for oscilloscope communication tools, but naming patterns vary (e.g., modbus_rtu_timing and project_status are noun-first, while others are verb-first). This mixed style is readable but not fully predictable.
With 20 tools, the set is at the heavy end for a specialized server, but each tool serves a specific function. Some tools like capture_uart_2mbps_tcp and auto_find_waveform_tcp feel niche or redundant, suggesting the count could be slightly trimmed.
Core oscilloscope operations (connect, configure, measure, capture, screenshot) are well covered, and there are dedicated analysis tools for UART, RS485, and Modbus. However, there is no explicit RS485 capture tool, and some operations like separate trigger configuration are bundled into broader tools, leaving minor gaps.
Maintenance
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.
- DNS-DATA RemoteDeprecatedcom.dns-data
Connect AI assistants to authorized Windows and macOS devices for files, commands, and management.
Connect Claude, Cursor, Codex, and other AI tools to your robotics mission data.
Zero-setup MCP gateway securely connecting AI to your tools with authentication and workflows
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server that enables AI assistants to control Siglent SDS oscilloscopes over a local network using SCPI commands. It allows users to measure signals, configure channel and acquisition settings, and capture waveforms or screenshots through natural language.1316 npm9MIT
- AlicenseNot gradedqualityDmaintenanceEnables 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
- FlicenseNot gradedqualityDmaintenanceEnables remote control of Siglent oscilloscopes via SCPI over TCP/IP, allowing natural language commands for configuration, measurements, and waveform data retrieval.-
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to control Rigol MSO5000 oscilloscopes through VISA, including acquisition, channels, trigger, timebase, waveform generator, display, and front-panel controls, with risk-based permission gating for direct SCPI operations.4MIT