Modbus TCP MCP服务器

一个为Modbus TCP设备提供语义化寄存器映射和自然语言控制的MCP服务器,支持YAML设备配置和内置模拟器。

  • by KerberosClaw
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 KerberosClaw/kc_modbus_mcp

使用说明

“读取出厂温度”--Modbus MCP

正体中文

看,没人想记住那个登记簿 40001 是温度传感器。生命太短暂,Modbus地址太多。这是一个用于Modbus TCP设备的MCP服务器——您可以在YAML中定义设备配置文件,然后AI代理可以像文明人一样按名称读/写PLC寄存器。

它还附带了 内置模拟器,因为我们都知道你的桌子上没有PLC。(如果你这样做,请拂去灰尘。)


为什么存在

我一直在查看现有的Modbus MCP服务器,并不断发现同样的四个令人失望的地方:

  1. 无语义寄存器映射 --人工智能必须知道原始地址,比如 40001要求它“读取温度”会让你一脸茫然。
  2. 无数据类型转换 --所有内容都以原始uint16的形式返回,因为显然float32太花哨了。
  3. 无内置模拟器 --想测试吗?去买硬件。或者乞求同事。或者盯着天花板看。
  4. 无设备配置文件 --无法预先配置连接细节和注册映射,因此您可以像1998年一样一遍又一遍地键入相同的主机/端口/slave_id。

所以我做了不合理的事情,自己修好了这四个。


建筑

User (CLI / Chat / OpenClaw)
  → AI Agent (Claude / OpenClaw / etc.)
    → MCP Protocol (Streamable HTTP)
      → kc_modbus_mcp (FastMCP Server)
        → Profile Manager (YAML device profiles)
        → pymodbus (async Modbus TCP client)
      → Modbus TCP Device / Built-in Simulator

特性

  • 自然语言控制 --“读取出厂温度”就行了。显示器上没有粘贴地址查找表。
  • YAML设备配置文件 --将寄存器名称映射到地址、数据类型、单位和缩放比例。最后,配置读起来像英语。
  • 8个MCP工具 --5个基于配置文件的+3个原始模式,用于需要完全黑客的时候。
  • 自动数据类型转换 --float32、int32、uint16、bool——支持字节顺序和小数位数,因为凌晨2点在脑子里做算术运算不是一种性格特征。
  • 内置Modbus TCP模拟器 --正弦波温度、随机湿度/压力、可写线圈。你想象中的工厂做得很好。
  • Docker就绪 -- docker compose up -d 你在做生意。两个集装箱,零借口。
  • OpenClaw技能 --为喜欢命令行生活方式的本地LLM代理编写包装器脚本。

演示


安全通知: 这是一个为可信局域网环境设计的POC/开发项目。MCP服务器未实现身份验证。原始模式允许对任何可访问的Modbus设备进行读/写访问。在没有额外安全措施的情况下,不要将服务端口暴露给公共互联网。

快速开始

三个端子,五分钟,无需焊接。

1.克隆并安装

git clone https://github.com/KerberosClaw/kc_modbus_mcp.git
cd kc_modbus_mcp
uv sync

2.启动模拟器

uv run python simulator.py
# Modbus TCP simulator running on port 5020

3.启动MCP服务器

# In another terminal
uv run python server.py
# MCP server running on port 8765, loaded devices.yaml

4.使用MCP客户端进行测试

npm install -g mcporter
mcporter config add modbus --url http://localhost:8765/mcp
mcporter call modbus.list_devices
mcporter call modbus.read_device device=factory_sensor register=temperature
mcporter call modbus.write_device device=factory_sensor register=motor_speed value=1500
mcporter call modbus.device_status device=factory_sensor

或者使用Docker Compose

对于“我不想打开三个终端”的人群(可以理解):

docker compose up -d
# Simulator on :5020, MCP server on :8765

设备配置文件(YAML)

这就是魔法发生的地方。好吧,“魔法”是慷慨的——它只是YAML。但这比记住十六进制地址要好。在中定义Modbus设备 devices.yaml:

devices:
  factory_sensor:
    host: 192.168.1.100
    port: 502
    slave_id: 1
    byte_order: big               # big | little | mixed
    registers:
      temperature:
        address: 0
        function_code: 3          # 3=holding, 4=input
        data_type: float32        # uint16, int16, uint32, int32, float32, bool
        scale: 0.1
        unit: "°C"
        access: read
        description: "Ambient temperature sensor"
      motor_speed:
        address: 4
        function_code: 3
        data_type: uint16
        unit: "RPM"
        access: read_write
        description: "Motor speed setpoint"
      pump_on:
        address: 0
        function_code: 1          # 1=coil
        data_type: bool
        access: read_write
        description: "Pump on/off switch"

支持的数据类型

类型 寄存器 范围
bool 线圈(1位) 真/假
uint16 1 0 – 65535
int16 1 -32768 – 32767
uint32 2 0 – 4294967295
int32 2 -2147483648 – 2147483647
float32 2 ieee754

支持的功能代码

代码 名称 访问权限
1 读取线圈 读取
2 读取离散输入 读取
3 读保持寄存器 读/写
4 读取输入寄存器 读取

MCP工具

配置文件模式(主)

用户友好的东西。这个项目存在的原因。

工具 说明
list_devices 列出所有已配置的设备
list_registers 列出带有元数据的设备的所有寄存器
read_device 读取命名寄存器--返回转换值+单位
write_device 将值写入命名寄存器
device_status 检查设备是否在线

原始模式(高级)

因为当你需要绕过所有这些漂亮的抽象概念,像周二一样与寄存器交谈时。

工具 说明
read_registers 按主机/端口/slave_id/fc/地址读取原始数据
write_registers 按主机/端口/slave_id/fc/地址进行原始写入
scan_registers 扫描非零值的地址范围

内置模拟器

一个基于pymodbus的Modbus TCP服务器,假装是一个工厂。数据是假的,但协议是真实的。不需要硬件——你的笔记本电脑现在就是工厂。

注册 地址 FC 类型 行为
温度 HR 0-1 3 float32 正弦波20~30°C
湿度 HR 2-3 float32 随机40~60%RH
motor_speed HR 4 3 uint16 保存写入值
压力 IR 0 4 uint16 随机900~1100kPa
pump_on 线圈0 1 bool 保存写入值
valve_open 线圈1 1 bool 保存写入值

项目结构

kc_modbus_mcp/
├── server.py               # MCP Server entry point
├── simulator.py            # Built-in Modbus TCP simulator
├── devices.yaml            # Example device profile
├── src/
│   ├── profile.py          # YAML profile loader + register resolver
│   ├── client.py           # pymodbus async client wrapper
│   ├── converter.py        # Data type conversion (raw ↔ engineering value)
│   └── tools.py            # MCP tool definitions
├── openclaw-skill/         # OpenClaw skill wrapper
├── tests/                  # Automated tests
├── docker-compose.yml
├── Dockerfile
├── pyproject.toml
├── DESIGN.md               # Design document (Chinese)
├── .env.example
└── LICENSE

环境变量

包括合理的默认值,因为任何人都不应该仅仅为了看看它们是否正常工作而进行配置。

变量 默认值 描述
MODBUS_PROFILE devices.yaml 设备配置文件YAML的路径
MCP_HOST 0.0.0.0 MCP服务器绑定地址
MCP_PORT 8765 MCP服务器端口
SIMULATOR_HOST 0.0.0.0 模拟器绑定地址
SIMULATOR_PORT 5020 模拟器端口

OpenClaw 集成

对于OpenClaw/local LLM代理,包装器脚本将冗长的MCP调用转换为您可以实际键入而不会出现腕管综合征的内容:

modbus list
modbus status factory_sensor
modbus read factory_sensor temperature
modbus write factory_sensor motor_speed 1500

看 openclaw-skill/SKILL.md 了解详情。


待办事项

我一定会做的事情。最终。可能。

  • []多设备连接池
  • []具有可配置缓存间隔的轮询模式
  • []更改检测(值更改时通知)
  • []Modbus RTU(串行)支持
  • []用于设备配置文件编辑的Web UI