关于 Generic SCPI Instrument
Generic SCPI Instrument 是通过 VISA、TCP 或串行连接与 SCPI 仪器通信的 MCP 服务。它支持原始命令和可配置的允许、拒绝列表,并将单条查询读取与需客户端确认的写入分开。
主要功能
- 01通过 VISA、TCP 或串行连接
- 02识别仪器并列出 VISA 资源
- 03发送单条 SCPI 查询
- 04执行经过检查的命令批次
- 05读取二进制块和波形数据
- 06配置命令允许和拒绝列表
适用场景
- 01读取 SCPI 仪器的测量值
- 02获取二进制波形或轨迹数据
- 03限制 Agent 可执行的命令
- 04出现问题后应用已配置的安全状态
MCP 相关
向 MCP 客户端提供 SCPI 查询、写入、批处理、二进制块读取以及仪器安全和连接功能。读取仅接受单条查询;更改状态的工具需要客户端确认,并可受命令策略约束。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx labmcp-scpiLABMCP_ADDRESSInstrument address, e.g. serial:///dev/ttyUSB0 or tcp://192.168.1.50:5025LABMCP_SIMULATESet to 1 to use the built-in simulator (no hardware)LABMCP_READ_ONLYSet to 1 to disable all state-changing toolsLABMCP_LIMITSSafety limit overrides, e.g. max_temperature_c=80本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
14收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
通用 SCPI 仪器 — MCP 服务
让 AI Agent 与任何 IEEE 488.2 / SCPI 仪器对话:万用表、示波器、源测量单元、电源、电子负载、函数发生器、频谱分析仪和计数器。它支持 GPIB、USBTMC、LAN(VXI-11、HiSLIP、原始套接字)和 RS-232。由于 Agent 会直接写入原始 SCPI 命令,服务会在底层提供安全保障。读取路径只接受单条查询。任何会更改仪器状态的操作,都必须通过 MCP 客户端请求你确认的工具执行。你可以为服务设置命令允许列表和拒绝列表,以及自定义安全状态命令。
使用 Keysight 或 Rohde & Schwarz 仪器? 请改用厂商的官方 MCP 服务:Keysight MCP Server for Instrument Control 或随 RsInstrument 提供的 MCP 服务(
python -m RsInstrument.mcp)。labmcp-scpi适用于其他所有设备:Tektronix/Keithley、Rigol、Siglent、SRS、Aim-TTi、B&K Precision、GW Instek、较老的 HP/Agilent GPIB 设备等。
| 软件包 | labmcp-scpi |
| 仪器 | 任何支持 SCPI 或 IEEE 488.2 通用命令的仪器 |
| 接口 | GPIB、USBTMC、LAN VXI-11 / HiSLIP(均通过 VISA)、LAN 原始套接字(例如端口 5025)、RS-232 / USB 串口 |
| 协议 | SCPI-99 / IEEE 488.2(SCPI-99 标准,IVI Foundation);VISA 通过 PyVISA |
| 状态 | 🧪 模拟测试:已通过线级 SCPI 模拟器测试,尚未在硬件上验证。报告硬件测试结果 |
无需硬件即可试用
uvx labmcp-scpi --simulate --check
模拟器是一个小型通用台式仪器(*IDN? → LabMCP,SIM-DMM-PSU,SIM000001,1.0.0)。它是一台 0–30 V / 3 A 电源,为 100 Ω 负载供电,并内置跨接负载的 DMM。它支持 MEASure:VOLTage:DC?、CONFigure + READ?/FETCh?、[SOURce:]VOLTage/CURRent、OUTPut[:STATe]、TRIGger:COUNt、FORMat[:DATA] REAL,32|64 二进制数据块、FORMat:BORDer、*ESR?/*STB?,以及一个包含 10 条记录的 SYSTem:ERRor? 队列(溢出时返回 -350)。在 --simulate 模式下,安全状态为 OUTP OFF。
连接仪器
- **仪器设置:**启用你要使用的远程接口。
- **LAN:**设置固定 IP 地址。启用 VXI-11/HiSLIP(用于 VISA)或 SCPI 原始套接字服务器。许多仪器的套接字端口为 5025;请查看 LAN 设置页面或手册。
- **USB:**选择 USBTMC /“USB device (TMC)”,不要选择“USB mass storage”或虚拟 COM 端口。
- **GPIB:**记下仪器的 GPIB 地址。
- **RS-232:**设置波特率、奇偶校验和握手方式;如果仪器要求选择语言,请选择 SCPI。
- **查找仪器:**运行
uvx labmcp ports,或让 Agent 运行list_visa_resources。该工具无需--address即可运行,并通过 pyvisa-py 列出 VISA 资源;传入backend=@ivi可使用 NI-VISA 或其他厂商的 VISA 库。 - 测试连接:
uvx labmcp-scpi --address visa://TCPIP0::192.168.1.50::inst0::INSTR --check # LAN, VXI-11 uvx labmcp-scpi --address visa://TCPIP0::192.168.1.50::hislip0::INSTR --check # LAN, HiSLIP uvx labmcp-scpi --address tcp://192.168.1.50:5025 --check # raw socket uvx labmcp-scpi --address "visa://USB0::0x1AB1::0x0588::DS1ZA000000::INSTR" --check uvx labmcp-scpi --address "visa://GPIB0::22::INSTR?backend=@ivi" --check # NI-VISA uvx labmcp-scpi --address "serial:///dev/ttyUSB0?baudrate=9600&read_termination=CRLF" --check--check会输出解析后的*IDN?响应。如果超时,请检查终止符:SCPI 默认使用 LF,某些串口仪器需要设置read_termination=CRLF。同时检查波特率,以及仪器是否设置为 SCPI 而非仿真语言。
添加到 MCP 客户端
Claude Code
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 等)
{
"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)"
]
}
}
}
添加 --read-only 以仅允许查询。在只读模式下,scpi_write、scpi_batch 和 reset_instrument 将不可用。device_clear 和 apply_safe_state 仍可用。每台仪器运行一个服务,并为每个服务设置独立的键(scope、psu、dmm 等)。
工具
| 工具 | 类型 | 描述 |
|---|---|---|
apply_safe_state | 🛑 安全 | 将仪器置于实验室配置的安全状态(即 --option safe_state 程序消息,例如 'OUTP OFF'),然后读取错误队列。仅在配置了安全状态时列出。如果发现任何异常,请立即调用。 |
device_clear | 🛑 安全 | 恢复卡住或状态混乱的仪器:执行 VISA 设备清除(或丢弃套接字/串行链路上未读取的输入),报告错误队列,可选执行 ABORt,然后执行 *CLS。这不会让任意仪器进入安全状态(输出保持原样):如果实验室配置了安全状态,请使用 apply_safe_state;否则使用仪器自身的控制功能。 |
get_command_log | 👁 读取 | 返回最近发送到仪器的原始命令和收到的回复(最新记录在最后)。有助于调试和记录操作。 |
get_connection_info | 👁 读取 | 报告已连接的仪器(身份、地址、模拟或真实)、服务是否为只读,以及当前生效的安全限制。请先调用此工具。 |
get_errors | 👁 读取 | 读取并清除仪器的错误/事件队列(持续查询 SYSTem:ERRor?,直到返回 0,"No error")。条目按从旧到新的顺序返回;每条只能读取一次。空列表表示没有错误。 |
identify | 👁 读取 | 询问仪器的身份(*IDN?):制造商、型号、序列号、固件。 |
list_visa_resources | 👁 读取 | 列出此计算机上 VISA 可见的 GPIB/USBTMC/LAN(VXI-11、HiSLIP)仪器。无需 --address 即可使用。原始套接字仪器(tcp://host:5025)无法发现。 |
query_binary_block | 👁 读取 | 读取 IEEE 488.2 定长二进制块(波形、轨迹数据、屏幕截图、FORMat REAL/INTeger 读数)。查询必须通过与 scpi_query 相同的只读检查。返回长度、SHA-256,以及(可选)解码后的值和摘要统计信息;值会降采样至 max_points;完整数据请使用 save_path。超过 max_block_bytes 限制的块会被丢弃。 |
reconnect | 🛑 安全 | 关闭并重新打开与仪器的连接(例如仪器断电重启或重新插拔电缆后)。 |
reset_instrument | ⚠️ 危险 | 将仪器重置为默认设置(*RST,然后 *CLS),等待操作完成并检查错误。SCPI 要求执行 *RST 后关闭输出,但其他所有设置(电平、量程、触发器、限值)都会恢复为默认值,而且不同仪器的行为可能不同:重置任何连接到被测设备的仪器前,请先查阅手册。 |
scpi_batch | ⚠️ 危险 | 按顺序运行一组简短的 SCPI 命令和查询,并在每一步后检查错误队列。所有步骤都会在发送第一条命令之前根据命令策略进行检查,因此只要有一步被拒绝,就不会发送任何命令。返回每一步的回复和错误。约 14 分钟内未开始的步骤不会发送(状态为 not_run)。 |
scpi_primer | 👁 读取 | 简明的 SCPI 语法指南(长/短格式、查询、复合命令、常用命令、错误队列、二进制块),以及此服务当前生效的命令策略。无需连接即可使用。 |
scpi_query | 👁 读取 | 发送一条只读 SCPI 查询,并返回仪器的文本回复。 |
scpi_write | ⚠️ 危险 | 发送任意 SCPI 程序消息(设置、复合 'A;B' 消息、有副作用的查询),然后读取错误队列。如果消息包含查询,则返回其回复。这可能会改变仪器状态,包括打开输出;调用前请说明命令的作用。实验室拒绝列表中的命令,或不在允许列表中的命令,会在发送前被拒绝。 |
wait_operation_complete | 👁 读取 | 等待仪器完成所有待处理操作(*OPC? 返回 1),例如开始扫描、采集或等待信号源稳定后。 |
get_connection_info、get_command_log 和 reconnect 内置于每个 LabMCP 服务中。仅在配置了安全状态时才会列出 apply_safe_state。
命令策略
通用服务无法知道哪些 SCPI 命令会对你的仪器造成危险。它会执行力所能及的限制,并允许你添加其他限制:
| 规则 | 适用位置 | 处理方式 |
|---|---|---|
| 仅允许单条查询 | scpi_query、query_binary_block(READ,在只读模式下允许) | 命令头必须以 ? 结尾(VOLT? MAX 之类的参数也可以)。含有 ;、换行符或控制字符的消息会被拒绝。 |
| 内置副作用查询 | scpi_query、query_binary_block | *TST?(自检)、*CAL?、CALibration…? 和 DIAGnostic…? 在这里会被拒绝,必须通过 scpi_write 发送。 |
--option query_denylist=REGEX | scpi_query、query_binary_block | 添加实验室认为有副作用的查询,例如 SMU 上的 ^(MEAS|READ)。此类查询必须通过 scpi_write 发送。 |
--option write_denylist=REGEX(别名 denylist) | 每个原始工具 | 任何工具都不会发送匹配的命令。若两个名称设置了不同的模式,则会导致配置错误。 |
--option write_allowlist=REGEX | scpi_write、scpi_batch、reset_instrument | 如果设置了此项,这些工具只能发送匹配的命令(scpi_query 接受的查询始终允许)。任何含有 ; 的消息都会被拒绝,即使它位于引号内也一样。 |
--option safe_state=MESSAGE | apply_safe_state(SAFETY) | 让你的仪器进入安全状态的程序消息,例如 OUTP OFF。此消息会原样发送,且不会被列表拦截。 |
--option error_query=QUERY | 所有写入操作 | 错误队列查询,默认为 SYST:ERR?。 |
匹配规则:
- 模式是 Python 正则表达式,匹配时不区分大小写。
- 每条以
;分隔的消息单元都会按两种形式检查。第一种是发送时的单元,转换为大写、合并空白字符并去掉开头的冒号。第二种会将每个助记符缩短为 SCPI 短格式(SCPI-99 Vol. 1 §6.2.1)::OUTPut1:STATe ON会变为OUTP1:STAT ON。因此,^OUTP\d*(:STAT)? (?!OFF\b)会匹配OUTP ON、outp:stat 1、VOLT 5;:OUTPut:STATe ON和OUTPut2 ON。 - SCPI 布尔值接受任意数字(会进行四舍五入,任何非零值都表示 ON),因此
OUTP 2、OUTP 1.0和OUTP #H1也会打开输出。应像上面那样拒绝“除 OFF 以外的所有值”,而不是只列出(ON|1)。 - 拒绝列表使用
re.search。它还会解析相对命令头(OUTP:POL NORM;STAT ON会按OUTP:STAT ON检查),并在每个;处分割,即使它位于引号内也一样。允许列表必须匹配完整的单元。 scpi_batch的每个步骤都会在发送第一步之前检查完毕。
示例:
# 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'
环境变量 LABMCP_OPTIONS 会按逗号分割。对于包含逗号的正则表达式,请在命令行中传入,或将 LABMCP_OPTIONS 指定为 JSON 对象({"write_denylist": "..."})。
安全限制
| 限制 | 默认值 | 含义 |
|---|---|---|
max_operation_wait_s | 300 s | Agent 在请求 wait_operation_complete 时可指定的最长 *OPC? 等待时间 |
max_block_bytes | 16777216 bytes | 服务保留的最大二进制块大小。系统会根据块头检查大小;较大的负载会在到达时被丢弃(VISA:device clear),且绝不会存入内存。 |
启动时覆盖:--limit max_block_bytes=67108864。此服务不设电压或电流限制,因为它无法解析任意命令。请在仪器本身设置限制(OVP/OCP、顺应性、输出保护),使用拒绝列表,或使用特定仪器的服务。
示例提示词
- “连接的仪器是什么?读取其标识信息并检查错误队列。”
- “将 DMM 配置为直流电压、10 V 量程,读取 20 次,并告诉我平均值和标准差。”
- “将电源设为 3.3 V、电流限值设为 200 mA,分别读取这两个值,但暂时不要启用输出。”
- “以二进制块形式获取示波器通道 1 的波形,将其保存到 ~/data/ch1.csv,并汇总最小值、最大值和平均值。”
- “我们收到一个 -222 错误。它是什么意思?最近哪些命令导致了这个错误?”
- “出了点问题:先应用安全状态,然后清除接口。”
注意事项
- 通用服务无法保证任意仪器处于安全状态。
device_clear会执行四项操作:VISA 设备清除(对于原始套接字和串行链路,它只会丢弃未读取的输入)、读取错误队列、发送ABORt,以及发送*CLS。它会恢复通信并停止扫描,但不会关闭输出。对于任何会输出能量的设备,请配置safe_state。对于危险设备,如果有对应的专用 LabMCP 服务,请使用它:它可以强制执行实际的设定值限制。 - 查询不一定是只读操作。 对于 Keithley 2400 等源测量单元,
MEASure?、READ?、INITiate和CONFigure可能会打开源输出(Keithley 2400 Series SourceMeter User's Manual,2400S-900-01 Rev. G,第 11 和 17 节)。因此,在--read-only模式下,scpi_query默认会拒绝MEASure?和READ?,而FETCh?仍会返回上次读数。如果仪器是无法输出的电表,请设置--option allow_measure_in_read_only=true。非只读模式下,对于 SMU,请添加--option query_denylist=^(MEAS|READ),以要求这些命令通过scpi_write确认后才能执行。 *RST:SCPI-99 Vol. 2 第 15.12 节要求在*RST后执行OUTPut:STATe OFF。但*RST也会重置电平、量程、限值和触发设置,而且并非所有仪器都遵循此要求。- 每个
scpi_write/scpi_batch步骤执行后,都会读取(从而清空)错误队列。错误会显示在结果中。如果仪器无法识别某个查询,就不会返回任何内容:服务会超时(默认 5 s,可通过--timeout更改)、重新同步,并报告错误队列中的-113。 - 未实现
SYSTem:ERRor?的仪器(某些较旧的仅支持 IEEE 488.2 的设备)会报告error_check: "unavailable"。如果你的仪器使用不同的错误查询,请设置--option error_query=…。 query_binary_block只读取确定长度的数据块(#<n><len><data>)。不接受不定长度的#0数据块。字节顺序遵循FORMat:BORDer(NORMal = 大端序)。timeout_s覆盖整个传输过程。解码后的 NaN 和无穷值会以null返回(并计入non_finite);保存的 CSV 中会保留为nan/inf。save_path必须以.csv(使用decode_as解码后的值,否则为原始字节)、.bin、.dat、.raw、.txt或图像扩展名(.png、.bmp、.jpg、.jpeg、.gif、.tif、.tiff)结尾。系统会展开~并创建缺失的文件夹。除非传入overwrite=true,否则不会替换已有文件;且会在向仪器发送任何内容之前进行检查。scpi_batch大约 14 分钟后会停止启动新步骤(其工具超时时间为 15 分钟)。未发送的步骤会标记为not_run。- 文本以 ASCII 格式发送。包含控制字符或非 ASCII 字符的命令会被拒绝,服务会添加 LF 终止符。
- 拒绝列表是防护措施,并非万无一失。它通过匹配文本进行判断,因此厂商特有的别名或宏(
*DMC、用户定义序列)可能绕过它。请设置好仪器自身的保护限值。
硬件验证
| 型号 | 固件 | 接口 | 验证者 | 日期 |
|---|---|---|---|---|
| 尚无: 成为首位验证者 |
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。