kc_modbus_mcp

kc_modbus_mcp

MCP server for Modbus TCP devices that enables AI agents to read/write PLC registers by name using YAML device profiles, with a built-in simulator.

Category
访问服务器

README

"Read the factory temperature" -- Modbus MCP

License: MIT Python FastMCP MCP

正體中文

Look, nobody wants to memorize that register 40001 is the temperature sensor. Life is too short and Modbus addresses are too many. This is an MCP Server for Modbus TCP devices -- you define device profiles in YAML, and then AI agents can read/write PLC registers by name like civilized beings.

It also ships with a built-in simulator, because we all know you don't have a PLC sitting on your desk. (And if you do, please dust it off.)


Why This Exists

I kept looking at existing MCP servers for Modbus and kept finding the same four disappointments:

  1. No semantic register mapping -- the AI has to know raw addresses like 40001. Asking it to "read temperature" gets you a blank stare.
  2. No data type conversion -- everything comes back as raw uint16, because apparently float32 is too fancy.
  3. No built-in simulator -- want to test? Go buy hardware. Or beg a colleague. Or stare at the ceiling.
  4. No device profiles -- no way to pre-configure connection details and register maps, so you get to type the same host/port/slave_id over and over like it's 1998.

So I did the unreasonable thing and fixed all four myself.


Architecture

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

Features

  • Natural language control -- "read the factory temperature" just works. No address lookup tables taped to your monitor.
  • YAML device profiles -- map register names to addresses, data types, units, and scaling. Finally, configuration that reads like English.
  • 8 MCP tools -- 5 profile-based + 3 raw mode for when you need to go full hacker.
  • Auto data type conversion -- float32, int32, uint16, bool -- with byte order and scale support, because doing bit math in your head at 2 AM is not a personality trait.
  • Built-in Modbus TCP simulator -- sine-wave temperature, random humidity/pressure, writable coils. Your imaginary factory is doing great.
  • Docker-ready -- docker compose up -d and you're in business. Two containers, zero excuses.
  • OpenClaw skill -- wrapper script for local LLM agents who prefer the command line lifestyle.

Demo

<img src="docs/images/demo-snapshot.png" width="600" alt="AI agent reading Modbus device registers">


Security Notice: This is a POC/development project designed for trusted LAN environments. The MCP server does not implement authentication. Raw mode allows read/write access to any reachable Modbus device. Do not expose service ports to the public internet without additional security measures.

Quick Start

Three terminals, five minutes, zero soldering required.

1. Clone and install

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

2. Start the simulator

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

3. Start the MCP server

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

4. Test with MCP client

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

Or use Docker Compose

For the "I don't want to open three terminals" crowd (understandable):

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

Device Profile (YAML)

This is where the magic happens. Well, "magic" is generous -- it's just YAML. But it beats memorizing hex addresses. Define your Modbus devices in 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"

Supported Data Types

Type Registers Range
bool coil (1 bit) true/false
uint16 1 0 – 65535
int16 1 -32768 – 32767
uint32 2 0 – 4294967295
int32 2 -2147483648 – 2147483647
float32 2 IEEE 754

Supported Function Codes

Code Name Access
1 Read Coils read
2 Read Discrete Inputs read
3 Read Holding Registers read/write
4 Read Input Registers read

MCP Tools

Profile Mode (primary)

The user-friendly stuff. The reason this project exists.

Tool Description
list_devices List all configured devices
list_registers List all registers of a device with metadata
read_device Read a named register -- returns converted value + unit
write_device Write a value to a named register
device_status Check if a device is online

Raw Mode (advanced)

For when you need to bypass all that nice abstraction and talk to registers like it's a bare metal Tuesday.

Tool Description
read_registers Raw read by host/port/slave_id/fc/address
write_registers Raw write by host/port/slave_id/fc/address
scan_registers Scan address range for non-zero values

Built-in Simulator

A pymodbus-based Modbus TCP server that pretends to be a factory. The data is fake but the protocol is real. No hardware needed -- your laptop is the factory now.

Register Address FC Type Behavior
temperature HR 0-1 3 float32 Sine wave 20~30°C
humidity HR 2-3 3 float32 Random 40~60%RH
motor_speed HR 4 3 uint16 Holds written value
pressure IR 0 4 uint16 Random 900~1100 kPa
pump_on Coil 0 1 bool Holds written value
valve_open Coil 1 1 bool Holds written value

Project Structure

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

Environment Variables

Sensible defaults included, because nobody should have to configure things just to see if they work.

Variable Default Description
MODBUS_PROFILE devices.yaml Path to device profile YAML
MCP_HOST 0.0.0.0 MCP server bind address
MCP_PORT 8765 MCP server port
SIMULATOR_HOST 0.0.0.0 Simulator bind address
SIMULATOR_PORT 5020 Simulator port

OpenClaw Integration

For OpenClaw / local LLM agents, a wrapper script turns verbose MCP calls into something you can actually type without getting carpal tunnel:

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

See openclaw-skill/SKILL.md for details.


TODO

Things I will definitely get to. Eventually. Probably.

  • [ ] Multi-device connection pooling
  • [ ] Polling mode with configurable cache interval
  • [ ] Change detection (notify on value changes)
  • [ ] Modbus RTU (Serial) support
  • [ ] Web UI for device profile editing

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选