Generic SCPI Instrument

io.github.K-Dense-AI由 GitHub 账号 K-Dense-AI 发布v0.1.3更新于 Oct 27, 2026

Generic MCP server for any SCPI instrument over VISA, TCP or serial, with command allow/deny lists.

已验证STDIO仅桌面开发者工具数据与分析

概览

AI 生成的概览

本地 MCP 服务器,让助手通过 VISA、TCP 或串口向几乎任何 SCPI 仪器发送查询与命令,并支持命令允许/拒绝列表。

可以做什么
  • 识别仪器身份、列出本机可见的 VISA 资源,并报告连接信息、只读状态与生效的安全限制
  • 发送单条只读 SCPI 查询,读取波形、截图等 IEEE 488.2 二进制块,可保存到文件
  • 发送 SCPI 程序消息或短命令序列、复位仪器、等待挂起操作完成
  • 通过设备清除或重连恢复卡住的仪器,并执行已配置的安全状态
  • 读取并清空仪器错误队列,查看原始命令与回复日志
  • 提供 SCPI 语法速查和当前命令策略
适用场景
适合让助手操作万用表、示波器、电源、源表、函数发生器等支持 SCPI 的台式仪器,尤其是没有官方 MCP 服务器的品牌。也适用于脚本化测量、波形采集和排查仪器错误。
运行要求
以 Python 包(uvx labmcp-scpi)在本地通过 stdio 运行,仅限桌面端。需在 LABMCP_ADDRESS 或地址参数中提供仪器地址,并具备可用的接口:GPIB、USBTMC、局域网 VXI-11/HiSLIP 或原始套接字、RS-232。依赖 PyVISA 及 VISA 后端,NI-VISA 可选。内置模拟器(LABMCP_SIMULATE)可在无硬件时测试。
安装前请注意
服务器发送原始 SCPI,命令可能改变仪器状态,包括打开输出;reset_instrument 与 scpi_write 被标为危险操作。它无法强制电压或电流限制,应在仪器本身设置保护。拒绝列表只做文本匹配,可能被厂商别名绕过。device_clear 不会关闭输出;对会输出能量的设备应配置安全状态。只读模式(LABMCP_READ_ONLY)会禁用改变状态的工具。目前仅在模拟器上测试,尚未在真实硬件上验证。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Generic SCPI Instrument,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

Generic SCPI Instrument — MCP Server

Let an AI agent talk to any IEEE 488.2 / SCPI instrument: multimeters, oscilloscopes, source-measure units, power supplies, electronic loads, function generators, spectrum analyzers and counters. It works over GPIB, USBTMC, LAN (VXI-11, HiSLIP, raw socket) and RS-232. Because the agent writes raw SCPI, the server puts the safety in the plumbing. The read path accepts only single queries. Anything that changes the instrument goes through tools the MCP client asks you to confirm. You can give the server command allow and deny lists and a safe-state command of your own.

Keysight or Rohde & Schwarz instrument? Use the vendor's official MCP server instead: Keysight MCP Server for Instrument Control or the MCP server that ships with RsInstrument (python -m RsInstrument.mcp). labmcp-scpi covers everything else: Tektronix/Keithley, Rigol, Siglent, SRS, Aim-TTi, B&K Precision, GW Instek, older HP/Agilent GPIB gear, and more.

Packagelabmcp-scpi
InstrumentsAny instrument that speaks SCPI or IEEE 488.2 common commands
InterfacesGPIB, USBTMC, LAN VXI-11 / HiSLIP (all via VISA), LAN raw socket (e.g. port 5025), RS-232 / USB-serial
ProtocolSCPI-99 / IEEE 488.2 (SCPI-99 standard, IVI Foundation); VISA via PyVISA
Status🧪 simulated: tested against a wire-level SCPI simulator, not yet verified on hardware. Report a hardware test

Try it without hardware

bash
uvx labmcp-scpi --simulate --check

The simulator is a small, generic bench instrument (*IDN? → LabMCP,SIM-DMM-PSU,SIM000001,1.0.0). It is a 0–30 V / 3 A supply driving a 100 Ω load, with a built-in DMM across the load. It supports MEASure:VOLTage:DC?, CONFigure + READ?/FETCh?, [SOURce:]VOLTage/CURRent, OUTPut[:STATe], TRIGger:COUNt, FORMat[:DATA] REAL,32|64 binary blocks, FORMat:BORDer, *ESR?/*STB?, and a 10-entry SYSTem:ERRor? queue (overflow gives -350). In --simulate mode, the safe state is OUTP OFF.

Connect your instrument

  1. Instrument setup: enable the remote interface you want to use.
    • LAN: set a fixed IP address. Enable VXI-11/HiSLIP (for VISA) or the SCPI raw-socket server. Many instruments use port 5025 for the socket; check the LAN settings page or the manual.
    • USB: select USBTMC / "USB device (TMC)", not "USB mass storage" or a virtual COM port.
    • GPIB: note the instrument's GPIB address.
    • RS-232: set the baud rate, parity and handshake, and select SCPI as the language if the instrument asks.
  2. Find it: uvx labmcp ports, or ask the agent to run list_visa_resources. That tool works without --address and lists VISA resources through pyvisa-py; pass backend=@ivi to use NI-VISA or another vendor VISA library.
  3. Test the connection:
    bash
    uvx labmcp-scpi --address visa://TCPIP0::192.168.1.50::inst0::INSTR --check      # LAN, VXI-11uvx labmcp-scpi --address visa://TCPIP0::192.168.1.50::hislip0::INSTR --check    # LAN, HiSLIPuvx labmcp-scpi --address tcp://192.168.1.50:5025 --check                        # raw socketuvx labmcp-scpi --address "visa://USB0::0x1AB1::0x0588::DS1ZA000000::INSTR" --checkuvx labmcp-scpi --address "visa://GPIB0::22::INSTR?backend=@ivi" --check         # NI-VISAuvx labmcp-scpi --address "serial:///dev/ttyUSB0?baudrate=9600&read_termination=CRLF" --check
    --check prints the parsed *IDN? reply. If it times out, check the terminator: SCPI uses LF by default, and some serial instruments need read_termination=CRLF. Also check the baud rate, and that the instrument is set to SCPI rather than an emulation language.

Add to your MCP client

Claude Code

bash
claude mcp add scope -- uvx labmcp-scpi --address visa://TCPIP0::192.168.1.50::inst0::INSTR

Claude Desktop / Cursor / Windsurf (claude_desktop_config.json, .cursor/mcp.json, …)

json
{  "mcpServers": {    "psu": {      "command": "uvx",      "args": [        "labmcp-scpi", "--address", "tcp://192.168.1.50:5025",        "--option", "safe_state=OUTP OFF",        "--option", "write_denylist=^OUTP\\d*(:STAT)? (?!OFF\\b)"      ]    }  }}

Add --read-only to allow only queries. In read-only mode scpi_write, scpi_batch and reset_instrument disappear. device_clear and apply_safe_state stay available. Run one server per instrument, each with its own key (scope, psu, dmm, …).

Tools

ToolKindDescription
apply_safe_state🛑 safetyPut the instrument into the lab's configured safe state (the --option safe_state program message, e.g. 'OUTP OFF'), then read the error queue. Only listed when a safe state is configured. Call it immediately if anything looks wrong.
device_clear🛑 safetyRecover a stuck or confused instrument: VISA device clear (or discard unread input on socket/serial links), report the error queue, optionally ABORt, then *CLS. This does NOT make an arbitrary instrument safe (outputs stay as they are): use apply_safe_state if the lab configured one, or the instrument's own controls.
get_command_log👁 readReturn the most recent raw commands sent to / replies received from the instrument (newest last). Useful for debugging and for recording what was done.
get_connection_info👁 readReport which instrument is connected (identity, address, simulated or real), whether the server is read-only, and the active safety limits. Call this first.
get_errors👁 readRead and clear the instrument's error/event queue (SYSTem:ERRor? until 0,"No error"). Entries are returned oldest first; each can only be read once. An empty list means no errors.
identify👁 readAsk the instrument who it is (*IDN?): manufacturer, model, serial number, firmware.
list_visa_resources👁 readList GPIB / USBTMC / LAN (VXI-11, HiSLIP) instruments visible to VISA on this computer. Works without --address. Raw-socket instruments (tcp://host:5025) are not discoverable.
query_binary_block👁 readRead an IEEE 488.2 definite-length binary block (waveforms, trace data, screenshots, FORMat REAL/INTeger readings). The query must pass the same read-only checks as scpi_query. Returns length, SHA-256 and (optionally) decoded values with summary statistics, downsampled to max_points; use save_path for the full data. Blocks larger than the max_block_bytes limit are discarded.
reconnect🛑 safetyClose and re-open the connection to the instrument (e.g. after it was power cycled or a cable was re-plugged).
reset_instrument⚠️ hazardReset the instrument to its default settings (*RST, then *CLS), wait for completion and check errors. SCPI requires outputs OFF after *RST, but every other setting (levels, ranges, triggers, limits) returns to its default and some instruments differ: check the manual before resetting anything connected to a device under test.
scpi_batch⚠️ hazardRun a short sequence of SCPI commands and queries in order, checking the error queue after every step. Every step is checked against the command policy BEFORE the first one is sent, so a refused step means nothing was sent. Returns per-step replies and errors. Steps not started within ~14 minutes are not sent (status not_run).
scpi_primer👁 readConcise SCPI syntax guide (long/short forms, queries, compound commands, common commands, error queue, binary blocks) plus this server's active command policy. Works without a connection.
scpi_query👁 readSend ONE read-only SCPI query and return the instrument's text reply.
scpi_write⚠️ hazardSend any SCPI program message (settings, compound 'A;B' messages, queries with side effects) and then read the error queue. If the message contains a query, its reply is returned. This can change the instrument's state, including switching outputs on; say what the command does before calling it. Commands in the lab's denylist, or outside its allowlist, are refused before anything is sent.
wait_operation_complete👁 readWait until the instrument has finished all pending operations (*OPC? returns 1), e.g. after starting a sweep, an acquisition or a settling source.

get_connection_info, get_command_log and reconnect are built into every LabMCP server. apply_safe_state is listed only when a safe state is configured.

Command policy

A generic server cannot know which SCPI commands are dangerous on your instrument. It enforces what it can and lets you add the rest:

RuleWhereWhat happens
Single query onlyscpi_query, query_binary_block (READ, allowed in read-only mode)The header must end in ? (parameters such as VOLT? MAX are fine). Messages with ;, line breaks or control characters are refused.
Built-in side-effect queriesscpi_query, query_binary_block*TST? (self-test), *CAL?, CALibration…? and DIAGnostic…? are refused here. They must go through scpi_write.
--option query_denylist=REGEXscpi_query, query_binary_blockExtra queries that your lab treats as having side effects, e.g. ^(MEAS|READ) on an SMU. They then need scpi_write.
--option write_denylist=REGEX (alias denylist)every raw toolNo tool ever sends a matching command. Setting both names to different patterns is a configuration error.
--option write_allowlist=REGEXscpi_write, scpi_batch, reset_instrumentIf set, these tools may only send commands that match (queries that scpi_query accepts are always allowed). Any message containing ; is refused, even inside quotes.
--option safe_state=MESSAGEapply_safe_state (SAFETY)The program message that makes your instrument safe, e.g. OUTP OFF. It is sent as-is and never blocked by the lists.
--option error_query=QUERYall writesError-queue query, default SYST:ERR?.

Matching rules:

  • Patterns are Python regular expressions, matched case-insensitively.
  • Each ;-separated message unit is checked in two forms. The first is the unit as sent, upper-cased, with collapsed whitespace and no leading colon. The second reduces every mnemonic to its SCPI short form (SCPI-99 Vol. 1 §6.2.1): :OUTPut1:STATe ON becomes OUTP1:STAT ON. So ^OUTP\d*(:STAT)? (?!OFF\b) catches OUTP ON, outp:stat 1, VOLT 5;:OUTPut:STATe ON and OUTPut2 ON.
  • SCPI booleans accept any number (it is rounded, and anything non-zero means ON), so OUTP 2, OUTP 1.0 and OUTP #H1 also switch an output on. Deny "everything except OFF", as above, rather than listing (ON|1).
  • The denylist uses re.search. It also resolves relative headers (OUTP:POL NORM;STAT ON is checked as OUTP:STAT ON) and splits at every ;, even inside quotes. The allowlist must match a whole unit.
  • Every step of scpi_batch is checked before the first step is sent.

Examples:

bash
# Power supply: the agent may set levels and switch the output OFF, but only a human switches it on--option 'write_denylist=^OUTP\d*(:STAT)? (?!OFF\b)' --option 'safe_state=OUTP OFF'# DMM: allow measurement configuration only--option 'write_allowlist=(CONF|SENS|TRIG|INIT|FORM|ABOR)(:\S+)*( .*)?'# SMU: measuring can switch the output on, so require confirmation for it--option 'query_denylist=^(MEAS|READ)' --option 'safe_state=OUTP OFF'

The environment variable LABMCP_OPTIONS splits on commas. For regular expressions that contain commas, pass them on the command line or give LABMCP_OPTIONS as a JSON object ({"write_denylist": "..."}).

Safety limits

LimitDefaultMeaning
max_operation_wait_s300 sLongest *OPC? wait an agent may request (wait_operation_complete)
max_block_bytes16777216 bytesLargest binary block the server keeps. The size is checked from the block header; a larger payload is thrown away as it arrives (VISA: device clear) and never held in memory.

Override at launch: --limit max_block_bytes=67108864. This server has no voltage or current limits because it cannot interpret arbitrary commands. Set limits on the instrument itself (OVP/OCP, compliance, output protection), use a denylist, or use an instrument-specific server.

Example prompts

  • "What instrument is connected? Read its identity and check the error queue."
  • "Configure the DMM for DC volts on the 10 V range, take 20 readings, and give me the mean and standard deviation."
  • "Set the supply to 3.3 V with a 200 mA current limit, read both back, but don't enable the output yet."
  • "Grab channel 1's waveform from the scope as a binary block, save it to ~/data/ch1.csv, and summarise min, max and mean."
  • "We got a -222 error. What does it mean, and which of the last commands caused it?"
  • "Something's wrong: apply the safe state, then clear the interface."

Notes

  • A generic server cannot make an arbitrary instrument safe. device_clear does four things: a VISA device clear (on raw socket and serial links it only discards unread input), reads the error queue, sends ABORt, and sends *CLS. It recovers communication and stops sweeps. It does not switch outputs off. Configure safe_state for anything that sources energy. For hazardous gear, use an instrument-specific LabMCP server where one exists: it can enforce real setpoint limits.
  • Queries are not always read-only. On source-measure units such as the Keithley 2400, MEASure?, READ?, INITiate and CONFigure can switch the source output on (Keithley 2400 Series SourceMeter User's Manual, 2400S-900-01 Rev. G, §11 and §17). In --read-only mode, scpi_query therefore refuses MEASure? and READ? by default, while FETCh? still returns the last reading. Set --option allow_measure_in_read_only=true if the instrument is a meter that cannot source. When not read-only, add --option query_denylist=^(MEAS|READ) for SMUs so these commands need confirmation through scpi_write.
  • *RST: SCPI-99 Vol. 2 §15.12 requires OUTPut:STATe OFF after *RST. But *RST also resets levels, ranges, limits and trigger settings, and not every instrument complies.
  • The error queue is read (and so cleared) after every scpi_write/scpi_batch step. The errors appear in the result. A query the instrument doesn't recognise produces no reply: the server times out (5 s by default, --timeout to change), resynchronises, and reports the -113 from the queue.
  • Instruments that don't implement SYSTem:ERRor? (some older IEEE 488.2-only gear) report error_check: "unavailable". Set --option error_query=… if your instrument uses a different error query.
  • query_binary_block reads definite-length blocks (#<n><len><data>) only. Indefinite #0 blocks are refused. Byte order follows FORMat:BORDer (NORMal = big-endian). timeout_s covers the whole transfer. Decoded NaN and infinite values are returned as null (and counted in non_finite); the saved CSV keeps them as nan/inf.
  • save_path must end in .csv (decoded values with decode_as, otherwise the raw bytes), .bin, .dat, .raw, .txt or an image extension (.png, .bmp, .jpg, .jpeg, .gif, .tif, .tiff). ~ is expanded and missing folders are created. An existing file is never replaced unless you pass overwrite=true, and the check happens before anything is sent to the instrument.
  • scpi_batch stops starting new steps after about 14 minutes (its tool timeout is 15 minutes). Steps that were not sent are marked not_run.
  • Text is sent as ASCII. Commands with control or non-ASCII characters are refused, and the server adds the LF terminator.
  • A denylist is a guard rail, not a guarantee. It matches text, so vendor-specific aliases or macros (*DMC, user-defined sequences) can evade it. Keep the instrument's own protection limits set.

Hardware verification

ModelFirmwareInterfaceVerified byDate
none yet: be the first

来源:servers/protocols/scpi-instrument/README.md,提交 46545ea

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

2
  1. v0.1.3最新Sep 27, 2026
  2. v0.1.1Sep 26, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分