@codesys/mcp-toolkit 1.1.4 → 1.2.1
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/.claude/settings.local.json +25 -0
- package/CHANGELOG.md +36 -26
- package/CLAUDE.md +26 -0
- package/CONTRIBUTING.md +72 -72
- package/LICENSE +21 -21
- package/README.md +152 -145
- package/README.md.enhanced +155 -155
- package/codesys-mcp-toolkit-1.2.0.tgz +0 -0
- package/codesys-mcp-toolkit-1.2.1.tgz +0 -0
- package/dist/codesys_interop.js +29 -2
- package/dist/scripts/check_status.py +21 -0
- package/dist/scripts/compile_project.py +65 -0
- package/dist/scripts/create_method.py +80 -0
- package/dist/scripts/create_pou.py +96 -0
- package/dist/scripts/create_project.py +54 -0
- package/dist/scripts/create_property.py +78 -0
- package/dist/scripts/ensure_project_open.py +154 -0
- package/dist/scripts/find_object_by_path.py +111 -0
- package/dist/scripts/get_pou_code.py +91 -0
- package/dist/scripts/get_project_structure.py +72 -0
- package/dist/scripts/open_project.py +25 -0
- package/dist/scripts/save_project.py +29 -0
- package/dist/scripts/set_pou_code.py +104 -0
- package/dist/server.js +124 -11
- package/dist/sessionManager.js +401 -0
- package/docs/index.md +26 -26
- package/docs/installation.md +84 -84
- package/docs/session_management.md +84 -0
- package/examples/README.md +78 -78
- package/examples/sample_config.json +32 -32
- package/package.json +51 -48
- package/scriptDoc.txt +8679 -8679
- package/scripts/build.js +25 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import sys, scriptengine as script_engine, os, traceback
|
|
2
|
+
|
|
3
|
+
# Import ensure_project_open function from the template
|
|
4
|
+
# This will be prepended by the script loader
|
|
5
|
+
def ensure_project_open(target_project_path):
|
|
6
|
+
# Function implementation will be included from ensure_project_open.py
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
# Import find_object_by_path function from the template
|
|
10
|
+
# This will be prepended by the script loader
|
|
11
|
+
def find_object_by_path_robust(start_node, full_path, target_type_name="object"):
|
|
12
|
+
# Function implementation will be included from find_object_by_path.py
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
POU_FULL_PATH = "{POU_FULL_PATH}" # Expecting format like "Application/MyPOU" or "Folder/SubFolder/MyPOU"
|
|
16
|
+
DECLARATION_CONTENT = """{DECLARATION_CONTENT}"""
|
|
17
|
+
IMPLEMENTATION_CONTENT = """{IMPLEMENTATION_CONTENT}"""
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
print("DEBUG: set_pou_code script: POU_FULL_PATH='%s', Project='%s'" % (POU_FULL_PATH, PROJECT_FILE_PATH))
|
|
21
|
+
primary_project = ensure_project_open(PROJECT_FILE_PATH)
|
|
22
|
+
if not POU_FULL_PATH: raise ValueError("POU full path empty.")
|
|
23
|
+
|
|
24
|
+
# Find the target POU/Method/Property object
|
|
25
|
+
target_object = find_object_by_path_robust(primary_project, POU_FULL_PATH, "target object")
|
|
26
|
+
if not target_object: raise ValueError("Target object not found using path: %s" % POU_FULL_PATH)
|
|
27
|
+
|
|
28
|
+
target_name = getattr(target_object, 'get_name', lambda: POU_FULL_PATH)()
|
|
29
|
+
print("DEBUG: Found target object: %s" % target_name)
|
|
30
|
+
|
|
31
|
+
# --- Set Declaration Part ---
|
|
32
|
+
declaration_updated = False
|
|
33
|
+
# Check if the content is actually provided (might be None/empty if only impl is set)
|
|
34
|
+
has_declaration_content = 'DECLARATION_CONTENT' in locals() or 'DECLARATION_CONTENT' in globals()
|
|
35
|
+
if has_declaration_content and DECLARATION_CONTENT is not None: # Check not None
|
|
36
|
+
if hasattr(target_object, 'textual_declaration'):
|
|
37
|
+
decl_obj = target_object.textual_declaration
|
|
38
|
+
if decl_obj and hasattr(decl_obj, 'replace'):
|
|
39
|
+
try:
|
|
40
|
+
print("DEBUG: Accessing textual_declaration...")
|
|
41
|
+
decl_obj.replace(DECLARATION_CONTENT)
|
|
42
|
+
print("DEBUG: Set declaration text using replace().")
|
|
43
|
+
declaration_updated = True
|
|
44
|
+
except Exception as decl_err:
|
|
45
|
+
print("ERROR: Failed to set declaration text: %s" % decl_err)
|
|
46
|
+
traceback.print_exc() # Print stack trace for detailed error
|
|
47
|
+
else:
|
|
48
|
+
print("WARN: Target '%s' textual_declaration attribute is None or does not have replace(). Skipping declaration update." % target_name)
|
|
49
|
+
else:
|
|
50
|
+
print("WARN: Target '%s' does not have textual_declaration attribute. Skipping declaration update." % target_name)
|
|
51
|
+
else:
|
|
52
|
+
print("DEBUG: Declaration content not provided or is None. Skipping declaration update.")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# --- Set Implementation Part ---
|
|
56
|
+
implementation_updated = False
|
|
57
|
+
has_implementation_content = 'IMPLEMENTATION_CONTENT' in locals() or 'IMPLEMENTATION_CONTENT' in globals()
|
|
58
|
+
if has_implementation_content and IMPLEMENTATION_CONTENT is not None: # Check not None
|
|
59
|
+
if hasattr(target_object, 'textual_implementation'):
|
|
60
|
+
impl_obj = target_object.textual_implementation
|
|
61
|
+
if impl_obj and hasattr(impl_obj, 'replace'):
|
|
62
|
+
try:
|
|
63
|
+
print("DEBUG: Accessing textual_implementation...")
|
|
64
|
+
impl_obj.replace(IMPLEMENTATION_CONTENT)
|
|
65
|
+
print("DEBUG: Set implementation text using replace().")
|
|
66
|
+
implementation_updated = True
|
|
67
|
+
except Exception as impl_err:
|
|
68
|
+
print("ERROR: Failed to set implementation text: %s" % impl_err)
|
|
69
|
+
traceback.print_exc() # Print stack trace for detailed error
|
|
70
|
+
else:
|
|
71
|
+
print("WARN: Target '%s' textual_implementation attribute is None or does not have replace(). Skipping implementation update." % target_name)
|
|
72
|
+
else:
|
|
73
|
+
print("WARN: Target '%s' does not have textual_implementation attribute. Skipping implementation update." % target_name)
|
|
74
|
+
else:
|
|
75
|
+
print("DEBUG: Implementation content not provided or is None. Skipping implementation update.")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# --- SAVE THE PROJECT TO PERSIST THE CODE CHANGE ---
|
|
79
|
+
# Only save if something was actually updated to avoid unnecessary saves
|
|
80
|
+
if declaration_updated or implementation_updated:
|
|
81
|
+
try:
|
|
82
|
+
print("DEBUG: Saving Project (after code change)...")
|
|
83
|
+
primary_project.save() # Save the overall project file
|
|
84
|
+
print("DEBUG: Project saved successfully after code change.")
|
|
85
|
+
except Exception as save_err:
|
|
86
|
+
print("ERROR: Failed to save Project after setting code: %s" % save_err)
|
|
87
|
+
detailed_error = traceback.format_exc()
|
|
88
|
+
error_message = "Error saving Project after code change for '%s': %s\\n%s" % (target_name, save_err, detailed_error)
|
|
89
|
+
print(error_message); print("SCRIPT_ERROR: %s" % error_message); sys.exit(1)
|
|
90
|
+
else:
|
|
91
|
+
print("DEBUG: No code parts were updated, skipping project save.")
|
|
92
|
+
# --- END SAVING ---
|
|
93
|
+
|
|
94
|
+
print("Code Set For: %s" % target_name)
|
|
95
|
+
print("Path: %s" % POU_FULL_PATH)
|
|
96
|
+
print("SCRIPT_SUCCESS: Declaration and/or implementation set successfully.")
|
|
97
|
+
sys.exit(0)
|
|
98
|
+
|
|
99
|
+
except Exception as e:
|
|
100
|
+
detailed_error = traceback.format_exc()
|
|
101
|
+
error_message = "Error setting code for object '%s' in project '%s': %s\\n%s" % (POU_FULL_PATH, PROJECT_FILE_PATH, e, detailed_error)
|
|
102
|
+
print(error_message)
|
|
103
|
+
print("SCRIPT_ERROR: %s" % error_message)
|
|
104
|
+
sys.exit(1)
|
package/dist/server.js
CHANGED
|
@@ -67,6 +67,7 @@ const codesys_interop_1 = require("./codesys_interop");
|
|
|
67
67
|
const path = __importStar(require("path"));
|
|
68
68
|
const promises_1 = require("fs/promises");
|
|
69
69
|
const scriptLoader_1 = require("./scriptLoader");
|
|
70
|
+
const sessionManager_1 = require("./sessionManager");
|
|
70
71
|
// --- Wrap server logic in an exported function ---
|
|
71
72
|
function startMcpServer(config) {
|
|
72
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -113,6 +114,10 @@ function startMcpServer(config) {
|
|
|
113
114
|
});
|
|
114
115
|
}
|
|
115
116
|
// --- End Helper Function ---
|
|
117
|
+
// --- Initialize Session Manager ---
|
|
118
|
+
const sessionManager = new sessionManager_1.CodesysSessionManager(codesysExePath, codesysProfileName);
|
|
119
|
+
console.error('SERVER.TS: Session manager initialized');
|
|
120
|
+
// --- End Session Manager Initialization ---
|
|
116
121
|
// --- Preload script templates ---
|
|
117
122
|
try {
|
|
118
123
|
yield (0, scriptLoader_1.preloadAllScriptTemplates)();
|
|
@@ -145,7 +150,7 @@ function startMcpServer(config) {
|
|
|
145
150
|
console.error(`SERVER.TS Resource request: ${uri.href}`);
|
|
146
151
|
try {
|
|
147
152
|
const scriptContent = yield (0, scriptLoader_1.loadScriptTemplate)('check_status');
|
|
148
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
153
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
149
154
|
const outputLines = result.output.split(/[\r\n]+/).filter(line => line.trim());
|
|
150
155
|
const statusData = {};
|
|
151
156
|
outputLines.forEach(line => {
|
|
@@ -191,7 +196,7 @@ function startMcpServer(config) {
|
|
|
191
196
|
const scriptContent = (0, scriptLoader_1.interpolateScript)(combinedScript, {
|
|
192
197
|
'PROJECT_FILE_PATH': absoluteProjPath.replace(/\\/g, '\\\\')
|
|
193
198
|
});
|
|
194
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
199
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
195
200
|
let structureText = `Error retrieving structure for ${absoluteProjPath}.\n\n${result.output}`;
|
|
196
201
|
let isError = !result.success;
|
|
197
202
|
if (result.success && result.output.includes("SCRIPT_SUCCESS")) {
|
|
@@ -248,7 +253,7 @@ function startMcpServer(config) {
|
|
|
248
253
|
'PROJECT_FILE_PATH': absoluteProjPath.replace(/\\/g, '\\\\'),
|
|
249
254
|
'POU_FULL_PATH': sanitizedPouPath
|
|
250
255
|
});
|
|
251
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
256
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
252
257
|
let codeText = `Error retrieving code for object '${sanitizedPouPath}' in project '${absoluteProjPath}'.\n\n${result.output}`;
|
|
253
258
|
let isError = !result.success;
|
|
254
259
|
if (result.success && result.output.includes("SCRIPT_SUCCESS")) {
|
|
@@ -303,7 +308,7 @@ function startMcpServer(config) {
|
|
|
303
308
|
const scriptContent = (0, scriptLoader_1.interpolateScript)(combinedScript, {
|
|
304
309
|
'PROJECT_FILE_PATH': absPath.replace(/\\/g, '\\\\')
|
|
305
310
|
});
|
|
306
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
311
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
307
312
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
308
313
|
return {
|
|
309
314
|
content: [{
|
|
@@ -372,7 +377,7 @@ function startMcpServer(config) {
|
|
|
372
377
|
'TEMPLATE_PROJECT_PATH': templatePath.replace(/\\/g, '\\\\')
|
|
373
378
|
});
|
|
374
379
|
console.error(">>> create_project (copy-then-open): PREPARED SCRIPT:", scriptContent.substring(0, 500) + "...");
|
|
375
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
380
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
376
381
|
console.error(">>> create_project (copy-then-open): EXECUTION RESULT:", JSON.stringify(result));
|
|
377
382
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
378
383
|
return {
|
|
@@ -405,7 +410,7 @@ function startMcpServer(config) {
|
|
|
405
410
|
const scriptContent = (0, scriptLoader_1.interpolateScript)(combinedScript, {
|
|
406
411
|
'PROJECT_FILE_PATH': absPath.replace(/\\/g, '\\\\')
|
|
407
412
|
});
|
|
408
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
413
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
409
414
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
410
415
|
return {
|
|
411
416
|
content: [{
|
|
@@ -449,7 +454,7 @@ function startMcpServer(config) {
|
|
|
449
454
|
'PARENT_PATH': sanParentPath
|
|
450
455
|
});
|
|
451
456
|
console.error(">>> create_pou: PREPARED SCRIPT:", scriptContent.substring(0, 500) + "...");
|
|
452
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
457
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
453
458
|
console.error(">>> create_pou: EXECUTION RESULT:", JSON.stringify(result));
|
|
454
459
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
455
460
|
return {
|
|
@@ -500,7 +505,7 @@ function startMcpServer(config) {
|
|
|
500
505
|
'IMPLEMENTATION_CONTENT': sanImplCode
|
|
501
506
|
});
|
|
502
507
|
console.error(">>> set_pou_code: PREPARED SCRIPT:", scriptContent.substring(0, 500) + "...");
|
|
503
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
508
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
504
509
|
console.error(">>> set_pou_code: EXECUTION RESULT:", JSON.stringify(result));
|
|
505
510
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
506
511
|
return {
|
|
@@ -550,7 +555,7 @@ function startMcpServer(config) {
|
|
|
550
555
|
'PROPERTY_TYPE': sanPropType
|
|
551
556
|
});
|
|
552
557
|
console.error(">>> create_property: PREPARED SCRIPT:", scriptContent.substring(0, 500) + "...");
|
|
553
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
558
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
554
559
|
console.error(">>> create_property: EXECUTION RESULT:", JSON.stringify(result));
|
|
555
560
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
556
561
|
return {
|
|
@@ -600,7 +605,7 @@ function startMcpServer(config) {
|
|
|
600
605
|
'RETURN_TYPE': sanReturnType
|
|
601
606
|
});
|
|
602
607
|
console.error(">>> create_method: PREPARED SCRIPT:", scriptContent.substring(0, 500) + "...");
|
|
603
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
608
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
604
609
|
console.error(">>> create_method: EXECUTION RESULT:", JSON.stringify(result));
|
|
605
610
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
606
611
|
return {
|
|
@@ -633,7 +638,7 @@ function startMcpServer(config) {
|
|
|
633
638
|
const scriptContent = (0, scriptLoader_1.interpolateScript)(combinedScript, {
|
|
634
639
|
'PROJECT_FILE_PATH': absPath.replace(/\\/g, '\\\\')
|
|
635
640
|
});
|
|
636
|
-
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName);
|
|
641
|
+
const result = yield (0, codesys_interop_1.executeCodesysScript)(scriptContent, codesysExePath, codesysProfileName, sessionManager);
|
|
637
642
|
const success = result.success && result.output.includes("SCRIPT_SUCCESS");
|
|
638
643
|
// Check for actual compile errors in the output log
|
|
639
644
|
const hasCompileErrors = result.output.includes("Compile complete --") && !/ 0 error\(s\),/.test(result.output);
|
|
@@ -658,6 +663,114 @@ function startMcpServer(config) {
|
|
|
658
663
|
};
|
|
659
664
|
}
|
|
660
665
|
}));
|
|
666
|
+
// --- Session Management Tools ---
|
|
667
|
+
server.tool("start_session", "Starts a persistent CODESYS session for improved performance with multiple operations", {}, () => __awaiter(this, void 0, void 0, function* () {
|
|
668
|
+
console.error("Tool call: start_session");
|
|
669
|
+
try {
|
|
670
|
+
const currentState = sessionManager.getState();
|
|
671
|
+
if (currentState === sessionManager_1.SessionState.RUNNING || currentState === sessionManager_1.SessionState.BUSY) {
|
|
672
|
+
return {
|
|
673
|
+
content: [{
|
|
674
|
+
type: "text",
|
|
675
|
+
text: "CODESYS session is already running"
|
|
676
|
+
}],
|
|
677
|
+
isError: false
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
if (currentState === sessionManager_1.SessionState.STARTING) {
|
|
681
|
+
return {
|
|
682
|
+
content: [{
|
|
683
|
+
type: "text",
|
|
684
|
+
text: "CODESYS session is already starting"
|
|
685
|
+
}],
|
|
686
|
+
isError: false
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
yield sessionManager.startSession();
|
|
690
|
+
return {
|
|
691
|
+
content: [{
|
|
692
|
+
type: "text",
|
|
693
|
+
text: "CODESYS session started successfully"
|
|
694
|
+
}],
|
|
695
|
+
isError: false
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
catch (error) {
|
|
699
|
+
console.error(`Error starting session: ${error.message}`);
|
|
700
|
+
return {
|
|
701
|
+
content: [{
|
|
702
|
+
type: "text",
|
|
703
|
+
text: `Failed to start CODESYS session: ${error.message}`
|
|
704
|
+
}],
|
|
705
|
+
isError: true
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
}));
|
|
709
|
+
server.tool("stop_session", "Stops the persistent CODESYS session", {}, () => __awaiter(this, void 0, void 0, function* () {
|
|
710
|
+
console.error("Tool call: stop_session");
|
|
711
|
+
try {
|
|
712
|
+
const currentState = sessionManager.getState();
|
|
713
|
+
if (currentState === sessionManager_1.SessionState.STOPPED) {
|
|
714
|
+
return {
|
|
715
|
+
content: [{
|
|
716
|
+
type: "text",
|
|
717
|
+
text: "CODESYS session is already stopped"
|
|
718
|
+
}],
|
|
719
|
+
isError: false
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
if (currentState === sessionManager_1.SessionState.STOPPING) {
|
|
723
|
+
return {
|
|
724
|
+
content: [{
|
|
725
|
+
type: "text",
|
|
726
|
+
text: "CODESYS session is already stopping"
|
|
727
|
+
}],
|
|
728
|
+
isError: false
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
yield sessionManager.stopSession();
|
|
732
|
+
return {
|
|
733
|
+
content: [{
|
|
734
|
+
type: "text",
|
|
735
|
+
text: "CODESYS session stopped successfully"
|
|
736
|
+
}],
|
|
737
|
+
isError: false
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
catch (error) {
|
|
741
|
+
console.error(`Error stopping session: ${error.message}`);
|
|
742
|
+
return {
|
|
743
|
+
content: [{
|
|
744
|
+
type: "text",
|
|
745
|
+
text: `Failed to stop CODESYS session: ${error.message}`
|
|
746
|
+
}],
|
|
747
|
+
isError: true
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
}));
|
|
751
|
+
server.tool("session_status", "Returns the status of the CODESYS session", {}, () => __awaiter(this, void 0, void 0, function* () {
|
|
752
|
+
console.error("Tool call: session_status");
|
|
753
|
+
try {
|
|
754
|
+
const state = sessionManager.getState();
|
|
755
|
+
return {
|
|
756
|
+
content: [{
|
|
757
|
+
type: "text",
|
|
758
|
+
text: `CODESYS session status: ${state}`
|
|
759
|
+
}],
|
|
760
|
+
isError: false
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
catch (error) {
|
|
764
|
+
console.error(`Error getting session status: ${error.message}`);
|
|
765
|
+
return {
|
|
766
|
+
content: [{
|
|
767
|
+
type: "text",
|
|
768
|
+
text: `Failed to get CODESYS session status: ${error.message}`
|
|
769
|
+
}],
|
|
770
|
+
isError: true
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
}));
|
|
661
774
|
// --- End Tools ---
|
|
662
775
|
console.error("SERVER.TS: Resources and Tools defined.");
|
|
663
776
|
// --- End MCP Resources / Tools Definitions ---
|