siglent-sds-mcp
Click on "Install 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-mcpSetup 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: siglent-sds-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)
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/wolog1/siglent-sds-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server