关于 OPC-UA MCP Server
OPC-UA MCP Server 将 LLM 接入工业 OPC-UA 服务,支持浏览、搜索、读写及订阅实时数据。它结合持久化缓存与地址空间索引,并支持 stdio 或 HTTP 传输。
主要功能
- 01读取数据并校验写入类型
- 02递归浏览节点
- 03搜索已索引的浏览名称
- 04订阅实时更新
- 05持久化缓存和订阅
- 06使用凭据或证书认证
适用场景
- 01检查 OPC-UA 地址空间
- 02读取或更新节点值
- 03监控节点实时变化
MCP 相关
它提供 OPC-UA 连接管理、发现、搜索、浏览、读写和订阅等 MCP 工具,并提供节点数据及服务信息资源。客户端可通过 stdio 或 HTTP 连接。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e OPCUA_ENDPOINT -e OPCUA_AUTH_MODE -e OPCUA_USERNAME -e OPCUA_PASSWORD -e OPCUA_SECURITY_POLICY -e OPCUA_SECURITY_MODE -e SERVER_TRANSPORT ghcr.io/mwieczorkiewicz/opcua-mcp:main-29734c4OPCUA_ENDPOINTOPC-UA server endpoint to connect to, e.g. opc.tcp://your-plc-host:4840OPCUA_AUTH_MODE密钥Authentication mode against the OPC-UA serverOPCUA_USERNAMEUsername, required if OPCUA_AUTH_MODE=usernameOPCUA_PASSWORD密钥Password, required if OPCUA_AUTH_MODE=usernameOPCUA_SECURITY_POLICYOPC-UA transport security policy, e.g. Basic256Sha256OPCUA_SECURITY_MODEOPC-UA transport security mode, e.g. SignAndEncryptSERVER_TRANSPORTMCP transport: stdio (for local MCP clients) or http (for remote/hosted deployments)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/mwieczorkiewicz/opcua-mcp:main-29734c4stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
OPC-UA MCP 服务
一个 MCP 服务,让大模型通过 stdio 或 HTTP 读取、写入、浏览、搜索和订阅 OPC-UA 工业自动化服务上的实时数据,并内置持久化缓存和可搜索的地址空间索引。
https://github.com/user-attachments/assets/0b676e6e-17ce-42f5-918f-9a615e939008
快速开始
使用随附的 Microsoft OPC-UA 测试服务和 Claude 可访问的公共隧道,即可最快端到端体验:
git clone https://github.com/mwieczorkiewicz/opcua-mcp.git
cd opcua-mcp
make compose-up # starts a test OPC-UA server, opcua-mcp, and a public HTTPS tunnel
make connector-url # prints a URL like https://xyz.trycloudflare.com/mcp
将该 URL 粘贴到 Claude 的 Settings → Connectors → Add custom
connector 中,然后让它浏览服务或读取数值。完成后,使用
make compose-down 停止运行——有关该隧道会暴露哪些内容,以及如何改为连接自己的 OPC-UA 服务,请参阅
docs/deployment.md。
在本地构建和运行
go build -o opcua-mcp ./cmd/opcua-mcp.go
# stdio (default) - no OPC-UA connection until the client calls opcua_connect
./opcua-mcp
# HTTP - connects eagerly at startup
SERVER_TRANSPORT=http OPCUA_ENDPOINT=opc.tcp://localhost:4840 ./opcua-mcp
需要 Go 1.26+;如需运行测试服务或进行容器化部署,也可选装 Docker。
功能
- 读取 / 写入 节点值;写入时会进行类型验证,因此类型不匹配的值会在到达设备前被拒绝。
- 浏览 地址空间,可逐层或递归浏览;也可按名称而非节点 ID 查找节点。
- 订阅 推送式实时更新——订阅会在重启后保留,并在重新连接时自动恢复。
- 缓存 读取结果、浏览结果和类型信息到磁盘(bbolt),避免重复查询时往返访问设备;写入会自动使相关缓存条目失效。
- 在后台发现并搜索地址空间,并使用 Bleve 为模糊或部分浏览名称查询建立索引。
- 支持匿名、用户名 / 密码或证书身份验证,并可配置 OPC-UA 安全策略和模式。
有关缓存层、订阅管理器和发现索引如何协同工作,请参阅 docs/architecture.md。
MCP 工具
| 工具 | 描述 |
|---|---|
opcua_read | 读取一个或多个节点值。已订阅的节点从实时缓存中提供;其他节点会实时读取,除非 max_age_ms 允许使用缓存值。 |
opcua_write | 向节点写入值。写入前会验证值的类型是否与节点匹配。 |
opcua_get_value | 读取单个节点的值——这是对 opcua_read 的便捷封装。 |
opcua_get_value_by_name | 通过发现索引按浏览名称而非节点 ID 读取值。 |
opcua_browse | 列出节点的直接子节点。 |
opcua_browse_nodes | 从某个节点开始递归浏览,最多达到指定深度,并将子节点嵌套在其父节点下。 |
opcua_node_info | 获取节点的元数据(数据类型、访问级别等)。 |
opcua_find_similar_nodes | 根据发现索引模糊匹配浏览名称。 |
opcua_subscribe | 按指定间隔为一个或多个节点启动推送式更新。 |
opcua_unsubscribe | 按订阅 ID 或指定其节点之一来取消订阅。 |
opcua_list_subscriptions | 列出活动订阅。 |
opcua_connect / opcua_disconnect | 显式管理连接(主要适用于 stdio 模式)。 |
opcua_server_info | 获取 OPC-UA 服务元数据。 |
opcua_discovery_stats | 查看后台发现缓存统计信息(节点数量、深度分布、启用标志)。 |
opcua_force_discovery | 立即触发发现刷新,无需等待下一个周期。 |
opcua_debug_search / opcua_ensure_server_nodes | 用于排查节点未出现在搜索结果中的原因。 |
MCP 资源
| 资源 | 描述 |
|---|---|
opcua://node/{node_id} | 节点数据,例如 opcua://node/ns=2;i=1。支持以逗号分隔的多个节点。 |
opcua://server | OPC-UA 服务信息。 |
配置
配置通过 viper 从以下三个来源加载,优先级依次递增:
- 内置默认值(见下表)。
- 可选配置文件——TOML、YAML、JSON,或 viper 支持的其他格式。默认情况下,如果存在,则读取
./config.{yaml,yml,toml,json,...};使用CONFIG_FILE=/path/to/config.toml指定显式路径。配置文件完全可选——仅使用环境变量也足够。 - 环境变量(
SERVER_*、OPCUA_*、MCP_*、SEARCH_*、STORE_*)——始终优先于配置文件,因此现有仅使用环境变量的部署可以保持原样运行。
配置文件中的键与环境变量名称对应,转换为小写并嵌套在各自的前缀下,例如,SERVER_HTTP_PORT 会变成:
server:
http_port: "8080"
服务端
| 变量 | 默认值 | 描述 |
|---|---|---|
SERVER_TRANSPORT | stdio | stdio 或 http |
SERVER_HTTP_PORT | 8080 | HTTP 传输端口 |
SERVER_LOG_LEVEL | info | debug、info、warn、error |
SERVER_LOG_FORMAT | json | json 或 text |
SERVER_LOG_OUTPUT | stdout | stdout、stderr 或 file(在 stdio 模式下强制设为 stderr,因为 stdout 承载 MCP 流) |
SERVER_LOG_FILE | - | 日志文件路径;当 SERVER_LOG_OUTPUT=file 时必填 |
SERVER_LOG_ADD_SOURCE | false | 在日志条目中添加源文件/行号 |
OPC-UA 连接
| 变量 | 默认值 | 描述 |
|---|---|---|
OPCUA_ENDPOINT | opc.tcp://localhost:4840 | 服务端端点 |
OPCUA_AUTH_MODE | anonymous | anonymous、username 或 certificate |
OPCUA_USERNAME / OPCUA_PASSWORD | - | 当 AUTH_MODE=username 时必填 |
OPCUA_CERT_FILE / OPCUA_KEY_FILE | - | 当 AUTH_MODE=certificate 时必填 |
OPCUA_SERVER_CERT | - | 服务端证书文件路径 |
OPCUA_SECURITY_POLICY | None | None、Basic128Rsa15、Basic256、Basic256Sha256、Aes128_Sha256_RsaOaep |
OPCUA_SECURITY_MODE | None | None、Sign、SignAndEncrypt |
OPCUA_REQUEST_TIMEOUT | 30s | 每个请求的超时时间 |
OPCUA_SESSION_TIMEOUT | 60s | 会话超时时间 |
OPCUA_MAX_RETRIES | 3 | 连接重试次数 |
OPCUA_RETRY_DELAY | 1s | 重试间隔 |
MCP
| 变量 | 默认值 | 描述 |
|---|---|---|
MCP_NAME | OPC-UA MCP Server | 向客户端报告的服务端名称 |
MCP_VERSION | 1.0.0 | 向客户端报告的服务端版本 |
MCP_ENABLE_TOOLS | true | 启用工具 |
MCP_ENABLE_RESOURCES | true | 启用资源 |
MCP_ENABLE_PROMPTS | false | 启用提示词 |
MCP_HTTP_PATH | /mcp | HTTP 端点路径 |
发现与搜索
| 变量 | 默认值 | 描述 |
|---|---|---|
SEARCH_ENABLE_DISCOVERY | true | 启用后台节点发现 |
SEARCH_DISCOVERY_INTERVAL | 30s | 重新遍历地址空间的频率 |
SEARCH_DISCOVERY_ROOT_NODE | i=85 | 开始遍历的根节点(Objects 文件夹) |
SEARCH_MAX_DISCOVERY_DEPTH | 10 | 最大遍历深度 |
SEARCH_MAX_NODES_PER_BROWSE | 10000 | 限制每次浏览调用返回的节点数 |
SEARCH_ENABLE_SEARCH | true | 启用 Bleve 搜索索引 |
SEARCH_INDEX_PATH | ./search_index | 搜索索引目录 |
SEARCH_MAX_RESULTS | 100 | 每次搜索的最大结果数 |
SEARCH_MIN_SCORE | 0.1 | 最低匹配分数 |
SEARCH_ENABLE_CACHE | true | 读穿缓存的总开关。设为 false 后,每次 opcua_read/opcua_write/opcua_browse_nodes 调用都会实时执行,与缓存启用前的行为完全一致 |
持久化存储
使用磁盘上的 bbolt 数据库支持读穿缓存和订阅持久化。
| 变量 | 默认值 | 描述 |
|---|---|---|
STORE_DB_PATH | mcp_opcua_store.db | 数据库文件路径 |
STORE_OPEN_TIMEOUT | 5s | 打开文件时等待文件锁的时长 |
STORE_TYPEINFO_TTL | 24h | 缓存的类型信息有效期 |
STORE_BROWSE_TTL | 5m | 缓存的浏览结果有效期 |
STORE_BATCH_WINDOW | 25ms | 订阅通知写入存储的频率 |
STORE_BATCH_MAX_ITEMS | 250 | 每批写入的最大通知数 |
STORE_NOTIFY_CHAN_BUFFER | 1024 | 传入订阅通知的缓冲区大小 |
如果存储无法打开(例如上次异常关闭遗留的锁,或文件系统为只读),服务端会记录警告并继续运行,同时强制关闭缓存,且订阅工具会返回错误;其他所有工具不受影响。
遥测
opcua-mcp 会收集匿名的汇总使用遥测数据(使用了哪些工具、缓存命中率、错误类别——绝不会收集节点 ID、端点 URL、节点值或凭据),以帮助确定这个开源项目的维护优先级。默认开启;关于具体收集和不收集哪些内容,请参阅 docs/telemetry.md。
可通过以下任一方式选择退出:
| 变量 | 效果 |
|---|---|
DO_NOT_TRACK=1 | 跨项目社区惯例(consoledonottrack.com) |
OPCUA_MCP_TELEMETRY=false | 本项目自有开关 |
Docker
docker build -t opcua-mcp .
docker run -p 8080:8080 -e SERVER_TRANSPORT=http -e OPCUA_ENDPOINT=opc.tcp://your-server:4840 opcua-mcp
采用 Chainguard 最小化 Go 镜像进行多阶段构建,并从 scratch 运行——不含 shell,攻击面小。将 ./search_index 和
./mcp_opcua_store.db 挂载为卷,以便在重启后保留发现、缓存和订阅状态。完整的身份验证模式示例、Compose 开发环境以及 Claude 连接器隧道设置,请参阅
docs/deployment.md。
开发
make start-opcua-server # Microsoft OPC-UA test server in Docker
make run-with-test-server # run the app against it (auto start/stop)
go test ./... # unit tests
go test -race ./...
make test-integration # real Subscribe/reconnect/cache behavior via testcontainers-go (needs Docker)
VS Code 启动配置位于 .vscode/launch.example.json 中——将其复制到
.vscode/launch.json,即可使用会自动启动和停止测试服务端的 stdio/HTTP/身份验证调试目标。make help 会列出所有可用目标。
测试采用表驱动方式,并在 opcuaClient 接口边界处模拟 OPC-UA 客户端(internal/opcua/mock_client_test.go),而不是针对真实或模拟的服务端进行测试——关于被测组件如何配合,请参阅 docs/architecture.md;关于本仓库的提交消息格式,请参阅 docs/COMMIT_CONVENTION.md。
贡献
Fork 本仓库,进行修改,然后提交 PR——请参阅 CONTRIBUTING.md。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。