feat: enable/disable MCP HTTP based on desktop runtime environment

This commit is contained in:
Sparsh 2026-05-05 13:28:32 +05:30
parent b432045aa9
commit 64477774eb
3 changed files with 32 additions and 4 deletions

View file

@ -270,7 +270,7 @@ const spawnGitNexusServer = (): ChildProcess => {
[getGitNexusCliEntry(), 'serve', '--host', GITNEXUS_HOST],
{
cwd: getGitNexusRuntimeDir(),
env: getNodeProcessEnvironment(),
env: getNodeProcessEnvironment(app.isPackaged ? { GITNEXUS_DISABLE_MCP_HTTP: '1' } : {}),
stdio: ['ignore', 'pipe', 'pipe'],
windowsHide: true,
},

View file

@ -29,7 +29,6 @@ import { hybridSearch } from '../core/search/hybrid-search.js';
// Embedding imports are lazy (dynamic import) to avoid loading onnxruntime-node
// at server startup — crashes on unsupported Node ABI versions (#89)
import { LocalBackend } from '../mcp/local/local-backend.js';
import { mountMCPEndpoints } from './mcp-http.js';
import { fork } from 'child_process';
import { fileURLToPath, pathToFileURL } from 'url';
import { JobManager } from './analyze-job.js';
@ -38,6 +37,10 @@ import { extractRepoName, getCloneDir, cloneOrPull } from './git-clone.js';
const _require = createRequire(import.meta.url);
const pkg = _require('../../package.json');
export const shouldEnableMcpHttp = (): boolean => {
return process.env.GITNEXUS_DISABLE_MCP_HTTP !== '1';
};
/**
* Determine whether an HTTP Origin header value is allowed by CORS policy.
*
@ -560,7 +563,15 @@ export const createServer = async (port: number, host: string = '127.0.0.1') =>
// Initialize MCP backend (multi-repo, shared across all MCP sessions)
const backend = new LocalBackend();
await backend.init();
const cleanupMcp = mountMCPEndpoints(app, backend);
let cleanupMcp: () => Promise<void> = async () => {};
// Desktop packaged runtime disables MCP HTTP because the SDK import tree
// currently trips Electron's embedded Node resolver during server startup.
if (shouldEnableMcpHttp()) {
const { mountMCPEndpoints } = await import('./mcp-http.js');
cleanupMcp = mountMCPEndpoints(app, backend);
}
const jobManager = new JobManager();
// Shared repo lock — prevents concurrent analyze + embed on the same repo path,

View file

@ -1,7 +1,7 @@
import path from 'node:path';
import http from 'node:http';
import express from 'express';
import { describe, expect, it, vi, beforeEach } from 'vitest';
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
const { accessMock } = vi.hoisted(() => ({
accessMock: vi.fn(),
@ -17,6 +17,7 @@ import {
resolveWebDistDir,
landingPageHtml,
SPA_FALLBACK_REGEX,
shouldEnableMcpHttp,
staticCacheControlSetHeaders,
} from '../../src/server/api.js';
@ -94,6 +95,22 @@ describe('landingPageHtml', () => {
});
});
describe('shouldEnableMcpHttp', () => {
afterEach(() => {
vi.unstubAllEnvs();
});
it('enables MCP HTTP by default', () => {
expect(shouldEnableMcpHttp()).toBe(true);
});
it('disables MCP HTTP when requested by desktop runtime', () => {
vi.stubEnv('GITNEXUS_DISABLE_MCP_HTTP', '1');
expect(shouldEnableMcpHttp()).toBe(false);
});
});
describe('SPA fallback regex', () => {
it('allows root path', () => {
expect(SPA_FALLBACK_REGEX.test('/')).toBe(true);