genexus-mcp 2.56.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -8
- package/cli/commands/axi.js +3 -0
- package/cli/lib/config.js +55 -13
- package/cli/run.test.js +106 -0
- package/docs/llm_cli_mcp_playbook.md +7 -0
- package/package.json +2 -2
- package/publish/GxMcp.Gateway.deps.json +9 -9
- package/publish/GxMcp.Gateway.dll +0 -0
- package/publish/GxMcp.Gateway.exe +0 -0
- package/publish/GxMcp.Gateway.runtimeconfig.json +3 -3
- package/publish/Newtonsoft.Json.dll +0 -0
- package/publish/System.CodeDom.dll +0 -0
- package/publish/System.Management.dll +0 -0
- package/publish/System.Security.Permissions.dll +0 -0
- package/publish/System.Windows.Extensions.dll +0 -0
- package/publish/config.json +4 -4
- package/publish/gxmcp-manifest.json +46 -0
- package/publish/gxmcp-sbom.json +19 -0
- package/publish/nexus-ide.vsix +0 -0
- package/publish/tool_definitions.json +52 -52
- package/publish/worker/GxMcp.Worker.exe +0 -0
- package/scripts/verify-install.js +15 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ In practice: you point the MCP at your KB, then ask your AI assistant things lik
|
|
|
20
20
|
|
|
21
21
|
## What you can do with it
|
|
22
22
|
|
|
23
|
-
A quick map of what the agent can do against your real KB through the **
|
|
23
|
+
A quick map of what the agent can do against your real KB through the **50 tools** (details in [Tool Surface](#tool-surface)):
|
|
24
24
|
|
|
25
25
|
| Area | What the agent can do |
|
|
26
26
|
|---|---|
|
|
@@ -199,7 +199,7 @@ Once installed, here's what unlocks. Try these as your first prompts:
|
|
|
199
199
|
- *"Build the KB and report any errors."*
|
|
200
200
|
- *"Run the unit tests and show me which failed."*
|
|
201
201
|
|
|
202
|
-
The agent picks the right tool from the **
|
|
202
|
+
The agent picks the right tool from the **50 tools** the MCP exposes (read, edit, refactor, analyze, build, data-model authoring, layout automation, DB/DDL, versioning, security, SQL preview, etc.). The full tool list is in [Tool Surface](#tool-surface) below.
|
|
203
203
|
|
|
204
204
|
---
|
|
205
205
|
|
|
@@ -217,11 +217,26 @@ Auto-detected and auto-configured by the installer:
|
|
|
217
217
|
| OpenCode (CLI) | ✅ | Reads both direct and nested MCP layouts; restart required |
|
|
218
218
|
| Codex CLI | ✅ | Writes `~/.codex/config.toml` |
|
|
219
219
|
| VS Code / VS Code Insiders | ✅ | Native MCP (`User/mcp.json`); restart required |
|
|
220
|
-
| OpenCode Desktop |
|
|
220
|
+
| OpenCode Desktop | Manual setup | Detected and reported with exact local-server fields; add the server from the app's MCP settings |
|
|
221
221
|
| Any MCP client | Manual | Use the JSON snippet printed by `init` |
|
|
222
222
|
|
|
223
223
|
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
224
|
|
|
225
|
+
### OpenCode Desktop (manual setup)
|
|
226
|
+
|
|
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.
|
|
239
|
+
|
|
225
240
|
---
|
|
226
241
|
|
|
227
242
|
## Troubleshooting
|
|
@@ -251,7 +266,7 @@ Still stuck? [Open an issue](https://github.com/lennix1337/Genexus18MCP/issues)
|
|
|
251
266
|
|
|
252
267
|
## Tool Surface
|
|
253
268
|
|
|
254
|
-
The worker exposes **
|
|
269
|
+
The worker exposes **50 tools** to the MCP router, grouped by capability below. Most are umbrellas with an `action` (e.g. `genexus_db action=sql_ddl`); the detailed schemas live in [`src/GxMcp.Gateway/tool_definitions.json`](src/GxMcp.Gateway/tool_definitions.json).
|
|
255
270
|
|
|
256
271
|
**Orientation & health**
|
|
257
272
|
- `genexus_whoami` — KB context, version, worker/index/database health, self-update check, next-step hints
|
|
@@ -304,14 +319,14 @@ produced by `DataSelectorStructurePart.ToString()` on U16.
|
|
|
304
319
|
|
|
305
320
|
**Analysis, docs & API**
|
|
306
321
|
- `genexus_analyze` — cross-object semantic analysis (impact, dependencies, complexity, naming, code_metrics, summary, explain, `kb_stats` = KB activity/freshness, `table_relations` = table↔transaction relations + redundant attrs, …)
|
|
307
|
-
- `genexus_doc` — generate wiki /
|
|
322
|
+
- `genexus_doc` — generate wiki / dependency graphs / health reports
|
|
308
323
|
- `genexus_api` — introspect REST endpoints exposed by HTTP procedures
|
|
309
324
|
- `genexus_security` — audit KB security: `audit_gam` (env/GAM props), `scan_secrets` (regex over Source), `scan_native` (the SDK's own Security Scanner, `ISecurityScannerService`)
|
|
310
325
|
|
|
311
326
|
**Lifecycle, build, test & DB**
|
|
312
|
-
- `genexus_lifecycle` — build (incl. `compile_check`), validate, index, reorg, poll status
|
|
327
|
+
- `genexus_lifecycle` — directed `build` (incl. `compile_check`), incremental global `build_all`, forced global `rebuild`, validate, index, reorg, and poll status
|
|
313
328
|
- `genexus_test` — run native GXtest tests
|
|
314
|
-
- `genexus_db` — DB umbrella: schema-drift, `sql_ddl`/`sql_navigation`, static index advisor, `sample_data`, Domain/SDT type introspection, translation import, `reorg_impact`, and non-mutating `reorg_preview` with exact DDL only from a current Impact Analysis artifact
|
|
329
|
+
- `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
|
|
315
330
|
- `genexus_deploy` — deploy application (`IDeploymentService`): `list_targets` (read) / `deploy` (destructive, `confirm=true`)
|
|
316
331
|
- `genexus_run_object` / `genexus_browser` — resolve runtime URL and headless-browser verification
|
|
317
332
|
|
|
@@ -483,7 +498,7 @@ When the pool is full and no Worker is idle, the server returns `KB_POOL_FULL`
|
|
|
483
498
|
|
|
484
499
|
```mermaid
|
|
485
500
|
graph LR
|
|
486
|
-
A[AI Client / Nexus-IDE] -->|MCP stdio or HTTP /mcp| B[Gateway .NET
|
|
501
|
+
A[AI Client / Nexus-IDE] -->|MCP stdio or HTTP /mcp| B[Gateway .NET 10]
|
|
487
502
|
B -->|JSON-RPC over process boundary| C[Worker .NET Framework 4.8]
|
|
488
503
|
C -->|Native SDK| D[GeneXus KB]
|
|
489
504
|
```
|
package/cli/commands/axi.js
CHANGED
|
@@ -1857,6 +1857,9 @@ async function handleClients(subcommand, options, ctx) {
|
|
|
1857
1857
|
}
|
|
1858
1858
|
const help = [];
|
|
1859
1859
|
if (patch.patched.length > 0) help.push('Restart the affected AI client(s) to load the new MCP config.');
|
|
1860
|
+
if (patch.skipped.some((entry) => entry.registrationMode === 'manual')) {
|
|
1861
|
+
help.push('Some selected clients require manual setup; use meta.skippedClients[].manualSetup for the exact command and environment.');
|
|
1862
|
+
}
|
|
1860
1863
|
if (patch.failed.some((f) => f.reason && f.reason.includes('third-party or HTTP MCP server'))) {
|
|
1861
1864
|
help.push('A collision with an existing MCP server (e.g. official GeneXus MCP) was detected.');
|
|
1862
1865
|
help.push('Use --server-name=<customName> (e.g. --server-name Gx18byLennix) or pass --force.');
|
package/cli/lib/config.js
CHANGED
|
@@ -655,7 +655,7 @@ function getClientConfigTargets() {
|
|
|
655
655
|
// and how to wire it up, but never mutate its config blindly.
|
|
656
656
|
format: 'manual',
|
|
657
657
|
writeSupported: false,
|
|
658
|
-
manualNote: 'OpenCode Desktop:
|
|
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
659
|
path: path.join(appData, 'ai.opencode.desktop', 'mcp.json'),
|
|
660
660
|
installMarkers: [
|
|
661
661
|
path.join(localAppData, 'Programs', '@opencode-aidesktop'),
|
|
@@ -728,6 +728,27 @@ function clientCommandHealth(entry, client = null) {
|
|
|
728
728
|
return { stale: false, reason: null };
|
|
729
729
|
}
|
|
730
730
|
|
|
731
|
+
function buildManualClientSetup(client, targetConfigPath = null) {
|
|
732
|
+
return {
|
|
733
|
+
mode: 'manual',
|
|
734
|
+
managedConfigPath: client.path,
|
|
735
|
+
serverName: DEFAULT_MCP_SERVER_NAME,
|
|
736
|
+
transport: 'local',
|
|
737
|
+
command: process.platform === 'win32' ? 'npx.cmd' : 'npx',
|
|
738
|
+
args: ['-y', 'genexus-mcp@latest'],
|
|
739
|
+
environment: {
|
|
740
|
+
GX_CONFIG_PATH: targetConfigPath || '<config.json path printed by genexus-mcp init>'
|
|
741
|
+
},
|
|
742
|
+
steps: [
|
|
743
|
+
'Open OpenCode Desktop settings and select MCP.',
|
|
744
|
+
'Choose Add server, select Local, and enter the server name genexus18mcp.',
|
|
745
|
+
'Set the command, arguments, and GX_CONFIG_PATH environment value shown above.',
|
|
746
|
+
'Save the server and fully restart OpenCode Desktop so it reloads MCP configuration.',
|
|
747
|
+
'Call genexus_whoami to verify the GeneXus server and selected KB.'
|
|
748
|
+
]
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
|
|
731
752
|
// Read-only report of every supported agent on this platform: is it installed,
|
|
732
753
|
// is genexus registered, where, what launcher command it points at, and whether
|
|
733
754
|
// that command is stale. Backs the `genexus-mcp clients` command.
|
|
@@ -747,6 +768,7 @@ function clientsStatus(opts = {}) {
|
|
|
747
768
|
name: client.name,
|
|
748
769
|
installed: det.installed,
|
|
749
770
|
registered: entry !== null,
|
|
771
|
+
registrationMode: client.writeSupported === false ? 'manual' : 'automatic',
|
|
750
772
|
serverName,
|
|
751
773
|
isThirdParty: Boolean(isThirdParty),
|
|
752
774
|
writeSupported: client.writeSupported !== false,
|
|
@@ -756,7 +778,8 @@ function clientsStatus(opts = {}) {
|
|
|
756
778
|
commandStale: health.stale,
|
|
757
779
|
commandStaleReason: health.reason || (isThirdParty ? 'configured as third-party / HTTP MCP server (e.g. official GeneXus MCP)' : null),
|
|
758
780
|
detectedAt: det.markerHit || (det.hasConfig ? client.path : null),
|
|
759
|
-
note: client.writeSupported === false ? (client.manualNote || null) : null
|
|
781
|
+
note: client.writeSupported === false ? (client.manualNote || null) : null,
|
|
782
|
+
manualSetup: client.writeSupported === false ? buildManualClientSetup(client) : null
|
|
760
783
|
};
|
|
761
784
|
});
|
|
762
785
|
}
|
|
@@ -777,15 +800,6 @@ function patchClientConfig(targetConfigPath, opts = {}) {
|
|
|
777
800
|
// Validate corporate-install env var before we write it into N client configs.
|
|
778
801
|
// Otherwise we silently propagate a broken path to every AI client and the
|
|
779
802
|
// user only finds out when each one fails with "Failed to connect".
|
|
780
|
-
if (process.env.GENEXUS_MCP_GATEWAY_EXE && !fs.existsSync(process.env.GENEXUS_MCP_GATEWAY_EXE)) {
|
|
781
|
-
const err = new Error(
|
|
782
|
-
`GENEXUS_MCP_GATEWAY_EXE points to a path that does not exist: ${process.env.GENEXUS_MCP_GATEWAY_EXE}. ` +
|
|
783
|
-
`Refusing to write this into client configs. Unset the env var (to use the npx launcher) or re-run scripts/install.ps1 to materialize the exe.`
|
|
784
|
-
);
|
|
785
|
-
err.code = 'GATEWAY_EXE_MISSING';
|
|
786
|
-
throw err;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
803
|
const serverName = opts.serverName || DEFAULT_MCP_SERVER_NAME;
|
|
790
804
|
const force = Boolean(opts.force);
|
|
791
805
|
const onlyExisting = opts.onlyExisting !== false;
|
|
@@ -794,6 +808,24 @@ function patchClientConfig(targetConfigPath, opts = {}) {
|
|
|
794
808
|
platform: process.platform
|
|
795
809
|
});
|
|
796
810
|
|
|
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.
|
|
814
|
+
const writableCandidates = candidates.filter((client) =>
|
|
815
|
+
client.writeSupported !== false
|
|
816
|
+
&& (!onlyExisting || detectClientInstalled(client).installed)
|
|
817
|
+
);
|
|
818
|
+
if (writableCandidates.length > 0
|
|
819
|
+
&& process.env.GENEXUS_MCP_GATEWAY_EXE
|
|
820
|
+
&& !fs.existsSync(process.env.GENEXUS_MCP_GATEWAY_EXE)) {
|
|
821
|
+
const err = new Error(
|
|
822
|
+
`GENEXUS_MCP_GATEWAY_EXE points to a path that does not exist: ${process.env.GENEXUS_MCP_GATEWAY_EXE}. ` +
|
|
823
|
+
`Refusing to write this into client configs. Unset the env var (to use the npx launcher) or re-run scripts/install.ps1 to materialize the exe.`
|
|
824
|
+
);
|
|
825
|
+
err.code = 'GATEWAY_EXE_MISSING';
|
|
826
|
+
throw err;
|
|
827
|
+
}
|
|
828
|
+
|
|
797
829
|
const patched = [];
|
|
798
830
|
const failed = [];
|
|
799
831
|
const skipped = [];
|
|
@@ -802,9 +834,19 @@ function patchClientConfig(targetConfigPath, opts = {}) {
|
|
|
802
834
|
// Detect-only agents (e.g. OpenCode Desktop) can't be auto-written; surface
|
|
803
835
|
// the manual step instead of pretending we registered them.
|
|
804
836
|
if (client.writeSupported === false) {
|
|
805
|
-
|
|
806
|
-
|
|
837
|
+
const detection = detectClientInstalled(client);
|
|
838
|
+
if (onlyExisting && !detection.installed) {
|
|
839
|
+
skipped.push({ client: client.name, reason: 'not installed' });
|
|
840
|
+
continue;
|
|
807
841
|
}
|
|
842
|
+
skipped.push({
|
|
843
|
+
client: client.name,
|
|
844
|
+
reason: client.manualNote || 'manual setup required',
|
|
845
|
+
registrationMode: 'manual',
|
|
846
|
+
installed: detection.installed,
|
|
847
|
+
detectedAt: detection.markerHit || (detection.hasConfig ? client.path : null),
|
|
848
|
+
manualSetup: buildManualClientSetup(client, targetConfigPath)
|
|
849
|
+
});
|
|
808
850
|
continue;
|
|
809
851
|
}
|
|
810
852
|
// "Installed" keys off install markers (the agent itself is present), not
|
package/cli/run.test.js
CHANGED
|
@@ -791,6 +791,112 @@ 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', () => {
|
|
795
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-status-'));
|
|
796
|
+
try {
|
|
797
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
798
|
+
fs.mkdirSync(path.join(env.APPDATA, 'ai.opencode.desktop'), { recursive: true });
|
|
799
|
+
|
|
800
|
+
const result = runCli(['clients', '--format', 'json'], { env });
|
|
801
|
+
assert.equal(result.status, 0);
|
|
802
|
+
const row = JSON.parse(result.stdout).ok.clients.find((client) => client.id === 'opencode-desktop');
|
|
803
|
+
assert.ok(row, 'OpenCode Desktop should be listed');
|
|
804
|
+
assert.equal(row.installed, true);
|
|
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);
|
|
813
|
+
} finally {
|
|
814
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
815
|
+
}
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
test('clients add reports OpenCode Desktop manual skip without mutating its app-managed file', () => {
|
|
819
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-add-'));
|
|
820
|
+
try {
|
|
821
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
822
|
+
const cfgPath = path.join(tempRoot, 'config.json');
|
|
823
|
+
const desktopDir = path.join(env.APPDATA, 'ai.opencode.desktop');
|
|
824
|
+
const desktopConfig = path.join(desktopDir, 'mcp.json');
|
|
825
|
+
const original = { unrelated: { keep: true } };
|
|
826
|
+
fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
|
|
827
|
+
fs.mkdirSync(desktopDir, { recursive: true });
|
|
828
|
+
fs.writeFileSync(desktopConfig, JSON.stringify(original, null, 2));
|
|
829
|
+
|
|
830
|
+
const result = runCli(['clients', 'add', '--clients', 'opencode-desktop', '--format', 'json'], {
|
|
831
|
+
env: { ...env, GX_CONFIG_PATH: cfgPath }
|
|
832
|
+
});
|
|
833
|
+
assert.equal(result.status, 0);
|
|
834
|
+
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);
|
|
843
|
+
} finally {
|
|
844
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
test('clients add always reports undetected OpenCode Desktop manual setup', () => {
|
|
849
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-opencode-desktop-undetected-'));
|
|
850
|
+
try {
|
|
851
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
852
|
+
const cfgPath = path.join(tempRoot, 'config.json');
|
|
853
|
+
fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
|
|
854
|
+
|
|
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
|
+
});
|
|
862
|
+
assert.equal(result.status, 0);
|
|
863
|
+
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');
|
|
870
|
+
} finally {
|
|
871
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
test('clients add still refuses a missing gateway for writable clients', () => {
|
|
876
|
+
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-client-missing-gateway-'));
|
|
877
|
+
try {
|
|
878
|
+
const env = sandboxHomeEnv(tempRoot);
|
|
879
|
+
const cfgPath = path.join(tempRoot, 'config.json');
|
|
880
|
+
const cursorConfig = path.join(tempRoot, '.cursor', 'mcp.json');
|
|
881
|
+
fs.writeFileSync(cfgPath, JSON.stringify({ Environment: { KBPath: tempRoot } }));
|
|
882
|
+
|
|
883
|
+
const result = runCli(['clients', 'add', '--clients', 'cursor', '--format', 'json'], {
|
|
884
|
+
env: {
|
|
885
|
+
...env,
|
|
886
|
+
GX_CONFIG_PATH: cfgPath,
|
|
887
|
+
GENEXUS_MCP_GATEWAY_EXE: path.join(tempRoot, 'missing', 'GxMcp.Gateway.exe')
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
assert.equal(result.status, 1);
|
|
891
|
+
const parsed = JSON.parse(result.stdout);
|
|
892
|
+
assert.equal(parsed.error.code, 'operation_error');
|
|
893
|
+
assert.match(parsed.error.message, /GATEWAY_EXE_MISSING|does not exist/i);
|
|
894
|
+
assert.equal(fs.existsSync(cursorConfig), false, 'failed validation must not create a client config');
|
|
895
|
+
} finally {
|
|
896
|
+
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
|
|
794
900
|
test('getLauncher prefers the packaged gateway for Antigravity only', () => {
|
|
795
901
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'genexus-mcp-launcher-'));
|
|
796
902
|
const gatewayPath = path.join(tempRoot, 'publish', 'GxMcp.Gateway.exe');
|
|
@@ -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": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"mcpName": "io.github.lennix1337/genexus",
|
|
5
5
|
"description": "GeneXus 18 MCP server — read, edit, and analyze GeneXus knowledge base objects (transactions, web panels, procedures, SDTs) directly from Claude, Cursor, and other AI agents over the Model Context Protocol.",
|
|
6
6
|
"keywords": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"win32"
|
|
51
51
|
],
|
|
52
52
|
"engines": {
|
|
53
|
-
"node": ">=
|
|
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=
|
|
3
|
+
"name": ".NETCoreApp,Version=v10.0/win-x64",
|
|
4
4
|
"signature": ""
|
|
5
5
|
},
|
|
6
6
|
"compilationOptions": {},
|
|
7
7
|
"targets": {
|
|
8
|
-
".NETCoreApp,Version=
|
|
9
|
-
".NETCoreApp,Version=
|
|
10
|
-
"GxMcp.Gateway/
|
|
8
|
+
".NETCoreApp,Version=v10.0": {},
|
|
9
|
+
".NETCoreApp,Version=v10.0/win-x64": {
|
|
10
|
+
"GxMcp.Gateway/3.0.0": {
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
69
|
+
"GxMcp.Gateway/3.0.0": {
|
|
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": "
|
|
3
|
+
"tfm": "net10.0",
|
|
4
4
|
"frameworks": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Microsoft.NETCore.App",
|
|
7
|
-
"version": "
|
|
7
|
+
"version": "10.0.0"
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"name": "Microsoft.AspNetCore.App",
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "10.0.0"
|
|
12
12
|
}
|
|
13
13
|
],
|
|
14
14
|
"configProperties": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/publish/config.json
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
"KBPath": "C:\\\\KBs\\\\YourKB"
|
|
8
8
|
},
|
|
9
9
|
"Server": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
10
|
+
"McpStdio": true,
|
|
11
|
+
"HttpPort": 5000
|
|
12
12
|
},
|
|
13
13
|
"GeneXus": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
14
|
+
"InstallationPath": "C:\\\\Program Files (x86)\\\\GeneXus\\\\GeneXus18",
|
|
15
|
+
"WorkerExecutable": "worker\\\\GxMcp.Worker.exe"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "gxmcp-release-manifest/1",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"sourceCommit": "6f5c1a27df8447e25b9eca750daef40fa64207bc",
|
|
5
|
+
"generatedAtUtc": "2026-09-06T23:59:53.6616612Z",
|
|
6
|
+
"runtime": {
|
|
7
|
+
"gateway": "net10.0-windows",
|
|
8
|
+
"worker": "net48-x86",
|
|
9
|
+
"node": ">=22.0.0",
|
|
10
|
+
"recommendedNode": "24 LTS"
|
|
11
|
+
},
|
|
12
|
+
"protocolVersions": [
|
|
13
|
+
"2025-11-25",
|
|
14
|
+
"2026-07-28"
|
|
15
|
+
],
|
|
16
|
+
"schema": "tool_definitions.json",
|
|
17
|
+
"schemaSha256": "c43e3943a9b8f6fcb650014a31c1a29059e1e946bf03e1e0ae51893869d8c329",
|
|
18
|
+
"provenance": "gxmcp-sbom.json",
|
|
19
|
+
"artifacts": [
|
|
20
|
+
{
|
|
21
|
+
"path": "gxmcp-sbom.json",
|
|
22
|
+
"size": 552,
|
|
23
|
+
"sha256": "484fc2edbd6146b813a93f64559bc84ca519e1426adb48a01c64e865b91c8239"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "GxMcp.Gateway.exe",
|
|
27
|
+
"size": 162304,
|
|
28
|
+
"sha256": "947e70d3cc17075957405f9d6442741b44d13f0212daabf87f77e2df68815606"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "nexus-ide.vsix",
|
|
32
|
+
"size": 1318677,
|
|
33
|
+
"sha256": "e894e2255c5e2c853d64adf4191ada26e6a74ddb51df752c9c53fed2a281d81c"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"path": "tool_definitions.json",
|
|
37
|
+
"size": 103566,
|
|
38
|
+
"sha256": "c43e3943a9b8f6fcb650014a31c1a29059e1e946bf03e1e0ae51893869d8c329"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"path": "worker/GxMcp.Worker.exe",
|
|
42
|
+
"size": 2814464,
|
|
43
|
+
"sha256": "f6f966490c52b1e47fb70dfc3523c120d4a80a99292d8a772e3c7f2a8d77ed0b"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "gxmcp-provenance/1",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"sourceCommit": "6f5c1a27df8447e25b9eca750daef40fa64207bc",
|
|
5
|
+
"components": [
|
|
6
|
+
{
|
|
7
|
+
"name": "genexus-mcp",
|
|
8
|
+
"lockfile": "package-lock.json",
|
|
9
|
+
"size": 39915,
|
|
10
|
+
"sha256": "52f510e2c266fe270f40bb5884508377a0922edafc035263dbcd8d8d8902fd2e"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "nexus-ide",
|
|
14
|
+
"lockfile": "src/nexus-ide/package-lock.json",
|
|
15
|
+
"size": 274985,
|
|
16
|
+
"sha256": "1b4d8ecfb2037951701c50fce38f6db4702a96fd5a3c8a7f4a105b9cce834260"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
Binary file
|