codesys mcp持久化
用于CODESYS的MCP服务器,具有持久UI实例和基于文件的IPC。
与每个命令生成一个新的CODESYS进程的无头方法不同,此服务器启动CODESYS 其用户界面可见 并保持其运行。MCP工具调用通过基于文件的IPC观察器发送到同一个实例,因此更改会实时显示,用户可以在AI驱动的自动化过程中与IDE交互。
特性
- 持久模式 -CODESYS UI保持打开状态。命令在运行实例中执行
- 无头回退 -自动回退到
--noUI如果持久模式失败,则按命令生成 - 基于文件的IPC -使用原子文件写入和Python观察器脚本的经过验证的方法
- 命令序列化 -异步互斥确保一次只有一个命令
- 健康监测 -检测CODESYS崩溃并报告状态
- 40个MCP工具 -项目管理、POU编写、结构化编译器诊断、运行时监控、仿真、库管理、代码搜索、重构、设备树、现场总线I/O映射、归档
- 直接替换品 -MCP工具名称和参数与
@codesys/mcp-toolkit(原始工具包的表面是一个严格的子集)
安装
npm install -g codesys-mcp-persistent或者从存储库安装:
git clone https://github.com/luke-harriman/Codesys-MCP.git
cd Codesys-MCP
npm install
npm run build
npm link要求: 已安装Node.js 18+、Windows、CODESYS 3.5 SP19或SP21。
快速开始
添加到您的 .mcp.json (克劳德代码配置):
{
"mcpServers": {
"codesys": {
"command": "codesys-mcp-persistent",
"args": [
"--codesys-path", "C:\\Program Files\\CODESYS 3.5.21.0\\CODESYS\\Common\\CODESYS.exe",
"--codesys-profile", "CODESYS V3.5 SP21 Patch 3",
"--mode", "persistent"
]
}
}
}或者直接运行:
codesys-mcp-persistent \
--codesys-path "C:\Program Files\CODESYS 3.5.21.0\CODESYS\Common\CODESYS.exe" \
--codesys-profile "CODESYS V3.5 SP21 Patch 3"CLI参考
| 标志 | 描述 | 默认值 |
|---|---|---|
| `-p, --codesys-path | ||
| ` | CODESYS可执行文件的路径 | $CODESYS_PATH 或自动检测 |
-f, --codesys-profile | CODESYS配置文件名称 | $CODESYS_PROFILE 或 CODESYS V3.5 SP21 |
-w, --workspace | 相对路径的工作区目录 | 当前目录 |
-m, --mode | persistent (UI)或 headless (--noUI) | persistent |
--no-auto-launch | 启动时不启动CODESYS | 已启用自动启动 |
--fallback-headless | 如果持续失败,则退回到无头模式 | true |
--keep-alive | 服务器停止后保持CODESYS运行 | false |
--kill-existing-codesys | 杀死任何跑步者 CODESYS.exe 启动前(默认情况下为dev便利。关闭以保护外部IDE会话) | false |
--timeout | 默认命令超时 | 60000 |
--detect | 列出已安装的CODESYS版本并退出 | - |
--verbose | 启用详细日志记录 | - |
--debug | 启用调试日志记录 | - |
-V, --version | 显示版本号 | - |
-h, --help | 显示帮助 | - |
环境变量 CODESYS_PATH 和 CODESYS_PROFILE 当没有提供相应的标志时,将其用作默认值。
MCP工具
管理工具
| 工具 | 说明 |
|---|---|
launch_codesys | 手动启动CODESYS(与 --no-auto-launch) |
shutdown_codesys | 关闭持久CODESYS实例 |
get_codesys_status | 获取当前状态、PID、执行模式 |
项目工具
| 工具 | 说明 |
|---|---|
open_project | 打开现有的CODESYS项目文件 |
create_project | 从标准样板创建新项目 |
save_project | 保存当前打开的项目 |
compile_project | 构建具有结构化错误输出的主应用程序(超时120秒) |
get_compile_messages | 在不触发新构建的情况下检索最后的编译器消息 |
POU/代码编写工具
| 工具 | 说明 |
|---|---|
create_pou | 创建程序、功能块或函数 |
set_pou_code | 设置声明和/或实现代码。还接受方法和属性路径(例如。 Application/MyFB/MethodName) |
create_property | 在功能块中创建属性 |
create_method | 在功能块中创建方法 |
create_dut | 创建数据单元类型(结构、枚举、联合、别名) |
create_gvl | 使用可选的初始声明创建全局变量列表 |
create_folder | 在项目树中创建组织文件夹 |
delete_object | 删除用户创建的项目对象(POU、DUT、GVL、文件夹等)。拒绝系统节点(Application, Device, Plc Logic, Library Manager, Task Configuration, MainTask, Communication, Ethernet, Project Settings等)和任何顶级路径 |
rename_object | 重命名任何项目对象 |
get_all_pou_code | 批量读取项目中的所有声明和实现代码(120秒超时) |
search_code | 正则表达式(或文字子字符串)在每个POU/Method/Property/DUT/GVL主体中搜索。退货 {path, section, line, col, text} 点击数 |
find_references | 在项目中搜索符号名称的单词边界。包裹 search_code 随着 \bsymbol\b |
rename_symbol | 尽最大努力在所有POU主体上进行文本重命名。两阶段写作(计划+申请)。拒绝IEC关键字- dryRun=true 默认情况下 |
在线/运行时工具
| 工具 | 说明 |
|---|---|
connect_to_device | 登录到PLC运行时。可选通过 ipAddress (以及 gatewayName,默认值 Gateway-1)在登录前设置设备地址 |
disconnect_from_device | 从PLC运行时注销。如果未连接,则无操作(返回成功) |
set_credentials | 设置默认值 username/password 用于后续登录。用户名必须非空。对于无身份验证运行时,请不要调用此工具 |
set_simulation_mode | 打开/关闭设备级模拟模式。在之前运行 connect_to_device 当没有物理PLC可用时 |
get_application_state | 检查PLC应用程序是否正在运行、停止或异常 |
read_variable | 从正在运行的PLC读取实时变量值(例如。, PLC_PRG.bMotorRunning) |
write_variable | 在正在运行的PLC上写入/强制一个变量值 |
download_to_device | 将编译后的应用程序下载到PLC。 mode: auto (默认-尝试在线更改,回退到完整), online_change (如果被拒绝,则失败),或 full.120秒超时 |
start_stop_application | 启动或停止PLC应用程序 |
monitor_variables | 在有界持续时间内以固定间隔对一个或多个PLC变量进行采样。返回时间序列(上限为60秒。间隔为10毫秒) |
图书馆管理工具
| 工具 | 说明 |
|---|---|
list_project_libraries | 列出项目中引用的所有库及其版本信息 |
add_library | 向项目添加库引用。该库必须安装在本地CODESYS存储库中。传递完全限定的占位符名称(例如。 Standard, * (System))-赤裸裸的名字,比如 Util 不会解决 |
设备树工具
| 工具 | 说明 |
|---|---|
list_device_repository | 本地CODESYS设备存储库中安装的每个设备描述符的只读枚举。可选的 vendor, nameContains, maxResults 过滤器。退货 {name, vendor, device_type, device_id, version, description, category} 每个条目-用于验证的底物 add_device 论点 |
inspect_device_node | 项目设备节点的只读自检:描述符元数据、具有当前值的参数列表、子设备 |
add_device | 包裹 parent.add_device(name, type, id, version).搭配 list_device_repository 源代码规范 deviceType / deviceId / version 三元组而不是猜测 |
set_device_parameter | 实验。包裹 device.parameter[id].value = ... 随着倒退。许多现场总线参数仅为GUI,并返回明确的错误 |
map_io_channel | 将现场总线I/O通道绑定(或清除)到全局变量符号。通过斜线分隔的名称路径解析通道(Inputs/Byte 0/Bit 3)或数字索引(0/3).集 clearBinding: true 删除现有绑定 |
归档工具
| 工具 | 说明 |
|---|---|
create_project_archive | 将打开的项目另存为 .projectarchive。首先保存未保存的编辑。可选的 comment, includeLibraries, includeCompiledLibraries |
MCP资源
| 资源URI | 描述 |
|---|---|
codesys://project/status | CODESYS脚本状态和打开的项目信息 |
codesys://project/{path}/structure | 项目树结构 |
codesys://project/{path}/pou/{pou}/code | POU声明和实现代码 |
URI路径格式
这 {path} 和 {pou} 分段使用 RFC 6570保留扩展 -传递值 字面意思是生 : 和 /,而不是百分比编码。在Windows上,将反斜杠转换为正斜杠。示例:
codesys://project/C:/Users/me/Documents/MyPLC.project/structure
codesys://project/C:/Users/me/Documents/MyPLC.project/pou/Application/MyPOU/code
codesys://project/C:/Users/me/Documents/MyPLC.project/pou/Application/MyFB/Method1/code这 pou-code 资源还读取方法和属性体(尽管其名称),这是一个在后面有三个或更多段的路径 /pou/ 下一篇:FBs的孩子。如果对路径进行百分比编码(例如。 C%3A%2FUsers%2F...),该段被逐字传递并被视为相对路径,但会失败 Object reference not set to an instance of an object.
ListMcpResourcesTool 只返回静态 project-status 资源。这两个模板化资源是动态的(需要参数),不会出现在列表中。
⚠️ 副作用: 如果所请求的项目路径不同于当前打开的项目, ensure_project_open 将关闭当前的一个并打开请求的一个。这违反了“资源是只读的”的预期。将资源URI视为可以交换项目上下文。执行模式
持久模式(默认)
- 服务器启动
CODESYS.exe随着--runscript=watcher.py(没有--noUI) - CODESYS UI打开-用户可以查看IDE并与之交互
- 观察器脚本启动。NET后台线程,用于轮询
commands/目录,然后 将控制权交还给CODESYS 因此UI保持完全响应 - 当调用工具时,服务器会写入
.py脚本+.command.json到commands/ - 后台线程检测命令,并通过以下方式将执行封送到CODESYS UI线程上
system.execute_on_primary_thread() - 结果以原子方式写入
results/ - 工具所做的更改实时显示在CODESYS UI中
- UI在命令之间保持交互-仅在同步API调用(编译、打开)期间短暂暂停
无头模式
回到最初的方法:每个工具调用都会生成一个新的CODESYS流程 --noUI,运行脚本,然后退出。未显示UI。在以下情况下使用:
--mode headless已指定- 持久模式无法启动
--fallback-headless已启用 - CODESYS随
--no-auto-launch和launch_codesys还没接到电话
检测已安装的版本
codesys-mcp-persistent --detect扫描 Program Files 和 Program Files (x86) 用于CODESYS安装。
已知限制
这些是CODESYS脚本API或平台限制,而不是此服务器中的错误:
- 在创建时不强制执行标识符长度。
create_pou,create_dut,create_gvl接受任何长度的名称。CODESYS仅在编译或保存期间发出投诉。坚持使用≤32个字符的IEC标识符。 - DUT名称包含
.被CODESYS拒绝 随着The name 'X.Y' is not valid for this object.不要在标识符名称中使用点。 set_pou_code空字符串现在是禁止操作的。 经过declarationCode: ""(或implementationCode: "")被视为省略了它——该部分没有改变。要明确清除一个部分,请传递一个单行占位符,如下所示// cleared或评论块。delete_object不会通过旧客户端删除系统保留最后一段的用户对象。 allowlist使用精确路径匹配。名为的用户文件夹MainTask,Library Manager等,只要它们嵌套在非系统父路径下。find_object_by_pathambiguous解析返回None。 如果两个对象在项目树中共享一个名称,则助手现在拒绝选择获胜者。通过更具体的路径(例如。Application/SubFolder/MyPOU而不仅仅是MyPOU).add_library需要一个完全限定的占位符 匹配库管理器UI显示字符串(例如。Standard, * (System)).像这样的裸名Util失败于placeholder library X could not be resolved.set_default_credentials拒绝空用户名 随着ValueErrorTheset_credentials工具Zod验证username.min(1).is_simulation_modegetter返回None在ifm AE3100设备描述符上(可能还有其他描述符)。设定器工作。验证必须来自编译+在线→ 登录工作。online.create_online_application提高Stack empty即使通过以下方式进行模拟system.commands.Item('Simulation').execute('true').IDE的Login命令填充脚本API无法访问的内部上下文堆栈。解决方法:单击Online → Login每个会话在IDE中运行一次,或者在真实的PLC上运行。set_pou_code自动保存 -每次成功的调用都会写入磁盘。UI Ctrl+Z无法恢复之前的内容。- 在Windows上,原子文件写入不是严格意义上的原子 -守望者的
os.remove+os.rename序列会留下一个小窗口,读者看不到文件。IPC重试循环可以容忍,但并不理想。跟踪。
故障排除
未找到CODESYS 使用验证路径 --detect可执行文件通常位于: C:\Program Files\CODESYS 3.5.XX.X\CODESYS\Common\CODESYS.exe
项目文件已锁定 另一个CODESYS实例可能已打开该项目。先关闭它或使用持久模式,这样只有一个实例。
观察者超时(持久模式) 如果观察者在60秒内没有发出准备就绪的信号,请检查:
- CODESYS路径和配置文件正确
- 没有模式对话框阻止CODESYS启动
- 尝试
--verbose用于详细记录
UI在命令执行期间短暂暂停(持久模式) 观察器使用一个后台线程,将工作编组到UI线程上,因此UI在命令之间保持响应。在同步CODESYS API调用(编译、项目打开)期间,UI可能会短暂暂停——这是预期的,也是正常的。如果命令挂起,请检查CODESYS消息窗口中的模态对话框或错误。
命令超时 默认值为60秒(编译和下载为120秒)。增加 --timeout .检查CODESYS消息窗口是否有错误。
在线/运行时工具失败 在线工具(connect_to_device, read_variable等等)要求:
- CODESYS项目中配置的设备/网关(或
connect_to_device(ipAddress=...)在通话时设置一个,或set_simulation_mode(enable=true)仅适用于模拟器流) - 连接前要成功编译的项目
- 可访问的PLC或CODESYS SoftPLC运行时(不在模拟中时)
disconnect_from_device 未连接时可以安全呼叫-它会返回 Already disconnected. 而不是失败。
Stack empty 从 connect_to_device 启用模拟后 CODESYS脚本API的一个已知限制是: online.create_online_application 可以提高 Stack empty 即使在进行模拟时也是如此,因为内部上下文堆栈是由IDE选择填充的(在导航器中单击设备或应用程序)。解决方法:
- 点击
Online -> Login在会话的CODESYS IDE中执行一次,然后重试。项目级模拟标志将保持不变。 - 或者在真正的PLC/CODESYS Control Win软PLC上运行,而不是IDE模拟。
MCP服务器重新启动后锁定项目文件 如果之前的MCP会话留下了孤儿 CODESYS.exe 持有项目文件后,临时生成将失败,并显示“所选项目当前正在使用中”。通过任务管理器关闭孤儿,或传递 --kill-existing-codesys 到下一次启动(默认情况下关闭,因此我们永远不会终止您可能打开的外部IDE会话)。
add_library 报告“占位符库X无法解析” 这 add_library 工具调用 Library Manager.add_library(name),它只接受安装在CODESYS库存储库中的库名称。特殊字符串,如 "Util" 被拒绝。按照库管理器UI中显示的方式传递完全限定的占位符字符串,例如:
Standard, * (System)Util, 3.5.16.0 (3S - Smart Software Solutions GmbH)CAA Memory, * (CAA Technical Workgroup)
如果您不知道确切的占位符字符串,请通过CODESYS UI添加一次库以发现规范形式,然后在后续调用中使用该字符串。
路线图(仍有空白)
在0.6.0中实现: search_code, find_references, rename_symbol, monitor_variables, create_project_archive, inspect_device_node, add_device, set_device_parameter, list_device_repository, map_io_channel.仍在桌上:
| 能力 | 范围 | 为什么重要 |
|---|---|---|
generate_boot_application | 包装材料 Online.CreateBootApplication | 现场部署工件创建 |
configure_task | 循环/事件/自由任务配置+POU附件 | 循环时间敏感代码(PPVS拒绝延迟)需要可脚本化的任务配置 |
export_project_xml | proj.export_xml(...) | 从0.6.0开始,改为 create_project_archive.重新审视是否需要非确定性但可读的导出通道 |
发展
# Install dependencies
npm install
# Build (compiles TypeScript + copies Python scripts)
npm run build
# Run all tests
npm test
# Type check only
npm run typecheck
# Run tests in watch mode
npm run test:watch项目结构
src/
bin.ts CLI entry point
server.ts MCP tool/resource registration (40 tools, 3 resources)
launcher.ts CODESYS process management
ipc.ts File-based IPC transport
headless.ts Headless fallback executor
script-manager.ts Python template loading + interpolation
types.ts Shared TypeScript types
logger.ts Structured stderr logging
scripts/ Python scripts (watcher + helpers + tool scripts)
tests/
unit/ Unit tests (IPC, script manager, launcher)
integration/ Integration tests (script pipeline, manual CODESYS tests)
mock_watcher.py Standalone watcher for testing without CODESYS许可证
麻省理工学院
