mcpField
G
Generic SCPI Instrument

Generic SCPI Instrument

本地服务
github.com科研与教育235 周前更新

关于 Generic SCPI Instrument

Generic SCPI Instrument 是通过 VISA、TCP 或串行连接与 SCPI 仪器通信的 MCP 服务。它支持原始命令和可配置的允许、拒绝列表,并将单条查询读取与需客户端确认的写入分开。

主要功能

  1. 01通过 VISA、TCP 或串行连接
  2. 02识别仪器并列出 VISA 资源
  3. 03发送单条 SCPI 查询
  4. 04执行经过检查的命令批次
  5. 05读取二进制块和波形数据
  6. 06配置命令允许和拒绝列表

适用场景

  1. 01读取 SCPI 仪器的测量值
  2. 02获取二进制波形或轨迹数据
  3. 03限制 Agent 可执行的命令
  4. 04出现问题后应用已配置的安全状态

MCP 相关

向 MCP 客户端提供 SCPI 查询、写入、批处理、二进制块读取以及仪器安全和连接功能。读取仅接受单条查询;更改状态的工具需要客户端确认,并可受命令策略约束。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"k-dense-ai-labmcp-scpi": {
"command": "uvx",
"args": [
"labmcp-scpi"
],
"env": {
"LABMCP_ADDRESS": "<LABMCP_ADDRESS>",
"LABMCP_SIMULATE": "<LABMCP_SIMULATE>",
"LABMCP_READ_ONLY": "<LABMCP_READ_ONLY>",
"LABMCP_LIMITS": "<LABMCP_LIMITS>"
}
}
}
}
启动命令uvx labmcp-scpi
需要配置的环境变量
LABMCP_ADDRESSInstrument address, e.g. serial:///dev/ttyUSB0 or tcp://192.168.1.50:5025
LABMCP_SIMULATESet to 1 to use the built-in simulator (no hardware)
LABMCP_READ_ONLYSet to 1 to disable all state-changing tools
LABMCP_LIMITSSafety limit overrides, e.g. max_temperature_c=80

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypilabmcp-scpi0.1.3

工具

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。

连接仪器

  1. **仪器设置:**启用你要使用的远程接口。
    • **LAN:**设置固定 IP 地址。启用 VXI-11/HiSLIP(用于 VISA)或 SCPI 原始套接字服务器。许多仪器的套接字端口为 5025;请查看 LAN 设置页面或手册。
    • **USB:**选择 USBTMC /“USB device (TMC)”,不要选择“USB mass storage”或虚拟 COM 端口。
    • **GPIB:**记下仪器的 GPIB 地址。
    • **RS-232:**设置波特率、奇偶校验和握手方式;如果仪器要求选择语言,请选择 SCPI。
  2. **查找仪器:**运行 uvx labmcp ports,或让 Agent 运行 list_visa_resources。该工具无需 --address 即可运行,并通过 pyvisa-py 列出 VISA 资源;传入 backend=@ivi 可使用 NI-VISA 或其他厂商的 VISA 库。
  3. 测试连接:
    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=REGEXscpi_query、query_binary_block添加实验室认为有副作用的查询,例如 SMU 上的 ^(MEAS|READ)。此类查询必须通过 scpi_write 发送。
--option write_denylist=REGEX(别名 denylist)每个原始工具任何工具都不会发送匹配的命令。若两个名称设置了不同的模式,则会导致配置错误。
--option write_allowlist=REGEXscpi_write、scpi_batch、reset_instrument如果设置了此项,这些工具只能发送匹配的命令(scpi_query 接受的查询始终允许)。任何含有 ; 的消息都会被拒绝,即使它位于引号内也一样。
--option safe_state=MESSAGEapply_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_s300 sAgent 在请求 wait_operation_complete 时可指定的最长 *OPC? 等待时间
max_block_bytes16777216 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、用户定义序列)可能绕过它。请设置好仪器自身的保护限值。

硬件验证

型号固件接口验证者日期
尚无: 成为首位验证者

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。