genexus-mcp 2.50.0 → 2.52.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/cli/lib/client-adapters.js +189 -0
- package/cli/lib/client-adapters.test.js +50 -0
- package/cli/lib/config.js +17 -25
- package/package.json +2 -2
- package/publish/GxMcp.Gateway.deps.json +2 -2
- package/publish/GxMcp.Gateway.dll +0 -0
- package/publish/GxMcp.Gateway.exe +0 -0
- package/publish/config.json +5 -5
- package/publish/tool_definitions.json +1 -1
- package/publish/worker/GxMcp.Worker.exe +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
|
|
3
|
+
class BaseClientAdapter {
|
|
4
|
+
apply(_client, _launcher, _targetConfigPath, _opts = {}) {
|
|
5
|
+
throw new Error('apply() must be implemented by subclass');
|
|
6
|
+
}
|
|
7
|
+
remove(_client, _opts = {}) {
|
|
8
|
+
throw new Error('remove() must be implemented by subclass');
|
|
9
|
+
}
|
|
10
|
+
read(_client, _serverName) {
|
|
11
|
+
throw new Error('read() must be implemented by subclass');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
class McpServersJsonAdapter extends BaseClientAdapter {
|
|
16
|
+
constructor(configModule) {
|
|
17
|
+
super();
|
|
18
|
+
this.config = configModule || require('./config');
|
|
19
|
+
}
|
|
20
|
+
apply(client, launcher, targetConfigPath, opts = {}) {
|
|
21
|
+
return this.config.applyMcpServersJson(client.path, launcher, targetConfigPath, opts);
|
|
22
|
+
}
|
|
23
|
+
remove(client, opts = {}) {
|
|
24
|
+
return this.config.removeMcpServersJson(client.path, opts);
|
|
25
|
+
}
|
|
26
|
+
read(client, serverName) {
|
|
27
|
+
if (!fs.existsSync(client.path)) return null;
|
|
28
|
+
const parsed = this.config.readJsonFileSafe(client.path);
|
|
29
|
+
if (!parsed || typeof parsed !== 'object') return null;
|
|
30
|
+
let entry = parsed.mcpServers && parsed.mcpServers[serverName];
|
|
31
|
+
if (!entry && serverName === 'genexus18mcp') {
|
|
32
|
+
const legacyGx = parsed.mcpServers && parsed.mcpServers.genexus;
|
|
33
|
+
if (legacyGx && !this.config.isThirdPartyMcpEntry(legacyGx)) entry = legacyGx;
|
|
34
|
+
else if (parsed.mcpServers && parsed.mcpServers.genexus18) entry = parsed.mcpServers.genexus18;
|
|
35
|
+
}
|
|
36
|
+
if (!entry) return null;
|
|
37
|
+
return {
|
|
38
|
+
command: entry.command,
|
|
39
|
+
args: Array.isArray(entry.args) ? entry.args : [],
|
|
40
|
+
env: (entry.env && typeof entry.env === 'object') ? entry.env : {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
class VsCodeServersAdapter extends BaseClientAdapter {
|
|
46
|
+
constructor(configModule) {
|
|
47
|
+
super();
|
|
48
|
+
this.config = configModule || require('./config');
|
|
49
|
+
}
|
|
50
|
+
apply(client, launcher, targetConfigPath, opts = {}) {
|
|
51
|
+
return this.config.applyVsCodeServersJson(client.path, launcher, targetConfigPath, opts);
|
|
52
|
+
}
|
|
53
|
+
remove(client, opts = {}) {
|
|
54
|
+
return this.config.removeVsCodeServersJson(client.path, opts);
|
|
55
|
+
}
|
|
56
|
+
read(client, serverName) {
|
|
57
|
+
if (!fs.existsSync(client.path)) return null;
|
|
58
|
+
const parsed = this.config.readJsonFileSafe(client.path);
|
|
59
|
+
if (!parsed || typeof parsed !== 'object') return null;
|
|
60
|
+
let entry = parsed.servers && parsed.servers[serverName];
|
|
61
|
+
if (!entry && serverName === 'genexus18mcp') {
|
|
62
|
+
const legacyGx = parsed.servers && parsed.servers.genexus;
|
|
63
|
+
if (legacyGx && !this.config.isThirdPartyMcpEntry(legacyGx)) entry = legacyGx;
|
|
64
|
+
else if (parsed.servers && parsed.servers.genexus18) entry = parsed.servers.genexus18;
|
|
65
|
+
}
|
|
66
|
+
if (!entry) return null;
|
|
67
|
+
return {
|
|
68
|
+
command: entry.command,
|
|
69
|
+
args: Array.isArray(entry.args) ? entry.args : [],
|
|
70
|
+
env: (entry.env && typeof entry.env === 'object') ? entry.env : {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
class OpenCodeJsoncAdapter extends BaseClientAdapter {
|
|
76
|
+
constructor(configModule) {
|
|
77
|
+
super();
|
|
78
|
+
this.config = configModule || require('./config');
|
|
79
|
+
}
|
|
80
|
+
apply(client, launcher, targetConfigPath, opts = {}) {
|
|
81
|
+
return this.config.applyOpenCodeJson(client.path, launcher, targetConfigPath, opts);
|
|
82
|
+
}
|
|
83
|
+
remove(client, opts = {}) {
|
|
84
|
+
return this.config.removeOpenCodeJson(client.path, opts);
|
|
85
|
+
}
|
|
86
|
+
read(client, serverName) {
|
|
87
|
+
if (!fs.existsSync(client.path)) return null;
|
|
88
|
+
const parsed = this.config.readJsonFileSafe(client.path);
|
|
89
|
+
if (!parsed || typeof parsed !== 'object' || !parsed.mcp || typeof parsed.mcp !== 'object') return null;
|
|
90
|
+
const nested = parsed.mcp.servers && typeof parsed.mcp.servers === 'object' && !Array.isArray(parsed.mcp.servers);
|
|
91
|
+
const container = nested ? parsed.mcp.servers : parsed.mcp;
|
|
92
|
+
let entry = container[serverName];
|
|
93
|
+
if (!entry && serverName === 'genexus18mcp') {
|
|
94
|
+
const legacyGx = container.genexus;
|
|
95
|
+
if (legacyGx && !this.config.isThirdPartyMcpEntry(legacyGx)) entry = legacyGx;
|
|
96
|
+
else if (container.genexus18) entry = container.genexus18;
|
|
97
|
+
}
|
|
98
|
+
if (!entry) return null;
|
|
99
|
+
const cmd = Array.isArray(entry.command) ? entry.command[0] : entry.command;
|
|
100
|
+
const args = Array.isArray(entry.command) ? entry.command.slice(1) : (Array.isArray(entry.args) ? entry.args : []);
|
|
101
|
+
const env = (entry.environment && typeof entry.environment === 'object') ? entry.environment
|
|
102
|
+
: ((entry.env && typeof entry.env === 'object') ? entry.env : {});
|
|
103
|
+
return { command: cmd, args, env };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
class CodexTomlAdapter extends BaseClientAdapter {
|
|
108
|
+
constructor(configModule) {
|
|
109
|
+
super();
|
|
110
|
+
this.config = configModule || require('./config');
|
|
111
|
+
}
|
|
112
|
+
apply(client, launcher, targetConfigPath, opts = {}) {
|
|
113
|
+
return this.config.applyCodexToml(client.path, launcher, targetConfigPath, opts);
|
|
114
|
+
}
|
|
115
|
+
remove(client, opts = {}) {
|
|
116
|
+
return this.config.removeCodexToml(client.path, opts);
|
|
117
|
+
}
|
|
118
|
+
read(client, serverName) {
|
|
119
|
+
if (!fs.existsSync(client.path)) return null;
|
|
120
|
+
let content = '';
|
|
121
|
+
try {
|
|
122
|
+
content = fs.readFileSync(client.path, 'utf8');
|
|
123
|
+
} catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
let parsed = this.config.extractCodexTomlEntry(content, serverName);
|
|
127
|
+
if (!parsed && serverName === 'genexus18mcp') {
|
|
128
|
+
const legacyGx = this.config.extractCodexTomlEntry(content, 'genexus');
|
|
129
|
+
if (legacyGx && !this.config.isThirdPartyMcpEntry(legacyGx)) parsed = legacyGx;
|
|
130
|
+
else {
|
|
131
|
+
const legacyGx18 = this.config.extractCodexTomlEntry(content, 'genexus18');
|
|
132
|
+
if (legacyGx18) parsed = legacyGx18;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!parsed) return null;
|
|
136
|
+
return {
|
|
137
|
+
command: parsed.command,
|
|
138
|
+
args: Array.isArray(parsed.args) ? parsed.args : [],
|
|
139
|
+
env: (parsed.env && typeof parsed.env === 'object') ? parsed.env : {}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const adapters = {
|
|
145
|
+
'mcpServers': new McpServersJsonAdapter(),
|
|
146
|
+
'vscode-servers': new VsCodeServersAdapter(),
|
|
147
|
+
'opencode': new OpenCodeJsoncAdapter(),
|
|
148
|
+
'codex-toml': new CodexTomlAdapter()
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
function getClientAdapter(format) {
|
|
152
|
+
const adapter = adapters[format];
|
|
153
|
+
if (!adapter) {
|
|
154
|
+
throw new Error(`Unknown client format: ${format}`);
|
|
155
|
+
}
|
|
156
|
+
return adapter;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
class ClientConfigManager {
|
|
160
|
+
constructor(configModule) {
|
|
161
|
+
this.config = configModule || require('./config');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
apply(client, launcher, targetConfigPath, opts = {}) {
|
|
165
|
+
const adapter = getClientAdapter(client.format);
|
|
166
|
+
return adapter.apply(client, launcher, targetConfigPath, opts);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
remove(client, opts = {}) {
|
|
170
|
+
const adapter = getClientAdapter(client.format);
|
|
171
|
+
return adapter.remove(client, opts);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
read(client, serverName) {
|
|
175
|
+
if (client.writeSupported === false) return null;
|
|
176
|
+
const adapter = getClientAdapter(client.format);
|
|
177
|
+
return adapter.read(client, serverName);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = {
|
|
182
|
+
BaseClientAdapter,
|
|
183
|
+
McpServersJsonAdapter,
|
|
184
|
+
VsCodeServersAdapter,
|
|
185
|
+
OpenCodeJsoncAdapter,
|
|
186
|
+
CodexTomlAdapter,
|
|
187
|
+
getClientAdapter,
|
|
188
|
+
ClientConfigManager
|
|
189
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const test = require('node:test');
|
|
2
|
+
const assert = require('node:assert/strict');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const {
|
|
7
|
+
getClientAdapter,
|
|
8
|
+
McpServersJsonAdapter,
|
|
9
|
+
VsCodeServersAdapter,
|
|
10
|
+
OpenCodeJsoncAdapter,
|
|
11
|
+
CodexTomlAdapter,
|
|
12
|
+
ClientConfigManager
|
|
13
|
+
} = require('./client-adapters');
|
|
14
|
+
|
|
15
|
+
test('getClientAdapter returns correct strategy for each format', () => {
|
|
16
|
+
assert.ok(getClientAdapter('mcpServers') instanceof McpServersJsonAdapter);
|
|
17
|
+
assert.ok(getClientAdapter('vscode-servers') instanceof VsCodeServersAdapter);
|
|
18
|
+
assert.ok(getClientAdapter('opencode') instanceof OpenCodeJsoncAdapter);
|
|
19
|
+
assert.ok(getClientAdapter('codex-toml') instanceof CodexTomlAdapter);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('ClientConfigManager applies and reads mcpServers format cleanly', () => {
|
|
23
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gx-cli-test-'));
|
|
24
|
+
const configPath = path.join(tmpDir, 'mcp.json');
|
|
25
|
+
const client = { id: 'test-cursor', name: 'Test Cursor', format: 'mcpServers', path: configPath };
|
|
26
|
+
const launcher = { command: 'node', args: ['run.js'] };
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const manager = new ClientConfigManager();
|
|
30
|
+
manager.apply(client, launcher, 'C:\\MyKb\\config.json', { serverName: 'genexus18mcp' });
|
|
31
|
+
|
|
32
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
33
|
+
const parsed = JSON.parse(raw);
|
|
34
|
+
assert.ok(parsed.mcpServers);
|
|
35
|
+
assert.ok(parsed.mcpServers.genexus18mcp);
|
|
36
|
+
assert.equal(parsed.mcpServers.genexus18mcp.command, 'node');
|
|
37
|
+
|
|
38
|
+
const readEntry = manager.read(client, 'genexus18mcp');
|
|
39
|
+
assert.ok(readEntry);
|
|
40
|
+
assert.equal(readEntry.command, 'node');
|
|
41
|
+
|
|
42
|
+
const wasRemoved = manager.remove(client, { serverName: 'genexus18mcp' });
|
|
43
|
+
assert.equal(wasRemoved, true);
|
|
44
|
+
|
|
45
|
+
const afterRemove = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
46
|
+
assert.equal(afterRemove.mcpServers.genexus18mcp, undefined);
|
|
47
|
+
} finally {
|
|
48
|
+
try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch { }
|
|
49
|
+
}
|
|
50
|
+
});
|
package/cli/lib/config.js
CHANGED
|
@@ -861,33 +861,13 @@ function unpatchClientConfig(opts = {}) {
|
|
|
861
861
|
}
|
|
862
862
|
|
|
863
863
|
function applyClientEntry(client, launcher, targetConfigPath, opts = {}) {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return applyMcpServersJson(client.path, launcher, targetConfigPath, opts);
|
|
867
|
-
case 'opencode':
|
|
868
|
-
return applyOpenCodeJson(client.path, launcher, targetConfigPath, opts);
|
|
869
|
-
case 'codex-toml':
|
|
870
|
-
return applyCodexToml(client.path, launcher, targetConfigPath, opts);
|
|
871
|
-
case 'vscode-servers':
|
|
872
|
-
return applyVsCodeServersJson(client.path, launcher, targetConfigPath, opts);
|
|
873
|
-
default:
|
|
874
|
-
throw new Error(`Unknown client format: ${client.format}`);
|
|
875
|
-
}
|
|
864
|
+
const { getClientAdapter } = require('./client-adapters');
|
|
865
|
+
return getClientAdapter(client.format).apply(client, launcher, targetConfigPath, opts);
|
|
876
866
|
}
|
|
877
867
|
|
|
878
868
|
function removeClientEntry(client, opts = {}) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
return removeMcpServersJson(client.path, opts);
|
|
882
|
-
case 'opencode':
|
|
883
|
-
return removeOpenCodeJson(client.path, opts);
|
|
884
|
-
case 'codex-toml':
|
|
885
|
-
return removeCodexToml(client.path, opts);
|
|
886
|
-
case 'vscode-servers':
|
|
887
|
-
return removeVsCodeServersJson(client.path, opts);
|
|
888
|
-
default:
|
|
889
|
-
throw new Error(`Unknown client format: ${client.format}`);
|
|
890
|
-
}
|
|
869
|
+
const { getClientAdapter } = require('./client-adapters');
|
|
870
|
+
return getClientAdapter(client.format).remove(client, opts);
|
|
891
871
|
}
|
|
892
872
|
|
|
893
873
|
function applyMcpServersJson(filePath, launcher, targetConfigPath, { serverName = DEFAULT_MCP_SERVER_NAME, force = false } = {}) {
|
|
@@ -1534,5 +1514,17 @@ module.exports = {
|
|
|
1534
1514
|
getLauncher,
|
|
1535
1515
|
readClientCommandEntry,
|
|
1536
1516
|
isOurMcpEntry,
|
|
1537
|
-
DEFAULT_MCP_SERVER_NAME
|
|
1517
|
+
DEFAULT_MCP_SERVER_NAME,
|
|
1518
|
+
applyMcpServersJson,
|
|
1519
|
+
removeMcpServersJson,
|
|
1520
|
+
applyVsCodeServersJson,
|
|
1521
|
+
removeVsCodeServersJson,
|
|
1522
|
+
applyOpenCodeJson,
|
|
1523
|
+
removeOpenCodeJson,
|
|
1524
|
+
applyCodexToml,
|
|
1525
|
+
removeCodexToml,
|
|
1526
|
+
extractCodexTomlEntry,
|
|
1527
|
+
isThirdPartyMcpEntry,
|
|
1528
|
+
applyClientEntry,
|
|
1529
|
+
removeClientEntry
|
|
1538
1530
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genexus-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.52.0",
|
|
4
4
|
"mcpName": "io.github.lennix1337/genexus",
|
|
5
5
|
"description": "GeneXus 18 MCP server — read, edit, and analyze GeneXus knowledge base objects (transactions, web panels, procedures, SDTs) directly from Claude, Cursor, and other AI agents over the Model Context Protocol.",
|
|
6
6
|
"keywords": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"automation"
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
|
-
"test": "node --test cli/run.test.js",
|
|
33
|
+
"test": "node --test cli/run.test.js cli/lib/client-adapters.test.js",
|
|
34
34
|
"lint": "eslint cli scripts eslint.config.js --max-warnings=0",
|
|
35
35
|
"test:one": "node scripts/test-one.js",
|
|
36
36
|
"prepack": "node scripts/clean-package.js",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"targets": {
|
|
8
8
|
".NETCoreApp,Version=v8.0": {},
|
|
9
9
|
".NETCoreApp,Version=v8.0/win-x64": {
|
|
10
|
-
"GxMcp.Gateway/2.
|
|
10
|
+
"GxMcp.Gateway/2.52.0": {
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"Newtonsoft.Json": "13.0.3",
|
|
13
13
|
"System.Management": "10.0.5",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"libraries": {
|
|
69
|
-
"GxMcp.Gateway/2.
|
|
69
|
+
"GxMcp.Gateway/2.52.0": {
|
|
70
70
|
"type": "project",
|
|
71
71
|
"serviceable": false,
|
|
72
72
|
"sha512": ""
|
|
Binary file
|
|
Binary file
|
package/publish/config.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
+
"Environment": {
|
|
3
|
+
"KBPath": "C:\\\\KBs\\\\YourKB"
|
|
4
|
+
},
|
|
2
5
|
"Logging": {
|
|
3
6
|
"Level": "Debug",
|
|
4
7
|
"Path": "logs"
|
|
5
8
|
},
|
|
6
9
|
"Server": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
10
|
+
"HttpPort": 5000,
|
|
11
|
+
"McpStdio": true
|
|
9
12
|
},
|
|
10
13
|
"GeneXus": {
|
|
11
14
|
"WorkerExecutable": "C:\\Projetos\\Genexus18MCP\\publish\\\\worker\\\\GxMcp.Worker.exe",
|
|
12
15
|
"InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18"
|
|
13
|
-
},
|
|
14
|
-
"Environment": {
|
|
15
|
-
"KBPath": "C:\\\\KBs\\\\YourKB"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
{"name":"genexus_search_source","description":"Regex/semantic search across Procedure/DataProvider/WebPanel/Transaction source. Requires the KB index to be Ready — check genexus_lifecycle action=status if results look empty.","inputSchema":{"type":"object","properties":{"callee":{"type":"string","description":"Method/function name (qualified or unqualified)."},"argMatches":{"type":"object","description":"Positional arg index to expected literal text."},"pattern":{"type":"string"},"typeFilter":{"type":"string"},"objectName":{"type":"string","description":"Restrict the scan to these exact object name(s), comma-separated. Makes a search inside one known object O(object) not O(KB), and bypasses the type whitelist."},"startIndex":{"type":"integer","description":"Legacy object-boundary resume. For a page that ended inside an object, prefer the opaque cursor returned in nextCursor."},"cursor":{"type":"string","description":"Opaque continuation token from nextCursor; preferred when a result page ended inside an object. Do not edit."},"timeoutMs":{"type":"integer","description":"Wall-clock budget (default 30000). Raise it to scan more objects per call."},"scope":{"type":"array","items":{"type":"string","enum":["source","rules","conditions","events","webForm","layout"]},"description":"Parts to scan with line-numbered context. Default [source]. webForm/layout scans the WebPanel/Transaction visual XML (control names, captions, classes, bindings)."},"fields":{"type":"array","items":{"type":"string","enum":["source","caption","description","parmNames","webForm"]},"description":"Whole-field metadata match (returns matchedValue, no line context). Default [source]. Prefer scope=[webForm] for line-context WebForm hits; use fields=[webForm] only for a coarse contains-match."},"maxResults":{"type":"integer"},"caseSensitive":{"type":"boolean"},"includeComments":{"type":"boolean"},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N distinct objects in response."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"pattern":"ControlType=\"Radio\""},{"pattern":"for each","typeFilter":"Procedure","maxResults":20}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
27
27
|
{"name":"genexus_kb","description":"Manage open KBs, startup config, and GeneXus environments. list/open/close/set_default operate on WorkerPool; set_default selects the implicit target for calls that omit kb (an explicit kb always wins for parallel or cross-KB work); set_startup/get_startup mirror IDE 'Set As Startup Object'; list_environments lists all configured environments; get_environment reads the active environment; set_environment selects an environment.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["list","open","close","set_default","set_startup","get_startup","list_environments","get_environment","set_environment"]},"alias":{"type":"string","description":"KB alias. open: auto from path basename if omitted."},"path":{"type":"string","description":"Absolute KB path (required for open if alias not in config)."},"name":{"type":"string","description":"Object name (required for set_startup)."},"environment":{"type":"string","description":"Environment name/folder (required for set_environment), e.g. development."}},"required":["action"],"examples":[{"action":"open","path":"C:\\KBs\\MyKb"},{"action":"list"},{"action":"list_environments"},{"action":"get_environment"},{"action":"set_environment","environment":"development"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
28
28
|
{"name":"genexus_navigation","description":"View navigation report (IDE Right-click → View Navigation). latest=true returns cached report from .gx/navigation-cache; else runs fresh.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["view"]},"name":{"type":"string"},"latest":{"type":"boolean","default":false,"description":"Return the most recent cached navigation if any; otherwise run fresh."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"view","name":"Customer"},{"action":"view","name":"Customer","latest":true}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
29
|
-
{"name":"genexus_api","description":"
|
|
29
|
+
{"name":"genexus_api","description":"Inspect HTTP procedures and native API routes. action=list|describe|routes_inspect|routes_clone|routes_update|snapshot|diff_baseline. API route writes use typed ServiceGroupSource, optimistic versioning, full snapshot, rollback and post-save reread; no lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","describe","routes_inspect","routes_clone","routes_update","snapshot","diff_baseline"]},"api":{"type":"string","description":"API name (routes_inspect|routes_clone|routes_update)."},"sourcePrefix":{"type":"string","description":"Source method/path prefix, e.g. inbound."},"targetPrefix":{"type":"string","description":"Target method/path prefix, e.g. reverse."},"expectedVersion":{"type":"string","description":"versionToken returned by the preceding dry run or inspection."},"dryRun":{"type":"boolean","default":true,"description":"routes_clone/routes_update: preview first; false writes only with expectedVersion."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore the complete API snapshot when post-save verification diverges."},"operation":{"type":"string","description":"Operation value carried by the reused request contract, e.g. REVERSE."},"target":{"type":"string","description":"Procedure or API name (action=describe)."},"name":{"type":"string","description":"Baseline name (action=snapshot)."},"baseline":{"type":"string","description":"Baseline name under .gx/api-baselines/ or absolute path (action=diff_baseline)."},"pathPrefix":{"type":"string","description":"Folder prefix filter (action=list)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"routes_inspect","api":"OrdersApi"},{"action":"routes_clone","api":"OrdersApi","sourcePrefix":"inbound","targetPrefix":"reverse","operation":"REVERSE","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
30
30
|
{"name":"genexus_apply_pattern","description":"Apply a pattern (e.g. WorkWithPlus) to a parent (IDE Right-click → Apply Pattern). Transaction=family-gen; WebPanel/WebComponent/SDPanel=direct-attach (pass settings.template). mode=diagnose (or dryRun=true) returns findings without mutating. Working on Smart Devices? → resources/read uri=genexus://kb/skills/sd-panel-mobile for Main object semantics. mode=actions manages typed grid actions and Action Groups, persists and re-reads PatternInstance, supports dryRun diff, and never adds security permissions automatically.","inputSchema":{"type":"object","required":["name","pattern"],"properties":{"name":{"type":"string","description":"Target KBObject name."},"pattern":{"type":"string","description":"Pattern key ('WorkWithPlus') or GUID."},"mode":{"type":"string","enum":["apply","diagnose","actions"],"description":"apply (default) mutates; diagnose returns reasons without applying. actions exposes typed WWP action-group editing."},"action":{"type":"string","enum":["list_actions","add_grid_action","update_action","move_action","remove_action"],"description":"mode=actions operation."},"group":{"type":"string"},"actionName":{"type":"string"},"newGroup":{"type":"string"},"position":{"type":"integer","minimum":0},"procedure":{"type":"string"},"selection":{"type":"string","enum":["current","multiple"]},"enabledWhen":{"type":"string"},"visibleWhen":{"type":"string"},"icon":{"type":"string"},"description":{"type":"string"},"confirmation":{"type":"string"},"confirmTitle":{"type":"string"},"settings":{"type":"object","description":"Pattern-instance settings tree."},"reapply":{"type":"boolean","default":false,"description":"Re-run on existing instance."},"validate":{"type":"boolean","default":false,"description":"After apply, build the generated host. Adds validation block (60-180s). Catches binding errors."},"dryRun":{"type":"boolean","default":false,"description":"Alias for mode=diagnose. When true, returns pattern findings without mutating. With mode=actions it previews the typed action diff."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"name":"Customer","pattern":"WorkWithPlus"},{"name":"Customer","pattern":"WorkWithPlus","mode":"diagnose"},{"name":"Customer","pattern":"WorkWithPlus","mode":"actions","action":"add_grid_action","group":"Actions","actionName":"Approve","procedure":"ApproveCustomer","dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
31
31
|
{"name":"genexus_edit_and_build","description":"Edit + rebuild callers in one call. Returns edit diff + impact + a build block that may include taskId/pollTarget for lifecycle follow-up. validate=true/validationMode=specify validates the saved object; rollbackOnFailure restores its pre-write snapshot on specification failure.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Target object name."},"part":{"type":"string","description":"Part (Source, Rules, ...)."},"content":{"type":"string","description":"New content. For mode=patch may be {find,replace} object."},"patch":{"description":"Same shape as genexus_edit.patch. Auto-sets mode=patch."},"mode":{"type":"string","enum":["full","patch"],"default":"patch"},"type":{"type":"string","description":"Disambiguates ambiguous names."},"dryRun":{"type":"boolean","default":false},"validate":{"type":"boolean","default":false},"validationMode":{"type":"string","enum":["specify"],"default":"specify"},"rollbackOnFailure":{"type":"boolean","default":true},"buildIncludeCallees":{"type":"string","enum":["none","direct","transitive"],"default":"direct"},"buildPlanCap":{"type":"integer","default":200},"waitForIndex":{"type":"boolean","default":true},"waitTimeoutMs":{"type":"integer","default":30000},"visualVerify":{"type":"boolean","default":false,"description":"Post-edit headless screenshot + pixel-diff vs baseline. See tool-help."}},"required":["name","part"],"examples":[{"name":"Customer","part":"Source","patch":{"find":"oldValue","replace":"newValue"},"validate":true},{"name":"Customer","part":"Rules","mode":"patch","patch":{"find":"error(","replace":"msg("},"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
32
32
|
{"name":"genexus_security","description":"Audit KB security. action=audit_gam scans GAM/env props; action=scan_secrets greps Source for credential-shaped literals. Returns findings with severity.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["audit_gam","scan_secrets","scan_native"]},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"audit_gam"},{"action":"scan_secrets"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
Binary file
|