genexus-mcp 2.57.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -183,6 +183,7 @@ Once installed, here's what unlocks. Try these as your first prompts:
183
183
  - *"Add a menu option 'Customers' to MainMenu that opens CustomerWW."*
184
184
 
185
185
  **WorkWithPlus pattern editing** (full structural + theming control)
186
+ - *"Add a typed tab with variables, an action, and nested responsive tables to a WorkWithPlus WebPanel."*
186
187
  - *"In WorkWithPlusOrder, add a 'Duplicate' button to the transaction view alongside Save/Cancel/Delete."*
187
188
  - *"Group the Customer transaction attributes into a 'Contact Info' section with theme class GroupTelaResp."*
188
189
  - *"On the WorkWithPlusInvoice list, add a new ordering by InvoiceDate descending."*
@@ -217,25 +218,17 @@ Auto-detected and auto-configured by the installer:
217
218
  | OpenCode (CLI) | ✅ | Reads both direct and nested MCP layouts; restart required |
218
219
  | Codex CLI | ✅ | Writes `~/.codex/config.toml` |
219
220
  | VS Code / VS Code Insiders | ✅ | Native MCP (`User/mcp.json`); restart required |
220
- | OpenCode Desktop | Manual setup | Detected and reported with exact local-server fields; add the server from the app's MCP settings |
221
+ | OpenCode Desktop | ✅ | Shares `opencode.jsonc` with OpenCode CLI; restart required |
221
222
  | Any MCP client | Manual | Use the JSON snippet printed by `init` |
222
223
 
223
224
  Run **`npx genexus-mcp clients`** at any time to see which agents are installed, which have `genexus` registered, and whether any point at a stale gateway exe. To (re)register specific ones: `npx genexus-mcp clients add --clients antigravity,vscode`.
224
225
 
225
- ### OpenCode Desktop (manual setup)
226
+ ### OpenCode Desktop
226
227
 
227
- The CLI detects OpenCode Desktop but does not write its app-managed `mcp.json`.
228
- After `init` prints the path to `config.json`, open **Settings → MCP → Add server
229
- → Local** in OpenCode Desktop and enter:
230
-
231
- - Name: `genexus18mcp`
232
- - Command: `npx.cmd` on Windows, `npx` elsewhere
233
- - Arguments: `-y genexus-mcp@latest`
234
- - Environment: `GX_CONFIG_PATH=<the config.json path printed by init>`
235
-
236
- Save the server, fully restart OpenCode Desktop, and call `genexus_whoami` to
237
- verify the GeneXus server and selected KB. The CLI intentionally leaves the
238
- Desktop-managed configuration file untouched.
228
+ OpenCode Desktop shares its MCP configuration file (`opencode.jsonc` or `opencode.json`)
229
+ with OpenCode CLI. Running `genexus-mcp init --write-clients` or `genexus-mcp clients add --clients opencode-desktop`
230
+ automatically registers `genexus18mcp` in the shared config. After registration,
231
+ fully restart OpenCode Desktop so it reloads its MCP configuration.
239
232
 
240
233
  ---
241
234
 
@@ -313,7 +306,7 @@ produced by `DataSelectorStructurePart.ToString()` on U16.
313
306
  **Refactor, patterns & compare**
314
307
  - `genexus_refactor` — rename, extract procedure, WWP condition set
315
308
  - `genexus_apply_pattern` — apply a GeneXus pattern (WorkWith, WorkWithPlus, …); `mode=actions` manages typed WorkWithPlus grid actions and Action Groups
316
- - `genexus_wwp` — WorkWithPlus Action Group / grid-action editing: `list`, `add_action`, `update_action`, `move_action`, `remove_action`
309
+ - `genexus_wwp` — typed WorkWithPlus editing: Action Groups, atomic native `add_grid_attribute`, plus `add_tab`, `move_tab`, and `remove_tab` for WebPanel tabs and typed children
317
310
  - `genexus_compare` — IDE "Compare Objects" parity (`IComparerService`)
318
311
  - `genexus_merge` — 2- or 3-way object merge (`IMergeService`)
319
312
 
@@ -324,7 +317,7 @@ produced by `DataSelectorStructurePart.ToString()` on U16.
324
317
  - `genexus_security` — audit KB security: `audit_gam` (env/GAM props), `scan_secrets` (regex over Source), `scan_native` (the SDK's own Security Scanner, `ISecurityScannerService`)
325
318
 
326
319
  **Lifecycle, build, test & DB**
327
- - `genexus_lifecycle` — build (incl. `compile_check`), validate, index, reorg, poll status
320
+ - `genexus_lifecycle` — directed `build` (incl. `compile_check`), incremental global `build_all`, forced global `rebuild`, validate, index, reorg, and poll status
328
321
  - `genexus_test` — run native GXtest tests
329
322
  - `genexus_db` — DB umbrella: schema-drift, `sql_ddl`/`sql_navigation`, static index advisor, `sample_data`, typed Transaction record query/insert/update with dry-run, optimistic versioning, reread and verified rollback, Domain/SDT type introspection, translation import, `reorg_impact`, and non-mutating `reorg_preview` with exact DDL only from a current Impact Analysis artifact
330
323
  - `genexus_deploy` — deploy application (`IDeploymentService`): `list_targets` (read) / `deploy` (destructive, `confirm=true`)
@@ -378,6 +371,8 @@ WorkWithPlus patterns are XML documents that drive Transaction-and-Selection scr
378
371
  | Reorganize Transaction view (form layout, action row) | edit under `/instance/transaction/...` | ✅ verified live |
379
372
  | Reorganize Selection view (list/grid, filters, orders) | edit under `/instance/level/selection/...` | ✅ verified live |
380
373
  | Auto-rebuild `childrenOrderedList` from XML order | done implicitly on every write; report under `childrenOrderedListReconciliation` | ✅ verified live |
374
+ | Add / move / remove WebPanel tabs and typed controls | `genexus_wwp` `add_tab` / `move_tab` / `remove_tab` | ✅ native Pattern SDK commands; snapshot + re-read + WebForm projection verification |
375
+ | Add or reconcile one grid Attribute caption | `genexus_wwp` `add_grid_attribute` | ✅ isolated dry-run, full PatternInstance/WebForm snapshots, exact rollback and no implicit lifecycle |
381
376
 
382
377
  **Recommended workflow for a screen redesign:**
383
378
 
@@ -389,6 +384,25 @@ WorkWithPlus patterns are XML documents that drive Transaction-and-Selection scr
389
384
 
390
385
  **Custom buttons use `<userAction>`, not `<standardAction>`.** `Trn_Enter` / `Trn_Cancel` / `Trn_Delete` are the only registered standard actions on a WorkWithPlus transaction; any custom button (Duplicate, Audit, Export, etc.) must be a `<userAction caption="…" name="…" buttonClass="btn ButtonGreen" confirm="False" />`. The MCP's reconciler treats `<userAction>` as a peer of `<standardAction>` (same typeCode 17/18 by context), so they coexist in the same `TableActions` row and the IDE renders them side-by-side.
391
386
 
387
+ For WebPanel tabs, prefer the native typed operation instead of whole-XML replacement:
388
+
389
+ ```json
390
+ {
391
+ "action": "add_tab",
392
+ "name": "SamplePanel",
393
+ "controlName": "IntegrationV3",
394
+ "title": "Integration API V3",
395
+ "position": 5,
396
+ "children": [
397
+ { "type": "variable", "name": "Operation", "basicType": "VarChar", "length": 40 },
398
+ { "type": "userAction", "name": "SendIntegration", "caption": "Send" }
399
+ ],
400
+ "dryRun": true
401
+ }
402
+ ```
403
+
404
+ The dry-run returns a typed diff and `versionToken`. Pass it as `baseVersion` on the persisted call. The write uses Pattern SDK element commands, requires exact PatternInstance/WebForm snapshots, preserves Apply-on-save, re-reads the PatternInstance, projects and re-reads the parent WebForm, and rolls both parts back on any failed confirmation. It never invokes lifecycle operations.
405
+
392
406
  **Things to know (orientation, not gotchas):**
393
407
 
394
408
  - **WorkWithPlus normalizes some attributes after every save.** Certain fields are bound to the underlying transaction (e.g., `title` on top-level groups derives from the transaction's friendly name). When `"Apply this pattern on save"` is enabled on the WorkWithPlus object, the engine recomputes those fields — same behavior whether you edit in the IDE or via MCP. To make a hard override stick, toggle that flag via MCP:
@@ -498,7 +512,7 @@ When the pool is full and no Worker is idle, the server returns `KB_POOL_FULL`
498
512
 
499
513
  ```mermaid
500
514
  graph LR
501
- A[AI Client / Nexus-IDE] -->|MCP stdio or HTTP /mcp| B[Gateway .NET 8]
515
+ A[AI Client / Nexus-IDE] -->|MCP stdio or HTTP /mcp| B[Gateway .NET 10]
502
516
  B -->|JSON-RPC over process boundary| C[Worker .NET Framework 4.8]
503
517
  C -->|Native SDK| D[GeneXus KB]
504
518
  ```
package/cli/lib/config.js CHANGED
@@ -650,13 +650,9 @@ function getClientConfigTargets() {
650
650
  {
651
651
  id: 'opencode-desktop',
652
652
  name: 'OpenCode Desktop',
653
- // Detect-only: the Desktop app's MCP config schema differs from the CLI
654
- // and isn't auto-written yet. We report it so the user knows it's there
655
- // and how to wire it up, but never mutate its config blindly.
656
- format: 'manual',
657
- writeSupported: false,
658
- manualNote: 'OpenCode Desktop manual setup: Settings > MCP > Add server > Local; name genexus18mcp; command npx.cmd on Windows (npx elsewhere); args -y genexus-mcp@latest; environment GX_CONFIG_PATH=<config.json path printed by init>; save, fully restart the app, then call genexus_whoami. The CLI does not write the app-managed Desktop mcp.json.',
659
- path: path.join(appData, 'ai.opencode.desktop', 'mcp.json'),
653
+ format: 'opencode',
654
+ path: resolveOpenCodeConfigPath(xdgConfig),
655
+ detectByMarkerOnly: true,
660
656
  installMarkers: [
661
657
  path.join(localAppData, 'Programs', '@opencode-aidesktop'),
662
658
  path.join(appData, 'ai.opencode.desktop'),
@@ -693,8 +689,9 @@ function detectClientInstalled(client) {
693
689
  break;
694
690
  }
695
691
  }
692
+ const installed = client.detectByMarkerOnly ? (markerHit !== null) : (hasConfig || markerHit !== null);
696
693
  return {
697
- installed: hasConfig || markerHit !== null,
694
+ installed,
698
695
  hasConfig,
699
696
  markerHit,
700
697
  markersChecked: markers
@@ -808,9 +805,8 @@ function patchClientConfig(targetConfigPath, opts = {}) {
808
805
  platform: process.platform
809
806
  });
810
807
 
811
- // A direct gateway path only matters to clients that can be written. A
812
- // detect-only client such as OpenCode Desktop must still receive manual
813
- // setup guidance when its app-managed config is not detectable.
808
+ // A direct gateway path only matters to clients that can be written. Any
809
+ // detect-only client must still receive manual setup guidance when not writable.
814
810
  const writableCandidates = candidates.filter((client) =>
815
811
  client.writeSupported !== false
816
812
  && (!onlyExisting || detectClientInstalled(client).installed)
@@ -831,7 +827,7 @@ function patchClientConfig(targetConfigPath, opts = {}) {
831
827
  const skipped = [];
832
828
 
833
829
  for (const client of candidates) {
834
- // Detect-only agents (e.g. OpenCode Desktop) can't be auto-written; surface
830
+ // Detect-only agents can't be auto-written; surface
835
831
  // the manual step instead of pretending we registered them.
836
832
  if (client.writeSupported === false) {
837
833
  const detection = detectClientInstalled(client);
package/cli/run.test.js CHANGED
@@ -791,7 +791,7 @@ test('clients list returns structured status with summary', () => {
791
791
  assert.equal(typeof row.registered, 'boolean');
792
792
  });
793
793
 
794
- test('clients list reports OpenCode Desktop as manual with exact setup fields', () => {
794
+ test('clients list reports OpenCode Desktop with shared opencode config', () => {
795
795
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-status-'));
796
796
  try {
797
797
  const env = sandboxHomeEnv(tempRoot);
@@ -803,70 +803,85 @@ test('clients list reports OpenCode Desktop as manual with exact setup fields',
803
803
  assert.ok(row, 'OpenCode Desktop should be listed');
804
804
  assert.equal(row.installed, true);
805
805
  assert.equal(row.registered, false);
806
- assert.equal(row.writeSupported, false);
807
- assert.equal(row.registrationMode, 'manual');
808
- assert.equal(row.manualSetup.transport, 'local');
809
- assert.deepEqual(row.manualSetup.args, ['-y', 'genexus-mcp@latest']);
810
- assert.equal(row.manualSetup.environment.GX_CONFIG_PATH, '<config.json path printed by genexus-mcp init>');
811
- assert.ok(row.manualSetup.steps.some((step) => step.includes('genexus_whoami')));
812
- assert.match(row.note, /does not write/i);
806
+ assert.equal(row.writeSupported, true);
807
+ assert.equal(row.registrationMode, 'automatic');
808
+ assert.equal(row.manualSetup, null);
809
+ assert.equal(row.note, null);
810
+ assert.equal(row.configPath, path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json'));
811
+
812
+ // When the shared opencode.jsonc has the server registered, Desktop is recognized as registered
813
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.jsonc');
814
+ fs.mkdirSync(path.dirname(opencodeCfg), { recursive: true });
815
+ fs.writeFileSync(opencodeCfg, JSON.stringify({
816
+ mcp: {
817
+ genexus18mcp: {
818
+ type: 'local',
819
+ command: ['npx.cmd', '-y', 'genexus-mcp@latest'],
820
+ environment: { GX_CONFIG_PATH: 'C:\\test\\config.json' }
821
+ }
822
+ }
823
+ }, null, 2));
824
+
825
+ const resultRegistered = runCli(['clients', '--format', 'json'], { env });
826
+ assert.equal(resultRegistered.status, 0);
827
+ const rowRegistered = JSON.parse(resultRegistered.stdout).ok.clients.find((client) => client.id === 'opencode-desktop');
828
+ assert.equal(rowRegistered.installed, true);
829
+ assert.equal(rowRegistered.registered, true);
830
+ assert.equal(rowRegistered.command, 'npx.cmd');
831
+ assert.equal(rowRegistered.configPath, opencodeCfg);
832
+ assert.equal(rowRegistered.registrationMode, 'automatic');
813
833
  } finally {
814
834
  fs.rmSync(tempRoot, { recursive: true, force: true });
815
835
  }
816
836
  });
817
837
 
818
- test('clients add reports OpenCode Desktop manual skip without mutating its app-managed file', () => {
838
+ test('clients add patches OpenCode Desktop into shared opencode config', () => {
819
839
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-add-'));
820
840
  try {
821
841
  const env = sandboxHomeEnv(tempRoot);
822
842
  const cfgPath = path.join(tempRoot, 'config.json');
823
843
  const desktopDir = path.join(env.APPDATA, 'ai.opencode.desktop');
824
- const desktopConfig = path.join(desktopDir, 'mcp.json');
825
- const original = { unrelated: { keep: true } };
826
844
  fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
827
845
  fs.mkdirSync(desktopDir, { recursive: true });
828
- fs.writeFileSync(desktopConfig, JSON.stringify(original, null, 2));
829
846
 
830
847
  const result = runCli(['clients', 'add', '--clients', 'opencode-desktop', '--format', 'json'], {
831
848
  env: { ...env, GX_CONFIG_PATH: cfgPath }
832
849
  });
833
850
  assert.equal(result.status, 0);
834
851
  const parsed = JSON.parse(result.stdout);
835
- assert.deepEqual(parsed.ok.patchedClients, []);
836
- const skipped = parsed.meta.skippedClients.find((entry) => entry.client === 'OpenCode Desktop');
837
- assert.ok(skipped && /Settings > MCP|manual setup/i.test(skipped.reason));
838
- assert.equal(skipped.registrationMode, 'manual');
839
- assert.equal(skipped.installed, true);
840
- assert.equal(skipped.manualSetup.environment.GX_CONFIG_PATH, cfgPath);
841
- assert.ok(parsed.help.some((entry) => /manual setup/i.test(entry)));
842
- assert.deepEqual(JSON.parse(fs.readFileSync(desktopConfig, 'utf8')), original);
852
+ assert.ok(parsed.ok.patchedClients.includes('OpenCode Desktop'));
853
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json');
854
+ assert.ok(fs.existsSync(opencodeCfg), 'shared opencode config should be created');
855
+ const written = JSON.parse(fs.readFileSync(opencodeCfg, 'utf8'));
856
+ assert.ok(written.mcp.genexus18mcp, 'shared config should contain genexus18mcp entry');
857
+ assert.equal(written.mcp.genexus18mcp.environment.GX_CONFIG_PATH, cfgPath);
858
+
859
+ const listRes = runCli(['clients', '--format', 'json'], { env });
860
+ const row = JSON.parse(listRes.stdout).ok.clients.find((client) => client.id === 'opencode-desktop');
861
+ assert.ok(row && row.registered, 'OpenCode Desktop should now report registered');
843
862
  } finally {
844
863
  fs.rmSync(tempRoot, { recursive: true, force: true });
845
864
  }
846
865
  });
847
866
 
848
- test('clients add always reports undetected OpenCode Desktop manual setup', () => {
867
+ test('OpenCode Desktop is not falsely reported as installed when only CLI config exists', () => {
849
868
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-undetected-'));
850
869
  try {
851
870
  const env = sandboxHomeEnv(tempRoot);
852
- const cfgPath = path.join(tempRoot, 'config.json');
853
- fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
871
+ const opencodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.jsonc');
872
+ fs.mkdirSync(path.dirname(opencodeCfg), { recursive: true });
873
+ fs.writeFileSync(opencodeCfg, JSON.stringify({ mcp: {} }));
854
874
 
855
- const result = runCli(['clients', 'add', '--clients', 'opencode-desktop', '--format', 'json'], {
856
- env: {
857
- ...env,
858
- GX_CONFIG_PATH: cfgPath,
859
- GENEXUS_MCP_GATEWAY_EXE: path.join(tempRoot, 'missing', 'GxMcp.Gateway.exe')
860
- }
861
- });
875
+ const result = runCli(['clients', '--format', 'json'], { env });
862
876
  assert.equal(result.status, 0);
863
877
  const parsed = JSON.parse(result.stdout);
864
- assert.deepEqual(parsed.ok.patchedClients, []);
865
- const skipped = parsed.meta.skippedClients.find((entry) => entry.client === 'OpenCode Desktop');
866
- assert.ok(skipped, 'undetected detect-only client should still be actionable');
867
- assert.equal(skipped.installed, false);
868
- assert.equal(skipped.manualSetup.environment.GX_CONFIG_PATH, cfgPath);
869
- assert.equal(skipped.manualSetup.command, process.platform === 'win32' ? 'npx.cmd' : 'npx');
878
+ const desktopRow = parsed.ok.clients.find((client) => client.id === 'opencode-desktop');
879
+ assert.ok(desktopRow, 'OpenCode Desktop should be present in targets');
880
+ assert.equal(desktopRow.installed, false, 'Desktop must not be detected installed without its install markers');
881
+
882
+ const cliRow = parsed.ok.clients.find((client) => client.id === 'opencode');
883
+ assert.ok(cliRow, 'OpenCode CLI should be present in targets');
884
+ assert.equal(cliRow.installed, true, 'OpenCode CLI is detected installed via config file');
870
885
  } finally {
871
886
  fs.rmSync(tempRoot, { recursive: true, force: true });
872
887
  }
@@ -1133,6 +1148,31 @@ test('init auto-registers detected OpenCode in either config layout', () => {
1133
1148
  }
1134
1149
  });
1135
1150
 
1151
+ test('init auto-registers detected OpenCode Desktop when its marker is present', () => {
1152
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-init-'));
1153
+ try {
1154
+ const env = sandboxHomeEnv(tempRoot);
1155
+ const kbDir = path.join(tempRoot, 'kb');
1156
+ fs.mkdirSync(kbDir, { recursive: true });
1157
+ fs.mkdirSync(path.join(env.APPDATA, 'ai.opencode.desktop'), { recursive: true });
1158
+
1159
+ const result = runCli(
1160
+ ['init', '--kb', kbDir, '--gx', testGxPath, '--no-smoke', '--format', 'json'],
1161
+ { cwd: kbDir, env: { ...env, ...testGatewayEnv } }
1162
+ );
1163
+ assert.equal(result.status, 0, `init should succeed: ${result.stderr}`);
1164
+
1165
+ const parsed = JSON.parse(result.stdout);
1166
+ assert.ok(parsed.meta.patchedClients.includes('OpenCode Desktop'));
1167
+ const openCodeCfg = path.join(env.XDG_CONFIG_HOME, 'opencode', 'opencode.json');
1168
+ assert.ok(fs.existsSync(openCodeCfg));
1169
+ const written = JSON.parse(fs.readFileSync(openCodeCfg, 'utf8'));
1170
+ assert.ok(written.mcp.genexus18mcp);
1171
+ } finally {
1172
+ fs.rmSync(tempRoot, { recursive: true, force: true });
1173
+ }
1174
+ });
1175
+
1136
1176
  test('clients add replaces a legacy genexus18 entry instead of duplicating it', () => {
1137
1177
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-legacy-'));
1138
1178
  const env = sandboxHomeEnv(tempRoot);
@@ -124,6 +124,13 @@ Follow-up flow:
124
124
 
125
125
  Do not treat timeout as hard failure when `operationId` is present.
126
126
 
127
+ For a complete incremental build of the selected Knowledge Base, use
128
+ `genexus_lifecycle(action='build_all')` without `target`. It runs the native
129
+ `BuildAll` task when available, reports completion evidence, and returns
130
+ `ReorgRequired` instead of applying a schema reorganization implicitly. Use
131
+ `action='build'` for a directed target and `action='rebuild'` for the forced
132
+ Rebuild All contract.
133
+
127
134
  ## Pagination and Token Budgeting
128
135
 
129
136
  Read/list defaults are intentionally broad for humans, but not for LLMs.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genexus-mcp",
3
- "version": "2.57.0",
3
+ "version": "3.0.1",
4
4
  "mcpName": "io.github.lennix1337/genexus",
5
5
  "description": "GeneXus 18 MCP server — read, edit, and analyze GeneXus knowledge base objects (transactions, web panels, procedures, SDTs) directly from Claude, Cursor, and other AI agents over the Model Context Protocol.",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  "win32"
51
51
  ],
52
52
  "engines": {
53
- "node": ">=18.0.0"
53
+ "node": ">=22.0.0"
54
54
  },
55
55
  "author": "lennix1337",
56
56
  "license": "MIT",
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "runtimeTarget": {
3
- "name": ".NETCoreApp,Version=v8.0/win-x64",
3
+ "name": ".NETCoreApp,Version=v10.0/win-x64",
4
4
  "signature": ""
5
5
  },
6
6
  "compilationOptions": {},
7
7
  "targets": {
8
- ".NETCoreApp,Version=v8.0": {},
9
- ".NETCoreApp,Version=v8.0/win-x64": {
10
- "GxMcp.Gateway/2.57.0": {
8
+ ".NETCoreApp,Version=v10.0": {},
9
+ ".NETCoreApp,Version=v10.0/win-x64": {
10
+ "GxMcp.Gateway/3.0.1": {
11
11
  "dependencies": {
12
12
  "Newtonsoft.Json": "13.0.3",
13
13
  "System.Management": "10.0.5",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "System.CodeDom/10.0.5": {
29
29
  "runtime": {
30
- "lib/net8.0/System.CodeDom.dll": {
30
+ "lib/net10.0/System.CodeDom.dll": {
31
31
  "assemblyVersion": "10.0.0.0",
32
32
  "fileVersion": "10.0.526.15411"
33
33
  }
@@ -38,7 +38,7 @@
38
38
  "System.CodeDom": "10.0.5"
39
39
  },
40
40
  "runtime": {
41
- "runtimes/win/lib/net8.0/System.Management.dll": {
41
+ "runtimes/win/lib/net10.0/System.Management.dll": {
42
42
  "assemblyVersion": "10.0.0.5",
43
43
  "fileVersion": "10.0.526.15411"
44
44
  }
@@ -49,7 +49,7 @@
49
49
  "System.Windows.Extensions": "10.0.3"
50
50
  },
51
51
  "runtime": {
52
- "lib/net8.0/System.Security.Permissions.dll": {
52
+ "lib/net10.0/System.Security.Permissions.dll": {
53
53
  "assemblyVersion": "10.0.0.0",
54
54
  "fileVersion": "10.0.326.7603"
55
55
  }
@@ -57,7 +57,7 @@
57
57
  },
58
58
  "System.Windows.Extensions/10.0.3": {
59
59
  "runtime": {
60
- "runtimes/win/lib/net8.0/System.Windows.Extensions.dll": {
60
+ "runtimes/win/lib/net10.0/System.Windows.Extensions.dll": {
61
61
  "assemblyVersion": "10.0.0.0",
62
62
  "fileVersion": "10.0.326.7603"
63
63
  }
@@ -66,7 +66,7 @@
66
66
  }
67
67
  },
68
68
  "libraries": {
69
- "GxMcp.Gateway/2.57.0": {
69
+ "GxMcp.Gateway/3.0.1": {
70
70
  "type": "project",
71
71
  "serviceable": false,
72
72
  "sha512": ""
Binary file
Binary file
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "runtimeOptions": {
3
- "tfm": "net8.0",
3
+ "tfm": "net10.0",
4
4
  "frameworks": [
5
5
  {
6
6
  "name": "Microsoft.NETCore.App",
7
- "version": "8.0.0"
7
+ "version": "10.0.0"
8
8
  },
9
9
  {
10
10
  "name": "Microsoft.AspNetCore.App",
11
- "version": "8.0.0"
11
+ "version": "10.0.0"
12
12
  }
13
13
  ],
14
14
  "configProperties": {
Binary file
Binary file
Binary file
@@ -2,16 +2,16 @@
2
2
  "Environment": {
3
3
  "KBPath": "C:\\\\KBs\\\\YourKB"
4
4
  },
5
+ "GeneXus": {
6
+ "WorkerExecutable": "worker\\\\GxMcp.Worker.exe",
7
+ "InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18"
8
+ },
5
9
  "Logging": {
6
- "Path": "logs",
7
- "Level": "Debug"
10
+ "Level": "Debug",
11
+ "Path": "logs"
8
12
  },
9
13
  "Server": {
10
14
  "HttpPort": 5000,
11
15
  "McpStdio": true
12
- },
13
- "GeneXus": {
14
- "InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18",
15
- "WorkerExecutable": "worker\\\\GxMcp.Worker.exe"
16
16
  }
17
17
  }
@@ -0,0 +1,47 @@
1
+ {
2
+ "schemaVersion": "gxmcp-release-manifest/1",
3
+ "version": "3.0.1",
4
+ "sourceCommit": "16737be62b087071a46744b64fb406ae1c092d1c",
5
+ "sourceCommitPolicy": "exact-tag",
6
+ "generatedAtUtc": "2026-09-07T15:00:21.7001814Z",
7
+ "runtime": {
8
+ "gateway": "net10.0-windows",
9
+ "worker": "net48-x86",
10
+ "node": ">=22.0.0",
11
+ "recommendedNode": "24 LTS"
12
+ },
13
+ "protocolVersions": [
14
+ "2025-11-25",
15
+ "2026-07-28"
16
+ ],
17
+ "schema": "tool_definitions.json",
18
+ "schemaSha256": "98f4680e9da9505db5be670e3562002a114bbcfd2bf56703ce1d7424abb431aa",
19
+ "provenance": "gxmcp-sbom.json",
20
+ "artifacts": [
21
+ {
22
+ "path": "gxmcp-sbom.json",
23
+ "size": 590,
24
+ "sha256": "de0f58d64013a142aced1f70041f14d615bef52e80fec702308fedbe20645c7c"
25
+ },
26
+ {
27
+ "path": "GxMcp.Gateway.exe",
28
+ "size": 162304,
29
+ "sha256": "10612de14e9bf693ffbebb2d4dacfd9f4964978be3a839ecc1d2a27655b79b78"
30
+ },
31
+ {
32
+ "path": "nexus-ide.vsix",
33
+ "size": 1318668,
34
+ "sha256": "d119604573da301222e78694a73cc18dd82ac86cba6b5eac5c891f3a45a1294e"
35
+ },
36
+ {
37
+ "path": "tool_definitions.json",
38
+ "size": 104391,
39
+ "sha256": "98f4680e9da9505db5be670e3562002a114bbcfd2bf56703ce1d7424abb431aa"
40
+ },
41
+ {
42
+ "path": "worker/GxMcp.Worker.exe",
43
+ "size": 2848768,
44
+ "sha256": "0ec449681a26738a247a52e8f50e13bd203311a3acf34ca7868b22d150f31554"
45
+ }
46
+ ]
47
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "schemaVersion": "gxmcp-provenance/1",
3
+ "version": "3.0.1",
4
+ "sourceCommit": "16737be62b087071a46744b64fb406ae1c092d1c",
5
+ "sourceCommitPolicy": "exact-tag",
6
+ "components": [
7
+ {
8
+ "name": "genexus-mcp",
9
+ "lockfile": "package-lock.json",
10
+ "size": 39914,
11
+ "sha256": "417f4f5e2cf75646bf5a3cb2eed8d454553b6ddcec617bc81daf63f8f40a060a"
12
+ },
13
+ {
14
+ "name": "nexus-ide",
15
+ "lockfile": "src/nexus-ide/package-lock.json",
16
+ "size": 274983,
17
+ "sha256": "11d8e03bfc38157c3621315a56ed9f5dbe7c1410c3e9765da13326005eeb4fdb"
18
+ }
19
+ ]
20
+ }
Binary file
@@ -5,12 +5,12 @@
5
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}},
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","items":{"type":"object","properties":{"name":{"type":"string"},"content":{"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."},"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."}},"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}},
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."},"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
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 preserves the legacy compatibility envelope and returns NotImplemented until a typed code explanation is available. 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"]},"format":{"type":"string","enum":["json","ascii"],"description":"mode=dependency_heatmap: ascii adds rendered bar chart."},"kb":{"type":"string","description":"KB alias."},"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":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
11
- {"name":"genexus_lifecycle","description":"Build, validate, index, or poll the KB. action=specify runs a spec-check (Spec+Gen only, no Compile/deploy) returning spc*/gen* diagnostics for the target fast (catch spec errors without a full build). action=build with mode=compile_check spec+gen+compiles the target(s) PLUS their transitive callers and skips the KB-wide DeveloperMenu regen (the dominant build-all cost) -- a fast 'did my edit break the build?' check that requires a target. Long ops are async with operationId. dryRun=true (build/rebuild/index) returns the build plan or index plan without executing. Build results carry generateEvidence + effective_status=SucceededWithGaps when a Succeeded build emitted no fresh .cs (don't trust Status=Succeeded alone); a 2nd concurrent build is refused (BuildAlreadyRunning). See genexus://kb/tool-help/genexus_lifecycle for the build-evidence checklist, actions, and target formats.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["build","cancel","specify","rebuild","reorg","reorg_preview","validate","validate-kb","sync","index","status","result","snapshots-list","snapshots-restore"],"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')."},"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/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/rebuild/index: returns the plan (object list / index entries) 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."}},"required":["action"],"examples":[{"action":"build"},{"action":"status","target":"op:abc123"},{"action":"build","mode":"compile_check","target":"MyObject"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"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 preserves the legacy compatibility envelope and returns NotImplemented until a typed code explanation is available. 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 to carry through the compatibility envelope."},"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":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
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":"Dump SDK surface (types/methods/props) to docs/sdk-probe/. Use when hunting for entry points.","inputSchema":{"type":"object","properties":{"outputDir":{"type":"string","description":"Absolute path. Default <repo>/docs/sdk-probe/."}},"examples":[{}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
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":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
14
14
  {"name":"genexus_worker_reload","description":"Reload worker. modes: soft (drain+respawn), hard (copy sourceDir+respawn). force=true: gateway kills directly. See tool-help.","inputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["soft","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}},
@@ -25,8 +25,8 @@
25
25
  {"name":"genexus_doc","description":"Use to generate structured docs (wiki, dependency graph, health reports). Don't use for programmatic analysis (see genexus_analyze) or source (see genexus_read).","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["wiki","visualize","health"],"description":"wiki: generate markdown docs; visualize: generate dependency graph; health: produce health report."},"target":{"type":"string","description":"Object or domain name (required for wiki/visualize)."}},"required":["action"],"examples":[{"action":"wiki","target":"Customer"},{"action":"health"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
26
26
  {"name":"genexus_search_source","description":"Regex/semantic search across Procedure/DataProvider/WebPanel/Transaction source. Restrict a scan by object name, persisted GUID, EntityKey, or module/folder-qualified path. Requires the KB index to be Ready — check genexus_lifecycle action=status if results look empty.","inputSchema":{"type":"object","properties":{"callee":{"type":"string","description":"Method/function name (qualified or unqualified)."},"argMatches":{"type":"object","description":"Positional arg index to expected literal text."},"pattern":{"type":"string"},"typeFilter":{"type":"string"},"objectName":{"type":"string","description":"Restrict the scan to these exact object name(s), comma-separated. Makes a search inside one known object O(object) not O(KB), and bypasses the type whitelist."},"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."},"startIndex":{"type":"integer","description":"Legacy object-boundary resume. For a page that ended inside an object, prefer the opaque cursor returned in nextCursor."},"cursor":{"type":"string","description":"Opaque continuation token from nextCursor; preferred when a result page ended inside an object. Do not edit."},"timeoutMs":{"type":"integer","description":"Wall-clock budget (default 30000). Raise it to scan more objects per call."},"scope":{"type":"array","items":{"type":"string","enum":["source","rules","conditions","events","webForm","layout"]},"description":"Parts to scan with line-numbered context. Default [source]. webForm/layout scans the WebPanel/Transaction visual XML (control names, captions, classes, bindings)."},"fields":{"type":"array","items":{"type":"string","enum":["source","caption","description","parmNames","webForm"]},"description":"Whole-field metadata match (returns matchedValue, no line context). Default [source]. Prefer scope=[webForm] for line-context WebForm hits; use fields=[webForm] only for a coarse contains-match."},"maxResults":{"type":"integer"},"caseSensitive":{"type":"boolean"},"includeComments":{"type":"boolean"},"inline_read_top":{"type":"integer","description":"0-3. Inline reads of top N distinct objects in response."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"pattern":"ControlType=\"Radio\""},{"pattern":"for each","typeFilter":"Procedure","maxResults":20}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
27
27
  {"name":"genexus_kb","description":"Manage open KBs, startup config, and GeneXus environments. list/open/close/set_default operate on WorkerPool; set_default selects the implicit target for calls that omit kb (an explicit kb always wins for parallel or cross-KB work); set_startup/get_startup mirror IDE 'Set As Startup Object'; list_environments lists all configured environments; get_environment reads the active environment; set_environment selects an environment.","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["list","open","close","set_default","set_startup","get_startup","list_environments","get_environment","set_environment"],"description":"KB pool or startup-selection operation to perform."},"alias":{"type":"string","description":"KB alias. open: auto from path basename if omitted."},"path":{"type":"string","description":"Absolute KB path (required for open if alias not in config)."},"name":{"type":"string","description":"Object name (required for set_startup)."},"environment":{"type":"string","description":"Environment name/folder (required for set_environment), e.g. development."}},"required":["action"],"examples":[{"action":"open","path":"C:\\KBs\\MyKb"},{"action":"list"},{"action":"list_environments"},{"action":"get_environment"},{"action":"set_environment","environment":"development"}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
28
- {"name":"genexus_navigation","description":"View navigation report (IDE Right-click → View Navigation). latest=true reads the most recent report from .gx/navigation-cache; latest=false runs fresh and refreshes that per-KB cache.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["view"],"description":"Navigation report operation to execute."},"name":{"type":"string"},"latest":{"type":"boolean","default":false,"description":"Read the most recent cached navigation when true; when false, run fresh and refresh the per-KB navigation cache."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"view","name":"Customer"},{"action":"view","name":"Customer","latest":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
29
- {"name":"genexus_api","description":"Inspect HTTP procedures and native API routes. action=list|describe|routes_inspect|routes_clone|routes_update|snapshot|diff_baseline. API route writes use typed ServiceGroupSource, optimistic versioning, full snapshot, rollback and post-save reread; no lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","describe","routes_inspect","routes_clone","routes_update","snapshot","diff_baseline"],"description":"API introspection, route-editing, or baseline operation to perform."},"api":{"type":"string","description":"API name (routes_inspect|routes_clone|routes_update)."},"sourcePrefix":{"type":"string","description":"Source method/path prefix, e.g. inbound."},"targetPrefix":{"type":"string","description":"Target method/path prefix, e.g. reverse."},"routes":{"type":"array","items":{"type":"object","required":["sourceMethod","method","route"],"additionalProperties":false,"properties":{"sourceMethod":{"type":"string"},"method":{"type":"string"},"route":{"type":"string","pattern":"^/"},"verb":{"type":"string"}}}},"expectedVersion":{"type":"string","description":"versionToken returned by the preceding dry run or inspection."},"dryRun":{"type":"boolean","default":true,"description":"routes_clone/routes_update: preview first; false writes only with expectedVersion."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore the complete API snapshot when post-save verification diverges."},"operation":{"type":"string","description":"Operation value carried by the reused request contract, e.g. REVERSE."},"target":{"type":"string","description":"Procedure or API name (action=describe)."},"name":{"type":"string","description":"Baseline name (action=snapshot)."},"baseline":{"type":"string","description":"Baseline name under .gx/api-baselines/ or absolute path (action=diff_baseline)."},"pathPrefix":{"type":"string","description":"Folder prefix filter (action=list)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"routes_inspect","api":"OrdersApi"},{"action":"routes_clone","api":"OrdersApi","sourcePrefix":"inbound","targetPrefix":"reverse","operation":"REVERSE","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
28
+ {"name":"genexus_navigation","description":"View navigation report (IDE Right-click → View Navigation). latest=true reads the most recent report from .gx/navigation-cache; latest=false runs fresh and refreshes that per-KB cache.","inputSchema":{"type":"object","required":["action","name"],"properties":{"action":{"type":"string","enum":["view"],"description":"Navigation report operation to execute."},"name":{"type":"string"},"latest":{"type":"boolean","default":false,"description":"Read the most recent cached navigation when true; when false, run fresh and refresh the per-KB navigation cache."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"view","name":"Customer"},{"action":"view","name":"Customer","latest":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
29
+ {"name":"genexus_api","description":"Inspect HTTP procedures and native API routes. action=list|describe|routes_inspect|routes_clone|routes_update|snapshot|diff_baseline. API route writes use typed ServiceGroupSource, optimistic versioning, full snapshot, rollback and post-save reread; no lifecycle operation is implicit.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","describe","routes_inspect","routes_clone","routes_update","snapshot","diff_baseline"],"description":"API introspection, route-editing, or baseline operation to perform."},"api":{"type":"string","description":"API name (routes_inspect|routes_clone|routes_update)."},"sourcePrefix":{"type":"string","description":"Source method/path prefix, e.g. inbound."},"targetPrefix":{"type":"string","description":"Target method/path prefix, e.g. reverse."},"routes":{"type":"array","items":{"type":"object","required":["sourceMethod","method","route"],"additionalProperties":false,"properties":{"sourceMethod":{"type":"string"},"method":{"type":"string"},"route":{"type":"string","pattern":"^/"},"verb":{"type":"string"}}}},"expectedVersion":{"type":"string","description":"versionToken returned by the preceding dry run or inspection."},"versionToken":{"type":"string","description":"Backward-compatible alias for expectedVersion; pass the token returned by the preceding dry run or inspection."},"dryRun":{"type":"boolean","default":true,"description":"routes_clone/routes_update: preview first; false writes only with expectedVersion or versionToken."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore the complete API snapshot when post-save verification diverges."},"operation":{"type":"string","description":"Operation value carried by the reused request contract, e.g. REVERSE."},"target":{"type":"string","description":"Procedure or API name (action=describe)."},"name":{"type":"string","description":"Baseline name (action=snapshot)."},"baseline":{"type":"string","description":"Baseline name under .gx/api-baselines/ or absolute path (action=diff_baseline)."},"pathPrefix":{"type":"string","description":"Folder prefix filter (action=list)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list"},{"action":"routes_inspect","api":"OrdersApi"},{"action":"routes_clone","api":"OrdersApi","sourcePrefix":"inbound","targetPrefix":"reverse","operation":"REVERSE","dryRun":true,"rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
30
30
  {"name":"genexus_apply_pattern","description":"Apply a pattern (e.g. WorkWithPlus) to a parent (IDE Right-click → Apply Pattern). Transaction=family-gen; WebPanel/WebComponent/SDPanel=direct-attach (pass settings.template). mode=diagnose (or dryRun=true) returns findings without mutating. Working on Smart Devices? → resources/read uri=genexus://kb/skills/sd-panel-mobile for Main object semantics. mode=actions manages typed grid actions and Action Groups, persists and re-reads PatternInstance, supports dryRun diff, and never adds security permissions automatically.","inputSchema":{"type":"object","required":["name","pattern"],"properties":{"name":{"type":"string","description":"Target KBObject name."},"pattern":{"type":"string","description":"Pattern key ('WorkWithPlus') or GUID."},"mode":{"type":"string","enum":["apply","diagnose","actions"],"description":"apply (default) mutates; diagnose returns reasons without applying. actions exposes typed WWP action-group editing."},"action":{"type":"string","enum":["list_actions","add_grid_action","update_action","move_action","remove_action"],"description":"mode=actions operation."},"group":{"type":"string","description":"Action group name (e.g. TableActions)."},"actionName":{"type":"string","description":"Name of the action to add, update, or remove."},"newGroup":{"type":"string","description":"move_action: destination action group."},"position":{"type":"integer","minimum":0,"description":"zero-based index among actions in group."},"procedure":{"type":"string","description":"Target Procedure to execute on action click."},"selection":{"type":"string","enum":["current","multiple"],"description":"Execution scope: current (single record) or multiple."},"enabledWhen":{"type":"string","description":"Condition expression for action enablement."},"visibleWhen":{"type":"string","description":"Condition expression for action visibility."},"icon":{"type":"string","description":"Action icon name or class."},"description":{"type":"string","description":"Action tooltip / description text."},"confirmation":{"type":"string","description":"Confirmation message prompt."},"confirmTitle":{"type":"string","description":"Confirmation dialog title."},"settings":{"type":"object","description":"Pattern-instance settings tree."},"reapply":{"type":"boolean","default":false,"description":"Re-run on existing instance."},"validate":{"type":"boolean","default":false,"description":"After apply, build the generated host. Adds validation block (60-180s). Catches binding errors."},"dryRun":{"type":"boolean","default":false,"description":"Alias for mode=diagnose. When true, returns pattern findings without mutating. With mode=actions it previews the typed action diff."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"name":"Customer","pattern":"WorkWithPlus"},{"name":"Customer","pattern":"WorkWithPlus","mode":"diagnose"},{"name":"Customer","pattern":"WorkWithPlus","mode":"actions","action":"add_grid_action","group":"Actions","actionName":"Approve","procedure":"ApproveCustomer","dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
31
31
  {"name":"genexus_edit_and_build","description":"Edit + rebuild callers in one call. Returns edit diff + impact + a build block that may include taskId/pollTarget for lifecycle follow-up. validate=true/validationMode=specify validates the saved object; rollbackOnFailure restores its pre-write snapshot on specification failure.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Target object name."},"part":{"type":"string","description":"Part (Source, Rules, ...)."},"content":{"type":"string","description":"New content. For mode=patch may be {find,replace} object."},"patch":{"description":"Same shape as genexus_edit.patch. Auto-sets mode=patch."},"mode":{"type":"string","enum":["full","patch"],"default":"patch"},"type":{"type":"string","description":"Disambiguates ambiguous names."},"dryRun":{"type":"boolean","default":false},"validate":{"type":"boolean","default":false},"validationMode":{"type":"string","enum":["specify"],"default":"specify"},"rollbackOnFailure":{"type":"boolean","default":true},"buildIncludeCallees":{"type":"string","enum":["none","direct","transitive"],"default":"direct"},"buildPlanCap":{"type":"integer","default":200},"waitForIndex":{"type":"boolean","default":true},"waitTimeoutMs":{"type":"integer","default":30000},"visualVerify":{"type":"boolean","default":false,"description":"Post-edit headless screenshot + pixel-diff vs baseline. See tool-help."}},"required":["name","part"],"examples":[{"name":"Customer","part":"Source","patch":{"find":"oldValue","replace":"newValue"},"validate":true},{"name":"Customer","part":"Rules","mode":"patch","patch":{"find":"error(","replace":"msg("},"dryRun":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false}},
32
32
  {"name":"genexus_security","description":"Audit KB security. action=audit_gam scans GAM/env props; action=scan_secrets greps Source for credential-shaped literals; action=scan_native drives the native GeneXus Security Scanner (ISecurityScannerService). Returns findings with severity.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["audit_gam","scan_secrets","scan_native"],"description":"audit_gam: scans GAM and environment properties; scan_secrets: greps Source for credentials; scan_native: drives native GeneXus Security Scanner."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"audit_gam"},{"action":"scan_secrets"}]},"annotations":{"readOnlyHint":true,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false}},
@@ -48,5 +48,5 @@
48
48
  {"name":"genexus_transfer","description":"Real XPZ export/import over the SDK's IKnowledgeManagerService — dependency-aware, IDE Export/Import parity (NOT the filesystem copy genexus_io/kb_import do). action=export (targets[]+outputFile; includeDependencies=true exports transitive closure) | inspect (explore an .xpz, read-only) | import (apply into KB; dryRun defaults true=preview via ExploreExport; dryRun=false requires confirm=true).","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["export","inspect","import"],"description":"XPZ export, inspection, or import operation to perform."},"targets":{"type":"array","items":{"type":"string"},"description":"export: object names to export."},"outputFile":{"type":"string","description":"export: absolute .xpz output path."},"includeDependencies":{"type":"boolean","description":"export: compute transitive dependency closure (Calls, Tables) and export all referenced objects.","default":false},"file":{"type":"string","description":"inspect/import: absolute .xpz path."},"type":{"type":"string","description":"export: disambiguate object type."},"dryRun":{"type":"boolean","description":"import: true (default) previews; false applies (needs confirm)."},"confirm":{"type":"boolean","description":"import with dryRun=false: required."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"export","targets":["Customer"],"outputFile":"C:\\tmp\\cust.xpz"},{"action":"export","targets":["Customer"],"outputFile":"C:\\tmp\\cust_full.xpz","includeDependencies":true},{"action":"inspect","file":"C:\\tmp\\cust.xpz"}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
49
49
  {"name":"genexus_deploy","description":"Deploy application over the SDK. action=list_targets (read-only, default) enumerates deployment target types (IDeploymentTargetService); action=deploy (destructive, confirm=true) runs IDeploymentService.Deploy(model).","inputSchema":{"type":"object","properties":{"action":{"type":"string","enum":["list_targets","deploy"],"description":"Deployment-target or deployment execution operation to perform."},"confirm":{"type":"boolean","description":"deploy: required (builds + ships the app)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list_targets"},{"action":"deploy","confirm":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}},
50
50
  {"name":"genexus_generator_reference","description":"Native typed .NET generator references used by GxExternalReference. list and dry-run actions are read-only. add/remove validate a managed assembly when a path is supplied, require optimistic baseVersion for changes, save only the native GeneratorsPart, reread it, and restore the complete generator-property snapshot on verification failure. No lifecycle action runs implicitly.","inputSchema":{"type":"object","additionalProperties":false,"required":["action","environment","generator"],"properties":{"action":{"type":"string","enum":["list","dry_run_add","add","dry_run_remove","remove"],"description":"Typed .NET generator-reference operation to perform."},"environment":{"type":"string","description":"Active GeneXus Environment name; the tool never switches environments."},"generator":{"type":"string","description":"Generator display name, e.g. Default (.NET)."},"assembly":{"type":"string","description":"Assembly file name for add/remove, e.g. SpreadsheetLibrary.dll."},"assemblyPath":{"type":"string","description":"Absolute path or KB-relative path used to validate a managed assembly. Required for add unless found in a standard model/bin location."},"baseVersion":{"type":"string","description":"Optimistic token returned by list or a dry-run. Required for a real state change."},"dryRun":{"type":"boolean","default":false,"description":"Force add/remove to remain read-only."},"rollbackOnFailure":{"type":"boolean","default":true,"description":"Restore and verify the complete prior generator-property snapshot if save/reread diverges."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list","environment":".Net Environment","generator":"Default (.NET)"},{"action":"dry_run_add","environment":".Net Environment","generator":"Default (.NET)","assembly":"SpreadsheetLibrary.dll","assemblyPath":"C:\\KBs\\Sample\\CSharpModel\\web\\bin\\SpreadsheetLibrary.dll"},{"action":"add","environment":".Net Environment","generator":"Default (.NET)","assembly":"SpreadsheetLibrary.dll","assemblyPath":"C:\\KBs\\Sample\\CSharpModel\\web\\bin\\SpreadsheetLibrary.dll","baseVersion":"sha256:<token>","rollbackOnFailure":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":true,"openWorldHint":false}},
51
- {"name":"genexus_wwp","description":"WorkWithPlus Action Group / grid-action editing (issue #58). action=list (read-only) lists the PatternInstance's action containers and their <userAction>/<standardAction> children; add_action adds a custom userAction to an existing or new group (procedure existence verified, selection single|multiple, enabledWhen condition, icon, description, confirm, position); update_action changes those attributes; move_action relocates an action between groups or reorders it; remove_action deletes an action (confirm=true). dryRun=true returns the XML diff without persisting. Edits target the WorkWithPlus host's PatternInstance XML (survives pattern reapply). NEVER creates Security/GAM permissions. Attributes are passed verbatim to the WWP XML; the SDK's own save normalization is reported honestly via the pattern write verification.","inputSchema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["list","add_action","update_action","move_action","remove_action"],"description":"WorkWithPlus action-group or grid-action operation to perform."},"name":{"type":"string","description":"Transaction, WebPanel, or WorkWithPlus<Object> host."},"group":{"type":"string","description":"Action group/container name (TableActions row). add_action: creates a new group when absent; update/remove: scope filter."},"actionName":{"type":"string","description":"Action name (e.g. 'Reativar')."},"caption":{"type":"string","description":"add/update: button caption (defaults to actionName)."},"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":"add/update: availability condition text (e.g. 'MonitorIntegracaoStatus = DSituacaoProcessamento.Suspenso'). Stored verbatim; expression semantics are not validated."},"icon":{"type":"string","description":"add/update: button icon."},"description":{"type":"string","description":"add/update: tooltip/description."},"confirm":{"type":"boolean","description":"add/update: confirmation prompt; remove_action: required to delete (unless dryRun)."},"buttonClass":{"type":"string","description":"add/update: theme button class (e.g. 'btn ButtonCinza')."},"position":{"type":"integer","description":"add/move/update: zero-based index among the group's actions."},"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 the XML diff without persisting (default false)."},"kb":{"type":"string","description":"KB alias."}},"examples":[{"action":"list","name":"MonitorIntegracaoWW"},{"action":"add_action","name":"MonitorIntegracaoWW","group":"Processamento","actionName":"Reativar","procedure":"MonitorIntegracaoReativar","selection":"multiple","enabledWhen":"MonitorIntegracaoStatus = DSituacaoProcessamento.Suspenso","dryRun":true},{"action":"remove_action","name":"MonitorIntegracaoWW","actionName":"Reativar","confirm":true}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}}
51
+ {"name":"genexus_wwp","description":"Typed WorkWithPlus action, tab, and grid edits with dryRun, optimistic concurrency, exact snapshots, post-save reread, projection verification, and rollback. No lifecycle operation is implicit.","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"],"description":"WorkWithPlus action-group, tab, or grid-attribute 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 or grid-column caption."},"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"}},"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."}},"$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}]},"annotations":{"readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false}}
52
52
  ]
Binary file
@@ -11,11 +11,25 @@ const path = require('path');
11
11
 
12
12
  const pkgRoot = path.join(__dirname, '..');
13
13
 
14
+ const packageVersion = (() => {
15
+ try {
16
+ return require(path.join(pkgRoot, 'package.json')).version || '0.0.0';
17
+ } catch {
18
+ return '0.0.0';
19
+ }
20
+ })();
21
+ const packageMajor = Number.parseInt(packageVersion.split('.')[0], 10) || 0;
22
+
14
23
  const required = [
15
24
  'publish/GxMcp.Gateway.exe',
16
25
  'publish/worker/GxMcp.Worker.exe',
26
+ 'publish/tool_definitions.json',
17
27
  ];
18
28
 
29
+ if (packageMajor >= 3) {
30
+ required.push('publish/gxmcp-manifest.json');
31
+ }
32
+
19
33
  const missing = required.filter((rel) => {
20
34
  try {
21
35
  return !fs.statSync(path.join(pkgRoot, rel)).isFile();
@@ -25,7 +39,7 @@ const missing = required.filter((rel) => {
25
39
  });
26
40
 
27
41
  if (missing.length === 0) {
28
- console.log('genexus-mcp: gateway + worker binaries verified.');
42
+ console.log(`genexus-mcp: Gateway, Worker, schema${packageMajor >= 3 ? ', and v3 manifest' : ''} verified.`);
29
43
  process.exit(0);
30
44
  }
31
45