Skip to main content
Glama

Smart200 MCP

用 MCP 驱动 S7-200 SMART(STEP 7-Micro/WIN SMART)做工程分析、程序部署、 在线监控与诊断 —— 对标本机 TIA Portal MCP,但架构完全不同:MicroWIN SMART 没有 Openness 等价物(无 COM、无命令行、内置 JSON-RPC 只管 PROFINET),所以做成 五层混合架构,各层可靠度不同,工具描述里都如实标注。

能力

状态

引擎调用(DLL 注入)

导出/导入/编译/权威验证/保存、下载到 PLC / 上传 PLC 程序 / RUN-STOP / 事件日志

✅ 注入链路已实测;在线类 ⚠️ 已接线冒烟过、未经真机验证

AWL 解析

程序块文本解析、交叉引用、程序验证(网络/指令/地址读写)

✅ 实测

离线工程解析

V2 .smart 解包、符号、POU 名、功能框统计、工程对比

✅ 11/11 真实工程验证

在线通讯(snap7)

读写 V/M/I/Q、全部点位/实时监控/点位图比对、CPU 状态/RUN-STOP/时钟/诊断探测

⚠️ 协议层按规范实现,未经真机验证

UI 自动化

读项目树(CPU 型号 + POU 列表)、点编译

✅ 实测(引擎路线打通后已非主力)

V3 .smartV3 离线解析:❌ 数据段加密 —— 但引擎注入可处理 V3 工程。 版本 0.6.0,共 42 个 MCP 工具

安装(两种方式任选)

方式 A:pip 安装打包好的 wheel(推荐)

pip install --no-deps dist/smart200_mcp-0.6.0-py3-none-any.whl
# 依赖单独装:
pip install "mcp>=2.0.0" "python-snap7>=3.1.0" "pywinauto>=0.6.9"

安装后生成控制台入口 smart200-mcp,MCP 配置里 command 直接指它:

{
  "mcpServers": {
    "smart200": {
      "type": "stdio",
      "command": "<Python 安装目录>/Scripts/smart200-mcp.exe",
      "timeoutMs": 120000
    }
  }
}

wheel 自带注入 DLL / 注入器(smart200_mcp/native/),拷到哪台 Windows 都能跑。

方式 B:源码运行

# 1. 依赖
pip install -r requirements.txt

# 2. (可选)重新编译注入 DLL —— 自动找 VS Build Tools,找不到会告诉你缺什么
python native/bootstrap/build.py

# 3. 挂上 MCP(command 指向 run.py)
claude mcp add smart200 -s user -- python <仓库路径>/run.py

挂好之后先跑 smart_doctor,它会一次说清缺什么、怎么补。

路径不用改。 仓库放哪个盘都行(注入 DLL 运行时自寻路径),MicroWIN 安装位置自动探测。 探测不到时按 smart_doctor 的提示设环境变量:

环境变量

作用

SMART200_EXE

MicroWIN 可执行文件完整路径(MWSmart.exe / MWSmartV3.exe)

SMART200_TEMPLATE

空白模板工程路径

SMART200_SCRIPT_TIMEOUT

单次注入等待上限,默认 180 秒;大工程编译/下载慢可调大

Related MCP server: tiacommander-mcp

42 个工具速查

先跑这个smart_doctor(环境自检)

分组

工具

部署(引擎注入)

smart_deploy(⭐ 一步到位:设符号→导入→编译→五关验证→落盘)smart_import_blocks smart_compile_and_export smart_validate_project smart_run_workflow smart_set_symbols smart_open_project

导出/查看

smart_export_all(全块+符号表自包含导出)smart_export_blocks smart_overview(谁调用谁一屏看清)smart_awl_analyze smart_check_stl(离线秒级预检)smart_xref(交叉引用)

离线解析

smart_probe smart_list_projects smart_analyze smart_symbols smart_function_blocks smart_compare

在线(snap7,直连 CPU)

smart_plc_info smart_plc_read smart_plc_write smart_plc_points(全部 I/Q/M 点位)smart_plc_monitor(实时轮询)smart_plc_compare_pointmap(点位图比对)smart_plc_run smart_plc_stop smart_plc_time(读/设/同步时钟)smart_plc_diag(SZL 诊断探测)smart_plc_blocks

在线(引擎路线,走软件通信栈)

smart_engine_status(连接/运行模式/目标连接点)smart_engine_run smart_engine_stop smart_plc_download下载到 PLCsmart_plc_upload上传 PLC 程序smart_plc_compare在线/离线差异报告smart_event_log

程序监控

smart_monitor_program(程序段监控:逐网络导通状态/线圈/操作数实时值)

界面

smart_ui_project_tree smart_ui_output smart_ui_compile

90% 的活只用一个工具

smart_deploy(
    awl_files=["motor.awl"],
    symbols={"电机启动": "I0.0", "电机运行": "Q0.0"},   # 可选:给 I/O 命名
    open_after=True,                                    # 顺手打开给人看
)

它一次注入里把设符号 → 导程序 → 编译 → 五关验证 → 保存全干完。 别拆成 smart_set_symbols + smart_deploy + smart_open_project 三次调用 —— 每次调用都要重启一个 MicroWIN 实例(约 16 秒等工程载入),拆开就是三倍时间。

典型场景

# 拿到一个别人的工程,先看结构
smart_overview(project_path=".../xxx.smart")

# 写完 AWL,先离线预检(秒级)
smart_check_stl(awl_path="motor.awl")

# 部署 + 五关验证(权威判据问软件本人)
smart_deploy(awl_files=["motor.awl"], symbols={...})

# 全工程交叉引用:每个地址被谁读写、调用图
smart_xref(project_path=".../xxx.smart")

# 现场监控:程序段状态(需真机 + 工程路径)
smart_monitor_program(ip="192.168.2.1", project_path=".../xxx.smart")

# 下载到 PLC / 与现场比对(需真机,confirm 门把关)
smart_plc_download(project_path=".../xxx.smart", confirm=True)
smart_plc_compare(project_path=".../xxx.smart")

五关验证(smart_deploy

血泪教训:软件的 COMPILE ret=0 不能当通过判据。 无效程序段会被标红并 排除在编译之外,其余照常编译 → 返回成功,据此报"已验证"会骗人(真踩过)。

干什么

性质

1 静态预检

stlcheck.py:一个 Network 只能有一条 rung

离线秒级,启发式

2 导入+编译

抓语法与交叉引用错误(CALL/ATCH 指向不存在的块)

必要不充分

3 引擎真值

POU_IsValidNet 逐网络问软件本人

权威判据

4 往返导出

逐块逐条核对指令流 + 网络数,抓静默丢弃

抓"说成功其实没做"

5 落盘校验

比对工程文件指纹,证明真的写进磁盘了

前四关都在同一个内存实例里问软件自己

第 3 关才是权威:第 1 关是我写的规则、可能有盲区,第 3 关是软件自己的答案。 两者在已知样本上完全一致(坏样本精确命中 9/9、好样本零误报),不一致时以第 3 关为准。

用 AWL 干活必须知道的几条(都是实测踩出来的)

  • 主程序的关键字是 ORGANIZATION_BLOCK,不是 PROGRAM_BLOCK。写错了 IMPORTPOU 照样返回 ret=0,但什么都没导进去(第 4 关才抓得到)。

  • 导入 OB1 会替换整个程序集 —— 先导入的子程序会被抹掉。所以主程序必须排最前 (smart_deploy 会自动重排并在报告里说明)。

  • 其余按依赖排:被 CALL 的子程序、被 ATCH 的中断程序要在引用它们的块之前。

  • 一个 .awl 含多个 BLOCK 时导入只吃到一个 → 拆成多个文件。

  • 未定义的符号名会让整个网络变成无效程序段(不是编译报错),第 3 关能抓到。

  • S7-200 SMART 没有 NETR/NETW(那是 S7-200 的 PPI 指令)。以太网 S7 通信用 GET VB780 / PUT VB800。写错的助记符不报错,而是被当成未定义符号 → 整段无效。 smart_check_stl 里有实测出来的黑名单,离线就能挡住。

  • AWL 直接用 UTF-8 写就行:编码与行尾会自动规范成软件要的 ANSI+CRLF。 遇到 GBK 表示不了的字符会报出行号+具体字符,不会静默替换成 ?

  • V2.8 落盘用 SAVE(SAVEAS 会崩)、V3 用 SAVEAS —— 引擎内部已按版本自动处理,别手动干预。

  • 从工程导出的 AWL 用的是符号名不是绝对地址(软件会把符号表里有名字的地址替换掉), 所以导出件依赖那份符号表smart_export_all 会一并导出 symbols.json, 拿整个目录就能原样重建工程。

符号表

给 I/O 地址命名后,AWL 里就能直接写符号名,可读性和现场维护性好得多:

smart_deploy(["motor.awl"], symbols={"电机启动": "I0.0", "电机停止": "I0.1", "电机运行": "Q0.0"})
Network 1
	LD     电机启动
	O      电机运行
	AN     电机停止
	=      电机运行

要点(踩了很多弯路才搞清):绝对地址符号走「I/O 变量」表(改那一行的名字,不是新建行); 「变量表 1」是 V 区变量表、地址由编译器自动分配,想绑死绝对地址就别用它; 符号表必须落盘保存(V2.8 SAVE / V3 SAVEAS,引擎已自动处理)。

示例工程(examples/

  • demo_station/:从空白模板从零生成、五关验证过的完整工程 —— 双工位自动上料·加工·出料站, 18 块 / 231 网络 / 635 条指令 / 158 种指令助记符,SCR 顺序控制、定时器/计数器、 模拟量、PID、高速计数、脉冲输出、字符串、通信全都有。src/*.awl 是 UTF-8 源码直接改。

  • cylinder_control_template/:两气缸控制模板(OB1 调 SBR0),带 I/O 分配表。

  • instruction_probe/:问软件"这条指令你到底认不认"的可复跑探针。 实测 22 条的结论是只有 NETR/NETW 不支持 —— 别凭印象回避指令。

安全红线(照搬 TIA MCP 的教训)

  1. 注入只允许打到本模块自己启动的实例engine._OWN_PIDS 白名单,机器强制)

  2. UI 层只接管已打开的实例,绝不替你打开/新建工程去顶掉正在编辑的内容

  3. 绝不按进程名批量杀 MWSmart.exe

  4. 写 PLC、下载、启停、点编译等会改变状态的操作,一律要求显式 confirm=True

  5. 找不到控件/解不开文件就抛异常,绝不静默返回空——那会把失败伪装成成功

  6. 改已存在的工程前自动备份 <工程>.bak

  7. 进程退出时收掉自己起的实例atexit),只收自己起的

  8. 注入串行化:命令/结果文件全局只有一份,并发会串台

  9. 上传 PLC 程序走副本,绝不覆盖原工程文件

测试

python tests/test_stlcheck.py     # 网络结构 / SMART 不支持的助记符
python tests/test_enginelog.py    # 引擎日志判据
python tests/test_persist.py      # 落盘校验 + 第4关往返判据
python tests/test_encoding.py     # AWL 编码与行尾规范化
python tests/test_report.py       # deploy 报告裁剪
python tests/test_export.py       # 拆块 / 符号表读取 / 调用关系解析
python tests/test_online_xref.py  # CPU状态解析 / V2.8无缩进AWL / 交叉引用 / 格式解码
python tests/test_monitor.py      # 程序段监控 STL 求值器
python tests/test_plceng.py       # 引擎在线命令日志判读
python tests/test_all.py          # 容器/解析层,部分小节需真实工程样本(缺了打印 SKIP)

离线部分 clone 下来就能跑。每套都含反向哨兵(哨兵若 PASS 就说明测试本身坏了), 关键修复还做过故障注入验证 —— 把修复改回去,确认测试真的会 FAIL,再还原并核对文件 MD5。

教训:判据自己有洞时,它会一路 PASS,看起来一切正常。 唯一的发现办法是把判据抽成独立函数、给它本身写单测。

已知边界(诚实标注)

  • 在线层(snap7 与引擎在线命令)均未经过真机验证:开发时手边无 CPU。接真机请先 用 smart_plc_info / smart_engine_status 试探;引擎在线命令的真机首验清单见 docs/ENGINE_ONLINE.md(含 opmode 枚举校准、下载首试步骤)。

  • 下载到 PLC 已接线但未真机验证PRJ_Download 全链(连接检查→能力探测→预检→下载) 已接好、冒烟测试通过(未连接时正确 SKIP),但没在真 CPU 上跑过。

  • smart_event_log 只回读条数:事件条目结构未逆向,内容解析待真机校准。

  • force 强制不支持:S7-200 SMART 固件不实现(协议层无对应物),不要对标博图的强制表。

  • smart_export_all 的符号表读取:V2.8 的 SYM_GetRow 卡死,读符号用 smart_symbols(离线解析)替代。

  • smart_ui_output:V2.8 输出窗口是自绘控件,UIA 读不到;编译结果请走 smart_compile_and_export 的引擎日志。

  • 不还原逐网络 LAD 图(定长记录字段布局未逆向完,强行输出等于编造);语言切换 (PRJ_SetLang 报成功没生效);离线拿不到当前 CPU 型号(改由 UI 层读)。

  • 编程语言只有 LAD / FBD / STL,没有 SCL —— 要写 SCL 得上 S7-1200/1500 + 博途。

文档索引

文档

内容

docs/V28_PORT.md

V3→V2.8 符号映射、实测记录、突破过程

docs/v28_storeretrieveverify_exports.txt

V2.8 全部 3565 个导出符号 dump

docs/ENGINE_ONLINE.md

引擎在线命令(下载/上传/启停/事件日志)接线说明 + 真机首验清单

docs/COMML7_DIRECT.md

commL7 通信栈逆向:脱机直连 CPU 的协议结论与验证对照表

DELIVERY.md

V2.8 移植版交付清单

致谢

基于 bulaofen0036-coder/Smart200-MicroWIN-MCP 移植到 STEP 7-Micro/WIN SMART V2.8 并扩展(在线监控、交叉引用、程序段监控、 引擎在线下载/上传/启停、脱机直连协议逆向)。

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    A
    maintenance
    MCP server that connects AI assistants to Siemens TIA Portal via the Openness API. AI-assisted PLC programming, project management, hardware configuration, cross-reference analysis, and deployment. 19 tools, 230 actions.
    35
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    The first and only MCP server for PLC (Programmable Logic Controller) intelligence. Give any AI agent direct access to industrial automation data — ladder logic, tag databases, cross-references, fault root cause analysis, and sequence blockers
    MIT