@codesys/mcp-toolkit 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -0
- package/README.md +109 -9
- package/README.zh-CN.md +72 -9
- package/dist/actions.d.ts +9 -4
- package/dist/actions.js +1 -1
- package/dist/actions.js.map +1 -1
- package/dist/codesys/debug.d.ts +5 -0
- package/dist/codesys/debug.js +89 -0
- package/dist/codesys/debug.js.map +1 -0
- package/dist/codesys/device-tools.d.ts +3 -0
- package/dist/codesys/device-tools.js +38 -0
- package/dist/codesys/device-tools.js.map +1 -0
- package/dist/codesys/graphical.d.ts +76 -0
- package/dist/codesys/graphical.js +226 -0
- package/dist/codesys/graphical.js.map +1 -0
- package/dist/codesys/lang.d.ts +39 -0
- package/dist/codesys/lang.js +177 -0
- package/dist/codesys/lang.js.map +1 -0
- package/dist/codesys/simtest.d.ts +48 -0
- package/dist/codesys/simtest.js +103 -0
- package/dist/codesys/simtest.js.map +1 -0
- package/dist/codesys/st.d.ts +1 -1
- package/dist/codesys/st.js.map +1 -1
- package/dist/codesys/trace.d.ts +19 -0
- package/dist/codesys/trace.js +139 -0
- package/dist/codesys/trace.js.map +1 -0
- package/dist/hmi/native.d.ts +89 -0
- package/dist/hmi/native.js +447 -0
- package/dist/hmi/native.js.map +1 -0
- package/dist/hmi/render.d.ts +90 -0
- package/dist/hmi/render.js +307 -0
- package/dist/hmi/render.js.map +1 -0
- package/dist/hmi/route.d.ts +32 -0
- package/dist/hmi/route.js +184 -0
- package/dist/hmi/route.js.map +1 -0
- package/dist/hmi/service.d.ts +45 -0
- package/dist/hmi/service.js +182 -0
- package/dist/hmi/service.js.map +1 -0
- package/dist/hmi/spec.d.ts +821 -0
- package/dist/hmi/spec.js +191 -0
- package/dist/hmi/spec.js.map +1 -0
- package/dist/hmi/templates.d.ts +11 -0
- package/dist/hmi/templates.js +92 -0
- package/dist/hmi/templates.js.map +1 -0
- package/dist/hmi/tools.d.ts +4 -0
- package/dist/hmi/tools.js +222 -0
- package/dist/hmi/tools.js.map +1 -0
- package/dist/hmi/value.d.ts +3 -0
- package/dist/hmi/value.js +26 -0
- package/dist/hmi/value.js.map +1 -0
- package/dist/panel/hmi.js +138 -0
- package/dist/panel.d.ts +3 -0
- package/dist/panel.js +17 -0
- package/dist/panel.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +7 -2
- package/dist/server.js.map +1 -1
- package/dist/tools.d.ts +5 -1
- package/dist/tools.js +18 -2
- package/dist/tools.js.map +1 -1
- package/dist/viewer.d.ts +1 -1
- package/dist/viewer.js +13 -2
- package/dist/viewer.js.map +1 -1
- package/package.json +1 -1
- package/watcher/mcp_alarms.py +134 -0
- package/watcher/mcp_debug.py +161 -0
- package/watcher/mcp_devices.py +83 -0
- package/watcher/mcp_lang.py +179 -0
- package/watcher/mcp_ops.py +3 -1
- package/watcher/mcp_trace.py +90 -0
- package/watcher/mcp_ui.py +54 -0
- package/watcher/mcp_visu.py +422 -0
- package/watcher/watcher.py +35 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,91 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.3.0] - 2026-11-14
|
|
11
|
+
|
|
12
|
+
Several of the new actions use CODESYS's own services inside the IDE, beyond
|
|
13
|
+
what its scripting API documents: `get_signature`, `find_references`,
|
|
14
|
+
`rename_symbol`, `trace_setup`, `trace_record`, the debug actions,
|
|
15
|
+
`hmi_export_codesys` and `--show-window`. They are experimental and checked on
|
|
16
|
+
the versions noted below.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- HMI screens: Claude designs live operator screens for the program
|
|
20
|
+
(`hmi_save_screen`): a process diagram with tanks, pumps, fans, valves and
|
|
21
|
+
animated pipes, plus gauges, values with sparklines, bars, status lights,
|
|
22
|
+
buttons, switches, setpoints, trends and alarms, bound to PLC variables, in a
|
|
23
|
+
dark or light theme. `hmi_screenshot` returns the screen as an image so the
|
|
24
|
+
model can check and polish its layout. `open_hmi` opens it in the browser
|
|
25
|
+
(127.0.0.1 with a token), live while the simulation runs; buttons, switches
|
|
26
|
+
and setpoints write to the simulation only. Screens are stored next to the
|
|
27
|
+
project as `<project>.hmi.json`.
|
|
28
|
+
- `hmi_export_codesys`: the same screen as a native CODESYS visualization,
|
|
29
|
+
with cards, gradients, SVG pump, fan and valve symbols in an embedded image
|
|
30
|
+
pool, live values, bars, tank levels, colour states, buttons, switches,
|
|
31
|
+
setpoints and alarm rows; a generated program scales values for bars and
|
|
32
|
+
levels. Built through CODESYS's visualization scripting and its element
|
|
33
|
+
creators. Returns a picture of the visualization. Checked on SP21.
|
|
34
|
+
- HMI projects with several pages: a shared header with links to every page and
|
|
35
|
+
the count of active alarms across all pages; page templates (`hmi_template`:
|
|
36
|
+
overview, unit, alarms, trends, settings); faceplate popups on pumps, fans
|
|
37
|
+
and valves; panel sizes 1280x720, 1920x1080, 1024x768 and 800x480; warnings
|
|
38
|
+
for overlapping symbols. Trend history survives page changes.
|
|
39
|
+
- HMI pipes connect to named ports on tanks, pumps, fans, valves and junctions
|
|
40
|
+
and are routed with right angles, so they meet the symbols exactly in the
|
|
41
|
+
browser and in CODESYS.
|
|
42
|
+
- `get_signature`: the interface of any POU or type from CODESYS's compiler,
|
|
43
|
+
including FBs in compiled libraries (TON, CTU, MC_...), with doc comments.
|
|
44
|
+
- `find_references`: where a variable, POU or type is declared, read, written
|
|
45
|
+
or called, with line and column. Both checked on SP21 and SP22.
|
|
46
|
+
- `trace_setup` and `trace_record`: CODESYS Trace in the simulation, returned
|
|
47
|
+
as a summary (BOOL edges and extremes with their times), a table and a
|
|
48
|
+
chart image. Checked on SP22 without a window.
|
|
49
|
+
- `create_graphical`: ladder, FBD and SFC programs and function blocks from a
|
|
50
|
+
structured description, generated as PLCopenXML. Checked on SP22: a ladder
|
|
51
|
+
latch, an AND into a TON and a three-step SFC compile and behave correctly
|
|
52
|
+
in the simulation.
|
|
53
|
+
- Debugging in the simulation: `breakpoint_set` (by line), `debug_status`,
|
|
54
|
+
`debug_step` (over, into, out), `debug_continue`, `breakpoint_clear`.
|
|
55
|
+
Checked on SP22 without a window.
|
|
56
|
+
- `rename_symbol`: rename a variable or POU everywhere it is used, from
|
|
57
|
+
CODESYS's cross-references (works without a window; CODESYS's own
|
|
58
|
+
refactoring needs one). Checked on SP22: 0 build errors after.
|
|
59
|
+
- `codesys_sim_test`: test cases in the simulation (write or force, cycles or
|
|
60
|
+
real time, expected values with comparisons and tolerances), reported as a
|
|
61
|
+
pass/fail table. Checked on SP22.
|
|
62
|
+
- `find_device` and `add_device`: search CODESYS's device repository and add
|
|
63
|
+
devices to the tree. Checked on SP22: Ethernet, a Modbus TCP Client and a
|
|
64
|
+
Modbus TCP Server device compile with 0 errors.
|
|
65
|
+
- `create_object` creates persistent variable lists (`persistent_vars`).
|
|
66
|
+
- `hmi_export_codesys` builds every page: page buttons in each header
|
|
67
|
+
(change shown visualization), the start page and client size of
|
|
68
|
+
TargetVisu and WebVisu, turning pumps and fans (8 frames chosen by the
|
|
69
|
+
clock), faceplates as CODESYS dialog visualizations, the pages' alarms in
|
|
70
|
+
CODESYS alarm management (an alarm group with Error/Warning/Info classes
|
|
71
|
+
and message texts), and visualization user groups with a Login button.
|
|
72
|
+
Checked on SP21: three pages and two dialogs compile with 0 errors; the
|
|
73
|
+
alarms show in CODESYS's alarm group editor with their messages after the
|
|
74
|
+
project is reopened, and in the simulation CODESYS's alarm manager reports
|
|
75
|
+
the raised fault as an active alarm.
|
|
76
|
+
- Input actions only go on shapes: CODESYS raises an assertion dialog when
|
|
77
|
+
an image element gets one.
|
|
78
|
+
- The browser viewer closes open connections when it stops, so an open HMI
|
|
79
|
+
tab no longer keeps the server from exiting. Screenshots retry once when
|
|
80
|
+
the headless browser hangs at start.
|
|
81
|
+
- Actions can return images.
|
|
82
|
+
- `--show-window` opens every object the model creates or writes in its editor
|
|
83
|
+
tab, so the CODESYS window shows the code as it is written, and, while the
|
|
84
|
+
simulation runs, its live values. CODESYS's scripting API has no call for
|
|
85
|
+
this, so it uses CODESYS's own frame (checked on SP21 and SP22); where that
|
|
86
|
+
isn't available, nothing opens and the call works as before.
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
- The Chinese README states model support directly and lists the models
|
|
90
|
+
tested with OpenCode, as suggested by Zhen Yang (Alfabete-spec), who
|
|
91
|
+
reviews the Chinese documentation.
|
|
92
|
+
|
|
8
93
|
## [2.2.0] - 2026-11-14
|
|
9
94
|
|
|
10
95
|
### Added
|
package/README.md
CHANGED
|
@@ -34,6 +34,9 @@ can watch the code change as it happens.
|
|
|
34
34
|
interfaces, without reading every object.
|
|
35
35
|
- **Shows its work.** A live panel with the project tree, the code as it is
|
|
36
36
|
written, compile results, and Accept or Revert for each change.
|
|
37
|
+
- **Designs operator screens.** Claude builds a live HMI for your program,
|
|
38
|
+
with tanks, pumps, valves, gauges, trends and alarms, looks at it, and
|
|
39
|
+
polishes it. You operate it in the browser against the simulation.
|
|
37
40
|
- **Never touches a real controller.** The only online connection is to
|
|
38
41
|
CODESYS's own simulation, and every online call checks for it first.
|
|
39
42
|
|
|
@@ -106,19 +109,33 @@ operation. [The reference](docs/reference.md) describes each one.
|
|
|
106
109
|
| --- | --- |
|
|
107
110
|
| **Projects** | `open_project` `create_project` `save_project` `close_project` `codesys_status` |
|
|
108
111
|
| **Read code** | `get_project_tree` `read_objects` `search_code` `get_outline` |
|
|
109
|
-
| **Change code** | `write_object` `create_object` `delete_object` `rename_object` |
|
|
112
|
+
| **Change code** | `write_object` `create_object` `create_graphical` `delete_object` `rename_object` |
|
|
110
113
|
| **Build** | `compile` |
|
|
111
|
-
| **Libraries** | `list_libraries` `add_library` `remove_library` `get_library_api` |
|
|
112
|
-
| **
|
|
114
|
+
| **Libraries** | `list_libraries` `add_library` `remove_library` `get_library_api` `get_signature` |
|
|
115
|
+
| **Navigate code** | `find_references` `rename_symbol` |
|
|
116
|
+
| **Tasks and I/O** | `list_tasks` `configure_task` `get_io_list` `get_devices` `find_device` `add_device` |
|
|
113
117
|
| **Change tracking** | `checkpoint` `get_changes` `revert_object` |
|
|
114
|
-
| **Simulation** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` |
|
|
118
|
+
| **Simulation** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` `codesys_sim_test` |
|
|
119
|
+
| **Trace** | `trace_setup` `trace_record` |
|
|
120
|
+
| **Debug** | `breakpoint_set` `breakpoint_clear` `debug_status` `debug_step` `debug_continue` |
|
|
121
|
+
| **HMI screens** | `hmi_save_screen` `hmi_template` `hmi_screenshot` `hmi_export_codesys` `hmi_list` `hmi_delete_screen` `open_hmi` |
|
|
115
122
|
| **Helpers** | `batch` `wait` `help` `open_workspace` |
|
|
116
123
|
|
|
117
124
|
`batch` runs up to 50 actions in one call, which is much faster than separate
|
|
118
125
|
calls.
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
|
|
127
|
+
Some actions go beyond what CODESYS's scripting API documents and use CODESYS's
|
|
128
|
+
own services inside the IDE: `get_signature`, `find_references`,
|
|
129
|
+
`rename_symbol`, `trace_setup`, `trace_record`, the debug actions,
|
|
130
|
+
`hmi_export_codesys` (with its alarms and user groups) and `--show-window`.
|
|
131
|
+
They are **experimental**: checked on CODESYS V3.5 SP21 and SP22 as noted in
|
|
132
|
+
the [changelog](CHANGELOG.md). On another version they may report that the
|
|
133
|
+
feature isn't available, or not work.
|
|
134
|
+
|
|
135
|
+
Claude writes Structured Text, and creates ladder (LD), FBD and SFC programs
|
|
136
|
+
and function blocks with `create_graphical` from a simple description of rungs,
|
|
137
|
+
networks or steps; CODESYS draws them. Existing graphical bodies can be read as
|
|
138
|
+
PLCopenXML but not edited in place yet. CFC isn't supported.
|
|
122
139
|
|
|
123
140
|
## Live panel
|
|
124
141
|
|
|
@@ -141,6 +158,78 @@ the browser never opens by itself.
|
|
|
141
158
|
|
|
142
159
|
[More about the panel](docs/reference.md#live-panel)
|
|
143
160
|
|
|
161
|
+
## HMI screens
|
|
162
|
+
|
|
163
|
+
Ask Claude for an operator screen and it designs one for your program: a
|
|
164
|
+
process diagram with tanks, pumps, fans, valves and flowing pipes, and gauges,
|
|
165
|
+
values, trends, status lights, alarms, buttons, switches and setpoints, all
|
|
166
|
+
bound to your PLC variables.
|
|
167
|
+
|
|
168
|
+

|
|
169
|
+
|
|
170
|
+
- **A whole HMI, not one screen.** Pages (overview, unit, alarms, trends,
|
|
171
|
+
settings) share a header that links to every page and counts the active
|
|
172
|
+
alarms of all pages. `hmi_template` gives Claude a good layout for each kind
|
|
173
|
+
of page to adapt. Panels: 1280x720, 1920x1080, 1024x768 or 800x480.
|
|
174
|
+
- **Faceplates.** Clicking a pump, fan or valve opens its popup: mode switch,
|
|
175
|
+
Start/Stop or Open/Close, Reset, live values and a setpoint.
|
|
176
|
+
- **Pipes connect themselves.** Tanks, pumps, fans, valves and junctions have
|
|
177
|
+
named ports (`T-101.right`, `P-101.in`, `V-102.out`). Claude says what a pipe
|
|
178
|
+
connects, and the toolkit routes it with right angles to meet each symbol
|
|
179
|
+
exactly, in the browser and in CODESYS alike. Unknown symbols or ports are
|
|
180
|
+
refused with the list of valid ones.
|
|
181
|
+
- **Claude checks its own work.** `hmi_screenshot` returns the screen as an
|
|
182
|
+
image, so Claude can see overlaps, empty space or unclear labels and fix
|
|
183
|
+
them before you look.
|
|
184
|
+
- **Live in your browser.** Ask Claude to open the HMI (`open_hmi`). The page
|
|
185
|
+
is served by the toolkit on 127.0.0.1 with a token, like the workspace. While
|
|
186
|
+
CODESYS's simulation runs, it shows live values, pumps spin, pipes flow and
|
|
187
|
+
trends draw. Buttons, switches and setpoints write to the simulation, so you
|
|
188
|
+
can operate your program before any hardware exists.
|
|
189
|
+
- **Stored with the project.** Screens are saved next to the project file as
|
|
190
|
+
`<project>.hmi.json`, so they travel with it and can go into version control.
|
|
191
|
+
- **Dark and light themes,** on a 1280x720 canvas that scales to any window.
|
|
192
|
+
|
|
193
|
+
The HMI writes only into CODESYS's own simulation, like the rest of the
|
|
194
|
+
toolkit. Screenshots use Microsoft Edge or Google Chrome, whichever is
|
|
195
|
+
installed.
|
|
196
|
+
|
|
197
|
+
### As a native CODESYS visualization
|
|
198
|
+
|
|
199
|
+
`hmi_export_codesys` builds the same screen as a real CODESYS visualization in
|
|
200
|
+
your project. It is an ordinary visualization object, so it goes with the
|
|
201
|
+
application like one you drew yourself (we checked it in CODESYS's simulation,
|
|
202
|
+
not on a controller). It doesn't use CODESYS's stock lamps: cards with gradients, SVG
|
|
203
|
+
pump, fan and valve symbols in an embedded image pool, live values, bars and
|
|
204
|
+
tank levels, colour states, buttons, switches, setpoints and alarm rows that
|
|
205
|
+
appear only while active. A generated program, `PRG_HMI_<screen>`, scales
|
|
206
|
+
values for the bars and levels. Claude gets a picture of the result.
|
|
207
|
+
|
|
208
|
+
A multi-page HMI comes out as one visualization per page with page buttons in
|
|
209
|
+
the header, the first page as the start page of TargetVisu and WebVisu at the
|
|
210
|
+
panel size, pumps and fans that turn while running, faceplates as CODESYS
|
|
211
|
+
dialogs, the pages' alarms in CODESYS's alarm management (Alarm Configuration,
|
|
212
|
+
with timestamps and acknowledge in the PLC), and user groups (Operator,
|
|
213
|
+
Maintenance, Admin) behind a Login button. Users and passwords are yours to add
|
|
214
|
+
in the Visualization Manager.
|
|
215
|
+
|
|
216
|
+

|
|
217
|
+
|
|
218
|
+
The alarms are CODESYS's own, not a copy in the HMI: an alarm group with its
|
|
219
|
+
observations, classes and messages, which CODESYS's alarm manager evaluates in
|
|
220
|
+
the PLC. In the simulation, raising the fault made the group report an active
|
|
221
|
+
alarm, and it stayed pending after the fault cleared, until acknowledged, as an
|
|
222
|
+
Error-class alarm should.
|
|
223
|
+
|
|
224
|
+

|
|
225
|
+
|
|
226
|
+
CODESYS's scripting can't create trend, meter or alarm-table elements, so
|
|
227
|
+
trends show their current values, gauges show a bar, and the alarm page shows a
|
|
228
|
+
row per alarm while it is active (acknowledge it in CODESYS's own alarm table,
|
|
229
|
+
which you can add from the toolbox). Checked on CODESYS V3.5 SP21 in the
|
|
230
|
+
simulation. A visualization needs the `FloatingPointUtils` library in CODESYS's
|
|
231
|
+
library repository; if it's missing, the export says so.
|
|
232
|
+
|
|
144
233
|
## Other clients and models
|
|
145
234
|
|
|
146
235
|
The server works with any MCP client, not only Claude. For
|
|
@@ -228,10 +317,19 @@ itself.
|
|
|
228
317
|
### Watch it in the CODESYS window
|
|
229
318
|
|
|
230
319
|
By default CODESYS runs headless. With `--show-window` the server starts it with
|
|
231
|
-
its normal window, so you can
|
|
232
|
-
|
|
320
|
+
its normal window, so you can watch the work in any MCP client: every object the
|
|
321
|
+
model creates or writes opens in its editor tab, with the new code in it.
|
|
322
|
+
|
|
323
|
+

|
|
233
324
|
|
|
234
|
-
|
|
325
|
+
While the simulation runs, the open editors show live values, as in CODESYS's own
|
|
326
|
+
online mode:
|
|
327
|
+
|
|
328
|
+

|
|
329
|
+
|
|
330
|
+
CODESYS's scripting API has no call for opening an editor, so the toolkit uses
|
|
331
|
+
CODESYS's own (undocumented) frame for it, checked on SP21 and SP22. If a CODESYS
|
|
332
|
+
version doesn't have it, nothing opens and everything else works as before.
|
|
235
333
|
|
|
236
334
|
While the server is connected, the window is for watching: the toolkit's script
|
|
237
335
|
keeps running in it (that is what lets it answer CODESYS's prompts, such as a
|
|
@@ -365,6 +463,8 @@ The persistent-watcher design borrows ideas from
|
|
|
365
463
|
[phobicdotno/Codesys-MCP-Master](https://github.com/phobicdotno/Codesys-MCP-Master)
|
|
366
464
|
(file-queue IPC, version-safe opening). Both are MIT-licensed.
|
|
367
465
|
|
|
466
|
+
The [Chinese README](README.zh-CN.md) was reviewed by Zhen Yang (Alfabete-spec).
|
|
467
|
+
|
|
368
468
|
## License
|
|
369
469
|
|
|
370
470
|
[MIT](LICENSE)
|
package/README.zh-CN.md
CHANGED
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
这是一个 [MCP](https://modelcontextprotocol.io)(模型上下文协议)服务器。它在后台保持一个
|
|
19
19
|
CODESYS 会话,让 AI 助手直接操作你的真实项目:用真正的 CODESYS 编译器编译,在 CODESYS
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
自带的仿真中测试,而你可以实时看到代码的变化。
|
|
21
|
+
|
|
22
|
+
工具包支持任何能够通过 MCP 客户端调用工具的 AI 模型。我们用 OpenCode 测试了 DeepSeek V4.1 Flash、
|
|
23
|
+
通义千问 Qwen 3.6 Plus、GLM 5.3 和 MiniMax M3,均完成了全部步骤(见[已测试的模型](#已测试的模型))。
|
|
22
24
|
|
|
23
25
|

|
|
24
26
|
|
|
@@ -134,10 +136,57 @@ Cline、Trae、通义灵码、Cursor、Claude Desktop 等使用 `mcpServers` 配
|
|
|
134
136
|
- **浏览器中的工作区。** 在其他客户端中,让模型“打开 CODESYS 工作区”(`open_workspace`),
|
|
135
137
|
同样的界面会在浏览器中打开,只监听本机 127.0.0.1,并带有访问令牌。浏览器不会自动打开。
|
|
136
138
|
- **CODESYS 窗口。** 启动参数加上 `--show-window`,CODESYS 会以正常窗口运行,而不是在后台
|
|
137
|
-
|
|
139
|
+
无界面运行。模型创建或修改的每个对象都会在编辑器标签页中打开,可以直接看到新写的代码;
|
|
140
|
+
仿真运行时,打开的编辑器会显示变量的实时值。工具包不会自动关闭这个窗口。
|
|
141
|
+
|
|
142
|
+

|
|
138
143
|
|
|
139
144
|

|
|
140
145
|
|
|
146
|
+
## HMI 操作画面
|
|
147
|
+
|
|
148
|
+
让 Claude 为你的程序设计操作画面:带储罐、泵、风机、阀门和流动管道的工艺流程图,以及仪表盘、
|
|
149
|
+
数值、趋势图、状态灯、报警、按钮、开关和设定值,全部绑定到 PLC 变量。
|
|
150
|
+
|
|
151
|
+

|
|
152
|
+
|
|
153
|
+
- **完整的 HMI,而不只是一个画面。** 多个页面(总览、单元、报警、趋势、设置)共用一个页眉,
|
|
154
|
+
页眉链接到每个页面并统计所有页面的活动报警。`hmi_template` 为每种页面提供良好的布局。
|
|
155
|
+
面板尺寸:1280x720、1920x1080、1024x768 或 800x480。
|
|
156
|
+
- **操作面板(faceplate)。** 点击泵、风机或阀门会弹出面板:模式开关、启动/停止或开/关、复位、
|
|
157
|
+
实时数值和设定值。
|
|
158
|
+
- **Claude 会检查自己的设计。** `hmi_screenshot` 把画面作为图片返回给 Claude,它能发现重叠、
|
|
159
|
+
空白或不清楚的标签并自行修正。
|
|
160
|
+
- **在浏览器中实时运行。** 让 Claude 打开 HMI(`open_hmi`)。页面由工具包在 127.0.0.1 上提供,
|
|
161
|
+
并带有访问令牌。CODESYS 仿真运行时显示实时数值,泵会转动,管道会流动;按钮、开关和设定值
|
|
162
|
+
写入仿真,在没有硬件之前就能操作你的程序。
|
|
163
|
+
- **管道自动连接。** 储罐、泵、风机、阀门和三通都有命名接口(如 `T-101.right`、`P-101.in`),Claude 只需说明管道连接哪两个接口,
|
|
164
|
+
工具包会以直角自动布线,在浏览器和 CODESYS 中都能精确对接。
|
|
165
|
+
- **与项目一起保存。** 画面保存在项目文件旁边的 `<项目名>.hmi.json` 中。
|
|
166
|
+
|
|
167
|
+
HMI 只写入 CODESYS 自带的仿真,不会连接真实控制器。
|
|
168
|
+
|
|
169
|
+
`hmi_export_codesys` 还能把同一个画面生成为项目中的原生 CODESYS 可视化(不用 CODESYS 自带的灯和按钮样式):
|
|
170
|
+
渐变卡片、嵌入图片池的 SVG 泵/风机/阀门符号、实时数值、液位和棒图、按钮、开关、设定值和报警行,
|
|
171
|
+
它是普通的可视化对象,随应用程序一起使用(我们在 CODESYS 仿真中验证过,未在真实控制器上测试)。
|
|
172
|
+
|
|
173
|
+
多页 HMI 会生成为每页一个可视化,页眉中有页面按钮;第一页设为 TargetVisu 和 WebVisu 的起始页;
|
|
174
|
+
运行中的泵和风机会转动;操作面板生成为 CODESYS 对话框;用户组(Operator、Maintenance、Admin)
|
|
175
|
+
配有登录按钮(用户和密码由你在 Visualization Manager 中添加)。
|
|
176
|
+
|
|
177
|
+

|
|
178
|
+
|
|
179
|
+
报警是 CODESYS 自己的报警,而不是 HMI 中的副本:导出会创建报警配置(Alarm Configuration)中的
|
|
180
|
+
报警组,包括观察条件、报警类别和报警消息,由 CODESYS 的报警管理器在 PLC 中计算。在仿真中触发
|
|
181
|
+
故障后,报警组报告一个活动报警;故障消失后它仍保持待确认状态,直到被确认,这正是 Error 类报警
|
|
182
|
+
应有的行为。
|
|
183
|
+
|
|
184
|
+

|
|
185
|
+
|
|
186
|
+
CODESYS 的脚本无法创建趋势、仪表或报警表元素,所以趋势显示当前值,仪表显示为棒图,报警页在
|
|
187
|
+
报警活动时显示一行(可在 CODESYS 自带的报警表中确认报警,报警表可从工具箱添加)。已在 CODESYS
|
|
188
|
+
V3.5 SP21 的仿真中验证。可视化需要 CODESYS 库存储库中有 `FloatingPointUtils` 库;如果缺少,导出会提示。
|
|
189
|
+
|
|
141
190
|
## 可用操作
|
|
142
191
|
|
|
143
192
|
所有操作都通过一个 MCP 工具 `codesys` 完成,每个操作对应一个 action。
|
|
@@ -147,18 +196,28 @@ Cline、Trae、通义灵码、Cursor、Claude Desktop 等使用 `mcpServers` 配
|
|
|
147
196
|
| --- | --- |
|
|
148
197
|
| **项目** | `open_project` `create_project` `save_project` `close_project` `codesys_status` |
|
|
149
198
|
| **读取代码** | `get_project_tree` `read_objects` `search_code` `get_outline` |
|
|
150
|
-
| **修改代码** | `write_object` `create_object` `delete_object` `rename_object` |
|
|
199
|
+
| **修改代码** | `write_object` `create_object` `create_graphical` `delete_object` `rename_object` |
|
|
151
200
|
| **编译** | `compile` |
|
|
152
|
-
| **库** | `list_libraries` `add_library` `remove_library` `get_library_api` |
|
|
153
|
-
|
|
|
201
|
+
| **库** | `list_libraries` `add_library` `remove_library` `get_library_api` `get_signature` |
|
|
202
|
+
| **代码导航** | `find_references` `rename_symbol` |
|
|
203
|
+
| **任务与 I/O** | `list_tasks` `configure_task` `get_io_list` `get_devices` `find_device` `add_device` |
|
|
154
204
|
| **改动跟踪** | `checkpoint` `get_changes` `revert_object` |
|
|
155
|
-
| **仿真** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` |
|
|
205
|
+
| **仿真** | `codesys_sim_start` `codesys_sim_stop` `codesys_sim_status` `codesys_sim_control` `codesys_sim_cycle` `codesys_sim_read` `codesys_sim_write` `codesys_sim_force` `codesys_sim_unforce` `codesys_sim_test` |
|
|
206
|
+
| **跟踪(Trace)** | `trace_setup` `trace_record` |
|
|
207
|
+
| **调试** | `breakpoint_set` `breakpoint_clear` `debug_status` `debug_step` `debug_continue` |
|
|
208
|
+
| **HMI 画面** | `hmi_save_screen` `hmi_template` `hmi_screenshot` `hmi_export_codesys` `hmi_list` `hmi_delete_screen` `open_hmi` |
|
|
156
209
|
| **辅助** | `batch` `wait` `help` `open_workspace` |
|
|
157
210
|
|
|
158
211
|
`batch` 可以在一次调用中执行最多 50 个操作,比逐个调用快得多。
|
|
159
212
|
|
|
160
|
-
|
|
161
|
-
|
|
213
|
+
有些操作超出了 CODESYS 脚本 API 文档的范围,使用 IDE 内部的 CODESYS 服务:`get_signature`、
|
|
214
|
+
`find_references`、`rename_symbol`、`trace_setup`、`trace_record`、调试操作、`hmi_export_codesys`
|
|
215
|
+
(包括报警和用户组)以及 `--show-window`。它们属于**实验性功能**:已在 CODESYS V3.5 SP21 和 SP22 上
|
|
216
|
+
验证(见[更新日志](CHANGELOG.md)),在其他版本上可能提示功能不可用,或无法正常工作。
|
|
217
|
+
|
|
218
|
+
Claude 编写结构化文本,并可用 `create_graphical` 根据梯级、网络或步骤的简单描述创建梯形图(LD)、
|
|
219
|
+
FBD 和 SFC 程序及功能块,由 CODESYS 绘制。已有的图形化代码可以以 PLCopenXML 形式读取,但还不能
|
|
220
|
+
就地编辑。不支持 CFC。
|
|
162
221
|
|
|
163
222
|
## 安全
|
|
164
223
|
|
|
@@ -180,6 +239,10 @@ PLCopenXML 形式读取,但不能编辑。
|
|
|
180
239
|
|
|
181
240
|
欢迎提交 Issue 和 Pull Request,中文或英文均可。
|
|
182
241
|
|
|
242
|
+
## 致谢
|
|
243
|
+
|
|
244
|
+
感谢 Zhen Yang(Alfabete-spec)审阅本中文文档。
|
|
245
|
+
|
|
183
246
|
## 许可证
|
|
184
247
|
|
|
185
248
|
[MIT](LICENSE)
|
package/dist/actions.d.ts
CHANGED
|
@@ -8,11 +8,16 @@
|
|
|
8
8
|
import type { McpServer } from "@modelcontextprotocol/server";
|
|
9
9
|
import * as z from "zod/v4";
|
|
10
10
|
export declare const TOOL_NAME = "codesys";
|
|
11
|
+
export type ActionContent = {
|
|
12
|
+
type: "text";
|
|
13
|
+
text: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "image";
|
|
16
|
+
data: string;
|
|
17
|
+
mimeType: string;
|
|
18
|
+
};
|
|
11
19
|
export type ActionResult = {
|
|
12
|
-
content:
|
|
13
|
-
type: "text";
|
|
14
|
-
text: string;
|
|
15
|
-
}[];
|
|
20
|
+
content: ActionContent[];
|
|
16
21
|
isError?: boolean;
|
|
17
22
|
};
|
|
18
23
|
export interface ActionConfig<S extends z.ZodObject = z.ZodObject> {
|
package/dist/actions.js
CHANGED
|
@@ -57,7 +57,7 @@ function batchAction(actions) {
|
|
|
57
57
|
let failed = false;
|
|
58
58
|
for (const [i, s] of steps.entries()) {
|
|
59
59
|
const r = await s.action.run(s.args);
|
|
60
|
-
out.push(`[${i + 1}/${steps.length}] ${s.name}${r.isError ? " FAILED" : ""}:\n${r.content.map((c) => c.text).join("\n")}`);
|
|
60
|
+
out.push(`[${i + 1}/${steps.length}] ${s.name}${r.isError ? " FAILED" : ""}:\n${r.content.map((c) => (c.type === "text" ? c.text : "(an image: call this action on its own to see it)")).join("\n")}`);
|
|
61
61
|
failed ||= !!r.isError;
|
|
62
62
|
if (r.isError && !continueOnError) {
|
|
63
63
|
if (i + 1 < steps.length)
|
package/dist/actions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ActionResult, RegisterAction } from "../actions.js";
|
|
2
|
+
import type { AppContext } from "../tools.js";
|
|
3
|
+
/** Implementation line (1-based) -> CODESYS position, for every statement. */
|
|
4
|
+
export declare function lineMap(impl: string, positions: number[]): Map<number, number>;
|
|
5
|
+
export declare function registerDebugActions(reg: RegisterAction, ctx: AppContext, run: (fn: () => Promise<string>) => Promise<ActionResult>): void;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Breakpoints and stepping in CODESYS's simulation (watcher/mcp_debug.py).
|
|
3
|
+
* CODESYS addresses statements by position; the low 32 bits of a position are
|
|
4
|
+
* the implementation line plus a per-object offset, so lines map to positions
|
|
5
|
+
* from the first statement's line.
|
|
6
|
+
*/
|
|
7
|
+
import * as z from "zod/v4";
|
|
8
|
+
import { currentCodesysSim } from "./simulation.js";
|
|
9
|
+
const low = (p) => p - Math.floor(p / 2 ** 32) * 2 ** 32;
|
|
10
|
+
/** Implementation line (1-based) -> CODESYS position, for every statement. */
|
|
11
|
+
export function lineMap(impl, positions) {
|
|
12
|
+
const lines = impl.split(/\r?\n/);
|
|
13
|
+
const first = lines.findIndex((l) => {
|
|
14
|
+
const t = l.trim();
|
|
15
|
+
return t && !t.startsWith("//") && !t.startsWith("(*");
|
|
16
|
+
});
|
|
17
|
+
const valid = positions.filter((p) => low(p) !== 0xffffffff);
|
|
18
|
+
const out = new Map();
|
|
19
|
+
if (first < 0 || !valid.length)
|
|
20
|
+
return out;
|
|
21
|
+
const base = low(valid[0]) - (first + 1);
|
|
22
|
+
for (const p of valid) {
|
|
23
|
+
const line = low(p) - base;
|
|
24
|
+
if (line >= 1 && line <= lines.length && !out.has(line))
|
|
25
|
+
out.set(line, p);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
export function registerDebugActions(reg, ctx, run) {
|
|
30
|
+
const b = ctx.bridge;
|
|
31
|
+
const needSim = () => {
|
|
32
|
+
if (!currentCodesysSim(ctx))
|
|
33
|
+
throw new Error("The simulation isn't running: call codesys_sim_start first. Breakpoints only work in CODESYS's simulation.");
|
|
34
|
+
};
|
|
35
|
+
const where = (s) => {
|
|
36
|
+
if (!/halt/i.test(s.state))
|
|
37
|
+
return `Simulation: ${s.state}.`;
|
|
38
|
+
const at = s.at;
|
|
39
|
+
if (!at?.path)
|
|
40
|
+
return `Simulation: ${s.state} (position unknown).`;
|
|
41
|
+
const map = lineMap(at.implementation ?? "", at.positions ?? []);
|
|
42
|
+
const line = [...map].find(([, p]) => p === at.position)?.[0];
|
|
43
|
+
const code = line ? (at.implementation ?? "").split(/\r?\n/)[line - 1]?.trim() : undefined;
|
|
44
|
+
const end = low(at.position) === 0xffffffff ? " at its end (RETURN)" : "";
|
|
45
|
+
return `Halted in ${at.path}${line ? ` at line ${line}: ${code}` : end} (instance ${at.instance}). Read values with codesys_sim_read, then debug_step or debug_continue.`;
|
|
46
|
+
};
|
|
47
|
+
reg("breakpoint_set", {
|
|
48
|
+
description: "Set a breakpoint in the running simulation at a line of a POU's implementation. The simulation halts there; debug_status shows where, codesys_sim_read reads values, debug_step steps, debug_continue goes on. For a function block give the instance, e.g. 'PLC_PRG.fbPump'.",
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
path: z.string().describe("POU, e.g. 'FB_Pump' or 'PLC_PRG'"),
|
|
51
|
+
line: z.number().int().min(1).describe("Line of the implementation (1 = first line)"),
|
|
52
|
+
instance: z.string().optional().describe("Instance path for a function block, e.g. 'PLC_PRG.fbPump' (a program is its own instance)"),
|
|
53
|
+
}),
|
|
54
|
+
}, async ({ path, line, instance }) => run(async () => {
|
|
55
|
+
needSim();
|
|
56
|
+
const p = await b.call("debug.positions", { path });
|
|
57
|
+
const map = lineMap(p.implementation, p.positions);
|
|
58
|
+
const lines = [...map.keys()].sort((x, y) => x - y);
|
|
59
|
+
const at = lines.find((l) => l >= line);
|
|
60
|
+
if (at === undefined)
|
|
61
|
+
throw new Error(`No statement at or after line ${line} of ${p.path}. Statement lines: ${lines.join(", ")}.`);
|
|
62
|
+
const inst = instance ?? p.path.split("/").pop();
|
|
63
|
+
await b.call("debug.set", { path, position: map.get(at), instance: inst });
|
|
64
|
+
const code = p.implementation.split(/\r?\n/)[at - 1]?.trim();
|
|
65
|
+
return `Breakpoint at ${p.path} line ${at}${at !== line ? ` (the first statement at or after line ${line})` : ""}: ${code} (instance ${inst}).`;
|
|
66
|
+
}));
|
|
67
|
+
reg("breakpoint_clear", { description: "Remove all breakpoints (the simulation then keeps running after debug_continue).", inputSchema: z.object({}) }, async () => run(async () => {
|
|
68
|
+
needSim();
|
|
69
|
+
const r = await b.call("debug.clear", {});
|
|
70
|
+
return r.cleared.length ? `Removed ${r.cleared.length} breakpoint(s).` : "There were no breakpoints.";
|
|
71
|
+
}));
|
|
72
|
+
reg("debug_status", { description: "Whether the simulation is running or halted at a breakpoint, and where (POU, line, code).", inputSchema: z.object({}) }, async () => run(async () => {
|
|
73
|
+
needSim();
|
|
74
|
+
return where(await b.call("debug.status", {}));
|
|
75
|
+
}));
|
|
76
|
+
reg("debug_step", {
|
|
77
|
+
description: "Step while halted: over (next statement), into (into a called POU), out (back to the caller).",
|
|
78
|
+
inputSchema: z.object({ kind: z.enum(["over", "into", "out"]).default("over") }),
|
|
79
|
+
}, async ({ kind }) => run(async () => {
|
|
80
|
+
needSim();
|
|
81
|
+
return where(await b.call("debug.step", { kind }));
|
|
82
|
+
}));
|
|
83
|
+
reg("debug_continue", { description: "Continue running after a halt (it halts again at the next breakpoint hit).", inputSchema: z.object({}) }, async () => run(async () => {
|
|
84
|
+
needSim();
|
|
85
|
+
const r = await b.call("debug.continue", {});
|
|
86
|
+
return `Simulation: ${r.state}.`;
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/codesys/debug.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Devices from CODESYS's device repository: find installed device descriptions
|
|
3
|
+
* (fieldbus masters and slaves, I/O modules) and add them to the device tree
|
|
4
|
+
* (watcher/mcp_devices.py). Offline: nothing goes online.
|
|
5
|
+
*/
|
|
6
|
+
import * as z from "zod/v4";
|
|
7
|
+
export function registerDeviceActions(reg, ctx, run) {
|
|
8
|
+
const b = ctx.bridge;
|
|
9
|
+
reg("find_device", {
|
|
10
|
+
description: "Search the device descriptions installed in CODESYS (fieldbus masters and slaves such as Modbus TCP, EtherCAT, CANopen, PROFINET; I/O modules; drives) by name. Returns type, id and version to pass to add_device.",
|
|
11
|
+
inputSchema: z.object({ text: z.string().describe("Part of the device name, e.g. 'Modbus TCP', 'EtherCAT Master', 'CANopen'"), limit: z.number().int().min(1).max(100).default(30) }),
|
|
12
|
+
}, async ({ text, limit }) => run(async () => {
|
|
13
|
+
const r = await b.call("devices.search", { text, limit }, { timeoutMs: 120_000 });
|
|
14
|
+
if (!r.devices.length)
|
|
15
|
+
return `No installed device description matches '${text}'. Install it with the CODESYS Installer or Tools > Device Repository.`;
|
|
16
|
+
return [
|
|
17
|
+
`${r.devices.length}${r.more ? "+" : ""} device(s) matching '${text}':`,
|
|
18
|
+
...r.devices.map((d) => `- ${d.name} (${d.vendor}${d.version ? `, ${d.version}` : ""}) type=${d.type} id='${d.id}' version='${d.version}'${d.description ? `: ${d.description}` : ""}`),
|
|
19
|
+
].join("\n");
|
|
20
|
+
}));
|
|
21
|
+
reg("add_device", {
|
|
22
|
+
description: "Add a device from the repository to the device tree, under a device: the controller (its name from get_devices, e.g. '/Device' or '/PLCWinNT') for an Ethernet adapter or bus interface, the adapter for a fieldbus master, the master for its slaves. Use type, id and version from find_device. 'plug' fills a slot of a device with fixed slots. Then map its I/O channels (get_devices shows them) and compile.",
|
|
23
|
+
inputSchema: z.object({
|
|
24
|
+
parent: z.string().describe("Device to add under, e.g. '/PLCWinNT' or '/PLCWinNT/Ethernet'"),
|
|
25
|
+
name: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).describe("Name of the new device, e.g. 'Modbus_TCP_Master'"),
|
|
26
|
+
type: z.number().int(),
|
|
27
|
+
id: z.string(),
|
|
28
|
+
version: z.string(),
|
|
29
|
+
module: z.string().optional(),
|
|
30
|
+
how: z.enum(["add", "insert", "plug"]).default("add"),
|
|
31
|
+
index: z.number().int().optional().describe("Position for insert"),
|
|
32
|
+
}),
|
|
33
|
+
}, async (a) => run(async () => {
|
|
34
|
+
const r = await b.call("devices.add", { ...a, save: ctx.autosave }, { timeoutMs: 120_000 });
|
|
35
|
+
return `Added ${a.name} at ${r.path}. Call get_devices to see its I/O channels, and compile.`;
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=device-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-tools.js","sourceRoot":"","sources":["../../src/codesys/device-tools.ts"],"names":[],"mappings":"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"}
|