codesysultra 1.0.3 → 1.0.5

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/dist/bin.js CHANGED
@@ -66,20 +66,15 @@ commander_1.program
66
66
  .version(version)
67
67
  .option('-p, --codesys-path <path>', 'Path to CODESYS executable (can contain spaces, use quotes if needed)', process.env.CODESYS_PATH || 'C:\\Program Files\\CODESYS 3.5.21.0\\CODESYS\\Common\\CODESYS.exe')
68
68
  .option('-f, --codesys-profile <profile>', 'CODESYS profile name (overrides CODESYS_PROFILE env var)', process.env.CODESYS_PROFILE || 'CODESYS V3.5 SP21')
69
- .option('-w, --workspace <dir>', 'Workspace directory for relative project paths', process.cwd());
70
- // 添加配置生成命令
71
- commander_1.program.command('config')
72
- .description('Generate configuration from CODESYS version info file')
73
- .option('-c, --codesys-path <path>', 'Path to CODESYS executable')
74
- .option('-v, --version-info <path>', 'Path to CODESYS version info file')
75
- .option('-o, --output <path>', 'Output configuration file path (optional, prints to console if not specified)')
76
- .action((options) => {
77
- generateConfig(options);
78
- });
69
+ .option('-w, --workspace <dir>', 'Workspace directory for relative project paths', process.cwd())
70
+ .option('-g, --generate-config', 'Generate configuration file from CODESYS version info (use with -c and -v)')
71
+ .option('-v, --version-info <path>', 'Path to CODESYS version info file (for config generation)')
72
+ .option('-o, --output <path>', 'Output configuration file path (for config generation)');
79
73
  commander_1.program.parse(process.argv); // Parse the arguments
80
74
  const options = commander_1.program.opts();
81
- // 如果执行的是config命令,不继续执行服务器启动
82
- if (process.argv[2] === 'config') {
75
+ // 如果是生成配置模式
76
+ if (options.generateConfig) {
77
+ generateConfig(options);
83
78
  process.exit(0);
84
79
  }
85
80
  // --- Log options Commander parsed ---
@@ -121,7 +116,7 @@ function generateConfig(options) {
121
116
  process.exit(1);
122
117
  }
123
118
  if (!options.codesysPath) {
124
- console.error('Error: CODESYS path is required. Use -c or --codesys-path option.');
119
+ console.error('Error: CODESYS path is required. Use -p or --codesys-path option.');
125
120
  process.exit(1);
126
121
  }
127
122
  const versionInfoPath = path.resolve(options.versionInfo);
@@ -328,5 +328,27 @@ function registerTools(server, config) {
328
328
  return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true };
329
329
  }
330
330
  }));
331
+ server.tool("get_all_tools", // Tool Name
332
+ "Retrieves all available tools and methods from the CODESYS project.", // Tool Description
333
+ {
334
+ projectFilePath: zod_1.z.string().describe("Path to the CODESYS project file (e.g., 'C:/Projects/MyPLC.project').")
335
+ }, (args) => __awaiter(this, void 0, void 0, function* () {
336
+ const { projectFilePath } = args;
337
+ let absPath = path.normalize(path.isAbsolute(projectFilePath) ? projectFilePath : path.join(WORKSPACE_DIR, projectFilePath));
338
+ console.error(`Tool call: get_all_tools: ${absPath}`);
339
+ try {
340
+ const escapedPath = absPath.replace(/\\/g, '\\\\');
341
+ const script = templates_1.GET_ALL_TOOLS_SCRIPT_TEMPLATE.replace("{PROJECT_FILE_PATH}", escapedPath);
342
+ console.error(">>> get_all_tools: PREPARED SCRIPT:", script.substring(0, 500) + "...");
343
+ const result = yield (0, codesys_interop_1.executeCodesysScript)(script, codesysExePath, codesysProfileName);
344
+ console.error(">>> get_all_tools: EXECUTION RESULT:", JSON.stringify(result));
345
+ const success = result.success && result.output.includes("SCRIPT_SUCCESS");
346
+ return { content: [{ type: "text", text: success ? result.output : `Failed to get tools. Output:\n${result.output}` }], isError: !success };
347
+ }
348
+ catch (e) {
349
+ console.error(`Error get_all_tools ${absPath}: ${e}`);
350
+ return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true };
351
+ }
352
+ }));
331
353
  // --- End Tools ---
332
354
  }
@@ -0,0 +1,89 @@
1
+ import sys, scriptengine as script_engine, os, traceback, inspect
2
+
3
+ {{ENSURE_PROJECT_OPEN_PYTHON_SNIPPET}}
4
+
5
+ def get_all_tools_and_methods():
6
+ try:
7
+ project = ensure_project_open(PROJECT_FILE_PATH)
8
+
9
+ print("\\n=== CODESYS Available Tools and Methods ===\\n")
10
+
11
+ def analyze_object(obj, indent=0, visited=None):
12
+ if visited is None:
13
+ visited = set()
14
+
15
+ obj_id = id(obj)
16
+ if obj_id in visited:
17
+ return
18
+ visited.add(obj_id)
19
+
20
+ indent_str = " " * indent
21
+ try:
22
+ name = getattr(obj, 'get_name', lambda: str(obj))() or "Unnamed"
23
+ obj_type = type(obj).__name__
24
+ except:
25
+ name = "Unknown"
26
+ obj_type = "Unknown"
27
+
28
+ print("%s- %s (%s)" % (indent_str, name, obj_type))
29
+
30
+ try:
31
+ members = inspect.getmembers(obj)
32
+ methods = []
33
+ properties = []
34
+
35
+ for member_name, member in members:
36
+ if member_name.startswith('_'):
37
+ continue
38
+ if inspect.ismethod(member) or inspect.isfunction(member):
39
+ try:
40
+ sig = inspect.signature(member)
41
+ methods.append(" %s%s" % (indent_str, member_name))
42
+ except:
43
+ methods.append(" %s%s" % (indent_str, member_name))
44
+ elif not inspect.ismethod(member) and not inspect.isfunction(member):
45
+ try:
46
+ val = getattr(obj, member_name)
47
+ if not inspect.ismethod(val) and not inspect.isfunction(val):
48
+ properties.append(" %s%s: %s" % (indent_str, member_name, type(val).__name__))
49
+ except:
50
+ pass
51
+
52
+ if methods:
53
+ print("%s Methods:" % indent_str)
54
+ for method in methods:
55
+ print(method)
56
+
57
+ if properties:
58
+ print("%s Properties:" % indent_str)
59
+ for prop in properties:
60
+ print(prop)
61
+
62
+ except Exception as e:
63
+ print("%s Error analyzing object: %s" % (indent_str, str(e)))
64
+
65
+ try:
66
+ if hasattr(obj, 'get_children'):
67
+ children = obj.get_children(False)
68
+ if children:
69
+ print("%s Children: %d" % (indent_str, len(children)))
70
+ for child in children:
71
+ analyze_object(child, indent + 1, visited)
72
+ except Exception as e:
73
+ print("%s Error getting children: %s" % (indent_str, str(e)))
74
+
75
+ analyze_object(project, max_depth=3)
76
+
77
+ print("\\n=== Analysis Complete ===")
78
+ print("SCRIPT_SUCCESS: All tools and methods retrieved successfully.")
79
+ sys.exit(0)
80
+
81
+ except Exception as e:
82
+ detailed_error = traceback.format_exc()
83
+ error_message = "Error analyzing CODESYS project '%s': %s\\n%s" % (PROJECT_FILE_PATH, e, detailed_error)
84
+ print(error_message)
85
+ print("SCRIPT_ERROR: %s" % error_message)
86
+ sys.exit(1)
87
+
88
+ if __name__ == "__main__":
89
+ get_all_tools_and_methods()
package/dist/templates.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.GET_POU_CODE_SCRIPT_TEMPLATE = exports.CREATE_METHOD_SCRIPT_TEMPLATE = exports.CREATE_PROPERTY_SCRIPT_TEMPLATE = exports.SET_POU_CODE_SCRIPT_TEMPLATE = exports.CREATE_POU_SCRIPT_TEMPLATE = exports.GET_PROJECT_STRUCTURE_SCRIPT_TEMPLATE = exports.COMPILE_PROJECT_SCRIPT_TEMPLATE = exports.SAVE_PROJECT_SCRIPT_TEMPLATE = exports.OPEN_PROJECT_SCRIPT_TEMPLATE = exports.CREATE_PROJECT_SCRIPT_TEMPLATE = exports.CHECK_STATUS_SCRIPT = exports.FIND_OBJECT_BY_PATH_PYTHON_SNIPPET = exports.ENSURE_PROJECT_OPEN_PYTHON_SNIPPET = void 0;
6
+ exports.GET_POU_CODE_SCRIPT_TEMPLATE = exports.CREATE_METHOD_SCRIPT_TEMPLATE = exports.CREATE_PROPERTY_SCRIPT_TEMPLATE = exports.SET_POU_CODE_SCRIPT_TEMPLATE = exports.CREATE_POU_SCRIPT_TEMPLATE = exports.GET_ALL_TOOLS_SCRIPT_TEMPLATE = exports.GET_PROJECT_STRUCTURE_SCRIPT_TEMPLATE = exports.COMPILE_PROJECT_SCRIPT_TEMPLATE = exports.SAVE_PROJECT_SCRIPT_TEMPLATE = exports.OPEN_PROJECT_SCRIPT_TEMPLATE = exports.CREATE_PROJECT_SCRIPT_TEMPLATE = exports.CHECK_STATUS_SCRIPT = exports.FIND_OBJECT_BY_PATH_PYTHON_SNIPPET = exports.ENSURE_PROJECT_OPEN_PYTHON_SNIPPET = void 0;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const templatesDir = path_1.default.join(__dirname, 'templates');
@@ -35,6 +35,7 @@ exports.OPEN_PROJECT_SCRIPT_TEMPLATE = injectDependencies(readTemplate('open_pro
35
35
  exports.SAVE_PROJECT_SCRIPT_TEMPLATE = injectDependencies(readTemplate('save_project.py'));
36
36
  exports.COMPILE_PROJECT_SCRIPT_TEMPLATE = injectDependencies(readTemplate('compile_project.py'));
37
37
  exports.GET_PROJECT_STRUCTURE_SCRIPT_TEMPLATE = injectDependencies(readTemplate('get_project_structure.py'));
38
+ exports.GET_ALL_TOOLS_SCRIPT_TEMPLATE = readTemplate('get_all_tools.py');
38
39
  exports.CREATE_POU_SCRIPT_TEMPLATE = injectDependencies(readTemplate('create_pou.py'));
39
40
  exports.SET_POU_CODE_SCRIPT_TEMPLATE = injectDependencies(readTemplate('set_pou_code.py'));
40
41
  exports.CREATE_PROPERTY_SCRIPT_TEMPLATE = injectDependencies(readTemplate('create_property.py'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codesysultra",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Model Context Protocol (MCP) server for CODESYS automation platform",
5
5
  "main": "dist/server.js",
6
6
  "bin": {
@@ -0,0 +1,13 @@
1
+ {
2
+ "mcpServers": {
3
+ "codesys_local": {
4
+ "command": "codesysultra",
5
+ "args": [
6
+ "--codesys-path",
7
+ "E:\\Soft\\Codesys\\CODESYS\\Common\\CODESYS.exe",
8
+ "--codesys-profile",
9
+ "CODESYS V3.5 SP21 Patch 4"
10
+ ]
11
+ }
12
+ }
13
+ }