Skip to content

Commit 016cfcd

Browse files
committed
fix: improve main module detection for npx compatibility
The previous module detection logic failed when running via npx due to symlink resolution differences. This caused the server to exit immediately without starting, resulting in "MCP error -32000: Connection closed". The fix uses realpathSync() to fully resolve both the module path and script path before comparison, handling symlinks and path normalization across different execution contexts (npx, node, direct execution). Fixes the issue where: - Connection failed after ~1s with "Connection closed" error - Server worked in development but failed when installed via npx
1 parent 85a0a26 commit 016cfcd

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ if (process.env.NODE_ENV !== 'production') {
2121
import { version } from 'node:process';
2222
import { fileURLToPath } from 'node:url';
2323
import { resolve } from 'node:path';
24+
import { realpathSync } from 'node:fs';
2425
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2526
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
2627
import {
@@ -241,7 +242,17 @@ async function main() {
241242
// We need to normalize both paths to handle different execution contexts (npx, node, etc.)
242243
const modulePath = fileURLToPath(import.meta.url);
243244
const scriptPath = process.argv[1] ? resolve(process.argv[1]) : '';
244-
const isMainModule = modulePath === scriptPath;
245+
246+
// Resolve both paths fully to handle symlinks and path normalization
247+
let isMainModule = false;
248+
try {
249+
const realModulePath = realpathSync(modulePath);
250+
const realScriptPath = scriptPath ? realpathSync(scriptPath) : '';
251+
isMainModule = realModulePath === realScriptPath;
252+
} catch (error) {
253+
// If realpath fails (e.g., file doesn't exist), fall back to simple comparison
254+
isMainModule = modulePath === scriptPath;
255+
}
245256

246257
if (isMainModule) {
247258
main().catch((error) => {

0 commit comments

Comments
 (0)