TIA Portal Openness MCP

Source and setup

View GitHub source

github.com

Setup guidance pending

See the original source for supported tools, dependencies, and permissions.

Installation test pending

TIA Portal Openness MCP connects an MCP client to Siemens TIA Portal V20 or V21 over stdio or HTTP. The repository documents 235 tools for project, hardware, PLC, HMI, and online operations, with 65 core tools listed by default. The Windows executables for V20 and V21 are separate. The documented prerequisites include the matching TIA Portal release and .NET Framework 4.8. The repository suggests running Doctor first and beginning with a read-only walkthrough of the project.

↓ 0 Downloads ↗ 0 Share clicks

Introduction source: official · Wang Hui · introduction-20261106 Reference

Author's original introduction

Drive Siemens TIA Portal V20 or V21 from any MCP client (stdio or HTTP)

Original SKILL.md

Skillπ does not display the original SKILL.md on this page. View the original source ↗ The source site governs the file contents, license, and use terms.

Version history

  1. v2.7.11 GitHub repository release ↗
    Original release notes

    ## [2.7.11] - 2026-11-07 - 服务端只读模式、软件单元的变量表与按单元导出、认出交叉引用诊断节点 工具数不变(238)。`GetPlcTags`、`ExportBlocks`、`ExportBlocksAsDocuments` 各多一个可选参数 `softwareUnit`; 新增启动参数 `--read-only`。 ### 新增 - **服务端只读模式(#67 第一阶段,感谢 @BoykaHe)**:启动时加 `--read-only`(或 `TIA_MCP_READ_ONLY=1`), 读取、导出、连接 / 打开 / 关闭工程照常;改工程、编译、保存、下载、写在线值、反射调用和不认识的工具一律拒绝, 被拒的调用什么都不执行。直接调用、`CallTool`、HTTP 走同一张表;`closeForeignProject=true` 和默认会改 Windows 用户组的 `Doctor` 也被拒(`Doctor(fix=false)` 放行);打开旧版本工程不做升级;导出碰到 PLC 在线时不自动断开在线, 改为报错。导出会写入(并覆盖)调用方指定的路径。这个开关只管 MCP 服务端,和 `tia` 命令行动词一起用会报错退出。 `lite` / `full` 档位只管列出哪些工具,不是写保护。 - **软件单元里的变量表和用户常量(#68,感谢 @BoykaHe)**:`GetPlcTagTables` 列出单元变量表 (`Software units/<单元>/<表>`),`ExportPlcTagTable` 按这个路径导出;`GetPlcTags` 默认读 PLC 根目录加全部单元, `softwareUnit` 只读一个单元。常量的 `value` 是原始定义文本,不求值;注释带全部项目语言。单元读不出来时 `complete=false` 并给出警告;指定了不存在的单元直接报错并列出现有单元。 - **按软件单元批量导出(#66,感谢 @BoykaHe)**:`ExportBlocks` / `ExportBlocksAsDocuments` 加 `softwareUnit`, 只导这个单元的块,不混入根目录和其他单元;`preservePath` 时放在 `Software units/<单元>/` 下。 不指定单元时 `meta.scope=plcRoot`,`excludedSoftwareUnits` 和消息里写明哪些单元没包含。 ### 修复 - **交叉引用碰到博途的诊断节点时报成「完整、0 条」(#60 补充,感谢 @BoykaHe 提供复现)**:博途有时在源对象的位置 放一句「请重新创建交叉引用信息」的提示,节点不抛错、Path 为空、References / Children 都是空的。现在名字是这类提示 (中 / 英 / 德)且 Path 为空时,不再读它的分支,结果标为不完整并点名所在分支。两个条件缺一不判。 - **`ExportBlocks` 的逐块失败只进日志**:某个块导出失败(文件被占用、许可证、Openness 拒绝)时,结果仍报成功、 调用方看不到。现在 `meta.failures` 逐条列出、`meta.failedBlocks` 计数,有失败时 `success=false`。

  2. v2.7.10 GitHub repository release ↗
    Original release notes

    ## [2.7.10] - 2026-11-07 - 交叉引用读进数据块成员、列块和类型覆盖软件单元、读 UDT 字段 工具数不变(238)。`GetTypeInfo` 多一个可选参数 `includeMembers`。 ### 修复 - **交叉引用读进子分支(#60 后半,感谢 @BoykaHe)**:`GetCrossReferences` 现在递归读取 `SourceObject.Children`。 V21 上全局 DB 和背景 DB 的引用都挂在成员子分支里,以前顶层读不到就是 0:真机上 `DB_HMI` 从 0 处变成 29 处, 一个背景 DB 从 2 处变成 84 处。每条结果新增 `SourceHierarchy`(如 `DB_HMI."DB_HMI".CmdStart`)。 某个分支读失败只停这个分支、兄弟分支照读,返回 `UnreadBranches` 列出没读到的分支;设深度和条数上限; 只读 Name / Path / References / Children / Locations,不碰 `UnderlyingObject`,不重试;博途进程退出直接报错。 删除预览里的引用也带层级路径。 - **`GetBlocksWithHierarchy` 漏掉软件单元里的块(#61,感谢 @BoykaHe)**:现在在顶层加一个 `Software units` 组、 每个单元一个子组,块路径为 `Software units/<单元>/<组>/<块>`,`ExportBlock` / `GetBlockInfo` 等直接认; 从根节点 `Program blocks/` 拼出来的路径也能解析。`meta.scope` 标明覆盖范围,单元读不出来时 `complete=false`、`excludedScopes` 列出被排除的范围。 - **绝对地址 HMI 变量的 PLC 同步自检空转**:`ValidateClassicHmiMinimalPackagePlcSync` 原来只核对符号寻址的 `ControllerTag`,全是绝对地址的包一个绑定都没核也报通过。现在 I/Q/M 地址按 PLC 清单里的地址逐个核对 (`%E`/`%A` 与 `%I`/`%Q` 视为同一地址),PLC 里没有变量的地址、清单不带地址、清单被截断、DB 地址无法离线核对, 都会给出警告和计数(绝对寻址本身不要求 PLC 变量,所以不阻断)。`GetPlcTags` 的结果可以原样传入。 ### 新增 - **软件单元里的 PLC 数据类型(#62,感谢 @BoykaHe)**:`GetTypes` 同时列出 PLC 根和各软件单元的类型,每项带 `TypePath`(如 `Software units/U1/UDT_A`)和 `Owner`;`GetTypeInfo` / `ExportType` / `ImportType` 等按这个路径 定位单元里的类型。单元读不出来时 `meta.complete=false`。 - **`GetTypeInfo(includeMembers=true)` 读 UDT 字段**:从导出结果里列出字段的层级路径、数据类型、显式初值(含数组元素 初值)和注释,同时支持 Member 直接嵌套和 Member → Sections → Section → Member 两种形状;文档里只要有没走到的 字段就 `complete=false` 并说明,原文仍以 `ExportType` 为准。类型未编译等原因导不出时,基本信息照常返回,字段部分 `complete=false` 并写明原因。

  3. v2.7.9 GitHub repository release ↗
    Original release notes

    ## [2.7.9] - 2026-11-07 - 中文入参不再被 HTTP 解坏、交叉引用残缺不报成功、经典 HMI 变量表支持绝对地址 工具数不变(238)。 ### 修复 - **HTTP 传输把中文 / 特殊字符入参解坏(感谢 @FalseLeonLai,来自 PR #59)**:请求头 `Content-Type` 不带 charset 时, .NET Framework 的 `HttpListenerRequest.ContentEncoding` 返回系统默认编码(中文 Windows 上是 GBK),而不是 null, 原来的「取不到就用 UTF-8」从不生效。组名里的不换行空格 U+00A0 被解成「聽」,该组下的块全部 `Block not found`, 中文路径和注释同样损坏。现在默认按 UTF-8 解码,只有客户端明确写了 charset 才按它解。stdio 方式不受影响。 - **`GetCrossReferences` 查到一半出错仍报成功(#60,感谢 @BoykaHe)**:Openness 枚举中途抛异常时,原来吞掉异常、 把已收集的半截(甚至空表)当完整结果返回,`success=true`。现在返回已收集的部分,同时 `Complete=false`、 `Truncation` 写明原因,`success=false`;结果对象没有 `Sources`、某个源的 `References` 取不到、或某个源带有尚未展开的 子分支(`Children`),也一样标不完整。枚举中博途进程退出则直接报错,不当作部分结果。 `DeletePlcBlock` / `DeletePlcTagTable` / `DeletePlcType` 的预览同步加 `crossReferenceComplete` / `crossReferenceTruncation`, 不完整时给出警告,避免「只查到 4 处引用」被当成全部。(子分支 `Children` 里的引用的递归读取另行跟进。) - **`BuildClassicHmiTagTableXml` 不支持绝对地址、静默忽略未知参数(#57,来自 #13 @King618219 的实测)**: 变量带 `LogicalAddress`(或 `Address`,如 `%M10.0`)时生成 `AddressAccessMode=Absolute` + `LogicalAddress` + `Connection`, 结构与 #13 中 V21 导入验证过的一致;连接名可在表级 `ConnectionName` 给出、变量级 `Connection` 覆盖; 表级 `Absolute=true` 时每个变量都必须有地址。不认识的键直接报错并列出支持的键(错误码 `InvalidParams`),原来会悄悄生成内部变量。 `analysis` 新增 `absoluteBindingCount`。V21 上经典 / 精简面板的变量导入只认绝对地址。 ### 新增 - **导出被拒时的结构化错误上下文(#63,感谢 @BoykaHe)**:`ExportBlock` / `ExportType` 在导出前检查不过或导出本身失败时,错误文字末尾附一行 `ERROR_CONTEXT: {json}`,含 `code`、`phase`(`precheck` / `export`)、对象身份、`scope`(单对象为 `object`, 博途进程已退出或没打开工程为 `session`)、`reason`、`rootCauseKnown`、`retryable`(恒为 false)和博途原话 `nativeMessage`。 只凭 "not permitted" 判断不出是权限还是能力限制,所以 `reason=notPermitted` 时 `rootCauseKnown=false`。

  4. v2.7.8 GitHub repository release ↗
    Original release notes

    ## [2.7.8] - 2026-10-26 - 读软件单元、Unified 离散报警、反射调用的拒绝文字说清楚 工具数 235 → 238;精简档不变(新工具用 FindTools 找、CallTool 调)。 ### 新增 - **`GetSoftwareUnits`(#55,感谢 @BoykaHe 的详细报告)**:列出 S7-1500 的软件单元(Software units)和每个单元里的块。 Openness 只能经 `PlcUnitProvider.UnitGroup.Units` 拿到单元,原来 `GetSoftwareTree` 和各块工具都看不到单元里的块。 - 每个块给出 `Software units/<单元>/<组>/<块>` 形式的路径,`ExportBlock`、`GetBlockInfo`、`DescribeBlockLogic` 等块工具直接认这个前缀,不用新参数。 - `GetSoftwareTree` 现在也列出各单元的块。 - **`EnsureUnifiedHmiDiscreteAlarm` / `GetUnifiedHmiDiscreteAlarms`(#54)**:建 / 改 WinCC Unified 离散报警并逐项读回; 列出现有报警和工程里实际有的报警类别。写入前先拒掉 TIA 会收下、但编译才报错的输入:触发变量不存在、 报警类别不存在、同一变量同一位已被别的报警占用、位号超出变量位宽,以及触发变量的数据类型不对—— V21 实测只有 Bool 和位串类型(Byte / Word / DWord / LWord)能当触发变量,整数(Int、UInt、DInt…)和 Real、String 都会在 HMI 编译时报 "The data type of the tag is not permitted for this type of alarm"。 ### 修复 - **反射调用的拒绝文字(#55)**:`InvokeService` / `InvokeObject` 在 `allowWrite=false` 时拒绝非白名单方法,原来返回 「Method not allowed (read-only mode)」,读起来像引擎整体处于只读模式。现在说明这是**这一次调用**的限制、 列出 `allowWrite=false` 时能调的方法,并指向 `GetObjectProperty` / `GetSoftwareUnits`。 ### 文档 - **`ApplyUnifiedHmiScreenDesignJson` 的字体(#54)**:每个控件可带 `font`,如 `{"Size": 28, "Weight": "Bold"}` (`Weight` / `Name` 用 TIA 的枚举名,如 `Bold`、`SiemensSans`),可用 `GetObjectProperty(propertyPath="Font.Size")` 读回。 原来已经支持,只是工具描述里没写。 - **一次放多个控件(#54)**:`ApplyUnifiedHmiScreenDesignJson` 一次调用放完整个画面(V21 实测 100 个控件约 9 秒, 单个控件 0.1–0.3 秒);逐个调 `EnsureUnifiedHmiScreenItem` 时,每个控件都要多一轮模型往返。

  5. v2.7.7 GitHub repository release ↗
    Original release notes

    工具数不变(235)。只影响 `EnsureUnifiedHmiConnection` 在 TIA V21 上新建连接的方式;V20 行为不变。 ### 修复 - **V21 上 `EnsureUnifiedHmiConnection` 改走硬件层连接接口(#13,感谢 @King618219 实测指出)。** V21 的 Openness 提供 `CommunicationManagement.Connections.Create<HmiConnection>(HMI 网口节点, PLC 的 CPU, PLC 网口节点)`: - **经典面板**(精简 / 精智,含二代屏):现在能自动建 PLC↔HMI 连接。HMI 变量通过 XML 导入时用绝对地址 (`AddressAccessMode=Absolute` + `LogicalAddress`,非优化 DB);起始画面仍需在博途界面里设一次。 - **WinCC Unified 面板**:新建的连接是**集成连接**(PLC 伙伴已设好),`EnsureUnifiedHmiTag` 可以直接按 PLC 变量名 符号绑定,不再必须用绝对地址和非优化 DB(#50、#53 相关)。 - 前提:两台设备的以太网口在同一条子网上(`ConnectDeviceNodesToProfinetSubnet`,HMI 端传接口模块,如 `HMI_1/HMI_1.IE_CP_1`)。没组网时直接拒绝并说明,不改任何东西。 - 同一对 HMI 和 PLC 之间已有连接时建不了第二条:报错会点名已有的连接,复用它的名字即可(已有的连接若是旧版 建的非集成连接、又需要符号绑定,在博途界面删掉后重跑本工具)。 - Unified 面板上硬件层建不成时退回原来的方式(非集成连接),并在结果里写明原因。 - **TIA V20**:没有这个接口,行为不变;经典面板的报错改为说明「V20 建不了、V21 可以」。

  6. v2.7.6 GitHub repository release ↗
    Original release notes

    工具数 224 → 235;精简档 62 → 65(三个删除工具按惯例以本名列出,CallTool 不转发)。 ### 新增 - **`GetPlcTags`**:直接列 PLC 变量(名称 / 类型 / 地址 / 注释 / HMI 可见性),不用先导出 XML; 可按变量表、名字片段、地址前缀筛(`%Q` = 所有输出),查某个地址被谁占、哪些地址还空着。 - **`SetPlcTag`**:建一个变量,或原地改已有变量的名字 / 类型 / 地址 / 注释;改完读回。重名拒绝; 地址被别的变量占着时提示(不拦,TIA 本身也允许重叠);注释语言不对时在任何改动之前就拒。 - **`DeletePlcTag`** / **`DeletePlcWatchTable`** / **`DeleteDevice`**:和 `DeletePlcBlock` 同一规格—— 默认 `dryRun=true` 只预览影响,确认后实删并读回。`DeleteDevice` 只认设备名或它的 CPU / 头模块名, 给模块名会拒绝(否则「删一个模块」会变成连程序删掉整个站)。 - **`CreatePlcTagTable`** / **`CreatePlcWatchTable`**:建空变量表 / 空监控表,可放进已有的组。 - **`CreateInstanceDB`**:直接给 FB 建背景 DB(默认名 `<FB>_DB`、自动编号),读回确认它属于这个 FB。 - **`RenamePlcObject`**:改块名 / 块号、数据类型名、变量表名、监控表名、设备名。先查重名;块开着 自动编号时改号会如实拒绝(Openness 关不掉自动编号);改 DB 名会提醒 HMI 侧按符号绑定的变量会断链。 - **`CompileHardware`**:编译一台设备的硬件组态(模块、地址、网络、固件),返回 TIA 的错误 / 警告—— `CompileSoftware` 只编程序,插模块、改地址之后用它查硬件问题。 - **`ArchiveProject`**:把打开的工程归档成一个 `.zap21` / `.zap20` 文件(备份、交接)。有未保存改动时 拒绝(引擎不替用户保存);同名归档不覆盖。 ### 修复 - **经典面板上调 `EnsureUnifiedHmiConnection` 只报 `Create(string) not found on ...ConnectionComposition`(#13 实测)。** 现在直接说明:这是经典 WinCC 面板(精简 / 精智),Openness 建不了经典 HMI 连接,要在博途界面里建一次; 这个工具只用于 WinCC Unified 面板。 - **V20 上导入 HMI 画面 / HMI 变量表 / HMI 连接 / 工艺对象 XML 会因版本头失败。** 这 4 个导入入口没像块、 数据类型、PLC 变量表那样先把 `<Engineering version="V21" />` 改成当前博途版本、补 UTF-8 BOM, 而引擎自己生成的 HMI XML 就写着 V21 头。现在 4 个入口都先做这一步(来源:fork GabrielSRR ffebe6e 指出)。 - **`Bootstrap` 和 `RunCapabilitySelfTest` 标称只读,却可能弹 UAC 把当前用户加进 Openness 组。** 两者调用的组检查在「不在组里」时会自动加组。现在只查不改;要加组请用 `EnsureOpennessUserGroup` 或 `Doctor`(fix=true)(来源:fork yaorb a0eeb38 指出)。

  7. v2.7.5 GitHub repository release ↗
    Original release notes

    连接失败说清原因、CLI 参数顺序(#51)+ Unified 连接不再假成功(#50)。 ### 修复 - **连不上博途时只报最后一句(#51)。** 引擎先逐个附加正在运行的博途,全都附加不上才新起一个实例;原来新起也失败时只报 `Connection to TiaPortal failed`,前面每个进程为什么附加不上只进了日志。现在报错里逐个列出(附加超时 / 异常类型和首行)。 - **全局参数写在命令前面时被静默当成 MCP 服务器(#51)。** `TiaMcpServer.exe --tia-major-version 21 prewarm` 原来不报错、以服务器模式起来后 exit 0。现在照常执行该命令;`gen --tia-major-version 21 x.json` 也不再把 `21` 当成 spec 路径。 - **`EnsureUnifiedHmiConnection` 报 "ensured",运行时却连不上(#50)。** `DisabledAtStartup` 原来保持 Openness 默认的 `True`(运行时不建立连接),`InitialAddress` 里的 IP 保持写死的 192.168.0.1/.2,伙伴 `Partner/Station/Node` 在 Openness 里只读、从未建立。现在 `DisabledAtStartup` 改为 `False`、两端 IP 按硬件组态改写,均读回确认;核对两端同子网;改不成就报失败。消息如实标注**非集成连接**:HMI 变量需用 `address` 绝对地址(非优化 DB)绑定;要按 PLC 符号绑定,请在博途「设备和网络 → 连接」里手动建集成连接。手动建的集成连接只读回、不改写地址。 - 工具说明、Bootstrap、SKILL 中「用符号绑定、不要绝对地址」的说法已更正。 ### 验证 - 离线自检 379/379。 - V21 隔离实例真机:连接被置为「启动不连 + 错 IP」时,2.7.4 照报成功、什么都没改;2.7.5 改正并读回。从零新建工程:2.7.4 建出的连接 `DisabledAtStartup=True`,2.7.5 为 `False`;V20 从零新建同样为 `False`。 ### 下载 `TIA_MCP_Delivery_v2.7.5_20261014.zip`:V21 + V20 双引擎,解压即用,用法同 2.7.4。

  8. v2.7.4 GitHub repository release ↗
    Original release notes

    ## 下载 **`TIA_MCP_Delivery_v2.7.4_20261007.zip`(见下方 Assets)** —— 完整交付包,解压即用,**同时带 V21 和 V20 两个引擎**。 - **V21 用户**:解压后跑 `配置MCP.bat`(或 `tia.cmd`) - **V20 用户**:解压后跑 `配置MCP-v20.bat`(或 `tia-v20.cmd`) git 克隆只带 V21 运行时(`runtime/v21`),V20 引擎只在这个 zip 里。 --- 一轮整体审查与加固(PR #45,感谢 @zy13027),加上两个 HMI 只读批量工具(PR #44,感谢 @DenLucas)。工具数 222 → 224。完整条目见 [CHANGELOG](CHANGELOG.md)。 ## 修复(摘要) - **Openness 调用从不串行**:宿主并行发来的请求会同时进入同一个博途句柄。现在所有需要博途的工具排队过同一把闸。 - **CallTool 对 9 个工具是坏的**(异步工具返回 `Task` 对象、注入参数永远报缺参),现在与直接调用一致。 - **HTTP 桥**:超时一次就连累后续所有请求;两个客户端用同一个请求 id 会串响应;`localhost` 前缀实际监听全部网卡,没设 key 时局域网机器带 `Host: localhost` 就能进来——现在没设 key 时只接本机 TCP 连接。 - **下载**:`DataBlockReinitialization` 等 4 个提示的应答类型/取值不对,从来没生效;下载后 CPU 可能停在 STOP;`Ok=false` 无错误文本时报成功;在线模块与组态不一致时不再静默接受(会写进 Warnings)。中止测试/调试功能改为显式参数 `abortActiveTests`。 - **工程保护**:CloseProject 会关掉用户自己开着的工程;先开自己的工程再挂接到用户工程后,「是不是我们开的」判定会过期;OpenProject 路径写错会白白关掉当前工程。 - **假成功**:GoOffline 吞异常、GoOnline 的 `ipAddress` 从未生效、`CheckDownloadReadiness` 的一致性写死为 true、SetWatchTableModifyValue 没写进也报成功、MoveBlockToGroup 失败会丢块、`ImportBlocksFromDirectory(overwrite=false)` 仍可能覆盖。 - 引擎在部分 V21 机器(装在非 C: 盘)上根本起不来。 - 全部工具带 MCP annotations;会动 CPU 或删数据的 7 个工具以本名列出,`CallTool` 不转发它们。 ## 新增 - **`GetHmiTagDetails` / `GetHmiScreenItemDetails`**:一次调用读出整张 HMI 变量表(含变量表分组里的表)或整个画面的全部对象属性,只读。读不到的对象列入 `Failed`、拼错的属性名写进 `Meta.unreadableAttributes`,不会报假成功;传 PLC 路径会直接拒绝。 - `InvokeObject` / `InvokeService` 放行只读的 `GetAttributes`。 ## 验证 - 离线自检 355 条全过(本轮新增的下载应答用例先在原代码上跑出红,修后转绿);V20 / V21 两个引擎 0 错误编译,版本号 2.7.4,exe 内无构建机路径;`Validate-Bundle -Strict`、死引用闸、精简档检查均通过。 - **TIA V21 隔离实例真机跑过**:建工程 + SCL + 编译 0 错、CallTool 建块组并移块后编译 0 错、CallTool 拒绝 DownloadToPlc、下载前预检、关闭自己建的工程;PLC + WinCC Unified PC 工程上读全部变量表、拼错属性名被报出、PLC 路径被拒、画面对象位置尺寸正确、未知画面报错。 **没验到的部分**:没有真 PLC / PLCSIM,**下载本身没有真机验证**(下载提示的应答只有离线用例 + 对 V21 程序集的反射核对);经典 HMI(精智/精简面板)和 V20 引擎没有真机跑。遇到问题请开 issue。 **提示**:V21 的 Openness 白名单在 `HKLM\SOFTWARE\Siemens\Automation\Openness\AllowList\<exe 名>`,不是 `21.0\Whitelist`;无界面运行时没登记会挂一个「Openness 访问」窗口等人点。

  9. v2.7.3 GitHub repository release ↗
    Original release notes

    ## 下载 **`TIA_MCP_Delivery_v2.7.3_20260916.zip`(见下方 Assets,约 11 MB)** —— 完整交付包,解压即用,**同时带 V21 和 V20 两个引擎**。 - **V21 用户**:解压后跑 `配置MCP.bat`(或 `tia.cmd`) - **V20 用户**:解压后跑 `配置MCP-v20.bat`(或 `tia-v20.cmd`) git 克隆只带 V21 运行时(`runtime/v21`),V20 引擎只在这个 zip 里。 --- 两条修复,都是「工具在,但一碰到真实工程就不干活」。工具数不变(222)。 ## 修复 **画面分组里的画面,对所有画面工具都是隐形的**(PR #41,感谢 @DenLucas 发现并修复)。 查画面只读 HMI 软件根上的 `Screens`,而真实的 WinCC Unified 工程几乎都用画面分组来组织画面(比如 `00_ScreenLayout/PopUps/LogOff`)。放进分组的画面 `GetHmiScreens` 列不出来、`DescribeHmiScreen` / `ExportHmiScreen` / `ExportHmiProgram` / `EnsureUnifiedHmiScreen` / 按钮动作绑定按名字找不到——只报一句「找不到」,没有任何迹象指向「是因为它在分组里」。现在这些工具都会递归进分组:Unified 走 `ScreenGroups → Groups`,经典 HMI 走 `ScreenFolder → Folders`。 合并时补了同一个坑的另外两处:反射桥的 `objectKind=HmiScreen` / `HmiScreenItem`(`DescribeObject`、`GetObjectProperty`、`InvokeObject` 等)原来也只查根目录。遍历逻辑抽成了不依赖 SDK 的独立文件,离线测试可以直接喂假对象。查找失败仍然当「找不到」处理,不会抛异常。 **写 Unified HMI 的 JS 事件脚本后强制跑 `SyntaxCheck()`,在 TIA V21 上会偶发把博途进程整个带走**(issue #36,感谢 @Moy-GH 报告)。 进程一没,刚写进去、还没保存的脚本也跟着丢。现在 `SetUnifiedHmiButtonEventScriptCode` 与 `EnsureUnifiedHmiButtonAction` 新增 `syntaxCheck` 参数,**默认 false**。不查的时候不再发 `syntaxErrorCount`(发个 `0` 就等于把「没查」谎报成「查过了没错」);检查真把进程干掉时不再返回成功,而是如实报告并给出恢复步骤。 ## 验证 - 离线自检 147 条全过(新增 10 条画面分组用例;故意把遍历改回只查根目录,其中 6 条会变红,证明用例是有效的)。 - 属性名对照 V21 Openness 程序集核对过:`HmiSoftware.ScreenGroups` → `HmiScreenGroup.Groups` / `Screens`;`HmiTarget.ScreenFolder` → `Folders` / `Screens`。 - 分组遍历由 PR 作者在真实 V21 工程(WinCC Unified)上验过:21 个画面全部列出,两层深的 `LogOff` 能按名字找到。 - 两个引擎在打包版本上重新编译:版本号 2.7.3、源码提交一致、V20/V21 是两份不同的构建;`Validate-Bundle` PASSED。 **没验到的部分**:合并时补的那一版遍历没有重新跑真机(MCP 自身建不出画面分组,本机也没有带分组的 Unified 工程),所以没重跑;经典 HMI(精智/精简面板)嵌套文件夹这条路径只有离线用例和程序集核对,没有真机验证。遇到问题请开 issue。

  10. v2.7.2 GitHub repository release ↗
    Original release notes

    ## 下载 **`TIA_MCP_Delivery_v2.7.2_20260905.zip`(见下方 Assets,约 12 MB)** —— 完整交付包,解压即用,**同时带 V21 和 V20 两个引擎**。 - **V21 用户**:解压后跑 `配置MCP.bat`(或 `tia.cmd`) - **V20 用户**:解压后跑 `配置MCP-v20.bat`(或 `tia-v20.cmd`) > 之前的版本里,`tia-v20.cmd` 会提示「V20 请到 GitHub Releases 下载交付 zip」, > 但历史发布**从来没有附过这个 zip** —— V20 用户按提示去下载,下不到。这一版补上了。 > git 克隆只带 V21 运行时(`runtime/v21`),V20 引擎只在这个 zip 里。 交付包已在**解压后的位置**独立验过:`Validate-Bundle` PASSED、两个引擎都起得来且 `tools/list` 都是 222。 --- 三条都来自 issue #33 的现场反馈,都是「工具在,但用不上」。 ## 修复 **名字里含 `/` 的设备项,从原理上寻不到址。** `deviceItemPath` 用 `/` 分段,而西门子的模块名本身常常自带 `/`:`DQ 16x24VDC/0.5A ST_1`、`AI 4xI 2-/4-wire ST_1`、`AQ 4xU/I ST_1`、`DI 6/DQ 4_1`。逐段比对的话,这些模块**不是找不到,是根本表达不出来**——所有按设备项路径取对象的硬件工具对它们一律失效。现在匹配子项时会把后续若干段拼回 `a/b/c` 再比,跨度从大到小试,先匹配更长(更具体)的那个。子项名是已知的有限集合,所以这不是猜;既不需要引入转义语法,也不改变原来能用的写法。 **设备项本级没有 I/O 地址时,只回一句「没有任何 I/O 地址」。** 地址在分布式 I/O(ET200 系列)和机架式站上常常挂在**子项**而不是模块对象本身,只说「没有」会让人以为工具读不到,转头去查一个没问题的组态。现在本级为空时会下钻一层,把**子项里有地址的**连同地址摘要一并列出来,可以直接换路径重试。 **`GetPlcTagTables` 返回空清单时,答不上来是哪一种空。** 三种成因返回的东西一模一样:这个 PLC 确实没有表 / `TagTables` 属性在这个版本上叫别的名字 / 读属性时抛了异常被吞掉。现在空清单会带上这次遍历的证据(`walkedGroupType` / `tagTablesPropertyFound` / `tagTablesPropertyError` / `groupsVisited` / `notes`),并明说「这不一定表示它没有表」。有表时行为一字不变。 ## 新增 **`ConnectIsolated`** —— 起一个全新的无头 TIA Portal 实例,不 attach、不修改、不关闭任何用户已经开着的窗口或工程。 这条是修一个**把人挡在门外**的组合缺陷:`Connect` 会优先接管**已经开着工程**的那个实例,而 `OpenProject` 又(正确地)拒绝动别人的工程——两条各自正确的行为叠在一起,结果是**只要用户在博途界面里开着任何工程,整台服务器就用不了**。有了这条路,可以一边在界面里干活,一边让 MCP 在自己的实例里跑自己的工程。 必须是该 MCP 进程里的第一个连接动作。已进 lite 默认档——挡掉这条出口等于让「用户正在用博途」变成一个无解的死局。 ## 验证 **V21**:真实工程副本(S7-1200 + S7-1500),全程在隔离实例里、没有碰当时正开着的用户工程(事后核对 portal 进程为证),合并 22/22。 **V20**:V20 引擎 + `--tia-major-version 20` + 一个 V20 工程副本,8/8。这轮顺带更正了 issue #33 里的两个推测: - **V20 读得到模块 I/O 地址**:同一台 S7-1200 上 `AI 2_1` 读到 1 条、`DI 6/DQ 4_1` 读到 2 条。所以「V20 的 Openness 不填充模块 I/O 地址」不是一条普遍限制——那更可能是分布式 I/O(ET200SP)特有的形态,地址挂在子项上,本版新增的子项提示正好用来定位它。 - **V20 的 `GetPlcTagTables` 枚举正常**:两个 PLC 分别列出 1 张和 5 张表。所以枚举返回空也不是 V20 的普遍问题,而是某个具体工程/软件对象的形态问题——本版新增的遍历证据字段就是为了把这种情况钉住。 反向哨兵覆盖:**拼出来的错名字仍必须报错**(防贪心匹配把错路径吃成对的)、普通模块照旧、`GetDeviceItemTree` 未被改坏、有变量表时不掺诊断字段、2.7.1 那批「假成功」修复无回归。 **仍未验到的部分**:手上的工程里没有 **ET200SP** 这种分布式 I/O 站,子项下钻是在 S7-1200 CPU 上验的(同一段代码,但没覆盖 ET200SP 的实际形态)。变量表枚举的**空清单分支**在这些工程上触发不到,改用临时插桩确认了证据字段确实被采集。 工具 221 → 222,lite 54 → 55(仍在 128 上限内)。离线套件 126/126,死引用闸门 PASS。

  11. v2.7.1 GitHub repository release ↗
    Original release notes

    纯修复版,没有新功能,工具数不变。修的全是同一族缺陷:**把「没做成」说成一个确定的结论**。 这类缺陷比崩溃危险得多。崩溃会让调用方停下来;一句「找到 0 个」「已下线」「0 处差异」会让它**继续往下走**,并把这个错误结论当作事实带进后面每一步。对着 AI 客户端尤其如此——它没有第二个信息源来质疑你。 ## 怎么找出来的 新增发版前闸门 `scripts/Sweep-WrongPathHonesty.py`:拿真项目给**每个只读工具**喂一条不存在的路径,凡是「返回成功」的都列为嫌疑。第一轮跑出 10 个。 这条检查**离线跑不了**(要判断"路径不存在时的反应"就得有真项目),所以它不在 CI 里,是发版前的手工闸门。脚本自带反向哨兵:正确输入必须仍然成功——否则「所有工具一律报错」的坏实现也能满分通过,那时它测的就不是诚实,是「有没有全坏」。 ## 主要修复 **`CompareSoftwareToOnline` 是这批里最贵的一条。** 这个工具的全部价值就是回答「要不要下载」。路径写错时它返回 `Entries=null` 的正常响应 → 调用方读到「0 处差异」→ 得出「在线离线一致,不用下载」。比对**失败**时同样如此,而且其中一条路径还硬写 `IsOnline=true`——实测拿到的正是 "The operation is not permitted in offline mode",即根本没在线,字段和消息自相矛盾。另外,以 `Identical` 结尾的比对状态被算成了差异,会把「一致」报成「N differences」。 **`GoOffline`** 路径写错、或 `OnlineProvider` 拿不到(那一路**什么都没做**),都回一句「'X' is now offline」。调用方以为在线会话已断开,实际它还挂着:后续 `CompileSoftware` / `Export*` 会被 "not permitted in online mode" 挡住,现场 CPU 的编程连接也一直被占。 **`GetSoftwareTree`** 路径不存在时把一句 "No PLC software found" 当作**树的内容**返回,工具层只判非空即算成功 → `message` 写着「Software tree retrieved from 'XXX'」而树体里写着找不到。同一个 `catch` 还把异常文本也当成树返回,**遍历炸在半路也报成功**。 **`GetTechnologyObjects`** 的「没连项目」「路径写错」「枚举炸了」三条全返回空列表,报成「找到 0 个技术对象」。空列表只有一个合法含义:解析到了这个 PLC,它确实没有 TO。 **`GetOnlineState` / `GoOnline`** 对不存在的 PLC 返回 `State="Offline"`——**给一个没测过的问题一个确定的答案**。拿不到 `OnlineProvider` 时改报 `State="Unknown"` 并说明「未测量 ≠ 离线」。 **反射桥 7 处 + HMI Describe 族 13 处**返回 `Message="Object not found"` + 空成员表。反射桥恰恰是**用来猜路径**的工具,猜错必须响,否则每次猜错都被记成一条「已确认为空」的事实,越猜越偏。这些现在报参数错误,不再是「服务器内部意外错误」。 **Describe 族的 `meta.success`** 原来写的是「成员表非空」,把**空**当成了**失败**:真实存在但没有成员的对象被报成失败,调用方于是去「修」一个没坏的东西。 **`ImportBlock` 的读回校验用文件名当块名**:把 OB100 的 XML 存成 `OB100.xml` 导进去,块在 TIA 里实际叫 `Startup`,于是一次成功的导入被报成 "NOT found after import";反过来块若被静默降级成 OB1,光比名字也可能"对上",只有块号抓得住。改为按 XML 里声明的**块名 + 块号**比对。 还修了 `GetPlcForceTables`,以及 FB/FC 构建器那条「照着报错改不动」的提示(它只报内部形参名,而调用方填的是另一个 JSON 字段)。 剩余 3 个嫌疑(`GetOpcUaConfig` / `GetPutGetAccess` / `ProbePlcMonitorOnlineCapabilities`)返回里带明确的 `ok=false`,自洽,**有意保留**。 ## 验证 真机跑在真实工程副本上(S7-1200 + S7-1500,V21):嫌疑 **10 → 3**;没连项目时会明说要先 `Connect`;路径写错时会失败并列出可用 PLC;**正确路径但离线时,错误指向在线状态而不是「找不到 PLC」**(这条专门防修过头)。反向哨兵确认 38 个只读工具用正确路径照旧成功。离线套件 126/126,死引用闸门 PASS。

  12. v2.7.0 GitHub repository release ↗
    Original release notes

    补的是**没有它就干不完活**的那类能力:以前能建块却删不掉块、能加整站却改不了模块地址、插不进信号板。同时修掉一条比缺功能更危险的静默错解析。 ## 新增(7 个工具,221 → 全量) **删除族**(#27)`DeletePlcBlock` / `DeletePlcTagTable` / `DeletePlcType` 默认 `dryRun=true`,预览给出解析到的完整路径、对象类型和**交叉引用**(删之前先看谁在用它)。真删之后**重新读一次**确认对象确实不在了才报成功,读不回来就明说「未验证」。删除路径**拒绝正则和通配符**——只接受一个精确路径。默认变量表拒删。 **硬件 I/O 地址**(#33)`GetDeviceItemIoAddresses` / `SetDeviceItemIoAddress` 地址是**引擎原值字节偏移**(`%I2.0` 就是 `startAddress=2`),返回里写明,不做换算。改地址默认 `dryRun=true`,实写后必定回读比对;地址重叠/越界/模块锁定由 TIA 判定,**具体原因原样报回**,不会静默成功。 **机架槽位**(#26)`GetDevicePlugLocations` / `PlugDeviceItem` 槽位号一律来自运行期 `GetPlugLocations()`,不硬编码。`PlugDeviceItem` 是「往已有设备插子模块」,和 `AddDevice`(新建整站)不是一回事。`dryRun` 走 Openness 真实可行性预检,不写工程。 ## 修复 **设备项路径打错一段,不再静默解析成它的父级。** 路径解析器在某一段匹配失败时会把窗口往后滑一格重试,最终被全局扫描命中路径中间的某一段并原样返回:`'S7-1200 station_1/PLC_1/不存在的模块'` 会解析成 `'PLC_1'` 本身——读地址读到父级的空清单、报「这个设备项没有 I/O 地址」,**改地址会改到父级头上**,调用方看不出任何异常。这条影响所有按设备项路径取对象的硬件工具,不只本版新增的。 **`SetDeviceItemIoAddress` 的负数起始地址在预演阶段就报错。** 原来校验只在实写那一路,`dryRun` 对负数一律回答「可以改」——预演反而成了误导。 ## 验证 真机跑在一份真实工程副本上(S7-1200 + S7-1500,V21),**19/19**:含实删块 + 独立回读确认块没了、实改地址 64→700 + 独立回读 + 还原、地址重叠必须失败且地址未变、再删已删掉的块必须报 NotFound。反向哨兵覆盖:`dryRun` 之后工程一字未改、正确的完整路径与省略站前缀的简写路径照旧解析、`GetDeviceItemTree` 未被路径解析器的改动改坏。离线套件 126/126,死引用闸门 PASS。 版本号从 2.5.4 跳到 2.7.0 是有意的:避免与另一条交付线的 2.6.0 撞号。

  13. v2.5.4 GitHub repository release ↗
    Original release notes

    这一版没有新功能,全是修复。它们有一个共同形状:**失败不会被看见** —— 要么把读不回来的结果当成通过,要么把异常吞掉换成一句错的具体结论, 要么让模型照着描述去调一个根本没注册的工具。调用方(尤其是 AI 客户端) 看到的都是绿灯,于是继续往下走,代价推迟到很后面才炸。 ### 修复 - **路径写错不再报「成功,0 个块」。** `GetBlocks` / `GetTypes` 在 PLC 路径解析不到时 照样返回空列表,工具层于是报成功。对模型来说这是最坏的回答:它会据此认为 PLC 是空的, 转头去建一堆已经存在的块。现在解析不到就是明确失败,并列出可用的 PLC 路径。 - **块列表遍历炸在半路,不再把残缺结果当完整结果返回。**「少了几个块」比「一个都没有」 更难发现,因为它看起来完全正常。 - **非法正则不再退化成「没有匹配的块」。** 原来每个块都套一层 try/catch 去跑 Regex, 模式写错时每个块都被吞掉、最后返回空列表 —— 把「你的模式非法」说成了 「工程里没有这样的块」。现在当场报错并说清怎么改。 - **按名字取块不再返回错块。** 名字里含正则元字符时走的是不锚定匹配 + 取第一个, 而西门子块名常带 `.`:请求 `FB_Motor.V2` 会命中 `X_FB_MotorAV2_Old`, **错块被以你请求的名字标注返回**,调用方无从察觉;导出、交叉引用都跟着挂到错误对象上。 现在的次序是:字面精确同名 → 锚定匹配 → 命中多个就报歧义并列出候选。 - **编译结果读不回来不再算作零错误。** `ErrorCount` 是可空的,`null` 专门表示 「没读回来」。五处写成 `(ErrorCount ?? 0) == 0`,其中包括 `tia compile` 命令 —— 它会**退 0**,脚本和 CI 会据此认为编译干净。 - **HMI 模板的「执行 JSON 检查」曾是恒真的同义反复。** 检查委托缺省时它退化成 「前面没报错且有条目」,判据里已经含着「没报错」,永远不可能新增一条错误。 而走这条空转路径的正是发版前的离线验收闸,以及描述里承诺检查 "execution JSON shape" 的那个工具。委托现在是必填的,编译期堵死。 - **批量 HMI 绑定不再把「没抛异常」当成绑上了。** 回读调了却把返回值扔掉; 而 Portal 层会把异常吞成 `success=false` 返回,调用方的 try/catch 永远看不到, 属性名不被控件接受时 TIA 也只是静默忽略。现在判据只认硬证据,读不回来显式标未验证。 - **设备树遍历出错不再被说成「你路径写错了」。** 遍历中途的异常被吞成「找不到」, 于是叫用户去改一个本来就对的路径。真因现在跟着原消息一起给出。 - **连接被拒不再制造孤儿 TIA 进程。** 授权/白名单被拒时继续扫下一个候选毫无意义, 扫空之后会去新起一个无头实例 —— 那次同样会被拒,但进程已经拉起来了, 在用户机器上空转。 - **工具描述不再点名不存在的工具。** 三个名字(`SetForceTableEntry`、`GetCpuOnlineState`、 `GetAxisParameters`)在 209 个注册工具里一个都没有。AI 客户端照做只会撞 tool-not-found,然后自己去找别的路子绕 —— 而其中一个撞上的正是「强制写值」 这种安全敏感操作。现在如实说明事实与真实存在的替代路径。 - **`SetWatchTableModifyValue` 补上物理安全提示。** 它是会真正驱动物理世界的动作里 唯一一个描述中没有一句警示的。 - **反射工具族(`GetObjectProperty` / `ListObjectChildren` / `InvokeObject` / `DescribeService` / `InvokeService`)补齐 `objectPath` 指引** —— 同族的 `DescribeObject` 写清了不同对象类型该填什么,这五个漏了,调用方必然要试错一次。 - **清掉一批恒返回 null 的死后备分支**,以及两个「算了没人看、而且算错」的返回值 (子组递归里写的是覆盖不是累积,最终只反映最后一个子组)。 ### 行为变化(升级前请看) 以前**静默成功**的几种情况现在是**明确失败**:PLC 路径写不对、正则写错、 块列表没读全、编译结果读不回来。如果你的脚本依赖「返回空列表 = 没有」, 需要改成处理错误 —— 那个空列表本来就可能是「没查成」,只是分不出来。 ### 新增:离线自检套件与 CI 这个仓库此前**没有任何测试工程、没有任何 CI**,上面这些修复因此没有东西盯着。 现在有了 `tools/tiaportal-mcp/tests/TiaMcpServer.Tests`(22 条,纯离线、不连 TIA) 和 `.github/workflows/offline-checks.yml`(回归套件 + 工具描述死引用对拍)。 每组用例都带反向哨兵;「执行 JSON 检查」那组还盯 API 形状 —— 委托一旦被改回可选参数,空转路径立刻复活,而所有传了委托的运行期用例一条都不会红。 ### 验证 - **真机**:TIA Portal V21,真实工程副本(101 个块),全程只读。8/8 —— 含 4 条反向哨兵 (正常列块不受影响、合法正则照常过滤 15/101、全限定真名照常取到、真实编译照常拿回 errorCount)。 - **离线**:22/22,并做过故障注入(把委托改回可选 → 2 条如期变红 → 字节级还原 → 全绿)。 - **未能真机复现、只有反向哨兵覆盖的**:编译结果读不回来那一支(无法让 TIA 造出这个状态)、 设备树遍历异常那一支(健康工程上造不出)、授权被拒那一支(复现它意味着故意触发一次授权拒绝)。 这三条的正常路径在上面的真机跑里都验过没被改坏,但**异常分支本身只有代码级依据**,如实标注。

  14. v2.5.3 GitHub repository release ↗
    Original release notes

    ## 新增:`CompileAndDiagnoseHmi` —— AI 能自己读 HMI 的编译错误(#24) `CompileAndDiagnosePlc` 的 HMI 对应版本。生成完画面/变量之后可以直接编译并拿回**结构化的错误与警告**(逐条带 `State` / `Description` / `Path`),模型据此自己改,不必再让工程师去博途界面里手工编译、再把报错文本贴回来。 - **WinCC Unified**:`HmiSoftware` 自身不可编译,实际编译的是**它所属的设备** —— 这与你在博途界面里编译 HMI 时发生的事情一致。因此**硬件组态的诊断会和画面诊断出现在同一份结果里**,这是预期行为。 - **经典屏(精智 / Comfort)**:编译 HMI software 自身。 工具数 208 → 209;精简档(默认)48 → 49,新工具属于金路径,默认档即可直接调用。 ## 发布前的真机验证 TIA Portal V21,MTP700 Unified Basic(6AV2 123-3GB32-0AW0): | 用例 | 结果 | |---|---| | Unified 屏(未配置起始画面,必然编译失败) | `State=Error`,`errorCount=3`,三条错误结构化返回(起始画面未配置 / 两条运行系统密码策略) | | 同工程内 S7-1513 PLC(回归) | `CompileAndDiagnosePlc` → `State=Success`,0 错 0 警 | 第一版实现在 Unified 上其实是**坏的**:编译目标的判据写成了「该对象是不是 `IEngineeringServiceProvider`」,而 Openness 里几乎所有对象都实现该接口——于是代码取到软件的直接父 `DeviceItem` 就收工,那一层却并不持有 `ICompilable`。`GetService<T>()` 在服务不存在时只返回 `null` 而不抛异常,所以它在 PLC 与经典屏上都能过,只在 Unified 上失败: ``` HmiSoftware via DeviceItemImpl.GetService<ICompilable>() returned null ``` 正式判据因此改为「**它到底给不给得出 `ICompilable`**」,并沿 owner 链逐层向上查找(Unified PC 站是 `Device → DeviceItem → DeviceItem` 的嵌套,层数不该被写死)。若一路都找不到,错误信息会把走过的每一层及其结果一并列出。 先前只在经典屏上验过 `Success 0/0`,**那仅覆盖 `HmiTarget` 一条分支**,不足以说明 Unified 可用——本版把两条分支分别验过才发布。 ## 修复:编译诊断不再被静默吞掉 `CompileAndDiagnosePlc` / `CompileAndDiagnoseHmi` 共用的诊断收集逻辑此前整体套在一个 `catch { }` 里。编译诊断是 Openness 代理对象树,代理可能在遍历途中失效(切换工程、TIA 界面抢走句柄);集合代理一旦在枚举时抛异常,**已经读到的诊断会连同异常一起被丢弃**,而 TIA 报出的 `errorCount` 仍是真实值。调用方看到的是 `errorCount: 5` 配上空的 `errors: []`,并且无从分辨「收集失败」与「本来就没有明细」。 现在逐条兜异常:能读到多少返回多少,读取过程中的问题写入 `info`(前缀 `[诊断收集不完整]`),并新增 `meta.diagnosticsComplete` 布尔字段供程序判断。 ## 升级说明 - 引擎二进制已更新(`runtime/v21/TiaMcpServer.exe`,2.5.3)。**替换引擎后 Openness 白名单需要重新登记一次**:以管理员身份运行 `runtime\v21\TiaMcpServer.exe whitelist-register --tia-major-version 21`,或在 TIA 助手的「环境体检」里点一键修复。 - `Validate-Bundle` 全绿;版本在 CHANGELOG / csproj / manifest / runtime 引擎四处一致(2.5.3);`tools-list` 与 manifest 工具数一致(209)。

  15. v2.5.2 GitHub repository release ↗
    Original release notes

    ## 修复 ### `GetPlcTagTables` 恒返回空列表(#22) 拿到的对象已经是 `PlcTagTableComposition` 了,代码却又去它身上找一个 `.TagTables` 属性——找不到;而且非空的属性提示列表还绕开了"直接当集合枚举"的分支,helper 把这一路吞成空列表。 于是**任何 S7-1200/1500 工程调这个工具都返回 `{"items":[], "success":true}`**,看着像"这个 PLC 没有变量表"。 与报告人怀疑的 DLL 补丁级别、槽位名 `-7A1` 都无关——换一台机器、换一个正常命名的 S7-1500 工程照样空。 已在一个含 7 个 PLC 的真实工程上验证:修复前每个 PLC 都返回 `[]`,修复后各自列出 1~6 张变量表,按名导出得到可用的 XML;传入不存在的表名会明确报错并列出可用表名。 同批: - **嵌在用户分组里的变量表现在也能列出/导出**(此前只扫根层)。分组内的表以 `分组名/表名` 返回,`ExportPlcTagTable` 两种写法都收。 - **枚举失败不再伪装成"没有变量表"**,拿不到容器时明确报错。 - `ExportPlcTagTable` 不再把"没这张表"和"找到了但导出被拒"报成同一句话。 ### vci-watch:不再自己拉起博途 判断"博途开着"此前数的是 `Siemens.Automation.Portal.exe` 的进程数。实测**一个开着工程的 GUI 就是 3 个进程**(GUI + HMICompiler + SearchReplaceBackgroundProcess),而一台没开任何工程、只剩一个 Openness 无头残留的机器同样数到 1。 后者会自维持:判定"博途开着" → 起引擎 → 引擎找不到能附着的工程 → **自己再拉起一个无头实例** → 600 秒超时被掐断 → 留下的残留让下一轮继续为真。实测整夜每 72 分钟空转一次。 现在两道闸:带 `-bootstrapper=` 的一律不算会话;起引擎后、`Connect` 之前先用 `ListPortalProcessProjects`(只探测、不拉起)确认真有工程可搭。另外无头残留会被记 PID、下一轮按完整命令行核对后补杀。 ### 版本一致性 `scripts/Validate-Bundle.ps1` 新增检查:CHANGELOG 首条、`csproj` 的 `AssemblyVersion`、manifest 的 `bundleVersion`/`packageName`、以及 `runtime\v21` 里 exe 的 FileVersion 必须一致,对不上直接判失败。 > 2.5.1(vci-watch 退避修复)此前只推到了 `v21` 分支,没进 `master`、没打 tag,**公开发布里从未出现过**;本版一并带上。 --- 工具数仍为 **208**(未增删工具)。完整说明见 [CHANGELOG.md](https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/blob/master/CHANGELOG.md)。

  16. v2.5.0 GitHub repository release ↗
    Original release notes

    **这版的主角**:TIA V21 的版本控制接口(Version Control Interface)。博途工程是二进制的, Git 没法 diff;VCI 把工程映射成一个普通文件夹、每个对象一份文本文件,于是"改了哪个块、改了哪一行" 第一次变得可 diff、可 review、可回滚。本版把整圈做成命令,**不需要在博途界面里点任何东西**。 ### 怎么用(三步) ``` 1) CreateVersionControlWorkspace(workspaceName="git", folderPath="D:\repos\my-plc") 2) ConnectProjectToWorkspace(dryRun=false) ← 整工程自动纳管,几百个块一条命令 3) SyncVersionControlWorkspace(direction="ProjectToWorkspace", dryRun=false) 然后:git add -A && git commit ``` 之后每次想知道改了什么:`GetVersionControlStatus(changedOnly=true)` —— 精确到块, 这就是 change log 的输入。完整指南见 **`docs/version-control-git.md`**。 ### 新增 - **VCI 五件套进入本包(工具数 203 → 208)**:`CreateVersionControlWorkspace` / `ConnectProjectToWorkspace` / `GetVersionControlWorkspaces` / `GetVersionControlStatus` / `SyncVersionControlWorkspace`。其中 `ConnectProjectToWorkspace` 是全新工具:递归遍历工程树,逐对象询问 `GetSupportedFileFormats`,支持的就纳管。**粗粒度优先**(能整体纳管就不往下拆), 不支持的对象**逐条报出**而非静默丢弃。默认 `dryRun=true`。 - **`tools/vci-watch/`**:约 300 行的看门狗,程序一改一编译就自动导出、写 CHANGELOG、`git commit`。 只用免费档工具;只读附着、绝不打开工程、绝不写工程、绝不替你编译;无变更时完全静默不产生空提交。 ### 分层调整:按“方向”分,不按“工具”分 免费档现在覆盖**完整闭环**——`CreateVersionControlWorkspace`、`ConnectProjectToWorkspace`、 `GetVersionControlWorkspaces`、`GetVersionControlStatus`,以及 `SyncVersionControlWorkspace(direction='ProjectToWorkspace')`(导出)。 这些**只读工程、只写文本**。唯一需要 Pro 的是 `direction='WorkspaceToProject'` (把 Git 里的版本灌回工程,**会覆盖工程里的块**)。 此前 Create/Connect/Sync 全在 Pro 侧,免费用户能查出"哪些块变了"却建不了工作区、导不出文本 —— 用不起来。 ### 修复 - **`GetVersionControlStatus` 返回的是类型名而不是状态**:`MappedObject.GetStatus()` 返回 `IndividualObjectCompareResult`,直接 `ToString()` 得到类名。改取 `.CompareState` (`Equal` / `Unequal` / `WorkspaceFileMissing` / `Unknown`)。此前整列状态都是无意义字符串。 - **同步会对已一致的对象报错**:Openness 拒绝对状态为 `Equal` 的映射调用 `Synchronize` (`Synchronize cannot be called on a workspace mapping that has a compare status of equal`), 在一个 345 对象的工程上会一次报出 345 条失败。现在 `Equal` 一律跳过,并在汇总里报出跳过数。 - **代理对象生命周期硬化**:Openness 的调用**一抛异常就会 dispose 掉相关对象**——问一次 "工程支不支持纳管"得到"不支持",`Workspace` 句柄当场作废,后续全报 `Access to a disposed object`(看着像博途崩了,其实没有)。扫描逻辑现在每次失败后重取句柄。 另外,通用反射桥 `GetComposition` 返回的是**临时代理,拿到即死**,遍历改为类型化。 ### 已知边界(工具会明说,不会假装成功) - **硬件组态进不了 VCI**(设备/模块/子网一律"不支持"),仍需 `.ap21` 备份或 CAx 导出。 - **专有技术保护的块导不出**:`The block is know-how protected. Export is not possible.` - **块改动后必须编译才导得出**:`The block is inconsistent. Compile the block prior to export.` 检测不受影响(未存盘也能检测到),只是导出要等编译。 - **`Unequal` 不等于内容变了**:`git checkout`/`pull` 把文件原样重写(时间戳变)同样判 `Unequal`, 自动化脚本提交前应再看一眼 `git status` 有没有真差异。 ### 验证 真实起重机项目(5 台 PLC、159 MB 工程):**345 个对象自动纳管**(约 165 秒), 文本仓 345 个 `.xml` / 22 MB;在博途界面里改块并编译 → 看门狗自动导出并提交,diff 就是那处改动; 反向(从 Git 版本还原回工程)→ 编译 0 错 0 警告。MCP 回归 **287/287**,V20/V21 双编译 0 错 0 警告。

  17. v2.4.1 GitHub repository release ↗
    Original release notes

    **这是一个会真实丢数据的缺陷修复,建议 v2.4.0 及更早版本用户尽快升级。** ## 现象 让 AI「新建一个工程」或「打开另一个工程」,结果它把你在博途界面里**正开着、正在改的**那个工程关掉了,**未保存的编辑一起丢**。 ## 根因 两个各自合理的设计叠加: 1. `Connect` 遍历运行中的 TIA 进程时,**优先接管「已经打开了工程」的那个** —— 这对 `AttachToOpenProject` 是正确的; 2. `CreateProject` / `OpenProject` 的第一步都是关闭当前工程。 叠加之后,「新建一个工程」实际执行的是「关掉工程师正在改的那个工程」。 **`Connect` 从来不保证给你一个隔离实例** —— 这是最容易误判的一点。 ## 修复 引擎现在区分「这个工程是不是本会话打开的」。检测到是**用户自己打开**的工程时,`CreateProject` / `OpenProject` **直接拒绝**,并给出两条出路: - 想在那个工程上干活 → 改用 `AttachToOpenProject` - 确实要关掉它 → 显式传 `closeForeignProject=true`(**先问用户**) 护栏放在工具层最前面:工具原本在委托给引擎之前就已经先关了工程,护栏放在下层来不及。 ## 验证 三阶段复现测试: - **A** 引擎建工程后留在 TIA 里并退出 - **B** 引擎全新连接,继承了一个自己没打开的工程(正是出事的场景)→ `CreateProject` 与 `OpenProject` **双双被拒** - **对照检查**:两次拒绝之后工程**仍然开着** —— 证明不是「关完再报错」 - `closeForeignProject=true` 逃生通道正常放行 ## 升级方式 下载下方 zip 解压覆盖,双击 `配置MCP.bat` 重新注册,重启 AI 客户端即可。v2.4.0 的精简工具档位与 `FindTools`/`CallTool` 全部保留。 sha256: `0ec207efc546306c756989d469e38a6ec996b76e23cf0f57f28e268c1a198430`

  18. v2.4.0 GitHub repository release ↗
    Original release notes

    本次不是加功能,是把「AI 拿到这个包能不能直接干活」这件事修对。 ## 问题:工具清单本身就是最大的开销 实测本版 V21 引擎: | | 工具数 | `tools/list` 体积 | 每轮 token | |---|---|---|---| | v2.3.2(默认) | 203 | 152 KB | ~38,800 | | **v2.4.0(默认)** | **48** | **33 KB** | **~8,500** | 宿主**每一轮对话**都要把工具 schema 重发给模型。更硬的是兼容性: - VS Code / GitHub Copilot 的 agent 模式**超过 128 个工具直接拒绝加载** - Windsurf 上限 **100** 也就是说,旧的默认档在这两个宿主上根本起不来。 启动本身不是瓶颈:热启 ~770 ms,`tools/list` ~25 ms。 ## 解决:精简档做默认,但留一条通往全部工具的路 **能力一个不少。** 没列出来的 155 个工具随用随取: ``` FindTools("watch table") → 工具名 + 参数签名 + 完整说明 CallTool("ExportPlcWatchTable", "{...}") → 照常执行,与直接调用无差别 ``` 这两个桥接工具本身约 700 tokens,换来全部 203 个工具的可达性。 **不用你交代 AI**:握手指令和 `Bootstrap` 都会说明「你看到的列表不是全部,缺什么先跑 FindTools,别下结论说做不到」。任何宿主、任何模型拿到就会用。 ## 档位怎么切 | 档位 | 怎么开 | 列出工具 | |---|---|---| | 精简(默认) | 什么都不用做 | ~48 | | 完整 | `配置MCP.bat --full`,或 `TiaMcpServer.exe --profile full`,或 `TIA_MCP_PROFILE=full` | 203 | 新增 `--profile lite|full` 命令行参数,优先级高于环境变量;**拼错的值一律退回 lite**,不会静默把宿主顶爆。 ## 其它修正 - **解压后第一次跑 tia.cmd 不再打出 `The system cannot find the path specified.`**:交付包只带 `runtime\v21`,但启动器过去先探 `bin\Release` 必然失败一次,新用户第一眼像是包坏了。改为优先用 `runtime`。 - **发布的 exe 不再嵌入构建机的绝对路径**(Release 不发 .pdb,那条调试记录只剩泄露路径的作用)。 - **交付包体积 11.5 MB → 5.9 MB**:旧包把引擎装了两份(`bin\Release` 一份、`runtime\v21` 一份),本版只留 `runtime\v21`——这也正是「启动器可能跑到另一个更旧的引擎」的根源。 - 引擎版本号补正 2.3.1 → 2.4.0(上一次发布是 v2.3.2,但 exe 里的版本号停在 2.3.1)。 ## 校验 - 全部工具逐个冒烟调用:无崩溃、无服务端掉线 - 桥接反例全部正确失败:错工具名(给出候选,含中间打错字)、非法 JSON、缺参数(打印完整签名)、自递归 - `Validate-Bundle.ps1` 新增引擎桥接门禁;`Check-LiteProfile.py` 修掉一处空跑通过(默认改 lite 后两次探测返回同一份清单,断言全部失效),并已用反例验证它确实会 FAIL - 交付 zip 解压后实跑:`tia 2.4.0.0`,默认 48 工具 **安装**:下载下方 zip 解压,双击 `配置MCP.bat` 即可注册进本机检测到的 AI 客户端。连不上就跑 `tia.cmd doctor`。 sha256: `cdbf54e0a146c300f00ed76e3397fe2cb453498a45ab6ff61de285a86920e603`

  19. v2.3.2 GitHub repository release ↗
    Original release notes

    本轮全部围绕「新机装完到第一次跑通」这一段。**工具能力零新增**,全是让现有能力更容易被用对。 > 累积 v2.3.1 与本轮内容(v2.3.1 此前只写进 CHANGELOG 未发布,一并在此发出)。 ## doctor:3 项 → 6 项,中文环境说中文 新机上最常卡住的三件事,此前一件都不查: | 新增检查 | 为什么必要 | |---|---| | **Openness 接口 DLL 能否真解析** | 装了 TIA ≠ 装了 Openness。旧检查只问注册表,于是「体检 OK、首次调用 FileLoadException」。现在复用 resolver 自己的搜索路径去探,两者不会再分叉 | | **MOTW(文件被标记为网络来源)** | 从下载的 zip 解压即中,.NET 拒绝加载 DLL,报错和「你的下载被 Windows 拦了」毫无关系 | | **.NET Framework 4.8** | README 的第一条前置条件 | CLI `tia doctor` 与 MCP `Doctor` 工具改为共用同一套检查,不会再各写一份。 doctor 还会区分「注册了」和「能用」:配置从别的机器带过来、或交付包换了位置,条目还在但 exe 已经不在,宿主只会静默起不来——现在直接报出失效路径并给修复命令。 ## AI 宿主 4 → 8 新增 **Codex(TOML) / Gemini CLI / Windsurf / Cline**。 - Codex 走 TOML 段落合并,保留你已有的其它 server,并写入 `startup_timeout_sec = 120`——TIA 启动远超 Codex 默认的 10 秒,不写会被当成崩溃杀掉。 - JSON 写入改为「临时文件 + 替换」的原子写:写到一半崩掉不会截断你的配置。 - `tia config --host codex|gemini|windsurf|cline`(按名字模糊匹配);`--print` 也会给出 Codex 片段。 ## 一键配置默认精简档 + lite 补齐金路径(含 2.3.1) - `tia config` 默认写 `TIA_MCP_PROFILE=lite`;要全量工具面显式 `--full`。 - lite 改为**显式工具名白名单**(不再按描述前缀过滤,成员不会随文案变动漂移),并补齐说明书点名的金路径工具:`ImportFromDocuments` / `GenerateBlocksFromExternalSource` / `GetBlocks` / `ExportAsDocuments` / `ImportBlocksFromDocuments` / `ExportBlocksAsDocuments` / `GetPlcTagTables` / `GetCrossReferences` 等,共 46 个,仍远低于 VS Code 的 128 上限。 - 新增 `scripts/Check-LiteProfile.py`,把「lite 必须能走完金路径」变成可执行断言。 ## git clone 开箱即用(含 2.3.1) 全部启动脚本双布局自动回退:先找交付 zip 布局,找不到改用 `runtime\v21`。`Validate-Bundle` 新增启动器哨兵,解析每个 `.cmd`/`.bat` 实际会启动的 exe 并核实存在。 > **V20 用户请注意**:本版交付包为 `TIA_MCP_Delivery_v2.3.2_V21only.zip`,**只含 V21 引擎**——本轮的 V20 二进制 > 尚未重新构建(需要装有 TIA V20 的机器)。V20 用户请继续使用 [v2.3.0](https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/tag/v2.3.0) 的双引擎交付包, > 或自行用 `TiaMcpServer.V20.csproj` 构建;本版的源码改动对两个版本都适用。V20 引擎补齐后会另发一版。 ## LAD 指南补三条(均以 1052 个真实 .s7dcl 语料核过) - 每个 NETWORK 前必须有独立 `{ S7_Language := "LAD" }` pragma——**10147/10147 个网络无一例外**;缺了报 `Syntax error 'NETWORK' expecting END_FUNCTION_BLOCK`。 - `P_Trig(mem)` 一个参数,`P_Contact(signal, mem)` 两个参数,不可混用。 - 泛型指令模板名随指令而异(实见 `SrcType`/`DestType`/`time_type`/`date_type`/`str_type`),报错会列出 `Allowed Template Names`,照读即可。 ## 修复 - `DownloadToPlc` 在多网卡机器上选错 PG/PC 接口(#14):改为按 IP 同网段排序选路,可用 `pgPcInterface` / `targetIpAddress` 显式指定,`CheckDownloadReadiness` 的 `meta.downloadRoutes` 可先行诊断。排序只用于**排序**,绝不否决下载。 ## 分支体例 新增官方 `v21` / `v20` 分支(与 v16~v19 同体例)。双版本共用的改动仍进 `master`,只有版本专属适配才进版本分支。

  20. v2.3.0 GitHub repository release ↗
    Original release notes

    回应"分析慢/准确率低/只敢用 SCL 躲梯形图"的痛点——加一个让模型/人像读 SCL 一样读 LAD 的工具: - **新工具 `DescribeBlockLogic(softwarePath, blockPath)`**[L1,lite 档也含]:导出块后把每个 LAD 网络**重建成可读的能流表达式**——串联触点用 `·`、并联用 `+`、常闭显示 `/操作数`;线圈 `( )/(S)/(R)`、MOVE/比较/定时器盒带管脚操作数;SCL/STL 网络内联成代码。**关键**:自动标注接到字面常量的触点——`⟨恒断·禁用本行⟩`(常开触点接 FALSE=永久断开、静默禁用整行,肉眼几乎看不出)、`⟨恒通⟩`(恒导通旁路)。比导出 FlgNet XML 手工追线又快又准。 - 实证:对 5T车 原生 `Auto_SpeedSet`(LAD+SCL+STL 混编)一眼标出"初始化切换"里被恒 FALSE 触点禁用的 `0006/0007` 握手行(`TP(..).Q · 0 ⟨恒断·禁用本行⟩`)——正是之前手工追半天才发现的坑;复位行 `MOVE 16#04FE` 无禁用标记=有效。端到端(测试PLC/FC_Alarm)输出 `"DemoData.HighAlarm" ( ) ⇐ ("DemoData.Temp" >= "DemoData.Limit")`。 - ServerInstructions 与 GetAuthoringGuide('lad') 补指引:**读 LAD 用 DescribeBlockLogic,别手解 XML**。 - 纯只读、Siemens-free 渲染器(`LadTextRenderer`),工具数 200→201。V20/V21 双编译 0 错,渲染器离线对真实块 + 端到端各验证一遍。 --- **同时包含 v2.2.9 修复**:ImportFromDocuments 嵌套组不再失败/丢块号 + 导入导出错误上抛真实原因。 **下载** `TIA_MCP_Delivery_v2.3.0_20260704.zip`(V21/V20 双 exe):解压→双击 `配置MCP.bat` 一键注册;读梯形图让 AI 调 `DescribeBlockLogic`;排障 `tia.cmd doctor`。

  21. v2.2.8 GitHub repository release ↗
    Original release notes

    围绕「外部环境部署 + 弱 AI + 出错率」(lite 档位与 Doctor 此前只存在于 SKILL 文档、代码在迁仓时丢失,本版补齐并超越原实现): - **lite 工具档位(弱模型/受限宿主)**:`TIA_MCP_PROFILE=lite` 环境变量生效——`tools/list` 只暴露 [L0]/[L1] 共 42 个核心工具(full=200),弱模型不再被 200 个工具淹没,VS Code 的 128 工具上限也不再爆。一键写入:`tia config --lite`(宿主配置里自动带 `env`),GUI 配置向导同步提供勾选。stdio 实测 full=200 / lite=42、核心工具(Bootstrap/Connect/GetProjectTree/ScaffoldProject/CompileSoftware/SaveProject/Doctor)全在。 - **`Doctor` 工具回归 + 新 CLI `tia doctor`**:MCP 工具版一次体检 TIA 安装/Openness 用户组/连接与项目状态,逐项给出精确修法,`fix=true` 自动补 Openness 组;**CLI 版 `tia doctor [--fix]` 在 MCP 宿主根本起不来 server 的时候也能用**(正是最需要体检的场景),额外检查 exe 编译版本与本机 TIA 版本匹配、四宿主配置是否已注册。stdio 调用与 CLI 实测输出正确。 - **启动失败不再无声**:TIA 未装(Openness 初始化 FileNotFound)与用户不在 Openness 组两条失败路径,stderr/日志给出中英文修复指引(指向 `tia doctor`),后者退出码从 0 改为 2,MCP 宿主能感知失败。 - **写操作默认干跑(约束加强)**:`ScaffoldProject` 的 `dryRun` 默认值 false→**true**——默认调用只做离线校验、不连 TIA 不建工程,干跑干净后需显式 `dryRun=false` 才真跑;干跑结果消息里明确指引下一步。与 ServerInstructions「永远先 dryRun」铁律一致,弱模型一把梭建废工程的路径被堵死。(行为变更:依赖旧默认值的调用方需显式传 `dryRun=false`。) - **VS Code 工具校验修复随本版 exe 发布**(源码 38043e9 已在 master):`InvokeObject`/`InvokeService` 数组入参 schema 补 `items`,VS Code 不再拒收。 - **配置脚本加固**:`配置MCP.bat`/`配置MCP-v20.bat` 先检查引擎 exe 存在(防"只拷了 bat"),完成后提示 `--lite`/`doctor`/`--print` 三条路。 - 验证:V20/V21 双编译 0 错;stdio 握手实测(full/lite 工具数、Doctor 诊断内容、instructions 下发);`tia doctor`/`tia config --print --lite` CLI 实测。 --- **下载**:`TIA_MCP_Delivery_v2.2.8_20260703.zip`(含 V21/V20 双 exe,解压后双击 `配置MCP.bat` 一键注册进 Claude Desktop / Claude Code / Cursor / VS Code;弱模型加 `--lite`;排障跑 `tia.cmd doctor`)。

  22. v2.2.7 GitHub repository release ↗
    Original release notes

    两个真实用户痛点的系统性修复:①配置要人肉填路径/版本(issue #9)②非 Claude 的 AI 生成代码质量差、耗时长。 ## 降门槛 - **版本自路由(修 #8 根因)**:拿错 exe 不再崩——exe 启动时按实际 TIA 版本自动转投旁边的兄弟 exe(V20↔V21,stdio 继承,MCP/CLI 全程无感) - **修多版本机器程序集解析劫持**:`TiaPortalLocation` 环境变量不再压过版本专属注册表(V20+V21 双装机器上 V20 exe 报 "Could not find DLL for version 20" 的根因) - **`tia config` 一键配置扩到 4 宿主(修 #9)**:Claude Desktop / Claude Code / Cursor / **VS Code** 全自动写入——自动发现自身路径、注册表版本、版本匹配的 exe;只写检测到的宿主;`--print` 出双 schema 片段 ## 提生成质量(其它 AI 也能写对代码) - **initialize 下发 instructions**:黄金路径 + BOM 编码规则 + 纪律,所有 MCP 客户端自动注入(不再依赖 SKILL.md) - **新工具 `GetAuthoringGuide(topic)`**:workflow/scl/lad/db/hmi/errors 六主题已验证语法速查,模型写码前一次拿全约束 - Bootstrap OperatingRules 补齐写码前置 ## 验证 双编译 0 错;V20 exe 自路由真机实测;config --print 实测;MCP 握手实测(199 工具 + instructions 下发 + 指南内容正确)。 ## 附件 `TIA_MCP_Delivery_v2.2.7_20260702.zip`(17.2MB)= 源码 + V20/V21 双 exe(均 2.2.7) > 含 v2.2.6 的全部内容(god-file 拆分重构 + CLI describe 增强 + Claude Code 插件清单),见 CHANGELOG。

  23. v2.2.4 GitHub repository release ↗
    Original release notes

    降低上手门槛——**无需第三方软件、无需手改配置文件**,把本 MCP 一键注册进 AI 宿主。 ### 新增 - **`tia config` 子命令**:自动把 `tia-portal` 写进 **Claude Desktop / Cursor** 配置——填入**正确的 exe 绝对路径**(不再有 `REPLACE_ME`)+ **自动检测的 TIA 版本**;**合并**进现有配置(保留你已有的其它 MCP server),原文件自动备份为 `*.bak`。 - `tia config`(写全部已知宿主)/ `--host claude|cursor`(指定其一)/ `--print`(只打印片段,供 Claude Code 等手动粘贴)。 - **双击脚本**:交付包根目录的 `配置MCP.bat`(V21)/ `配置MCP-v20.bat`(V20),双击即配。 ### 取代 原先要手动改 `cursor-mcp.example.json` 里的 `REPLACE_ME`、自己找配置文件位置、自己合并——现在一步搞定。 ### 验证 V20/V21 编译 0 错;`config --print` 真机输出正确(自动 exe 路径 + 版本);合并/备份/幂等逻辑单测通过。纯新增,不改动现有工具与行为,工具数不变(189)。 交付包 `TIA_MCP_Delivery_v2.2.4_20260615.zip` 解压后双击 `配置MCP.bat` 即可。

  24. v2.2.3 GitHub repository release ↗
    Original release notes

    针对"较弱的 AI 驱动本 MCP 时仍会出 bug"的反馈,从源头降低出错与卡死。**工具数不变(189),无破坏性改动。** ### 改进 - **自愈连接/绑定**:调用工具前忘了 Connect/Attach 时——若本机已有 TIA 在运行,自动附加并绑定其已打开的工程;已连接但未绑定则自动重绑;本机无 TIA 在运行则不擅自启动、直接给可执行提示。修复了"不按顺序调用→原始空引用崩溃"。 - **可恢复的错误指引**:新增异常翻译器(`McpHints`),按异常链识别 7 类常见失败(未连接 / 无工程 / 工程已被打开 / 名称路径错→提示查 GetProjectTree·GetSoftwareTree / TIA 版本不匹配 / Openness 用户组 / know-how 保护),统一注入 185 处通用 catch。错误从"只报原始异常"变为"告诉 AI 下一步该做什么"。 - **首调操作规则**:`Bootstrap` 新增 `OperatingRules`(调用顺序 / 写后必 Compile+Save / 名称要精确 / 读错误照做 / 大任务用 ScaffoldProject)。宿主即便不加载 SKILL.md,AI 第一次调用就拿到正确用法。 - **更清晰的前置错误**:误导性的 "No project is open" 改为可执行指引。 ### 验证 - V20 / V21 编译 0 错;翻译器离线单测 7/7 通过;对构建产物 stdio smoke test 通过(189 工具、5 条 OperatingRules)。 > 注:v2.2.2 已被既有的「S7DCL skill 文档」Release 占用,故本代码版本顺延为 2.2.3(已包含该 skill 文档内容)。 交付包 `TIA_MCP_Delivery_v2.2.3_20260615.zip` 含 V20+V21 双 exe + 完整源码 + skill + 模板,解压即用。

  25. v2.2.2 GitHub repository release ↗
    Original release notes

    ## v2.2.2 — S7DCL LAD/SCL 混编授权法(规范/文档 + 已验证样板) **纯文档/技能更新,无代码或工具改动**(LAD/S7DCL 相关工具早已具备:`ImportFromDocuments`/`ImportBlocksFromDocuments`/`ExportAsDocuments`/`ComposePlcLadFcBlockXml` 等)。本版把"如何正确用 `.s7dcl` 授权 LAD 及 LAD/SCL 混编"的实战知识固化进 skill。 ### 更新内容(`tools/tiaportal-mcp/skill/SKILL.md §9a`) - **关键纠错:LAD 导入语法 ≠ 导出语法。** 导入须用 `GT/LT/EQ/NE_Contact{ SrcType }( in1:=, in2:= )`、`P_Trig( #bit )`、`Move( in:=, out1=> )`;从导出文件抄来的 `Gt/Lt/Ne/Eq`、`PBox`、`Move{ Card; DisableENO }` 会导入失败。新增"导入 vs 导出"指令对照表。 - **逐网络 LAD/SCL 判断准则(不强行 LAD)**:互锁/限位/抱闸/工步/指示→LAD;算术/调用/状态机/通信/复杂条件→SCL。 - **LAD+SCL 混编已验证**:`S7_PreferredLanguage:="LAD"` 的块可逐网络插入 `{ S7_Language:="SCL" }` 网络。 - 纠正导入工作流为 `ImportFromDocuments`/`ImportBlocksFromDocuments` + `CompileAndDiagnosePlc`(含 `.s7res`/UTF-8 BOM/`Override` 保号要点)。 - 标题须 `MLC_*` 引用或省略(内联中文标题会导入失败)。 ### 新增样板 - `tools/tiaportal-mcp/skill/lad-cookbook/MCPVerify_Mixed_LADSCL.s7dcl(+.s7res)` —— 自包含的 LAD+SCL 混编 FB 模板(方向互锁 / 比较+定时 / SCL 算术 / 边沿),全用 import-verified 形式,导入编译 **0 错**。 ### 实证 江夏 5T车 V21:7 个块(02/03/04/09 手动 + A3_2/3/5 机构)按"逐网络判断"重做为 LAD/SCL 混编,全工程编译 0 错;A0_1/A4_1/通信类按判断保留 SCL。

  26. v2.2.1 GitHub repository release ↗
    Original release notes

    ## v2.2.1 — v2.2.0 在线工具真机验证 + 因果溯源在线模式消息修复 v2.2.0 新增的 3 个在线只读监控工具已在**真实 PLC(CPU 1211C @ 192.168.0.32)**端到端验证通过,并修复了真机验证中发现的一个消息误导问题。工具数不变(**189**,全部 `[L2]` 只读)。 ### 真机验证结果 - **`GetPlcRunStateS7`** — 正确读到 `RUN`;该 1211C 的 SZL 诊断缓冲不可用时按设计**干净降级**(仍给出 RUN/STOP)。 - **`SamplePlcLiveValuesS7`** — 采样 DB34 心跳/标志位,时间序列与 `min/max/avg` 正确(心跳随时间递增)。 - **`TraceTagCauseLive`** — 离线追溯 `EMG_STOP`,正确命中其在 `Crane_Communication` 网络4 的赋值及两个门控条件,并正确判定门控操作数为 DB 成员(无绝对地址 → 提示用 OPC UA 符号读)。 ### 修复 `TraceTagCause` / `TraceTagCauseLive`:当 TIA 与 PLC **在线连接**时,Openness 无法导出块(`Export ... not supported in online mode`)。此前所有块导出失败仍报 `No block writes 'X'`,会误导为"解析后无写入"。 - 新增 `analyzedBlockCount` 字段;当无任何块成功导出时返回 `INCONCLUSIVE`,并在在线模式失败时提示**先在 TIA 转至离线再重试**(S7 实时读为独立直连,不受转离线影响)。 - 两个工具的 Description 补充该离线导出前置条件。 ### 包含 - 双运行时:`TiaMcpServer.exe`(V21)+ `bin-v20`(V20),net48。 - 完整源码、Skill 规格、静态工具表、能力矩阵、PLC/HMI 模板、一键工程蓝图、手册。 > 免费开源(MIT),无许可证密钥。运行需 Windows + .NET Framework 4.8 + TIA Portal V20/V21,当前用户加入 `Siemens TIA Openness` 本地组。

  27. v2.1.0 GitHub repository release ↗
    Original release notes

    TIA Openness 是工程接口,读不到运行中 CPU 的实时值。本版新增一条独立于 Openness 的**运行时只读通道**,直连 CPU 读实时值。 ## 新增 5 个工具(全部 [L2],纯只读:不写 / 不强制 / 不改运行模式),工具数 181 → 186 - **ReadPlcLiveValuesS7** / **ProbeS7CpuIdentity** — S7 协议(ISO-on-TCP, 端口 102),绝对地址 `DB34.DBD116:DINT` / `M0.0` / `IW76`,单次几十~几百 ms。`expectModuleContains` 身份护栏。S7-1200/1500 需开 PUT/GET 且读非优化 DB。 - **ReadPlcLiveValuesOpcUa** — OPC UA(端口 4840,匿名无加密),会话按 endpoint 缓存复用(首次 ~1.7s,之后 ~150-220ms),失效自动重建一次;对锁的等待有界,避免不可达服务器导致后续调用堆积。 - **MonitorWatchTableLiveS7** — 经 Openness 取已有监控表条目地址(只读)+ S7 实时读,按 TIA `DEC_signed` 显示格式映射有符号类型。 - **TraceTagCause** — 离线静态溯因:导出代码块解析 SimaticML(LAD 线圈 S/R/= 与 ST 的 `:=`),找写入网络 + 门控条件操作数,再用 ReadPlcLiveValuesS7 实时读判断当前由谁驱动。 每个响应都带 `safety` 自证字段。真机(CPU 1211C @192.168.0.32)S7 / OPC UA / 监控表三法与博途显示逐字节交叉核对一致。双构建 V20/V21 均 0 错,FileVersion 2.1.0,runtime tools/list 实测 186。 中文使用指南见 `docs/在线实时读值_使用指南.md`。 ## 下载 `TIA_MCP_Delivery_v2.1.0_20260609.zip`:完整源码 + V20/V21 双 exe(含 .exe.config 与 Sharp7 / Workstation.UaClient 依赖)。解压即用。

  28. v2.0.2 GitHub repository release ↗
    Original release notes

    V20 兼容性修复小版本(修复 GitHub issue #2)。仍为双 V20/V21 binary、MIT。工具数 180 → **181**(新增 1 个离线工具)。 ## 修复 — V20 导入标签表报 `The engineering version 'V21' ... is not supported` `Portal.ImportPlcTagTable` 现在统一走 `PrepareXmlForImport`,把硬编码的 `<Engineering version="V21"/>` 头改写为当前连接的博途版本(并补 UTF-8 BOM)。此前块 / 类型导入已做此处理,唯独标签表漏过滤,导致 V20 上 `PlcBuildAndImport` 生成的变量表被 Openness 拒绝。 ## 新增 — `WritePlcSclSourceFile`(离线,第 181 个工具) 把 SCL 源文本写成本地 `.scl` 外部源文件(**UTF-8 带 BOM**,中文注释不乱码)。不连接博途、不导入,只落盘并返回路径与手动导入指引。 作为 V20 用户的稳妥后路:当 FC 逻辑块 XML 因 `Cannot create SW.Blocks.CompileUnit... token not supported`(V21 SimaticML 令牌)被 V20 拒绝时,改用博途「外部源文件 → 从源生成块」手动导入,绕开严格的 XML 令牌校验。 --- 下载 `TIA_MCP_Delivery_v2.0.2_20260608.zip`,解压即用(含双 V20/V21 exe + 依赖 + tia.cmd)。

  29. v2.0.1 GitHub repository release ↗
    Original release notes

    安全与隐私小版本,无行为变更、无新工具(仍 180 工具、双 V20/V21 binary、MIT)。 ## 安全 — 修复 XML 外部实体注入(XXE) 导入/解析 XML 工程产物(块 / 画面 / 变量表 / 监控表)的 6 处 `XmlDocument.Load(...)` 之前统一设置 `XmlResolver = null`,禁用外部实体与 DTD 解析。修复在 .NET Framework 4.8 上导入**第三方恶意 XML 文件**时可被 XXE 利用(本地文件读取 / SSRF / billion-laughs DoS)的风险。`XDocument.Load/Parse` 路径默认 `DtdProcessing.Prohibit`,本就安全。 ## 隐私 — 移除源码中的开发机个人路径 清除 `Program.cs` 中 11 处硬编码的作者机器路径,改为中性兜底(`Directory.GetCurrentDirectory()` / MyDocuments)。仅出现在 `--run-*` 开发者自测处理器,正常 MCP/CLI 运行不受影响。 下载 `TIA_MCP_Delivery_v2.0.1_20260604.zip`,解压即用(含双 exe + 依赖 + tia.cmd)。

  30. v2.0.0 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- 声明式 `tia` 命令行大版本:同一个 exe 既是 MCP 服务,也是命令行。任意 AI 产出一份 YAML/JSON spec,任意工程师跑一条命令即可从零建/改博途工程——无需 MCP 客户端、无需安装。 ## 亮点 - `tia gen <spec>`:一条命令从 spec 建完整工程(PLC+HMI+UDT/DB/标签表+SCL/LAD+编译+保存)。 - `tia patch <spec>`:增量 upsert 进已有工程。 - 还有 `compile/describe/export/import/prewarm/schema`,退出码 0/1/2。 - YAML + JSON 双解析;`--dry-run` 离线校验;`--json` 机器可读。 ## 上手优化(本版) - **`tia` 命令入口**:根目录 `tia.cmd`(V21)/`tia-v20.cmd`(V20),加 PATH 即可随处 `tia gen`。 - **模板开箱即用**:自动解析 spec 里的 `__BUNDLE__`,现成启停/电机模板无需手改路径。 - **修复相对工程路径**;`.bat` V21 缺失自动回退 V20。 ## 验证 - live 实机回归全过(真连 TIA V21):`tia gen` 16/16 步、编译 Success 0 错;patch/compile/describe/export/import/prewarm 全 rc=0。 - 双 V20/V21 binary、0 编译错误。 仍是完整 MCP 服务(`tia` verb 之外行为不变),CLI 与 MCP 共享同一引擎。 交付 zip:`TIA_MCP_Delivery_v2.0.0_20260603.zip`(源码 183 + 双版本 exe/依赖 116,6.07MB)。

  31. v1.0.0 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- 首个 1.0 大版本,聚焦「快、好用、不出错」。 ## 性能 - **默认 headless 启动**:冷启动约 200–340s → 约 10–28s(全量回归 21/21 通过,含 WinCC Unified HMI)。需 GUI 检查时启动加 `--with-ui`。 - **常驻实例(可选)**:`python scripts/prewarm_tia.py` 保活后,后续会话 Connect 约 0.8–1s。 ## 新工具 - **`ScaffoldProject`(L1)**:单个 JSON spec 一次调用生成完整工程(建项目→PLC/HMI 硬件→UDT/DB/标签表→SCL/LAD→编译→HMI 连接/画面/变量→保存)。支持 `dryRun=true` 离线校验。现成模板:`scaffold_spec_start_stop.json`(启停)、`scaffold_spec_motor.json`(电机)。 ## 可靠性 - HMI 软件路径自动探测(不再写死 `HMI_RT_1`) - 连接对挂死/孤儿 TIA 实例加超时跳过 - 单块导入回读校验(`Meta.verified`) ## 工具收敛 - 184 → **180**:下线 4 个 `Export*ToTemp` 变体 + 易混 Export/Import 工具补消歧描述 ## 安装 解压附件 zip,把 MCP 配置 `command` 指向包内 `tools/tiaportal-mcp/src/TiaMcpServer/bin/Release/net48/TiaMcpServer.exe`(V20 用 `bin-v20/Release/net48/`)。需 Windows + TIA Portal V20/V21 + .NET 4.8。

  32. v0.0.40 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- ## 0.0.40 ### 示例库质量 - 5 个 `scl-examples/*.scl` 重写:块头说明 + 每个接口变量(VAR_INPUT/OUTPUT/VAR)逐行中文注释 + 逻辑分区注释;逻辑更丰富(运行/剩余/完成百分比、限幅、方向、偏差%)。 - `FB_TimerCounterDemo` 用静态累计器消除"输出未初始化"告警 → 编译 0 错 0 警。 - `UDT_BasicStatus` / `DB_BasicStatus` 每个成员补 `commentZhCn` 中文注释。 ### 仓库管理 - 编译产物(exe/DLL/.config)移出 git 跟踪,改由本 Release zip 分发;消除"clean 误删 tracked 二进制 → MCP 启动崩溃"隐患。 ### 交付包 `TIA_MCP_Delivery_v0.0.40_20260602.zip` 含完整源码 + V21/V20 双 exe(0.0.40)+ 配置。clone 仓库需自行 build 或用本 zip。

  33. v0.0.37 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- ## 错误处理统一(E) 将 6 个错误域(Connect / Hmi / PlcGen / Compile / Import / AddDevice)的失败信号从 `return false/null` + 可变 `LastXxxError` 侧信道,统一为 `throw PortalException(code, msg)`,工具层统一 `catch (PortalException)` → `McpException`(结构化错误码进消息)。 - 删除 5 个侧信道字段(`LastHmiError`/`LastPlcGenError`/`LastCompileError`/`LastImportError`/`LastAddDeviceError`);`LastConnectError` 故意保留(喂 Bootstrap 诊断 + OpenProject/OpenSession 共用失败分支)。 - `throw PortalException` 19→90,`catch (PortalException)` 1→28;仅改 `Portal.cs` + `McpServer.cs`,净减 ~94 行。 - 批量导入逐项 `try/catch` 收集 `ImportFailure`,并修正了块/类型导入原先"一条失败中断整批"的不一致。 - 重建 V20/V21 双版本 exe(0.0.37,0 错误)。 > 本版同时包含 0.0.36(A:移除 4 个纯别名工具,削减工具表面)—— 0.0.36 未单独发布。 详见 CHANGELOG.md。zip 为仓库 tracked 内容(含双版本预编译 exe)。

  34. v0.0.35 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- -

  35. v0.0.34 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- -

  36. v0.0.33 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- TIA Portal MCP Server v0.0.33 (V20 + V21). ## 本次改进 - **去除内部"商业"措辞**:发布质检工具 `CommercialReadinessGateBuilder` → `ReleaseReadinessGateBuilder`,相关 JSON 键/Markdown 标题统一改为中性的 "Release Readiness Gate"(行为不变)。 - README 删除过时的"商业锁"说明(自 v0.0.32 起仓库已无任何授权代码,纯 MIT 开源)。 (延续 v0.0.31 的版本能力层 / Did-you-mean / HTTP 修复,及 v0.0.32 的商业授权移除。) ## 交付包 - `TIA_MCP_Delivery_v0.0.33_20260528.zip`:完整离线交付包(V20/V21 预编译 exe + skill + 模板 + 文档)。

  37. v0.0.32 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- TIA Portal MCP Server v0.0.32 (V20 + V21). ## 本次改进 - **移除商业授权脚手架**:删除 `CommercialLicense.cs`(机器码 / RSA license / `commercial.lock` 启动拦截)及 `--license-machine-code`、`--license-check` 两个 CLI 标志。仓库现为**纯 MIT 开源**,无任何授权代码,无需 license key。 - 重建 V20/V21 exe(serverVersion=0.0.32,0 错误),启动正常、版本能力门控不变。 (功能延续 v0.0.31:版本能力层 / Did-you-mean / HTTP transport 修复。) ## 交付包 - `TIA_MCP_Delivery_v0.0.32_20260528.zip`:完整离线交付包(V20/V21 预编译 exe + skill + 模板 + 文档 + manifest)。 详见 CHANGELOG.md。

  38. v0.0.31 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- TIA Portal MCP Server v0.0.31 (V20 + V21). ## 本次改进 - **版本能力层**:新增 `Capability` 单一真源 + `Bootstrap` 的 `Capabilities` 字段;模型一上来即知当前 TIA 版本支持哪些功能(V21 支持硬件 HMI 连接,V20 不支持)。新增错误码 `NotSupportedOnVersion`。 - **Did-you-mean**:块/类型找不到时返回候选名(`ExportBlock` 已有,新增 `ExportType`)。 - **HTTP transport 修复**:此前 `POST /mcp` 因异步 I/O 在 HttpListener 上挂起而永久阻塞,现改为同步 I/O + 30s 超时返回 504;curl 端到端实测通过。 ## 交付包 - `TIA_MCP_Delivery_v0.0.31_20260528.zip`:完整离线交付包(含 V20/V21 预编译 exe、skill、模板、文档、manifest)。 - 免费开源(MIT),无需 license key。运行时 `tools/list` 为工具清单权威来源。 详见 CHANGELOG.md。

  39. v0.0.30 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- **Fix**: Openness imports are now normalized to the connected portal version, so importing into **TIA Portal V20** no longer fails with `The engineering version 'V21' ... is not supported`. Applies to `ImportBlock` / `ImportType` / `PlcBuildAndImport`. **Also in this release** - Full source committed (the repo now compiles from source; CI builds V20 + V21). - Rebuilt **V20** (`bin-v20/Release`) and **V21** (`bin/Release`) executables, both `FileVersion 0.0.30`, end-to-end verified against live TIA V20 and V21. - MIT licensed; English `README.en.md` added. **Asset**: `TIA_MCP_Delivery_v0.0.30_20260528.zip` — prebuilt bundle (both exes + full source + docs + templates). Pick the exe by TIA version; see README. 修复:导入按所连博途版本归一化 `<Engineering version>`,V20 不再报 "engineering version 'V21' is not supported"。含完整源码、V20/V21 双 exe(均 0.0.30,实测通过)、MIT 协议、英文 README。

  40. v0.0.29 GitHub repository release ↗
    Original release notes

    > ⚠️ **此历史版本的下载包已下架。** 请使用最新版 → https://github.com/bulaofen0036-coder/TIA_Portal_Openness_MCP/releases/latest (v2.0.1,已修复 XXE 并清理)。 --- ## v0.0.29 完整离线交付包 - **V21 运行时**: `tools/tiaportal-mcp/src/TiaMcpServer/bin/Release/net48/TiaMcpServer.exe` - **V20 运行时**: `tools/tiaportal-mcp/src/TiaMcpServer/bin-v20/Release/net48/TiaMcpServer.exe` - 含模板、文档、Skill、源码;解压即用,无需再编译 - 相对 v0.0.28:仓库纳入双版本 exe/DLL;本 Release 附 `TIA_MCP_完整交付包_v0.0.29.zip` 详见 [CHANGELOG.md](CHANGELOG.md)。

Current listing version

introduction-20261106

Verify the source revision ↗

Permissions and checks before use

Automatically summarized from this main document. Matches may be examples or defensive advice; they are not actual permission declarations. Attachments, external dependencies and runtime behavior are not covered.

The main document is unavailable or exceeds this check’s scope; permissions are unknown.

These notices grant no permissions. Your host tool must still confirm file changes, secrets, external transfers or costs as needed.

Security rating and access scope

caution · Static evidence review; not a runtime safety guarantee.

Before use, confirm and authorize actual file access, external services and network destinations in your host. This review grants no runtime permissions.

Sources and use notice Some skill information on SkillPi comes from public sources or creator submissions. Rights in third-party content belong to their respective owners. Review the source license, required permissions, and usage risks before installing or running a skill.