ezhuk/modbus-mcp
If you are the rightful owner of modbus-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The Modbus MCP Server is a lightweight Model Context Protocol server that facilitates secure and standardized connections between LLM agents and Modbus devices, enabling seamless integration with Building Automation and Industrial Control systems.
Read Registers
Reads the contents of one or more registers on a remote unit.
Write Registers
Writes data to one or more registers on a remote unit.
Modbus MCP Server
A lightweight Model Context Protocol (MCP) server that connects LLM agents to Modbus devices in a secure, standardized way, enabling seamless integration of AI-driven workflows with Building Automation (BAS) and Industrial Control (ICS) systems, allowing agents to monitor real-time sensor data, actuate devices, and orchestrate complex automation tasks.
Getting Started
Use uv to add and manage the Modbus MCP server as a dependency in your project, or install it directly via uv pip install
or pip install
. See the Installation section of the documentation for full installation instructions and more details.
uv add modbus-mcp
The server can be embedded in and run directly from your application. By default, it exposes a Streamable HTTP
endpoint at http://127.0.0.1:8000/mcp/
.
# app.py
from modbus_mcp import ModbusMCP
mcp = ModbusMCP()
if __name__ == "__main__":
mcp.run(transport="http")
It can also be launched from the command line using the provided CLI
without modifying the source code.
modbus-mcp
Or in an ephemeral, isolated environment using uvx
. Check out the Using tools guide for more details.
uvx modbus-mcp
Configuration
For the use cases where most operations target a specific device, such as a Programmable Logic Controller (PLC) or Modbus gateway, its connection settings (host
, port
, and unit
) can be specified at runtime using environment variables so that all prompts that omit explicit connection parameters will be routed to this device.
export MODBUS_MCP_MODBUS__HOST=10.0.0.1
export MODBUS_MCP_MODBUS__PORT=502
export MODBUS_MCP_MODBUS__UNIT=1
These settings can also be specified in a .env
file in the working directory.
# .env
modbus_mcp_modbus__host=10.0.0.1
modbus_mcp_modbus__port=502
modbus_mcp_modbus__unit=1
When interacting with multiple devices, each device’s connection parameters (host
, port
, unit
) can be defined with a unique name
in a devices.json
file in the working directory. Prompts can then refer to devices by name
.
{
"devices": [
{"name": "Boiler", "host": "10.0.0.3", "port": 503, "unit": 3},
{"name": "Valve", "host": "10.0.0.4", "port": 504, "unit": 4}
]
}
MCP Inspector
To confirm the server is up and running and explore available resources and tools, run the MCP Inspector and connect it to the Modbus MCP server at http://127.0.0.1:8000/mcp/
. Make sure to set the transport to Streamable HTTP
.
npx @modelcontextprotocol/inspector
Core Concepts
The Modbus MCP server is built with FastMCP 2.0 and leverages its core building blocks - resource templates, tools, and prompts - to streamline Modbus read and write operations with minimal boilerplate and a clean, Pythonic interface.
Read Registers
Each register on a device is mapped to a resource (and exposed as a tool) and resource templates are used to specify connection details (host, port, unit) and read parameters (address, count).
@mcp.resource("tcp://{host}:{port}/{address}?count={count}&unit={unit}")
@mcp.tool(
annotations={"title": "Read Registers", "readOnlyHint": True, "openWorldHint": True}
)
async def read_registers(
host: str = settings.modbus.host,
port: int = settings.modbus.port,
address: int = 40001,
count: int = 1,
unit: int = settings.modbus.unit,
) -> int | list[int]:
"""Reads the contents of one or more registers on a remote unit."""
...
Write Registers
Write operations are exposed as a tool, accepting the same connection details (host, port, unit) and allowing to set the contents of one or more holding registers
or coils
in a single, atomic call.
@mcp.tool(
annotations={
"title": "Write Registers",
"readOnlyHint": False,
"openWorldHint": True,
}
)
async def write_registers(
data: list[int],
host: str = settings.modbus.host,
port: int = settings.modbus.port,
address: int = 40001,
unit: int = settings.modbus.unit,
) -> str:
"""Writes data to one or more registers on a remote unit."""
...
Authentication
To enable Bearer Token authentication for the Streamable HTTP
transport, provide the RSA public key in PEM format in the .env
file. Check out the Bearer Token Authentication section for more details.
Interactive Prompts
Structured response messages are implemented using prompts that help guide the interaction, clarify missing parameters, and handle errors gracefully.
@mcp.prompt(name="modbus_help", tags={"modbus", "help"})
def modbus_help() -> list[Message]:
"""Provides examples of how to use the Modbus MCP server."""
...
Here are some example text inputs that can be used to interact with the server.
Please read the value of register 40001 on 127.0.0.1:502.
Set register 40005 to 123 on host 192.168.1.10, unit 3.
Write [1, 2, 3] to holding registers starting at address 40010.
What is the status of input register 30010 on 10.0.0.5?
Examples
The examples
folder contains sample projects showing how to integrate with the Modbus MCP server using various client APIs to provide tools and context to LLMs.
- openai-agents - shows how to connect to the Modbus MCP server using the OpenAI Agents SDK.
- openai - a minimal app leveraging remote MCP server support in the OpenAI Python library.
- pydantic-ai - shows how to connect to the Modbus MCP server using the PydanticAI Agent Framework.
Docker
The Modbus MCP server can be deployed as a Docker container as follows:
docker run -d \
--name modbus-mcp \
--restart=always \
-p 8080:8000 \
--env-file .env \
ghcr.io/ezhuk/modbus-mcp:latest
This maps port 8080
on the host to the MCP server's port 8000
inside the container and loads settings from the .env
file, if present.
License
The server is licensed under the MIT License.