loading…
Search for a command to run...
loading…
An MCP server that enables AI assistants to control Siglent SDS oscilloscopes over a local network using SCPI commands. It allows users to measure signals, conf
An 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.
A Model Context Protocol (MCP) server that lets AI assistants control Siglent oscilloscopes over your local network. Connect Claude to your bench and measure, capture, and configure your scope through natural language.
This MCP server communicates with Siglent SDS oscilloscopes via SCPI commands over TCP sockets (port 5025). No VISA drivers or NI-MAX installation required — just a network connection to your scope.

Oscilloscope display captured through the screenshot MCP tool.

Natural-language scope control and measurement workflow in the terminal.
Key features:
| Status | Model |
|---|---|
| Tested | SDS1104X-E |
| Expected to work | SDS1000X-E series (SDS1202X-E, SDS1204X-E, etc.) |
| May work | Other Siglent SDS models with SCPI over TCP support |
The server uses standard SCPI commands from the SDS1000X-E Programming Guide. Other Siglent models that support the same command set over port 5025 should work with little or no modification.
You need a Siglent oscilloscope accessible on your network (TCP port 5025). Pick one of the three options below and add the config to your .mcp.json (in your project directory, or ~/.claude/.mcp.json for global access).
Replace 192.168.1.126 with your scope's IP address.
No Node.js installation required. Works on Linux, macOS, and Windows (via WSL2 or Docker Desktop).
{
"mcpServers": {
"siglent-sds": {
"type": "stdio",
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"ghcr.io/magnusjohansson/siglent-sds-mcp:latest"
]
}
}
}
Requires Node.js 20+. Downloads and runs the package automatically.
{
"mcpServers": {
"siglent-sds": {
"type": "stdio",
"command": "npx",
"args": ["-y", "siglent-sds-mcp"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
git clone https://github.com/magnusjohansson/siglent-sds-mcp.git
cd siglent-sds-mcp
npm install
npm run build
{
"mcpServers": {
"siglent-sds": {
"type": "stdio",
"command": "node",
"args": ["/path/to/siglent-sds-mcp/build/index.js"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
Replace /path/to/siglent-sds-mcp with the actual path to your clone.
| Variable | Required | Default | Description |
|---|---|---|---|
SIGLENT_IP |
No | — | Oscilloscope IP address for auto-connect on startup |
SIGLENT_PORT |
No | 5025 |
TCP port (only change if your setup differs) |
If SIGLENT_IP is set, the server attempts to connect to the scope immediately after starting. This runs in the background and does not block the MCP server — Claude can start using other tools right away. If the scope is offline or unreachable, the server logs a warning and you can connect manually later using the connect tool.
If SIGLENT_IP is not set, the server starts without a scope connection. Use the connect tool to connect when ready.
The Quick Start examples above use Claude Code's .mcp.json format, which includes a "type": "stdio" field. Other AI clients use the same JSON structure but without the "type" field and with different config file locations.
Edit claude_desktop_config.json:
%APPDATA%\Claude\claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.json{
"mcpServers": {
"siglent-sds": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"ghcr.io/magnusjohansson/siglent-sds-mcp:latest"
]
}
}
}
{
"mcpServers": {
"siglent-sds": {
"command": "npx",
"args": ["-y", "siglent-sds-mcp"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
Note: You must fully restart Claude Desktop after changing the config file.
Edit one of:
~/.cursor/mcp.json (available across all projects).cursor/mcp.json (shared with your team via version control)You can also add servers through the UI: Settings > Cursor Settings > MCP > Add new global MCP server.
{
"mcpServers": {
"siglent-sds": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"ghcr.io/magnusjohansson/siglent-sds-mcp:latest"
]
}
}
}
{
"mcpServers": {
"siglent-sds": {
"command": "npx",
"args": ["-y", "siglent-sds-mcp"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
Edit mcp_config.json:
%USERPROFILE%\.codeium\windsurf\mcp_config.json~/.codeium/windsurf/mcp_config.jsonYou can also configure servers through the UI: Cascade panel > MCP icon > Manage MCP Servers > View raw config.
{
"mcpServers": {
"siglent-sds": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"ghcr.io/magnusjohansson/siglent-sds-mcp:latest"
]
}
}
}
{
"mcpServers": {
"siglent-sds": {
"command": "npx",
"args": ["-y", "siglent-sds-mcp"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
Configuration is managed through the IDE's UI:
... button at the top{
"mcpServers": {
"siglent-sds": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"ghcr.io/magnusjohansson/siglent-sds-mcp:latest"
]
}
}
}
{
"mcpServers": {
"siglent-sds": {
"command": "npx",
"args": ["-y", "siglent-sds-mcp"],
"env": {
"SIGLENT_IP": "192.168.1.126"
}
}
}
}
Replace 192.168.1.126 with your scope's IP address in all examples above.
ChatGPT Desktop only supports remote HTTPS MCP servers (called "connectors"), not local stdio servers. Since this MCP server uses stdio transport, it is not directly compatible with ChatGPT Desktop.
12 tools across 6 categories. See docs/tools-reference.md for full parameter details.
| Category | Tool | Description |
|---|---|---|
| Connection | connect |
Connect to oscilloscope over TCP |
disconnect |
Close the connection | |
identify |
Query device ID (manufacturer, model, serial, firmware) | |
| Channel | get_channel |
Read channel configuration (vdiv, offset, coupling, etc.) |
configure_channel |
Set vdiv, offset, coupling, bandwidth limit, trace, probe | |
| Acquisition | get_acquisition_status |
Read timebase, sample rate, trigger settings |
configure_acquisition |
Set timebase, trigger, run/stop/single | |
| Measurement | measure |
Read a measurement (frequency, Vpp, RMS, etc.) |
measure_statistics |
Enable/read/reset measurement statistics | |
| Waveform | get_waveform |
Download voltage/time data arrays |
screenshot |
Capture scope screen as PNG | |
| SCPI | scpi_query / scpi_command |
Send arbitrary SCPI commands |
You: What's the current setup on channel 1?
Claude calls
get_channelwithchannel: "C1"and returns the volts/div, offset, coupling, and other settings.
You: Measure the frequency and peak-to-peak voltage on channel 2.
Claude calls
measuretwice — once withparameter: "FREQ"and once withparameter: "PKPK"on channel C2 — and reports both values.
You: Download the waveform from channel 1 and tell me what you see.
Claude calls
get_waveformon C1, receives voltage/time data, and analyzes the signal shape, frequency, amplitude, and any anomalies.
You: Show me what the scope screen looks like right now.
Claude calls
screenshot, receives a base64 BMP image, and displays it inline.
You: Set up channel 1 for a 3.3V logic signal — DC coupling, 1V/div, trigger on the rising edge at 1.6V.
Claude calls
configure_channel(setting vdiv, coupling) andconfigure_acquisition(setting trigger source, level, slope) in sequence.
Claude Code <-- stdio/JSON-RPC --> siglent-sds-mcp <-- TCP/SCPI --> Oscilloscope:5025
Promise.all), the queue ensures they're sent sequentially.#9XXXXXXXXX + data bytes + \n\n). The connection layer detects and parses these automatically.code * (vdiv / 25) - offset, with two's complement handling for signed values.npm run build # Compile TypeScript
npm run watch # Watch mode — recompile on changes
npm run dev # Build and run
npm run inspector # Launch with MCP Inspector for debugging
Build the image locally:
docker build -t siglent-sds-mcp .
Then use the local image in your .mcp.json:
{
"mcpServers": {
"siglent-sds": {
"type": "stdio",
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "SIGLENT_IP=192.168.1.126",
"siglent-sds-mcp"
]
}
}
}
src/
index.ts # Entry point, MCP server setup
connection.ts # TCP socket manager with query queue
tools/
connection.ts # connect, disconnect, identify
channel.ts # get_channel, configure_channel
acquisition.ts # configure_acquisition, get_acquisition_status
measure.ts # measure, measure_statistics
waveform.ts # get_waveform, screenshot
scpi.ts # scpi_query, scpi_command
The scope isn't connected yet. Either set SIGLENT_IP in your .mcp.json env for auto-connect, or use the connect tool manually.
telnet <scope-ip> 5025 from your machine)Some SCPI queries can take a few seconds, especially on slower scope models. The default timeout is 5 seconds. For scpi_query, you can increase the timeout with the timeout_ms parameter.
By default, Docker containers can reach LAN devices via the bridge network (NAT). If the container can't connect to your scope:
telnet 192.168.1.126 5025--network host to the Docker args:"args": ["run", "--rm", "-i", "--network", "host", "-e", "SIGLENT_IP=192.168.1.126", "ghcr.io/magnusjohansson/siglent-sds-mcp:latest"]
Note: --network host does not work on macOS or Windows Docker Desktop.The published image supports linux/amd64 and linux/arm64. Docker should pull the correct one automatically. If you see an exec format error, pull explicitly:
docker pull --platform linux/amd64 ghcr.io/magnusjohansson/siglent-sds-mcp:latest
This shouldn't happen — the server sets CHDR OFF on connect. If you see command headers in responses, try disconnecting and reconnecting.
MIT — see LICENSE for details.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"siglent-sds-mcp": {
"command": "npx",
"args": []
}
}
}