genexus-mcp 3.4.1 → 3.4.3
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/README.md +6 -1
- package/cli/commands/axi.js +35 -5
- package/cli/lib/config.js +230 -23
- package/cli/run.test.js +132 -2
- package/package.json +2 -1
- 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 +8 -8
- package/publish/gxmcp-manifest.json +10 -10
- package/publish/gxmcp-sbom.json +4 -4
- package/publish/tool_definitions.json +8 -8
- package/publish/worker/GxMcp.Worker.exe +0 -0
package/README.md
CHANGED
|
@@ -498,7 +498,8 @@ The installer writes a `config.json` for you. To customize networking, timeouts,
|
|
|
498
498
|
"BindAddress": "127.0.0.1",
|
|
499
499
|
"SessionIdleTimeoutMinutes": 10,
|
|
500
500
|
"WorkerIdleTimeoutMinutes": 60,
|
|
501
|
-
"MaxOpenKbs": 3
|
|
501
|
+
"MaxOpenKbs": 3,
|
|
502
|
+
"ArtifactOutputDirectory": "C:\\GenexusMCP\\Artifacts"
|
|
502
503
|
},
|
|
503
504
|
"GeneXus": {
|
|
504
505
|
"InstallationPath": "C:\\Program Files (x86)\\GeneXus\\GeneXus18",
|
|
@@ -516,6 +517,10 @@ The installer writes a `config.json` for you. To customize networking, timeouts,
|
|
|
516
517
|
|
|
517
518
|
> **Backward compatibility:** old configs with a single `Environment.KBPath` keep working — the gateway auto-migrates them to `KBs[]` + `DefaultKb` at load time.
|
|
518
519
|
|
|
520
|
+
### Generated documentation artifacts
|
|
521
|
+
|
|
522
|
+
`genexus_doc` keeps generated files outside the Worker installation so an update does not strand them in the install backup. By default the root is `%LOCALAPPDATA%\GxMcp\Artifacts`; each KB gets a stable `kb-<identity>` directory with `docs` and `html` children. Set `Server.ArtifactOutputDirectory` to choose another root; the per-KB child is still added. `GXMCP_ARTIFACT_OUTPUT_DIR` is the equivalent override for a directly launched Worker. Wiki responses report `result.file`; visualizer responses report `result.url`; both also report `result.outputDirectory`. Visualizer and health consume the active KB's canonical `IndexCacheService` snapshot, not a shared install-relative cache.
|
|
523
|
+
|
|
519
524
|
### Working with multiple KBs
|
|
520
525
|
|
|
521
526
|
Once you declare more than one KB in `Environment.KBs[]`, every tool accepts an optional `kb` argument:
|
package/cli/commands/axi.js
CHANGED
|
@@ -1522,7 +1522,8 @@ async function runInteractiveInit(ctx) {
|
|
|
1522
1522
|
meta: {
|
|
1523
1523
|
patchedClients: patchResult.patched,
|
|
1524
1524
|
failedClients: patchResult.failed,
|
|
1525
|
-
skippedClients: patchResult.skipped || []
|
|
1525
|
+
skippedClients: patchResult.skipped || [],
|
|
1526
|
+
verifiedClients: patchResult.verified || []
|
|
1526
1527
|
}
|
|
1527
1528
|
}
|
|
1528
1529
|
};
|
|
@@ -1844,6 +1845,7 @@ async function handleInit(options, ctx) {
|
|
|
1844
1845
|
patchedClients: patchResult.patched,
|
|
1845
1846
|
failedClients: patchResult.failed,
|
|
1846
1847
|
skippedClients: patchResult.skipped || [],
|
|
1848
|
+
verifiedClients: patchResult.verified || [],
|
|
1847
1849
|
smokeSkipped: !!options.noSmoke,
|
|
1848
1850
|
warmed: !!warm && warm.status === 'pass'
|
|
1849
1851
|
}
|
|
@@ -2137,9 +2139,25 @@ async function handleClients(subcommand, options, ctx) {
|
|
|
2137
2139
|
help.push(`Register installed-but-unregistered agents: genexus-mcp clients add --clients ${installedUnregistered.map((r) => r.id).join(',')}${serverName !== DEFAULT_MCP_SERVER_NAME ? ` --server-name ${serverName}` : ''}`);
|
|
2138
2140
|
}
|
|
2139
2141
|
const stale = rows.filter((r) => r.commandStale);
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
+
const missingLaunchers = stale.filter((r) => r.launcherStructuralState === 'missing');
|
|
2143
|
+
const invalidLaunchers = stale.filter((r) =>
|
|
2144
|
+
r.launcherSemanticState === 'invalid' && r.launcherStructuralState !== 'missing'
|
|
2145
|
+
);
|
|
2146
|
+
if (missingLaunchers.length > 0) {
|
|
2147
|
+
help.push(`These clients point at a missing gateway exe (will fail to connect) — re-register: genexus-mcp clients add --clients ${missingLaunchers.map((r) => r.id).join(',')}${serverName !== DEFAULT_MCP_SERVER_NAME ? ` --server-name ${serverName}` : ''}`);
|
|
2142
2148
|
}
|
|
2149
|
+
if (invalidLaunchers.length > 0) {
|
|
2150
|
+
help.push(`These clients have a known-invalid MCP launcher (check command and args) — re-register: genexus-mcp clients add --clients ${invalidLaunchers.map((r) => r.id).join(',')}${serverName !== DEFAULT_MCP_SERVER_NAME ? ` --server-name ${serverName}` : ''}`);
|
|
2151
|
+
}
|
|
2152
|
+
const otherStale = stale.filter((r) =>
|
|
2153
|
+
r.launcherStructuralState !== 'missing' && r.launcherSemanticState !== 'invalid'
|
|
2154
|
+
);
|
|
2155
|
+
if (otherStale.length > 0) {
|
|
2156
|
+
help.push(`These clients have a stale launcher — re-register: genexus-mcp clients add --clients ${otherStale.map((r) => r.id).join(',')}${serverName !== DEFAULT_MCP_SERVER_NAME ? ` --server-name ${serverName}` : ''}`);
|
|
2157
|
+
}
|
|
2158
|
+
const semanticValidCount = rows.filter((r) => r.launcherSemanticState === 'valid').length;
|
|
2159
|
+
const semanticInvalidCount = rows.filter((r) => r.launcherSemanticState === 'invalid').length;
|
|
2160
|
+
const semanticUnknownCount = rows.filter((r) => r.launcherSemanticState === 'unknown').length;
|
|
2143
2161
|
for (const r of rows) {
|
|
2144
2162
|
if (r.installed && !r.writeSupported && r.note) help.push(`${r.name}: ${r.note}`);
|
|
2145
2163
|
}
|
|
@@ -2148,7 +2166,15 @@ async function handleClients(subcommand, options, ctx) {
|
|
|
2148
2166
|
envelope: {
|
|
2149
2167
|
ok: {
|
|
2150
2168
|
clients: rows,
|
|
2151
|
-
summary: {
|
|
2169
|
+
summary: {
|
|
2170
|
+
total: rows.length,
|
|
2171
|
+
installed: installedCount,
|
|
2172
|
+
registered: registeredCount,
|
|
2173
|
+
semanticValid: semanticValidCount,
|
|
2174
|
+
semanticInvalid: semanticInvalidCount,
|
|
2175
|
+
semanticUnknown: semanticUnknownCount,
|
|
2176
|
+
serverName
|
|
2177
|
+
}
|
|
2152
2178
|
},
|
|
2153
2179
|
help
|
|
2154
2180
|
}
|
|
@@ -2214,7 +2240,11 @@ async function handleClients(subcommand, options, ctx) {
|
|
|
2214
2240
|
envelope: {
|
|
2215
2241
|
ok: { action: 'clients.add', configPath, serverName, patchedClients: patch.patched, patchedCount: patch.patched.length },
|
|
2216
2242
|
help,
|
|
2217
|
-
meta: {
|
|
2243
|
+
meta: {
|
|
2244
|
+
failedClients: patch.failed,
|
|
2245
|
+
skippedClients: patch.skipped,
|
|
2246
|
+
verifiedClients: patch.verified || []
|
|
2247
|
+
}
|
|
2218
2248
|
}
|
|
2219
2249
|
};
|
|
2220
2250
|
}
|
package/cli/lib/config.js
CHANGED
|
@@ -876,29 +876,217 @@ function listSupportedClientIds() {
|
|
|
876
876
|
return getClientConfigTargets().map((c) => c.id);
|
|
877
877
|
}
|
|
878
878
|
|
|
879
|
-
//
|
|
880
|
-
//
|
|
881
|
-
//
|
|
882
|
-
//
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
879
|
+
// The list command is intentionally local: it does not spawn a configured
|
|
880
|
+
// launcher or perform an MCP handshake. These states keep registration, path
|
|
881
|
+
// presence, and known command semantics separate while retaining commandStale
|
|
882
|
+
// as the actionable compatibility flag for a missing/known-invalid launcher.
|
|
883
|
+
function normalizeLauncherToken(value) {
|
|
884
|
+
return String(value || '').trim().replace(/^['"]|['"]$/g, '');
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
function launcherBaseName(command) {
|
|
888
|
+
const token = normalizeLauncherToken(command);
|
|
889
|
+
const lastSlash = Math.max(token.lastIndexOf('/'), token.lastIndexOf('\\'));
|
|
890
|
+
return token.slice(lastSlash + 1).toLowerCase();
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
function launcherHasExplicitPath(command) {
|
|
894
|
+
const token = normalizeLauncherToken(command);
|
|
895
|
+
return token.includes('/') || token.includes('\\');
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
function hasKnownNpxPackage(args) {
|
|
899
|
+
return Array.isArray(args) && args.some((arg) =>
|
|
900
|
+
typeof arg === 'string' && /^genexus-mcp(?:@[^\s]+)?$/i.test(arg.trim())
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
function nodeEntrypointInfo(args) {
|
|
905
|
+
if (!Array.isArray(args) || args.length === 0) return { state: 'missing', value: null };
|
|
906
|
+
|
|
907
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
908
|
+
const arg = typeof args[i] === 'string' ? args[i].trim() : '';
|
|
909
|
+
if (!arg) continue;
|
|
910
|
+
if (arg === '--') {
|
|
911
|
+
return args[i + 1]
|
|
912
|
+
? { state: 'entrypoint', value: args[i + 1] }
|
|
913
|
+
: { state: 'missing', value: null };
|
|
914
|
+
}
|
|
915
|
+
if (arg.startsWith('-')) {
|
|
916
|
+
// Inline/evaluated Node programs may start MCP, but their semantics
|
|
917
|
+
// cannot be established without executing them. Keep them unknown.
|
|
918
|
+
if (/^(?:-e|-p|--eval(?:=|$)|--print(?:=|$)|--check(?:=|$))/.test(arg)) {
|
|
919
|
+
return { state: 'indeterminate', value: null };
|
|
920
|
+
}
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
return { state: 'entrypoint', value: arg };
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
return { state: 'missing', value: null };
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
function isKnownNodeEntrypoint(entrypoint) {
|
|
930
|
+
const normalized = normalizeLauncherToken(entrypoint).replace(/\\/g, '/').toLowerCase();
|
|
931
|
+
return normalized === 'cli/run.js' || normalized.endsWith('/cli/run.js');
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
function clientCommandHealth(entry, client = null, { fs: fileSystem = fs } = {}) {
|
|
935
|
+
const unknown = {
|
|
936
|
+
stale: false,
|
|
937
|
+
reason: null,
|
|
938
|
+
structuralState: 'indeterminate',
|
|
939
|
+
semanticState: 'unknown',
|
|
940
|
+
semanticReason: null
|
|
941
|
+
};
|
|
942
|
+
const invalid = (reason, structuralState = 'present') => ({
|
|
943
|
+
stale: true,
|
|
944
|
+
reason,
|
|
945
|
+
structuralState,
|
|
946
|
+
semanticState: 'invalid',
|
|
947
|
+
semanticReason: reason
|
|
948
|
+
});
|
|
949
|
+
const valid = (structuralState = 'present') => ({
|
|
950
|
+
stale: false,
|
|
951
|
+
reason: null,
|
|
952
|
+
structuralState,
|
|
953
|
+
semanticState: 'valid',
|
|
954
|
+
semanticReason: null
|
|
955
|
+
});
|
|
956
|
+
const missingLauncherReason = 'configured launcher does not exist on disk';
|
|
957
|
+
|
|
958
|
+
if (entry === null || entry === undefined) {
|
|
959
|
+
return {
|
|
960
|
+
stale: false,
|
|
961
|
+
reason: null,
|
|
962
|
+
structuralState: 'not-registered',
|
|
963
|
+
semanticState: 'not-applicable',
|
|
964
|
+
semanticReason: null
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
if (typeof entry !== 'object') {
|
|
968
|
+
return invalid('configured local MCP entry has no command or URL', 'invalid');
|
|
969
|
+
}
|
|
970
|
+
if (entry.url || entry.type === 'http' || entry.type === 'sse' || entry.type === 'remote') {
|
|
971
|
+
return {
|
|
972
|
+
stale: false,
|
|
973
|
+
reason: null,
|
|
974
|
+
structuralState: 'not-applicable',
|
|
975
|
+
semanticState: 'not-applicable',
|
|
976
|
+
semanticReason: null
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const command = normalizeLauncherToken(entry.command);
|
|
981
|
+
if (!command) return invalid('configured local MCP entry has no command', 'invalid');
|
|
982
|
+
|
|
983
|
+
const args = Array.isArray(entry.args) ? entry.args : [];
|
|
984
|
+
const baseName = launcherBaseName(command);
|
|
985
|
+
const explicitPath = launcherHasExplicitPath(command);
|
|
986
|
+
const exists = explicitPath ? fileSystem.existsSync(command) : null;
|
|
987
|
+
const knownRuntimeLauncher = baseName === 'npx'
|
|
988
|
+
|| baseName === 'npx.cmd'
|
|
989
|
+
|| baseName === 'node'
|
|
990
|
+
|| baseName === 'node.exe'
|
|
991
|
+
|| baseName === 'genexus-mcp'
|
|
992
|
+
|| baseName === 'genexus-mcp.cmd'
|
|
993
|
+
|| baseName === 'start_mcp.bat'
|
|
994
|
+
|| baseName === 'gxmcp.gateway.exe';
|
|
995
|
+
const structuralState = explicitPath
|
|
996
|
+
? (exists ? 'present' : 'missing')
|
|
997
|
+
: (knownRuntimeLauncher ? 'present' : 'indeterminate');
|
|
998
|
+
|
|
999
|
+
if (baseName === 'gxmcp.gateway.exe') {
|
|
1000
|
+
if (!explicitPath) {
|
|
1001
|
+
return {
|
|
1002
|
+
...unknown,
|
|
1003
|
+
semanticReason: 'direct Gateway launcher must use an explicit path that can be checked locally'
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
if (!exists) return invalid(missingLauncherReason, 'missing');
|
|
1007
|
+
if (client && client.preferDirectGateway) {
|
|
1008
|
+
const currentPackageGateway = getGatewayExePath();
|
|
1009
|
+
if (fs.existsSync(currentPackageGateway) && normalizeExePath(command) !== normalizeExePath(currentPackageGateway)) {
|
|
1010
|
+
return {
|
|
1011
|
+
...valid('present'),
|
|
1012
|
+
stale: true,
|
|
1013
|
+
reason: 'configured launcher points at a different package gateway; re-register the client'
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
return valid('present');
|
|
889
1018
|
}
|
|
890
|
-
|
|
891
|
-
|
|
1019
|
+
|
|
1020
|
+
if (baseName === 'npx' || baseName === 'npx.cmd') {
|
|
1021
|
+
if (!exists && explicitPath) return invalid(missingLauncherReason, 'missing');
|
|
1022
|
+
if (hasKnownNpxPackage(args)) return valid(structuralState);
|
|
1023
|
+
if (args.length === 0) {
|
|
1024
|
+
return invalid('npx launcher requires the genexus-mcp package in args (for example -y genexus-mcp@latest)', structuralState);
|
|
1025
|
+
}
|
|
1026
|
+
return {
|
|
1027
|
+
...unknown,
|
|
1028
|
+
structuralState,
|
|
1029
|
+
semanticReason: 'npx launcher package is not recognized as genexus-mcp'
|
|
1030
|
+
};
|
|
892
1031
|
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
if (
|
|
896
|
-
|
|
1032
|
+
|
|
1033
|
+
if (baseName === 'node' || baseName === 'node.exe') {
|
|
1034
|
+
if (!exists && explicitPath) return invalid(missingLauncherReason, 'missing');
|
|
1035
|
+
const entrypoint = nodeEntrypointInfo(args);
|
|
1036
|
+
if (entrypoint.state === 'missing') {
|
|
1037
|
+
return invalid('node launcher requires a CLI entrypoint in args (for example cli/run.js)', structuralState);
|
|
1038
|
+
}
|
|
1039
|
+
if (entrypoint.state === 'indeterminate') {
|
|
1040
|
+
return {
|
|
1041
|
+
...unknown,
|
|
1042
|
+
structuralState,
|
|
1043
|
+
semanticReason: 'node launcher uses an evaluated entrypoint that cannot be verified locally'
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
if (!isKnownNodeEntrypoint(entrypoint.value)) {
|
|
1047
|
+
return {
|
|
1048
|
+
...unknown,
|
|
1049
|
+
structuralState,
|
|
1050
|
+
semanticReason: 'node entrypoint is not recognized as the genexus-mcp CLI'
|
|
1051
|
+
};
|
|
897
1052
|
}
|
|
1053
|
+
if (!fileSystem.existsSync(normalizeLauncherToken(entrypoint.value))) {
|
|
1054
|
+
return invalid(`configured node entrypoint does not exist on disk: ${entrypoint.value}`, structuralState);
|
|
1055
|
+
}
|
|
1056
|
+
return valid(structuralState);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
if (baseName === 'genexus-mcp' || baseName === 'genexus-mcp.cmd') {
|
|
1060
|
+
if (!exists && explicitPath) return invalid(missingLauncherReason, 'missing');
|
|
1061
|
+
return valid(structuralState);
|
|
1062
|
+
}
|
|
1063
|
+
if (baseName === 'start_mcp.bat' && explicitPath) {
|
|
1064
|
+
if (!exists) return invalid(missingLauncherReason, 'missing');
|
|
1065
|
+
return valid('present');
|
|
898
1066
|
}
|
|
899
|
-
return { stale: false, reason: null };
|
|
900
|
-
}
|
|
901
1067
|
|
|
1068
|
+
if (explicitPath && !exists) {
|
|
1069
|
+
return {
|
|
1070
|
+
...unknown,
|
|
1071
|
+
stale: true,
|
|
1072
|
+
reason: missingLauncherReason,
|
|
1073
|
+
structuralState: 'missing',
|
|
1074
|
+
semanticReason: 'launcher command is not recognized locally; run doctor for runtime validation'
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
if (explicitPath) {
|
|
1078
|
+
return {
|
|
1079
|
+
...unknown,
|
|
1080
|
+
structuralState: 'present',
|
|
1081
|
+
semanticReason: 'launcher command is not recognized locally; run doctor for runtime validation'
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
return {
|
|
1085
|
+
...unknown,
|
|
1086
|
+
structuralState,
|
|
1087
|
+
semanticReason: 'launcher command cannot be classified without a known local command shape'
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
902
1090
|
function buildManualClientSetup(client, targetConfigPath = null) {
|
|
903
1091
|
return {
|
|
904
1092
|
mode: 'manual',
|
|
@@ -945,7 +1133,11 @@ function clientsStatus(opts = {}) {
|
|
|
945
1133
|
writeSupported: client.writeSupported !== false,
|
|
946
1134
|
configPath: client.path,
|
|
947
1135
|
command: entry && entry.command ? entry.command : null,
|
|
1136
|
+
args: entry && Array.isArray(entry.args) ? entry.args : [],
|
|
948
1137
|
url: entry && entry.url ? entry.url : null,
|
|
1138
|
+
launcherStructuralState: health.structuralState,
|
|
1139
|
+
launcherSemanticState: health.semanticState,
|
|
1140
|
+
launcherSemanticReason: health.semanticReason,
|
|
949
1141
|
commandStale: health.stale,
|
|
950
1142
|
commandStaleReason: health.reason || (isThirdParty ? 'configured as third-party / HTTP MCP server (e.g. official GeneXus MCP)' : null),
|
|
951
1143
|
detectedAt: det.markerHit || (det.hasConfig ? client.path : null),
|
|
@@ -1000,6 +1192,7 @@ function patchClientConfig(targetConfigPath, opts = {}) {
|
|
|
1000
1192
|
const patched = [];
|
|
1001
1193
|
const failed = [];
|
|
1002
1194
|
const skipped = [];
|
|
1195
|
+
const verified = [];
|
|
1003
1196
|
|
|
1004
1197
|
for (const client of candidates) {
|
|
1005
1198
|
// Detect-only agents can't be auto-written; surface
|
|
@@ -1029,24 +1222,38 @@ function patchClientConfig(targetConfigPath, opts = {}) {
|
|
|
1029
1222
|
}
|
|
1030
1223
|
try {
|
|
1031
1224
|
fileSystem.mkdirSync(path.dirname(client.path), { recursive: true });
|
|
1032
|
-
|
|
1225
|
+
const launcher = getLauncher(client);
|
|
1226
|
+
applyClientEntry(client, launcher, targetConfigPath, {
|
|
1033
1227
|
serverName,
|
|
1034
1228
|
force,
|
|
1035
1229
|
globalConfig: Boolean(opts.globalConfig),
|
|
1036
1230
|
fs: fileSystem
|
|
1037
1231
|
});
|
|
1038
|
-
// Read-back: confirm the entry is actually present
|
|
1039
|
-
// parses,
|
|
1040
|
-
|
|
1232
|
+
// Read-back: confirm the entry is actually present, the file still
|
|
1233
|
+
// parses, and the generated command is a known valid local launcher.
|
|
1234
|
+
const writtenEntry = readClientCommandEntry(client, serverName, { fs: fileSystem });
|
|
1235
|
+
if (!writtenEntry) {
|
|
1041
1236
|
throw new Error(`post-write verification failed (${serverName} entry not found after write)`);
|
|
1042
1237
|
}
|
|
1238
|
+
const health = clientCommandHealth(writtenEntry, client, { fs: fileSystem });
|
|
1239
|
+
if (health.semanticState !== 'valid') {
|
|
1240
|
+
const reason = health.semanticReason || health.reason || `launcher semantic state is ${health.semanticState}`;
|
|
1241
|
+
throw new Error(`post-write verification failed (${reason})`);
|
|
1242
|
+
}
|
|
1243
|
+
verified.push({
|
|
1244
|
+
client: client.name,
|
|
1245
|
+
command: writtenEntry.command || null,
|
|
1246
|
+
args: Array.isArray(writtenEntry.args) ? writtenEntry.args : [],
|
|
1247
|
+
launcherStructuralState: health.structuralState,
|
|
1248
|
+
launcherSemanticState: health.semanticState
|
|
1249
|
+
});
|
|
1043
1250
|
patched.push(client.name);
|
|
1044
1251
|
} catch (err) {
|
|
1045
1252
|
failed.push({ client: client.name, reason: err && err.message ? err.message : 'Unknown error' });
|
|
1046
1253
|
}
|
|
1047
1254
|
}
|
|
1048
1255
|
|
|
1049
|
-
return { patched, failed, skipped };
|
|
1256
|
+
return { patched, failed, skipped, verified };
|
|
1050
1257
|
}
|
|
1051
1258
|
|
|
1052
1259
|
function unpatchClientConfig(opts = {}) {
|
package/cli/run.test.js
CHANGED
|
@@ -30,8 +30,19 @@ const { handleInit, resolveMcpSmokeTarget } = require('./commands/axi');
|
|
|
30
30
|
const cliPath = path.join(__dirname, 'run.js');
|
|
31
31
|
const testGxPath = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-gx-'));
|
|
32
32
|
fs.writeFileSync(path.join(testGxPath, 'genexus.exe'), '');
|
|
33
|
-
const
|
|
34
|
-
|
|
33
|
+
const testGatewayPath = path.join(os.tmpdir(), `genexus-mcp-test-${process.pid}`, 'GxMcp.Gateway.exe');
|
|
34
|
+
fs.mkdirSync(path.dirname(testGatewayPath), { recursive: true });
|
|
35
|
+
if (process.platform === 'win32') {
|
|
36
|
+
fs.copyFileSync(process.env.ComSpec || 'C:\\Windows\\System32\\cmd.exe', testGatewayPath);
|
|
37
|
+
} else {
|
|
38
|
+
fs.writeFileSync(testGatewayPath, '#!/bin/sh\nexit 0\n');
|
|
39
|
+
fs.chmodSync(testGatewayPath, 0o755);
|
|
40
|
+
}
|
|
41
|
+
const testGatewayEnv = { GENEXUS_MCP_GATEWAY_EXE: testGatewayPath };
|
|
42
|
+
test.after(() => {
|
|
43
|
+
fs.rmSync(testGxPath, { recursive: true, force: true });
|
|
44
|
+
fs.rmSync(testGatewayPath, { force: true });
|
|
45
|
+
});
|
|
35
46
|
|
|
36
47
|
function runCli(args, opts = {}) {
|
|
37
48
|
const spawnOptions = {
|
|
@@ -1641,6 +1652,125 @@ test('clients list flags a registered command pointing at a missing launcher as
|
|
|
1641
1652
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
1642
1653
|
});
|
|
1643
1654
|
|
|
1655
|
+
test('clients list separates a registered node launcher without an entrypoint from semantic validity', () => {
|
|
1656
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-node-no-entrypoint-'));
|
|
1657
|
+
try {
|
|
1658
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
1659
|
+
const codexCfg = path.join(env.HOME, '.codex', 'config.toml');
|
|
1660
|
+
fs.mkdirSync(path.dirname(codexCfg), { recursive: true });
|
|
1661
|
+
const nodeCommand = process.execPath.replace(/\\/g, '\\\\').replace(/"/g, '\\\\"');
|
|
1662
|
+
fs.writeFileSync(codexCfg, [
|
|
1663
|
+
'[mcp_servers.genexus18mcp]',
|
|
1664
|
+
`command = "${nodeCommand}"`,
|
|
1665
|
+
'args = []',
|
|
1666
|
+
''
|
|
1667
|
+
].join('\n'));
|
|
1668
|
+
|
|
1669
|
+
const result = runCli(['clients', '--format', 'json'], { env });
|
|
1670
|
+
assert.equal(result.status, 0, 'clients diagnostics retain the successful list exit code');
|
|
1671
|
+
const parsed = JSON.parse(result.stdout);
|
|
1672
|
+
const codex = parsed.ok.clients.find((client) => client.id === 'codex-cli');
|
|
1673
|
+
assert.ok(codex, 'Codex CLI should be listed');
|
|
1674
|
+
assert.equal(codex.registered, true, 'the config entry remains registered');
|
|
1675
|
+
assert.equal(codex.command, process.execPath, 'the effective command is reported');
|
|
1676
|
+
assert.deepEqual(codex.args, [], 'the effective args are reported');
|
|
1677
|
+
assert.equal(codex.launcherStructuralState, 'present', 'node.exe exists locally');
|
|
1678
|
+
assert.equal(codex.launcherSemanticState, 'invalid', 'node.exe without an entrypoint cannot start MCP');
|
|
1679
|
+
assert.match(codex.launcherSemanticReason, /entrypoint/i, 'the reason tells the operator what is missing');
|
|
1680
|
+
assert.equal(codex.commandStale, true, 'known invalid launcher is actionable through the existing stale flag');
|
|
1681
|
+
assert.match(codex.commandStaleReason, /entrypoint/i);
|
|
1682
|
+
} finally {
|
|
1683
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
test('clients list validates existing Gateway and known npx launchers locally', () => {
|
|
1688
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-known-launchers-'));
|
|
1689
|
+
try {
|
|
1690
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
1691
|
+
const gatewayPath = path.join(tempRoot, 'publish', 'GxMcp.Gateway.exe');
|
|
1692
|
+
const antigravityCfg = path.join(tempRoot, '.gemini', 'antigravity', 'mcp_config.json');
|
|
1693
|
+
const cursorCfg = path.join(tempRoot, '.cursor', 'mcp.json');
|
|
1694
|
+
const codexCfg = path.join(tempRoot, '.codex', 'config.toml');
|
|
1695
|
+
const nodeEntrypoint = path.join(__dirname, 'run.js');
|
|
1696
|
+
fs.mkdirSync(path.dirname(gatewayPath), { recursive: true });
|
|
1697
|
+
fs.mkdirSync(path.dirname(antigravityCfg), { recursive: true });
|
|
1698
|
+
fs.mkdirSync(path.dirname(cursorCfg), { recursive: true });
|
|
1699
|
+
fs.mkdirSync(path.dirname(codexCfg), { recursive: true });
|
|
1700
|
+
fs.writeFileSync(gatewayPath, 'gateway');
|
|
1701
|
+
fs.writeFileSync(antigravityCfg, JSON.stringify({
|
|
1702
|
+
mcpServers: { genexus18mcp: { command: gatewayPath, args: [] } }
|
|
1703
|
+
}, null, 2));
|
|
1704
|
+
fs.writeFileSync(cursorCfg, JSON.stringify({
|
|
1705
|
+
mcpServers: { genexus18mcp: { command: 'npx.cmd', args: ['-y', 'genexus-mcp@latest'] } }
|
|
1706
|
+
}, null, 2));
|
|
1707
|
+
const nodeCommand = process.execPath.replace(/\\/g, '\\\\');
|
|
1708
|
+
const nodeScript = nodeEntrypoint.replace(/\\/g, '\\\\');
|
|
1709
|
+
fs.writeFileSync(codexCfg, [
|
|
1710
|
+
'[mcp_servers.genexus18mcp]',
|
|
1711
|
+
`command = "${nodeCommand}"`,
|
|
1712
|
+
`args = ["${nodeScript}"]`,
|
|
1713
|
+
''
|
|
1714
|
+
].join('\n'));
|
|
1715
|
+
|
|
1716
|
+
const result = runCli(['clients', '--format', 'json'], {
|
|
1717
|
+
env: { ...env, GENEXUS_MCP_GATEWAY_EXE: gatewayPath }
|
|
1718
|
+
});
|
|
1719
|
+
assert.equal(result.status, 0, `${result.stderr}\n${result.stdout}`);
|
|
1720
|
+
const parsed = JSON.parse(result.stdout);
|
|
1721
|
+
const gateway = parsed.ok.clients.find((client) => client.id === 'antigravity');
|
|
1722
|
+
const npx = parsed.ok.clients.find((client) => client.id === 'cursor');
|
|
1723
|
+
assert.ok(gateway && npx, 'both configured clients should be listed');
|
|
1724
|
+
|
|
1725
|
+
assert.equal(gateway.registered, true);
|
|
1726
|
+
assert.equal(gateway.command, gatewayPath);
|
|
1727
|
+
assert.deepEqual(gateway.args, []);
|
|
1728
|
+
assert.equal(gateway.launcherStructuralState, 'present');
|
|
1729
|
+
assert.equal(gateway.launcherSemanticState, 'valid');
|
|
1730
|
+
assert.equal(gateway.commandStale, false);
|
|
1731
|
+
|
|
1732
|
+
assert.equal(npx.registered, true);
|
|
1733
|
+
assert.equal(npx.command, 'npx.cmd');
|
|
1734
|
+
assert.deepEqual(npx.args, ['-y', 'genexus-mcp@latest']);
|
|
1735
|
+
assert.equal(npx.launcherStructuralState, 'present');
|
|
1736
|
+
assert.equal(npx.launcherSemanticState, 'valid');
|
|
1737
|
+
assert.equal(npx.commandStale, false);
|
|
1738
|
+
|
|
1739
|
+
const node = parsed.ok.clients.find((client) => client.id === 'codex-cli');
|
|
1740
|
+
assert.ok(node, 'Codex CLI should be listed');
|
|
1741
|
+
assert.equal(node.command, process.execPath);
|
|
1742
|
+
assert.deepEqual(node.args, [nodeEntrypoint]);
|
|
1743
|
+
assert.equal(node.launcherStructuralState, 'present');
|
|
1744
|
+
assert.equal(node.launcherSemanticState, 'valid');
|
|
1745
|
+
assert.equal(node.commandStale, false);
|
|
1746
|
+
assert.equal(parsed.ok.summary.semanticInvalid, 0);
|
|
1747
|
+
} finally {
|
|
1748
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
|
|
1752
|
+
test('clients list keeps an existing unrecognized launcher indeterminate', () => {
|
|
1753
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-unknown-launcher-'));
|
|
1754
|
+
try {
|
|
1755
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
1756
|
+
const cursorCfg = path.join(tempRoot, '.cursor', 'mcp.json');
|
|
1757
|
+
fs.mkdirSync(path.dirname(cursorCfg), { recursive: true });
|
|
1758
|
+
fs.writeFileSync(cursorCfg, JSON.stringify({
|
|
1759
|
+
mcpServers: { genexus18mcp: { command: 'custom-mcp-launcher', args: ['--stdio'] } }
|
|
1760
|
+
}, null, 2));
|
|
1761
|
+
|
|
1762
|
+
const result = runCli(['clients', '--format', 'json'], { env });
|
|
1763
|
+
assert.equal(result.status, 0);
|
|
1764
|
+
const cursor = JSON.parse(result.stdout).ok.clients.find((client) => client.id === 'cursor');
|
|
1765
|
+
assert.equal(cursor.registered, true);
|
|
1766
|
+
assert.equal(cursor.launcherStructuralState, 'indeterminate');
|
|
1767
|
+
assert.equal(cursor.launcherSemanticState, 'unknown');
|
|
1768
|
+
assert.equal(cursor.commandStale, false, 'unknown commands are not treated as invalid');
|
|
1769
|
+
} finally {
|
|
1770
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
1771
|
+
}
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1644
1774
|
test('clients list marks an Antigravity launcher from an old package cache as stale', () => {
|
|
1645
1775
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-antigravity-stale-'));
|
|
1646
1776
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genexus-mcp",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.3",
|
|
4
4
|
"mcpName": "io.github.lennix1337/genexus",
|
|
5
5
|
"description": "GeneXus 17, GeneXus 18 MCP server — read, edit, and analyze Knowledge Base objects directly from Claude, Cursor, and other AI agents over the Model Context Protocol.",
|
|
6
6
|
"keywords": [
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"test": "node --test cli/run.test.js cli/lib/client-adapters.test.js cli/docs.test.js scripts/lint.test.js && npm run test:live-contract",
|
|
36
36
|
"lint": "node scripts/lint.js",
|
|
37
37
|
"test:live-contract": "pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/tests/test-live.test.ps1",
|
|
38
|
+
"test:integration": "pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/integration-preflight.ps1",
|
|
38
39
|
"test:upstream-drift": "pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/tests/test-upstream-drift.ps1",
|
|
39
40
|
"test:one": "node scripts/test-one.js",
|
|
40
41
|
"prepack": "node scripts/clean-package.js",
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"targets": {
|
|
8
8
|
".NETCoreApp,Version=v10.0": {},
|
|
9
9
|
".NETCoreApp,Version=v10.0/win-x64": {
|
|
10
|
-
"GxMcp.Gateway/3.4.
|
|
10
|
+
"GxMcp.Gateway/3.4.3": {
|
|
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/3.4.
|
|
69
|
+
"GxMcp.Gateway/3.4.3": {
|
|
70
70
|
"type": "project",
|
|
71
71
|
"serviceable": false,
|
|
72
72
|
"sha512": ""
|
|
Binary file
|
|
Binary file
|
package/publish/config.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"ResolutionPolicy": "strict"
|
|
4
|
-
},
|
|
5
|
-
"GatewayMode": "stdio-isolated",
|
|
2
|
+
"ConfigSchemaVersion": 2,
|
|
6
3
|
"GeneXus": {
|
|
7
4
|
"WorkerExecutable": "worker\\\\GxMcp.Worker.exe",
|
|
8
5
|
"InstallationPath": "C:\\Program Files (x86)\\GeneXus\\GeneXus18"
|
|
9
6
|
},
|
|
10
|
-
"
|
|
7
|
+
"GatewayMode": "stdio-isolated",
|
|
8
|
+
"Environment": {
|
|
9
|
+
"ResolutionPolicy": "strict"
|
|
10
|
+
},
|
|
11
11
|
"Server": {
|
|
12
|
-
"
|
|
12
|
+
"HttpPort": 0,
|
|
13
13
|
"TerseResponses": true,
|
|
14
|
-
"SessionIdleTimeoutMinutes": 10,
|
|
15
14
|
"McpStdio": true,
|
|
16
|
-
"
|
|
15
|
+
"EmitStructuredContent": false,
|
|
16
|
+
"SessionIdleTimeoutMinutes": 10,
|
|
17
17
|
"WorkerIdleTimeoutMinutes": 5
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "gxmcp-release-manifest/1",
|
|
3
|
-
"version": "3.4.
|
|
4
|
-
"sourceCommit": "
|
|
3
|
+
"version": "3.4.3",
|
|
4
|
+
"sourceCommit": "10e29a32d26678c9ca993f8dea6ef610ce8341d3",
|
|
5
5
|
"sourceCommitPolicy": "exact-tag",
|
|
6
|
-
"generatedAtUtc": "2026-09-
|
|
6
|
+
"generatedAtUtc": "2026-09-14T00:01:15.8745657Z",
|
|
7
7
|
"runtime": {
|
|
8
8
|
"gateway": "net10.0-windows",
|
|
9
9
|
"worker": "net48-x86",
|
|
@@ -15,28 +15,28 @@
|
|
|
15
15
|
"2026-07-28"
|
|
16
16
|
],
|
|
17
17
|
"schema": "tool_definitions.json",
|
|
18
|
-
"schemaSha256": "
|
|
18
|
+
"schemaSha256": "05b92690c10919de5059d00ab28fb4e91a67643436d0be186cecec6d962c3652",
|
|
19
19
|
"provenance": "gxmcp-sbom.json",
|
|
20
20
|
"artifacts": [
|
|
21
21
|
{
|
|
22
22
|
"path": "gxmcp-sbom.json",
|
|
23
23
|
"size": 590,
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "42f9bde3ac0c688fedb7d418b4215a3157e2ed89b6f958edaa2d4ba22d05426c"
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"path": "GxMcp.Gateway.exe",
|
|
28
28
|
"size": 162304,
|
|
29
|
-
"sha256": "
|
|
29
|
+
"sha256": "76d2ce02b5938f94a58e061eb7b9f2f5b6dafd8f9a3f959a4f023411911ae69a"
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"path": "tool_definitions.json",
|
|
33
|
-
"size":
|
|
34
|
-
"sha256": "
|
|
33
|
+
"size": 112952,
|
|
34
|
+
"sha256": "05b92690c10919de5059d00ab28fb4e91a67643436d0be186cecec6d962c3652"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"path": "worker/GxMcp.Worker.exe",
|
|
38
|
-
"size":
|
|
39
|
-
"sha256": "
|
|
38
|
+
"size": 3113984,
|
|
39
|
+
"sha256": "a28b91afe2f0b81e93d92854849d5bb6650bf78611426f7ada724cf8bd6b6e26"
|
|
40
40
|
}
|
|
41
41
|
]
|
|
42
42
|
}
|
package/publish/gxmcp-sbom.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "gxmcp-provenance/1",
|
|
3
|
-
"version": "3.4.
|
|
4
|
-
"sourceCommit": "
|
|
3
|
+
"version": "3.4.3",
|
|
4
|
+
"sourceCommit": "10e29a32d26678c9ca993f8dea6ef610ce8341d3",
|
|
5
5
|
"sourceCommitPolicy": "exact-tag",
|
|
6
6
|
"components": [
|
|
7
7
|
{
|
|
8
8
|
"name": "genexus-mcp",
|
|
9
9
|
"lockfile": "package-lock.json",
|
|
10
10
|
"size": 39914,
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "f49b17136dbbcb51605e2f56f2c18905d3b023565bf3bc02ad8c96fc04421c4f"
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"name": "nexus-ide",
|
|
15
15
|
"lockfile": "src/nexus-ide/package-lock.json",
|
|
16
16
|
"size": 274983,
|
|
17
|
-
"sha256": "
|
|
17
|
+
"sha256": "864c387fcd68d7dbb8651a159c0575c4f4b0089aeba93cc13ab9fc2b99a8268d"
|
|
18
18
|
}
|
|
19
19
|
]
|
|
20
20
|
}
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
{"name":"genexus_data_view","description":"Native, typed, atomic Transaction + Data View authoring over an existing physical table. action=inspect|dry_run|create|update|delete. dry_run performs validation without constructing or saving SDK objects. create/update persist the root-only Transaction and Data View, then reread and verify the committed pair; commit and verification status are reported separately. action=delete is destructive and requires confirm=true when dryRun=false. No action implicitly runs Specify, Generate, Build, Rebuild, Reorg, compilation, publish, execution, or tests; the response includes a no-DDL reorg preview.","inputSchema":{"type":"object","required":["action","transaction","dataViewName"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["inspect","dry_run","create","update","delete"],"description":"Operation to inspect, preview, create, update, or delete a native Data View mapping."},"transaction":{"type":"string","description":"Root-only Transaction name."},"dataViewName":{"type":"string","description":"Data View name associated with the Transaction logical table."},"dataStore":{"type":"string","description":"Existing GeneXus data store category (default Default)."},"schema":{"type":"string","description":"Existing physical schema."},"table":{"type":"string","description":"Existing physical table and GeneXus table-metadata name."},"attributeMappings":{"type":"array","items":{"type":"object","required":["attribute","column"],"additionalProperties":false,"properties":{"attribute":{"type":"string"},"column":{"type":"string"},"key":{"type":"boolean","default":false}}}},"updatable":{"type":"boolean","default":true},"expectedVersion":{"type":"string","description":"Optimistic concurrency token returned by inspect/dry_run/create/update/delete preview."},"dryRun":{"type":"boolean","default":false,"description":"Forces every action to remain read-only; create/update validate their complete definition and delete returns a deletion preview."},"confirm":{"type":"boolean","description":"Required for action=delete when dryRun=false; explicitly authorizes removing the Transaction and Data View."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Atomic SDK rollback is always enforced; this flag records the caller's rollback intent."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"dry_run","transaction":"LedgerEntryView","dataViewName":"LedgerEntryDV","dataStore":"Default","schema":"APP","table":"LEDGERENTRY","updatable":true,"attributeMappings":[{"attribute":"LedgerEntryId","column":"LedgerEntryId","key":true},{"attribute":"LedgerEntryAmount","column":"LedgerEntryAmount"}],"rollbackOnFailure":true},{"action":"delete","transaction":"LedgerEntryView","dataViewName":"LedgerEntryDV","confirm":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
3
3
|
{"name":"genexus_whoami","description":"KB context + version + health (worker/index/database) + next-step hints. Call FIRST every session. Lean by default; pass verbose=true ONCE for the inline playbooks + skills catalog of verified GeneXus reference resources (navigation, GAM, SD panel, WebPanel events). For a minimal connection+index health check use genexus_doctor.","inputSchema":{"type":"object","properties":{"verbose":{"type":"boolean","description":"Include the static playbooks + skills catalog + per-tool stats/heatmap. Default false (lean health payload)."}},"additionalProperties":false,"examples":[{},{"verbose":true}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
4
4
|
{"name":"genexus_recipe","description":"Named playbooks + self-extending macros. action=list|describe|suggest_macro|crystallize.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Recipe key (latest version), 'name@v1' (pinned), or 'list'."},"action":{"type":"string","enum":["list","describe","suggest_macro","crystallize"],"description":"list: show recipes; describe: inspect recipe; suggest_macro: detect repeated sequences; crystallize: save sequence as recipe."},"windowMinutes":{"type":"integer","description":"suggest_macro: history window (default 30)."},"minRepetitions":{"type":"integer","description":"suggest_macro: threshold (default 3)."},"macroName":{"type":"string","description":"crystallize: proposed name from suggest_macro."},"description":{"type":"string","description":"crystallize: human-readable description."},"steps":{"type":"array","items":{"type":"object","description":"Tool call step object or template."},"description":"crystallize: ordered array of tool call steps to include in the macro."}},"examples":[{"name":"list"},{"name":"wwp_on_transaction"},{"action":"suggest_macro"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
5
|
-
{"name":"genexus_query","description":"Search objects in active KB. Prefixes: name:, type:, usedby:, parent:, parentPath:, description:. name:\"X\" (or bare quoted \"X\") demands exact-name match — use it when you know the object's name. Compact by default. See genexus://kb/tool-help/genexus_query. Requires the KB index to be Ready — check genexus_lifecycle action=status if results look empty.","inputSchema":{"type":"object","properties":{"query":{"type":"string"},"typeFilter":{"type":"string"},"domainFilter":{"type":"string"},"limit":{"type":"integer"},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N."},"sort":{"type":"string","enum":["relevance","lastUpdate"],"description":"relevance (default) or lastUpdate (newest first; bypasses score ranking)."},"since":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate >= since."},"modifiedBefore":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate < modifiedBefore."},"cursor":{"type":"string","description":"Opaque token from prior nextCursor. Use with sort=lastUpdate for stable paging."},"kb":{"type":"string","description":"KB alias."},"axiCompact":{"type":"boolean","description":"Compact projection (default true).","default":true}},"required":["query"],"examples":[{"query":"type:Transaction parent:Customers"},{"query":"\"Customer\"","limit":5}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
5
|
+
{"name":"genexus_query","description":"Search objects in active KB. Prefixes: name:, type:, usedby:, parent:, parentPath:, description:. name:\"X\" (or bare quoted \"X\") demands exact-name match — use it when you know the object's name. Compact by default. See genexus://kb/tool-help/genexus_query. Requires the KB index to be Ready — check genexus_lifecycle action=status if results look empty.","inputSchema":{"type":"object","properties":{"query":{"type":"string"},"typeFilter":{"type":"string"},"domainFilter":{"type":"string"},"limit":{"type":"integer"},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N."},"sort":{"type":"string","enum":["relevance","lastUpdate"],"description":"relevance (default) or lastUpdate (newest first; bypasses score ranking)."},"since":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate >= since."},"modifiedBefore":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate < modifiedBefore."},"cursor":{"type":"string","description":"Opaque token from prior nextCursor. Use with sort=lastUpdate for stable paging."},"kb":{"type":"string","description":"KB alias."},"axiCompact":{"type":"boolean","description":"Compact projection (default true).","default":true},"exactMatch":{"type":"boolean","description":"Require an exact object-name match."}},"required":["query"],"examples":[{"query":"type:Transaction parent:Customers"},{"query":"\"Customer\"","limit":5}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
6
6
|
{"name":"genexus_list_objects","description":"List objects with pagination. Feed nextOffset until hasMore=false. Every item exposes its persisted GUID and path; verbose=true also exposes the typed EntityKey when available.","inputSchema":{"type":"object","properties":{"filter":{"type":"string","description":"Legacy: name OR description. Prefer nameFilter/descriptionFilter."},"nameFilter":{"type":"string","description":"Substring on name."},"descriptionFilter":{"type":"string","description":"Substring on description."},"pathPrefix":{"type":"string","description":"Folder prefix, e.g. 'Root Module/X/'."},"limit":{"type":"integer"},"offset":{"type":"integer"},"parent":{"type":"string"},"parentPath":{"type":"string"},"typeFilter":{"type":"string"},"verbose":{"type":"boolean","description":"Full item shape."},"sort":{"type":"string","enum":["name","lastUpdate"],"description":"name (default, type-bucketed) or lastUpdate (newest first)."},"since":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate >= since."},"modifiedBefore":{"type":"string","description":"ISO-8601 UTC. Only items with lastUpdate < modifiedBefore."},"cursor":{"type":"string","description":"Opaque token from prior nextCursor. Use with sort=lastUpdate for stable paging."},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N."},"kb":{"type":"string","description":"KB alias."},"axiCompact":{"type":"boolean","description":"Compact projection (default true).","default":true},"projection":{"type":"string","enum":["minimal","standard","verbose"],"description":"minimal=name+type+lastUpdate; standard=default compact; verbose=all fields. Overrides axiCompact when set."}},"examples":[{"limit":25},{"typeFilter":"Transaction","limit":10}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
7
7
|
{"name":"genexus_read","description":"Read object code and metadata. Omitting 'part' (RECOMMENDED) returns the COMPLETE object in 1 call (rules with parm, source/events, variables, structure, called signatures) tailored to the object type. Resolve modular objects by name/type, persisted GUID, EntityKey, or path. Pass 'part' only for targeted single-part reads. Response carries versionToken for safe writes. See genexus://kb/tool-help/genexus_read.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"targets":{"type":"array","items":{"type":"string"}},"guid":{"type":"string","description":"Persisted object GUID from genexus_list_objects."},"entityKey":{"type":"string","description":"Typed GeneXus EntityKey from genexus_list_objects verbose output."},"path":{"type":"string","description":"Module/folder-qualified object path from genexus_list_objects."},"part":{"type":"string","description":"DataSelector: parameters|conditions|orders|projection|definedBy|baseTransaction|baseTable|joins|structure."},"parts":{"type":"array","items":{"type":"string"},"description":"Selected parts; unavailable DataSelector parts appear in unsupportedParts. Mutually exclusive with part/offset/limit."},"offset":{"type":"integer"},"limit":{"type":"integer"},"type":{"type":"string"},"kb":{"type":"string","description":"KB alias."}},"examples":[{"name":"Customer"},{"name":"Customer","type":"Procedure","guid":"<guid-from-list>"},{"name":"Customer","path":"Operations/Customer","type":"Procedure"},{"name":"Customer","part":"Source"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
8
|
-
{"name":"genexus_edit","description":"Edit object part. name or targets (exclusive). mode: full|patch|ops. dryRun first. async=true returns an operationId for lifecycle polling. Text payloads for Source/Rules/Events/Code must contain real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence with LiteralLineBreaksDetected. For WWP edit host's PatternInstance NOT the parent WebForm (gets overwritten on reapply). Uncertain about a property/method/event? → resources/read uri=genexus://kb/skills/navigation (or gam-integrated-security / sd-panel-mobile / webpanel-events) first.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"part":{"type":"string"},"parts":{"type":"array","description":"Multi-part edit on a single object. Each item: {part, content, mode?}. Saves the object once atomically. Text content must use real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence.","items":{"type":"object","properties":{"part":{"type":"string"},"content":{"type":"string"},"mode":{"type":"string"}},"required":["part","content"]}},"mode":{"type":"string","enum":["full","patch","ops"]},"content":{"type":"string"},"ops":{"type":"array","description":"GeneXus semantic ops (NOT RFC 6902 JSON-Patch). Each item: {op, args}. Supported ops: set_attribute, add_attribute, remove_attribute (Transaction); add_rule, remove_rule (Transaction/Procedure/WebPanel); set_property (any kind). Use mode=patch for textual find/replace.","items":{"type":"object","properties":{"op":{"type":"string","enum":["set_attribute","add_attribute","remove_attribute","add_rule","remove_rule","set_property"]},"args":{"type":"object","description":"Op-specific args. set_attribute: {name, type?, description?}. add_attribute: {name, type, ...}. add_rule: {rule}. set_property: {name, value}."}},"required":["op"]}},"patch":{"description":"Shorthand for {find,replace}. Equivalent to operation=Replace + context=find + content=replace."},"context":{"type":"string","description":"Exact existing text to find (Replace) or anchor after (Insert_After). Required for both. For text parts, send real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence."},"operation":{"type":"string","enum":["Replace","Insert_After","Append"]},"expectedCount":{"type":"integer"},"replaceAll":{"type":"boolean","description":"patch mode only. Apply to ALL occurrences instead of requiring expectedCount to match exactly."},"dryRun":{"type":"boolean"},"async":{"type":"boolean","description":"Run as a background job. Result returns operationId/job_id for genexus_lifecycle polling."},"estimated_seconds":{"type":"integer","description":"When async=true, expected runtime used for progress/job metadata (default 30)."},"verifyRollback":{"type":"boolean"},"targets":{"type":"array","description":"Multi-target Source/Rules writes. Each target may include expectedVersion/baseVersion; all versions are checked before the first write.","items":{"type":"object","properties":{"name":{"type":"string"},"part":{"type":"string"},"content":{"type":"string"},"expectedVersion":{"type":"string"},"baseVersion":{"type":"string"}},"required":["name","content"]}},"type":{"type":"string"},"return_post_state":{"type":"boolean","description":"Omit post_state.diff (default true)."},"verbose":{"type":"boolean","description":"Add ±15-line slices to post_state."},"validate":{"type":"string","enum":["strict","best-effort","only"],"description":"strict (default) aborts on first error and post-write-verifies visual/PatternInstance writes (re-reads + diffs the persisted XML). best-effort applies what compiles and SKIPS the post-write XML re-read/diff (faster on large WebForm/PatternInstance writes; build to confirm). only runs in-memory, no persist."},"validationMode":{"type":"string","enum":["specify"],"description":"Issue #60: run the inline Specify pass (Spec+Gen, no Compile) against the edited object right after the write, returning structured spc*/gen* diagnostics in the same call. Combines with rollbackOnFailure."},"rollbackOnFailure":{"type":"boolean","description":"Explicit rollback only: restore a valid pre-write snapshot when post-save verification or validationMode=specify fails. No rollback occurs when false or omitted."},"requireObjectSave":{"type":"boolean","default":false,"description":"Events patch complete-save requirement. dryRun remains available; real writes are blocked before persistence with ObjectSaveIsolationUnverified until SDK/pattern save-event isolation is established. No override. baseVersion remains required for a real write."},"forceWrite":{"type":"boolean","default":false,"description":"WebForm only: persist despite SDK WebForm validation errors; response includes validationOverridden=true."},"verifyMode":{"type":"string","enum":["semantic","normalized","exact"],"default":"normalized","description":"Post-save text comparison for patch mode. Source/Rules default to normalized (EOL, encoding marker, trailing whitespace and repeated blank lines); exact preserves logical text but treats CRLF/LF as the same SDK Source rendering; semantic also tolerates SDK casing/spacing format changes. Comment-only Replace writes require baseVersion and return CommentOnlyWriteNotPersisted on a divergent forced re-read. The part is always re-read after Save."},"visualVerify":{"type":"boolean","default":false,"description":"Post-edit headless screenshot + pixel-diff vs baseline. See tool-help."},"baseVersion":{"type":"string","description":"Optimistic concurrency: pass the versionToken from the genexus_read this edit is based on. If the object changed since (e.g. edited in the IDE), the write is refused with VersionConflict instead of overwriting the newer version. Omit to skip the check."},"expectedVersion":{"type":"string","description":"Alias of baseVersion. The write is refused when the current version no longer matches."},"concurrencyPolicy":{"type":"string","enum":["warn","fail_if_open"],"default":"warn","description":"warn (default) or fail_if_open if open in GeneXus IDE."},"autoDeclareVariables":{"type":"boolean","default":false,"description":"When true, scans updated source for newly referenced &Variable tokens and auto-declares them in VariablesPart."},"kb":{"type":"string","description":"KB alias."},"changeSet":{"type":"object","required":["action","changes"],"properties":{"action":{"type":"string","enum":["preview","validate","apply"]},"changes":{"type":"array","items":{"type":"object","required":["name","content"],"properties":{"name":{"type":"string"},"part":{"type":"string","enum":["Source","Rules","Variables"]},"content":{"type":"string"},"expectedVersion":{"type":"string"}}}},"changeSetId":{"type":"string"},"baseRevision":{"type":"string"}}}},"examples":[{"name":"Customer","mode":"patch","part":"Source","patch":{"find":"old","replace":"new"}},{"name":"Customer","mode":"patch","part":"Rules","patch":{"find":"error(","replace":"msg("},"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
9
|
-
{"name":"genexus_inspect","description":"Use this for a compact object snapshot: metadata, variables, structure, signature and navigation context. Modular objects accept persisted GUID, EntityKey, or path in addition to name/type. Don't use it when you need full Source or exact part bytes; use genexus_read for that. runtimeIds needs a prior build.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"guid":{"type":"string","description":"Persisted object GUID from genexus_list_objects."},"entityKey":{"type":"string","description":"Typed GeneXus EntityKey from genexus_list_objects verbose output."},"path":{"type":"string","description":"Module/folder-qualified object path from genexus_list_objects."},"include":{"type":"array","items":{"type":"string","enum":["metadata","variables","signature","structure","parts","controls","events_repertoire","callers","runtimeIds"]}},"projection":{"type":"string","enum":["minimal","standard","verbose"],"description":"Token budget. minimal=name/type/lastUpdate; standard=default (vars≤40 name+type, source heads 1200c); verbose=full vars + 8000c heads."},"type":{"type":"string"},"kb":{"type":"string","description":"KB alias."}},"examples":[{"name":"Customer"},{"name":"Customer","type":"Procedure","path":"Operations/Customer"},{"name":"Customer","include":["variables","signature"]}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
10
|
-
{"name":"genexus_analyze","description":"Use this for cross-object semantic analysis. mode=context returns 360° task context in 1 call (object + called procedures' parm signatures + referenced tables' schemas/PKs + SDTs + callers). Other modes: impact, callers, hierarchy, navigation, linter, summary, explain. mode=explain is compatibility-only: it preserves the legacy response envelope and returns NotImplemented; use mode=summary for a concise overview, mode=context for 360° task context, or genexus_read for source. Requires Ready index for impact/callers.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"mode":{"type":"string","enum":["context","linter","navigation","hierarchy","impact","cross_platform_impact","callers","event_flow","data_context","ui_context","pattern_metadata","summary","dependency_heatmap","code_metrics","kb_stats","table_relations","explain"]},"code":{"type":"string","description":"mode=explain: legacy code snippet carried through the compatibility-only envelope; the result is NotImplemented. Use mode=summary, mode=context, or genexus_read for supported analysis."},"cursor":{"type":"string","description":"mode=context: continuation cursor returned by a budgeted context page."},"format":{"type":"string","enum":["json","ascii"],"description":"mode=dependency_heatmap: ascii adds rendered bar chart."},"kb":{"type":"string","description":"KB alias."},"maxBytes":{"type":"integer","description":"mode=context: maximum UTF-8 bytes for the returned context bundle (bounded by the server)."},"waitForIndex":{"type":"boolean","description":"mode=impact: block up to 30s for Ready index (default true).","default":true}},"required":["mode"],"examples":[{"name":"Customer","mode":"impact"},{"name":"Customer","mode":"summary"}]},"annotations":{"readOnlyHint":
|
|
8
|
+
{"name":"genexus_edit","description":"Edit object part. name or targets (exclusive). mode: full|patch|ops. dryRun first. async=true returns an operationId for lifecycle polling. Text payloads for Source/Rules/Events/Code must contain real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence with LiteralLineBreaksDetected. For WWP edit host's PatternInstance NOT the parent WebForm (gets overwritten on reapply). Uncertain about a property/method/event? → resources/read uri=genexus://kb/skills/navigation (or gam-integrated-security / sd-panel-mobile / webpanel-events) first.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"part":{"type":"string"},"parts":{"type":"array","description":"Multi-part edit on a single object. Each item: {part, content, mode?}. Saves the object once atomically. Text content must use real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence.","items":{"type":"object","properties":{"part":{"type":"string"},"content":{"type":"string"},"mode":{"type":"string"}},"required":["part","content"]}},"mode":{"type":"string","enum":["full","patch","ops"]},"content":{"type":"string"},"ops":{"type":"array","description":"GeneXus semantic ops (NOT RFC 6902 JSON-Patch). Each item: {op, args}. Supported ops: set_attribute, add_attribute, remove_attribute (Transaction); add_rule, remove_rule (Transaction/Procedure/WebPanel); set_property (any kind). Use mode=patch for textual find/replace.","items":{"type":"object","properties":{"op":{"type":"string","enum":["set_attribute","add_attribute","remove_attribute","add_rule","remove_rule","set_property"]},"args":{"type":"object","description":"Op-specific args. set_attribute: {name, type?, description?}. add_attribute: {name, type, ...}. add_rule: {rule}. set_property: {name, value}."}},"required":["op"]}},"patch":{"description":"Shorthand for {find,replace}. Equivalent to operation=Replace + context=find + content=replace."},"context":{"type":"string","description":"Exact existing text to find (Replace) or anchor after (Insert_After). Required for both. For text parts, send real line breaks; literal backslash sequences \\r\\n, \\n, or \\r are rejected before persistence."},"operation":{"type":"string","enum":["Replace","Insert_After","Append"]},"expectedCount":{"type":"integer"},"replaceAll":{"type":"boolean","description":"patch mode only. Apply to ALL occurrences instead of requiring expectedCount to match exactly."},"dryRun":{"type":"boolean"},"async":{"type":"boolean","description":"Run as a background job. Result returns operationId/job_id for genexus_lifecycle polling."},"estimated_seconds":{"type":"integer","description":"When async=true, expected runtime used for progress/job metadata (default 30)."},"verifyRollback":{"type":"boolean"},"targets":{"type":"array","description":"Multi-target Source/Rules writes. Each target may include expectedVersion/baseVersion; all versions are checked before the first write.","items":{"type":"object","properties":{"name":{"type":"string"},"part":{"type":"string"},"content":{"type":"string"},"expectedVersion":{"type":"string"},"baseVersion":{"type":"string"}},"required":["name","content"]}},"type":{"type":"string"},"return_post_state":{"type":"boolean","description":"Omit post_state.diff (default true)."},"verbose":{"type":"boolean","description":"Add ±15-line slices to post_state."},"validate":{"type":"string","enum":["strict","best-effort","only"],"description":"strict (default) aborts on first error and post-write-verifies visual/PatternInstance writes (re-reads + diffs the persisted XML). best-effort applies what compiles and SKIPS the post-write XML re-read/diff (faster on large WebForm/PatternInstance writes; build to confirm). only runs in-memory, no persist."},"validationMode":{"type":"string","enum":["specify"],"description":"Issue #60: run the inline Specify pass (Spec+Gen, no Compile) against the edited object right after the write, returning structured spc*/gen* diagnostics in the same call. Combines with rollbackOnFailure."},"rollbackOnFailure":{"type":"boolean","description":"Explicit rollback only: restore a valid pre-write snapshot when post-save verification or validationMode=specify fails. No rollback occurs when false or omitted."},"requireObjectSave":{"type":"boolean","default":false,"description":"Events patch complete-save requirement. dryRun remains available; real writes are blocked before persistence with ObjectSaveIsolationUnverified until SDK/pattern save-event isolation is established. No override. baseVersion remains required for a real write."},"forceWrite":{"type":"boolean","default":false,"description":"WebForm only: persist despite SDK WebForm validation errors; response includes validationOverridden=true."},"verifyMode":{"type":"string","enum":["semantic","normalized","exact"],"default":"normalized","description":"Post-save text comparison for patch mode. Source/Rules default to normalized (EOL, encoding marker, trailing whitespace and repeated blank lines); exact preserves logical text but treats CRLF/LF as the same SDK Source rendering; semantic also tolerates SDK casing/spacing format changes. Comment-only Replace writes require baseVersion and return CommentOnlyWriteNotPersisted on a divergent forced re-read. The part is always re-read after Save."},"visualVerify":{"type":"boolean","default":false,"description":"Post-edit headless screenshot + pixel-diff vs baseline. See tool-help."},"baseVersion":{"type":"string","description":"Optimistic concurrency: pass the versionToken from the genexus_read this edit is based on. If the object changed since (e.g. edited in the IDE), the write is refused with VersionConflict instead of overwriting the newer version. Omit to skip the check."},"expectedVersion":{"type":"string","description":"Alias of baseVersion. The write is refused when the current version no longer matches."},"concurrencyPolicy":{"type":"string","enum":["warn","fail_if_open"],"default":"warn","description":"warn (default) or fail_if_open if open in GeneXus IDE."},"autoDeclareVariables":{"type":"boolean","default":false,"description":"When true, scans updated source for newly referenced &Variable tokens and auto-declares them in VariablesPart."},"kb":{"type":"string","description":"KB alias."},"changeSet":{"type":"object","required":["action","changes"],"properties":{"action":{"type":"string","enum":["preview","validate","apply"]},"changes":{"type":"array","items":{"type":"object","required":["name","content"],"properties":{"name":{"type":"string"},"part":{"type":"string","enum":["Source","Rules","Variables"]},"content":{"type":"string"},"expectedVersion":{"type":"string"}}}},"changeSetId":{"type":"string"},"baseRevision":{"type":"string"}}},"module":{"type":"string","description":"mode=ops: Transaction module for modular objects."}},"examples":[{"name":"Customer","mode":"patch","part":"Source","patch":{"find":"old","replace":"new"}},{"name":"Customer","mode":"patch","part":"Rules","patch":{"find":"error(","replace":"msg("},"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
9
|
+
{"name":"genexus_inspect","description":"Use this for a compact object snapshot: metadata, variables, structure, signature and navigation context. Modular objects accept persisted GUID, EntityKey, or path in addition to name/type. Don't use it when you need full Source or exact part bytes; use genexus_read for that. runtimeIds needs a prior build.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"guid":{"type":"string","description":"Persisted object GUID from genexus_list_objects."},"entityKey":{"type":"string","description":"Typed GeneXus EntityKey from genexus_list_objects verbose output."},"path":{"type":"string","description":"Module/folder-qualified object path from genexus_list_objects."},"include":{"type":"array","items":{"type":"string","enum":["metadata","variables","signature","structure","parts","controls","events_repertoire","callers","runtimeIds"]}},"projection":{"type":"string","enum":["minimal","standard","verbose"],"description":"Token budget. minimal=name/type/lastUpdate; standard=default (vars≤40 name+type, source heads 1200c); verbose=full vars + 8000c heads."},"type":{"type":"string"},"kb":{"type":"string","description":"KB alias."},"verbose":{"type":"boolean","description":"Include verbose diagnostic fields."}},"examples":[{"name":"Customer"},{"name":"Customer","type":"Procedure","path":"Operations/Customer"},{"name":"Customer","include":["variables","signature"]}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
10
|
+
{"name":"genexus_analyze","description":"Use this for cross-object semantic analysis. mode=context (alias deep_context) returns 360° task context in 1 call (object + called procedures' parm signatures + referenced tables' schemas/PKs + SDTs + callers). Other modes: impact, callers, hierarchy, navigation, linter, summary, explain. mode=explain is compatibility-only: it preserves the legacy response envelope and returns NotImplemented; use mode=summary for a concise overview, mode=context for 360° task context, or genexus_read for source. Requires Ready index for impact/callers.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"mode":{"type":"string","enum":["context","deep_context","linter","navigation","hierarchy","impact","cross_platform_impact","callers","event_flow","data_context","ui_context","pattern_metadata","summary","dependency_heatmap","code_metrics","kb_stats","table_relations","explain"]},"code":{"type":"string","description":"mode=explain: legacy code snippet carried through the compatibility-only envelope; the result is NotImplemented. Use mode=summary, mode=context, or genexus_read for supported analysis."},"cursor":{"type":"string","description":"mode=context: continuation cursor returned by a budgeted context page."},"format":{"type":"string","enum":["json","ascii"],"description":"mode=dependency_heatmap: ascii adds rendered bar chart."},"kb":{"type":"string","description":"KB alias."},"maxBytes":{"type":"integer","description":"mode=context: maximum UTF-8 bytes for the returned context bundle (bounded by the server)."},"waitForIndex":{"type":"boolean","description":"mode=impact: block up to 30s for Ready index (default true).","default":true},"dryRun":{"type":"boolean","description":"mode=linter: with fix=true, reject the unsupported combination before any SDK read; with fix=false, lint remains read-only."},"fix":{"type":"boolean","description":"mode=linter: apply automatic fixes to the KB."},"top":{"type":"integer","description":"mode=code_metrics: maximum results (default 25)."},"waitTimeoutMs":{"type":"integer","description":"mode=impact: maximum index wait in milliseconds."}},"required":["mode"],"examples":[{"name":"Customer","mode":"impact"},{"name":"Customer","mode":"summary"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
11
11
|
{"name":"genexus_lifecycle","description":"Build, validate, index, or poll the KB. action=build_all runs the native incremental Build All for the entire selected KB (ForceRebuild=false); it rejects target, refuses silent reorganization, and returns completion evidence. action=rebuild remains the forced Rebuild All path. action=specify runs Spec+Gen only. action=build with mode=compile_check checks targets plus transitive callers without KB-wide DeveloperMenu regeneration. Long operations are async with operationId. dryRun=true previews without executing. Build results carry generateEvidence and effective_status. See genexus://kb/tool-help/genexus_lifecycle for actions and target formats.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["build","build_all","cancel","specify","rebuild","reorg","reorg_preview","validate","validate-kb","sync","index","status","result","snapshots-list","snapshots-restore","inspect","reconcile"],"description":"Lifecycle action to perform."},"mode":{"type":"string","enum":["compile_check"],"description":"With action=build: compile_check spec+gen+compiles target(s) plus their transitive callers and SKIPS the KB-wide DeveloperMenu regen (the dominant build-all cost). Fast 'did my edit break the build?' check; requires target."},"target":{"type":"string","description":"Object name(s), taskId, job_id, or op:<id>. Build accepts CSV ('Foo,Bar'); build_all is KB-global and rejects target."},"code":{"type":"string","description":"validate: in-memory code to check without persisting."},"limit":{"type":"integer","description":"validate-kb: maximum number of objects/conditions to validate."},"snapshotPath":{"type":"string","description":"snapshots-restore: path to pattern snapshot to restore."},"estimated_seconds":{"type":"integer","description":"Build: <20 sync, >=20 async (default 60)."},"wait_seconds":{"type":"integer","description":"Status/build long-poll cap, 0-600s."},"wait_until_done":{"type":"boolean","description":"Build/build_all/rebuild: block in one turn until terminal (up to wait_seconds, default 600)."},"wait":{"type":"integer","description":"Status block, 0-600s. With a build taskId (or since): event-driven, returns on change. On index status with no since: blocks until index is Ready."},"since":{"type":"string","description":"Status: prior _meta.snapshot for chained waits."},"compact":{"type":"boolean","description":"Status: counts + top-10 errors (default true)."},"force":{"type":"boolean","description":"Index: full SDK rescan (clears snapshot)."},"dryRun":{"type":"boolean","default":false,"description":"build/build_all/rebuild/index: returns the plan without executing."},"environment":{"type":"string","description":"Build: target environment name/folder. Switches active environment before building."},"includeCallees":{"type":"string","enum":["none","direct","transitive"],"description":"Build: expand call graph so callees compile first (default transitive)."},"callers":{"type":"boolean","description":"compile_check: expand transitive callers of the target (default true). Set false for a target-only check when the target is a base transaction/BC with a huge caller closure."},"callerCap":{"type":"integer","description":"compile_check: max callers to pull into the check (default 40). Closure beyond this is truncated and flagged."},"deploy":{"type":"boolean","description":"Build: force the full deploy (Theme/Image/Style/Module copy to web/bin + WebAppConfig) so the built object is runnable, not just compiled. Default false (fast compile-only path). Slower; use when you need to run/preview the object."},"buildPlanCap":{"type":"integer","description":"Build: max nodes before BuildPlanTooLarge (default 200)."},"kb":{"type":"string","description":"KB alias."},"part":{"type":"string","description":"validate: specific object part to check (e.g. Source, Rules)."},"page":{"type":"integer","description":"status/result: 1-based page number for paginated results."},"pageSize":{"type":"integer","description":"status/result: page size for paginated results (default 50)."},"page_size":{"type":"integer","description":"status/result: snake_case alias for pageSize."},"notifyOnFailure":{"type":"string","description":"build: Slack/Discord webhook URL to notify on terminal build failure."},"skipFullDeploy":{"type":"boolean","description":"build: skip full deployment stage to speed up compile pass."},"fastIncremental":{"type":"boolean","description":"build: experimental fast incremental build opt-in."},"operationKey":{"type":"string","description":"inspect/reconcile: original idempotency key; journal lookup is hash-scoped to the resolved KB."},"operationTool":{"type":"string","description":"inspect/reconcile: canonical mutating tool that owns the idempotency key, e.g. genexus_edit."},"confirmed":{"type":"boolean","description":"reconcile: must be true after independently reading the affected target; this never authorizes a retry with the same key."},"verification":{"type":"string","description":"reconcile: short operator/model verification statement. Only a hash is persisted; source and KB content are never journaled."},"observedTargetIds":{"type":"array","items":{"type":"string"},"description":"reconcile: target names observed by an independent read; send one name as a single-item array. Must match the durable target fence."},"observedRevision":{"type":"string","description":"reconcile: revision/version observed by an independent read; must match the durable revision fence."}},"required":["action"],"examples":[{"action":"build"},{"action":"build_all"},{"action":"status","target":"op:abc123"},{"action":"build","mode":"compile_check","target":"MyObject"},{"action":"inspect","operationTool":"genexus_edit","operationKey":"edit_20260905_01"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"outputSchema":{"type":"object","description":"Structured lifecycle result. Action-specific fields remain additive; text content is preserved for legacy clients.","properties":{"status":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"},"error":{"type":"string"},"operationId":{"type":"string"},"job_id":{"type":"string"},"pollTarget":{"type":"string"},"isError":{"type":"boolean"}},"additionalProperties":true}},
|
|
12
12
|
{"name":"genexus_test","description":"Execute native GeneXus tests (GXtest).","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"kb":{"type":"string","description":"KB alias."}},"required":["name"],"examples":[{"name":"MyTestProc"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}},
|
|
13
|
-
{"name":"genexus_sdk_probe","description":"Read the GeneXus SDK surface. mode=surface dumps types/methods/props to docs/sdk-probe/; mode=capabilities returns an in-memory capability matrix with honest signature-probe status.","inputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["surface","capabilities"],"description":"surface (default) writes the diagnostic probe; capabilities is read-only and returns status/evidence."},"outputDir":{"type":"string","description":"Absolute path for mode=surface. Default <repo>/docs/sdk-probe/."}},"examples":[{},{"mode":"capabilities"}]},"annotations":{"readOnlyHint":
|
|
13
|
+
{"name":"genexus_sdk_probe","description":"Read the GeneXus SDK surface. mode=surface dumps types/methods/props to docs/sdk-probe/; mode=capabilities returns an in-memory capability matrix with honest signature-probe status.","inputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["surface","capabilities"],"description":"surface (default) writes the diagnostic probe; capabilities is read-only and returns status/evidence."},"outputDir":{"type":"string","description":"Absolute path for mode=surface. Default <repo>/docs/sdk-probe/."}},"examples":[{},{"mode":"capabilities"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
14
14
|
{"name":"genexus_worker_reload","description":"Reload worker. modes: soft (drain+respawn), warm (restore validated index snapshot + soft respawn), hard (copy sourceDir+respawn). force=true: gateway kills directly. See tool-help.","inputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["soft","warm","hard"]},"force":{"type":"boolean","description":"Bypass drain; gateway kills + respawns. Use when worker is wedged."},"sourceDir":{"type":"string","description":"Required for mode=hard."},"drainTimeoutMs":{"type":"integer","description":"Soft only; default 30000."}},"examples":[{"mode":"soft"},{"mode":"hard","sourceDir":"C:\\Projetos\\Genexus18MCP\\src\\GxMcp.Worker\\bin\\Debug"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}},
|
|
15
15
|
{"name":"genexus_connection_recover","description":"Self-healing recovery for a broken MCP connection (connection closed, unresponsive worker). Probes every open worker, kills and respawns only the unhealthy ones (force=true targets all), confirms SDK-ready, and clears the semantic cache. Use when calls hang or return WorkerBusy.","inputSchema":{"type":"object","properties":{"force":{"type":"boolean","default":false,"description":"Recover ALL workers, even responsive ones."}},"examples":[{},{"force":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":true}},
|
|
16
16
|
{"name":"genexus_delete_object","description":"Delete an object from the KB through its native SDK identity. Irreversible — confirm=true required. Inspects native incoming references first; dryRun=true previews without deleting it.","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"},"confirm":{"type":"boolean"},"dryRun":{"type":"boolean","default":false,"description":"When true, returns the resolved object and native references without deleting it."},"expectedVersion":{"type":"string","description":"Optional optimistic-concurrency token returned by a prior dry run."},"kb":{"type":"string","description":"KB alias."}},"required":["name","confirm"],"examples":[{"name":"ObsoletePanel","type":"WebPanel","confirm":true},{"name":"TemporaryDomain","type":"Domain","confirm":true,"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
{"name":"genexus_kb_version","description":"KB model-version management (Create Version/Branch/Activate/Revert) over the SDK's KBVersionHelper — the IDE Version menu's code path. action=list is read-only; freeze/branch/set_active/revert mutate the KB's version tree. Version results keep lastUpdate separate from createdAt; createdAt is null with createdAtAvailable=false when the SDK has no reliable creation timestamp.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","freeze","branch","set_active","revert"],"description":"KB model-version or branch operation to perform."},"name":{"type":"string","description":"New version/branch name (freeze/branch)."},"description":{"type":"string","description":"New version/branch description (freeze/branch)."},"parentVersion":{"type":"string","description":"Parent version name (freeze/branch). Defaults to the active version."},"targetVersion":{"type":"string","description":"Version to activate (set_active) or revert to (revert)."},"fromVersion":{"type":"string","description":"revert: source version. Defaults to the active version."},"backupModel":{"type":"boolean","description":"freeze: back up the KB model. Default false."},"includeEnvironments":{"type":"boolean","description":"branch: include environments. Default false."},"autoUpdate":{"type":"boolean","description":"set_active: auto-update the working model. Default false."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"freeze","name":"v1.0","description":"Release 1.0"},{"action":"set_active","targetVersion":"Trunk"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
40
40
|
{"name":"genexus_browser","description":"Headless-browser verification umbrella. action=smoke (HTTP 200 + clean console), a11y (axe), wcag (caption/tooltip lint), capture (console/network/exceptions), cross (multi-engine), preview (render WebPanel + capture HTML/a11y/screenshot, optionally diff baseline). preview uses mode=render|run (default render; run auto-resolves the KB launcher, IDE F5 parity).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["smoke","a11y","wcag","capture","cross","preview"],"description":"Browser verification operation to execute."},"name":{"type":"string","description":"WebPanel name."},"mode":{"type":"string","enum":["render","run"],"description":"preview only."},"capture":{"type":"array","items":{"type":"string"},"description":"capture|cross|preview channels: console|network|exceptions|html|a11y|screenshot."},"browsers":{"type":"array","items":{"type":"string","enum":["chrome","firefox","safari","webkit"]},"description":"cross only."},"parms":{"type":"object","description":"preview only."},"launcher":{"type":"string","description":"preview only."},"buildFirst":{"type":"boolean","description":"preview only."},"waitMs":{"type":"integer","description":"preview only."},"diffBaseline":{"type":"boolean","description":"preview only."},"updateBaseline":{"type":"boolean","description":"preview only."},"fill":{"type":"object","description":"preview only."},"click":{"type":"string","description":"preview only."},"auth":{"type":"object","description":"preview only."},"emulate":{"type":"string","enum":["iPhone12","iPhone15Pro","iPadPro","Pixel7","desktop1920","desktop1280"],"description":"preview only."},"network":{"type":"string","enum":["fast","slow3g","fast3g","offline"],"description":"preview only."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"preview","name":"WPMain"},{"action":"cross","name":"WPMain","browsers":["chrome","firefox"]}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":true}},
|
|
41
41
|
{"name":"genexus_db","description":"Database umbrella. action: drift_check|drift_report (Transaction↔DB schema drift) | optimize_analyze|optimize_suggest|optimize_report (static index advisor) | sql_ddl|sql_navigation (SQL for Transaction/Procedure) | sample_data (fake INSERTs) | records_query|records_insert|records_update (typed application rows through Transaction metadata; writes default to dryRun; direct SQL only and no GeneXus business rules) | types_list|types_describe|types_validate (Domains/SDT constraints) | reorg_impact (timestamp/deep ImpactDatabase) | reorg_preview (non-mutating logical↔physical impact diff plus exact SQL only when a current artifact is available) | translations_import.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["drift_check","drift_report","optimize_analyze","optimize_suggest","optimize_report","sql_ddl","sql_navigation","sample_data","records_query","records_insert","records_update","types_list","types_describe","types_validate","translations_import","reorg_impact","reorg_preview"],"description":"Database operation. records_query is read-only; records_insert/records_update default to dryRun=true and require the matching single-use v2 preview token for persistence."},"deep":{"type":"boolean","description":"reorg_impact/reorg_preview only: run ISpecifierService.ImpactDatabase (specification, build-heavy) for the authoritative AnalysisResult. Default false (cheap timestamp heuristic)."},"name":{"type":"string","description":"Object/transaction/type name."},"trn":{"type":"string","description":"sample_data: Transaction name."},"transaction":{"type":"string","description":"records_*: root-level Transaction name."},"dataStore":{"type":"string","description":"records_*: existing active-environment datastore; defaults to the SDK default."},"where":{"type":"object","description":"records_query/update: equality filters only; update requires a filter."},"values":{"type":"object","description":"records_insert/update: typed attribute values."},"fields":{"type":"array","items":{"type":"string"},"description":"records_query: optional root-attribute projection."},"databaseManagedFields":{"type":"array","items":{"type":"string"},"description":"records_*: reviewed trigger-maintained fields; excludes keys and supplied values. Included in the preview token."},"limit":{"type":"integer","description":"records_query: 1-1000; default 100."},"expectedCount":{"type":"integer","description":"records_update: defaults to exactly one matched record."},"expectedVersion":{"type":"string","description":"records_*: v2 token from the matching write dry-run; query/v1 tokens cannot authorize writes."},"versionToken":{"type":"string","description":"records_*: alias of expectedVersion."},"dryRun":{"type":"boolean","default":true,"description":"records_insert/update: validate and reread the plan without writing."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"records_*: default true; validation failures roll back before commit. Post-commit compensation is refused to preserve concurrent writers."},"timeoutSeconds":{"type":"integer","description":"records_*: command timeout, 1-60 seconds."},"rows":{"type":"integer","description":"sample_data: 1-1000; default 5."},"includeSubordinated":{"type":"boolean","description":"sql_ddl only."},"levelNumber":{"type":"integer","description":"sql_navigation only."},"includeExecutionPlan":{"type":"boolean","description":"sql_navigation."},"includeIndexAdvisor":{"type":"boolean","description":"sql_navigation."},"format":{"type":"string","enum":["json","markdown"],"description":"optimize_report only."},"kind":{"type":"string","enum":["domain","sdt","all"],"description":"types_list filter."},"value":{"type":"string","description":"types_validate."},"type":{"type":"string","description":"types_validate / disambiguator."},"inputPath":{"type":"string","description":"translations_import: CSV path."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"drift_check"},{"action":"sql_ddl","name":"Customer"},{"action":"reorg_preview","name":"Customer","deep":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
42
|
-
{"name":"genexus_versioning","description":"Versioning umbrella. action: history_list|history_get|history_save|history_restore (snapshot store; restore+discard=true is IDE 'Discard changes' parity) | undo (revert last N edits) | time_travel (recover bytes from a past git commit) | blame (git blame an object part) | diff (text: mode=textVsText|currentVsText) | diff_generated (against=last-build|git-head).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["history_list","history_get","history_save","history_restore","undo","time_travel","blame","diff","diff_generated"],"description":"History, diff, time-travel, or rollback operation to perform."},"name":{"type":"string","description":"Object name for history, diff, time_travel, or blame."},"part":{"type":"string","description":"Object part name, e.g. Source, Rules, Events."},"versionId":{"type":"integer","description":"history_get/history_restore: numerical version ID."},"snapshot":{"type":"string","description":"history_restore: snapshot label or path to restore."},"discard":{"type":"boolean","description":"history_restore: true for IDE 'Discard changes' parity."},"dryRun":{"type":"boolean","description":"history_restore/undo: preview without mutating the KB."},"last":{"type":"integer","description":"undo: default 1, max 20."},"at":{"type":"string","description":"time_travel: ISO-8601 or commit sha."},"line":{"type":"integer","description":"blame: 1-based line number to annotate."},"filePath":{"type":"string","description":"blame: absolute or KB-relative file path."},"context":{"type":"integer","description":"blame: surrounding lines of context."},"mode":{"type":"string","enum":["textVsText","currentVsText"],"description":"diff."},"left":{"type":"string","description":"diff: left-side text or snapshot label."},"right":{"type":"string","description":"diff: right-side text or snapshot label."},"against":{"type":"string","enum":["last-build","git-head"],"description":"diff_generated."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"history_list","name":"Customer"},{"action":"time_travel","name":"Customer","at":"2026-05-20T10:00:00Z"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
42
|
+
{"name":"genexus_versioning","description":"Versioning umbrella. action: history_list|history_get|history_save|history_restore (snapshot store; restore+discard=true is IDE 'Discard changes' parity) | undo (revert last N edits) | time_travel (recover bytes from a past git commit) | blame (git blame an object part) | diff (text: mode=textVsText|currentVsText) | diff_generated (against=last-build|git-head).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["history_list","history_get","history_save","history_restore","undo","time_travel","blame","diff","diff_generated"],"description":"History, diff, time-travel, or rollback operation to perform."},"name":{"type":"string","description":"Object name for history, diff, time_travel, or blame."},"part":{"type":"string","description":"Object part name, e.g. Source, Rules, Events."},"partName":{"type":"string","description":"Legacy alias for part on history actions."},"versionId":{"type":"integer","description":"history_get/history_restore: numerical version ID."},"snapshot":{"type":"string","description":"history_restore: snapshot label or path to restore."},"discard":{"type":"boolean","description":"history_restore: true for IDE 'Discard changes' parity."},"dryRun":{"type":"boolean","description":"history_restore/undo: preview without mutating the KB."},"last":{"type":"integer","description":"undo: default 1, max 20."},"at":{"type":"string","description":"time_travel: ISO-8601 or commit sha."},"line":{"type":"integer","description":"blame: 1-based line number to annotate."},"filePath":{"type":"string","description":"blame: absolute or KB-relative file path."},"context":{"type":"integer","description":"blame: surrounding lines of context."},"mode":{"type":"string","enum":["textVsText","currentVsText"],"description":"diff."},"left":{"type":"string","description":"diff: left-side text or snapshot label."},"right":{"type":"string","description":"diff: right-side text or snapshot label."},"against":{"type":"string","enum":["last-build","git-head"],"description":"diff_generated."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"history_list","name":"Customer"},{"action":"time_travel","name":"Customer","at":"2026-05-20T10:00:00Z"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
43
43
|
{"name":"genexus_io","description":"IO umbrella for assets, Object Text exchange, screenshots, OCR. action: asset_find|asset_read|asset_write | export_part|import_part (single part) | export_kb_to_text|import_text_to_kb|validate_kb_text_files|delete_kb_objects (official GeneXus for Agents Object Text parity) | export_unified|screenshot_publish|ocr.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["asset_find","asset_read","asset_write","export_part","import_part","export_kb_to_text","import_text_to_kb","validate_kb_text_files","delete_kb_objects","export_unified","screenshot_publish","ocr"],"description":"Asset, single-part, batch Object Text, screenshot, or OCR operation."},"path":{"type":"string","description":"asset/screenshot_publish/ocr: file path; Object Text import/validate may use a manifest directory."},"name":{"type":"string","description":"single object name or comma-separated selector; export_unified uses one object."},"targets":{"type":"array","items":{},"description":"Object Text selector array. Items may be names or {name,type} objects. Omit for export_kb_to_text to export the full indexed KB."},"outputPath":{"type":"string","description":"export_part: destination file; export_kb_to_text: destination directory."},"inputPath":{"type":"string","description":"import_part: source file; import_text_to_kb/validate_kb_text_files: manifest or directory."},"part":{"type":"string","description":"Object Text or part-exchange part name (e.g. Source, Rules, WebForm)."},"type":{"type":"string","description":"Object type disambiguator/filter."},"module":{"type":"string","description":"Object Text module filter."},"pathPrefix":{"type":"string","description":"Object Text KB object-path prefix filter."},"overwrite":{"type":"boolean","description":"export_part/export_kb_to_text: overwrite existing output."},"confirm":{"type":"boolean","description":"delete_kb_objects: required for a real delete; dryRun remains non-mutating."},"dryRun":{"type":"boolean","description":"Object Text import/delete preview without persisting changes."},"async":{"type":"boolean","description":"Run a batch Object Text operation as a cancellable background job when supported."},"pattern":{"type":"string","description":"asset_find: glob pattern."},"relativeRoot":{"type":"string","description":"asset_find: root for relative paths."},"limit":{"type":"integer","description":"asset_find/Object Text: max results."},"includeContent":{"type":"boolean","description":"asset_find: inline file content."},"maxBytes":{"type":"integer","description":"asset_read: max bytes to return."},"contentBase64":{"type":"string","description":"asset_write: base64-encoded file content."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"export_kb_to_text","outputPath":"C:\\tmp\\customer-text","targets":[{"name":"Customer","type":"Transaction"}]},{"action":"validate_kb_text_files","inputPath":"C:\\tmp\\customer-text"},{"action":"delete_kb_objects","targets":["Procedure:OldProc"],"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
44
44
|
{"name":"genexus_variable","description":"Variables CRUD. add accepts varName or variables[] batch; modify changes type atomically. basedOn binds a Domain by native SDK identity. objectType=BusinessComponent with objectName+module binds a modular BC by EntityKey/GUID and verifies it after save. length/decimals override size; collection=true declares a collection; untyped add inherits a same-named attribute. dryRun validates and previews without mutation; async returns an operationId.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["add","delete","modify"],"description":"Variable-part operation to add, delete, or modify a variable."},"name":{"type":"string"},"varName":{"type":"string","description":"Single-variable form (add/delete/modify). For batch add use variables[] instead."},"variables":{"type":"array","description":"Batch add only: one object per variable — {varName, typeName?, length?, decimals?, collection?}. Added before a single save.","items":{"type":"object","required":["varName"],"properties":{"varName":{"type":"string"},"typeName":{"type":"string"},"length":{"type":"integer"},"decimals":{"type":"integer"},"collection":{"type":"boolean"},"basedOn":{"type":"string","description":"Domain name; native SDK reference."}}}},"typeName":{"type":"string","description":"Primitive (Character/Numeric/VarChar/Date/...), SDT/BC/Domain name, or WebSession. VarChar keeps VARCHAR semantics."},"objectType":{"type":"string","enum":["BusinessComponent"],"description":"add/modify: resolve an object-backed variable natively instead of interpreting typeName as a Domain."},"objectName":{"type":"string","description":"Business Component Transaction name, without module when module is passed separately."},"module":{"type":"string","description":"Module owning objectName. Required to disambiguate modular Business Components."},"expectedVersion":{"type":"string","description":"Optimistic-concurrency token for an object-backed add/modify. Stale state returns VersionConflict before mutation."},"length":{"type":"integer","description":"add/modify optional: overrides the length parsed from typeName."},"decimals":{"type":"integer","description":"add/modify optional: overrides decimals parsed from typeName."},"collection":{"type":"boolean","description":"add/modify optional: declare the variable as a collection."},"basedOn":{"type":"string","description":"modify optional: Domain."},"dryRun":{"type":"boolean","default":false,"description":"Validate and return the typed diff without changing any object, Attribute, hash, or version."},"validationMode":{"type":"string","enum":["specify"],"description":"Explicitly run the inline Specify pass after a legacy variable write. Never runs unless requested."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Object-backed variables always snapshot the complete owner and restore it on save/re-read divergence."},"async":{"type":"boolean","description":"Run as a background job. Result returns operationId/job_id for genexus_lifecycle polling."},"estimated_seconds":{"type":"integer","description":"When async=true, expected runtime used for progress/job metadata (default 30)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"add","name":"MyPanel","varName":"&Choice","typeName":"Numeric"},{"action":"add","name":"MyProc","varName":"&OrderRecord","objectType":"BusinessComponent","objectName":"OrderRecord","module":"Operations","dryRun":true},{"action":"add","name":"MyProc","variables":[{"varName":"&ApiKey","typeName":"VarChar","length":80},{"varName":"&CmdNro","typeName":"Numeric","length":9}]},{"action":"delete","name":"MyPanel","varName":"&OldVar"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
45
45
|
{"name":"genexus_telemetry","description":"Observability umbrella. action: executions (recent invocations) | watch_event (ops mentioning an event) | friction_append|friction_tail (.gx/friction.jsonl) | learning_report (aggregate friction) | logs (worker_debug.log tail) | profile_analyze|profile_hotspots|profile_correlate (GeneXus profiler XML).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["executions","watch_event","friction_append","friction_tail","learning_report","logs","profile_analyze","profile_hotspots","profile_correlate"],"description":"Telemetry, profiling, or friction-log operation to perform."},"target":{"type":"string","description":"executions/watch_event: object name to filter."},"event":{"type":"string","description":"watch_event: event name to match in operation payload."},"last":{"type":"integer","description":"executions/watch_event: max results."},"tool":{"type":"string","description":"friction_append: tool name that produced the friction entry."},"message":{"type":"string","description":"friction_append: description of the friction encountered."},"severity":{"type":"string","enum":["info","warn","error","critical"],"description":"friction_append: severity level."},"n":{"type":"integer","description":"friction_tail: number of recent lines to return."},"since":{"type":"string","description":"learning_report/logs: ISO-8601 start time filter."},"until":{"type":"string","description":"learning_report: ISO-8601 end time filter."},"tail":{"type":"integer","description":"logs: number of tail lines from worker_debug.log."},"filterCorrelation":{"type":"string","description":"logs: filter by correlation/operation ID."},"grep":{"type":"string","description":"logs: substring filter on log lines."},"path":{"type":"string","description":"profile_*: path to the GeneXus profiler XML file."},"top":{"type":"integer","description":"profile_hotspots: top-N hottest procedures to return."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"executions"},{"action":"friction_tail","n":20}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
|
|
@@ -51,6 +51,6 @@
|
|
|
51
51
|
{"name":"genexus_wwp","description":"Typed WorkWithPlus action, tab, grid, and native structural edits with dryRun, optimistic concurrency, exact snapshots, post-save reread, projection verification, and rollback. No lifecycle operation is implicit. Settings: embedded and separate WWP templates, paged reads and exact table-class dryRun; saves remain blocked.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","add_action","update_action","move_action","remove_action","add_tab","move_tab","remove_tab","add_grid_attribute","replace_web_component_with_user_action","settings_templates","settings_read","settings_edit"],"description":"WorkWithPlus action-group, tab, grid-attribute, or explicit native structural operation to perform."},"name":{"type":"string","description":"Transaction, WebPanel, or WorkWithPlus<Object> host."},"group":{"type":"string","description":"Action group name. add_action creates it when absent; update/remove use it as a filter."},"actionName":{"type":"string","description":"Action name."},"attribute":{"type":"string","description":"add_grid_attribute: GeneXus Attribute name."},"caption":{"type":"string","description":"Action caption. For a DropDownComponent pass the GeneXus expression used for the closed button, for example &Context.EmpresaDescricao."},"procedure":{"type":"string","description":"add/update: associated Procedure; existence is validated against the KB."},"selection":{"type":"string","enum":["single","multiple"],"description":"add/update: execution scope for grid actions."},"enabledWhen":{"type":"string","description":"Availability condition stored verbatim; expression semantics are not validated."},"icon":{"type":"string","description":"add/update: button icon."},"description":{"type":"string","description":"add/update: tooltip or description."},"confirm":{"type":"boolean","description":"Confirmation prompt; required to delete unless dryRun."},"buttonClass":{"type":"string","description":"add/update: theme button class."},"position":{"type":"integer","minimum":0,"description":"Zero-based action or tab index."},"toGroup":{"type":"string","description":"move_action: destination group (created when absent)."},"fromGroup":{"type":"string","description":"move_action: source group (optional; searched across groups when omitted)."},"dryRun":{"type":"boolean","description":"Return a typed diff and versionToken without mutation."},"controlName":{"type":"string","description":"Tab ControlName."},"title":{"type":"string","description":"add_tab: tab title."},"children":{"type":"array","description":"add_tab controls; flat children are wrapped in a responsive table.","items":{"$ref":"#/$defs/wwpControl"}},"sourceName":{"type":"string","description":"replace_web_component_with_user_action: existing WebComponent name."},"userActionName":{"type":"string","description":"replace_web_component_with_user_action: resulting UserAction name; defaults to sourceName."},"tablePath":{"type":"string","description":"replace_web_component_with_user_action: full breadcrumb including the source node, for example TableHeader > TableUserRole > EmpresaSelector."},"gxobject":{"type":"string","description":"replace_web_component_with_user_action: existing WebComponent Gxobject to retain; it must match the current node."},"controlType":{"type":"string","enum":["DropDownComponent"],"description":"replace_web_component_with_user_action: resulting UserAction ControlType."},"webComponentLoad":{"type":"string","enum":["On Web Panel load","On first click","On every click"],"description":"DropDownComponent load timing."},"trigger":{"type":"string","enum":["Click","Hover"],"description":"DropDownComponent trigger."},"baseVersion":{"type":"string","description":"Optimistic-concurrency token returned by dryRun/read."},"expectedVersion":{"type":"string","description":"Alias for baseVersion."},"versionToken":{"type":"string","description":"Backward-compatible alias for baseVersion."},"kb":{"type":"string","description":"KB alias."},"template":{"description":"Settings catalog path, wwp:<template-guid>, or unique template name.","type":"string"},"limit":{"type":"integer","minimum":0,"description":"Settings nodes per page; offset=0, limit=0 includes full separate-template XML."},"guid":{"type":"string","description":"Pattern Settings object GUID for settings_* actions."},"nodePath":{"description":"Settings node path returned by settings_read.","type":"string"},"entityKey":{"type":"string"},"value":{"type":"string"},"property":{"description":"Exact SDK property name.","type":"string"},"offset":{"minimum":0,"type":"integer"}},"$defs":{"wwpControl":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["variable","userAction","table"]},"name":{"type":"string"},"caption":{"type":"string"},"description":{"type":"string"},"basicType":{"type":"string"},"length":{"type":"integer","minimum":1},"decimals":{"type":"integer","minimum":0},"controlType":{"type":"string"},"controlValues":{"type":"string"},"controlEmptyItem":{"type":"boolean"},"controlEmptyItemText":{"type":"string"},"columns":{"type":"integer","minimum":1},"themeClass":{"type":"string"},"children":{"type":"array","items":{"$ref":"#/$defs/wwpControl"}}},"additionalProperties":false}},"examples":[{"action":"list","name":"SampleOrderWW"},{"action":"add_action","name":"SampleOrderWW","group":"Operations","actionName":"Retry","procedure":"RetrySampleOrder","selection":"multiple","dryRun":true},{"action":"add_tab","name":"SamplePanel","controlName":"Details","title":"Details","children":[{"type":"variable","name":"Status","basicType":"VarChar","length":40},{"type":"userAction","name":"Refresh","caption":"Refresh"}],"dryRun":true},{"action":"add_grid_attribute","name":"SampleOrderWW","attribute":"SampleOrderStatus","caption":"Status","dryRun":true},{"action":"replace_web_component_with_user_action","name":"WorkWithPlusWorkWithPlusMasterPage","sourceName":"EmpresaSelector","userActionName":"EmpresaSelector","tablePath":"TableHeader > TableUserRole > EmpresaSelector","gxobject":"WWP_MasterPageEmpresaSelectorWC","controlType":"DropDownComponent","caption":"&Context.EmpresaDescricao","webComponentLoad":"On every click","trigger":"Click","dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
|
|
52
52
|
{"name":"genexus_kb_diff","description":"Gateway-only filesystem comparison of two KB directories. Requires kbA and kbB aliases or paths; no active KB selection is used.","inputSchema":{"type":"object","required":["kbA","kbB"],"properties":{"kbA":{"type":"string"},"kbB":{"type":"string"}},"examples":[{"kbA":"development","kbB":"staging"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
|
|
53
53
|
{"name":"genexus_kb_import","description":"Gateway-only filesystem copy of one object between two KB directories. Requires source and object identity; run lifecycle index afterwards.","inputSchema":{"type":"object","required":["from","name","type"],"properties":{"from":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"to":{"type":"string"}},"examples":[{"from":"C:\\KBs\\source","to":"C:\\KBs\\target","name":"Customer","type":"Transaction"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
|
|
54
|
-
{"name":"genexus_sandbox","description":"Gateway-only filesystem sandbox management; clone or remove a KB directory without SDK dispatch.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["create","remove"]},"name":{"type":"string"},"from":{"type":"string"},"overwrite":{"type":"boolean"}},"examples":[{"action":"create","name":"probe","from":"C:\\KBs\\base"},{"action":"remove","name":"probe"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
|
|
55
|
-
{"name":"genexus_worker_pool","description":"Gateway-only worker-pool warm-spare configuration. Does not require a KB selection or dispatch to the Worker.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["warm_spares"]},"spareCount":{"type":"integer"},"count":{"type":"integer"}},"examples":[{"action":"warm_spares","spareCount":1}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}}
|
|
54
|
+
{"name":"genexus_sandbox","description":"Gateway-only filesystem sandbox management; clone or remove a KB directory without SDK dispatch.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["create","remove"],"description":"Sandbox operation to create or remove a KB directory."},"name":{"type":"string"},"from":{"type":"string"},"overwrite":{"type":"boolean"}},"examples":[{"action":"create","name":"probe","from":"C:\\KBs\\base"},{"action":"remove","name":"probe"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
|
|
55
|
+
{"name":"genexus_worker_pool","description":"Gateway-only worker-pool warm-spare configuration. Does not require a KB selection or dispatch to the Worker.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["warm_spares"],"description":"Worker-pool operation to warm spare workers."},"spareCount":{"type":"integer"},"count":{"type":"integer"}},"examples":[{"action":"warm_spares","spareCount":1}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}}
|
|
56
56
|
]
|
|
Binary file
|