Fix MCP protocol compliance and Windows compatibility

This commit fixes two critical issues for MCP STDIO transport:

1. Logger fix (src/logger.ts) - CRITICAL MCP protocol compliance
   - Change all log levels to use console.error() (stderr) exclusively
   - Previous code sent info/debug logs to stdout via console.log()
   - MCP protocol uses stdout for JSON-RPC messages
   - Logging to stdout corrupts protocol communication
   - Impact: Prevents intermittent MCP failures from log pollution

2. Windows compatibility fix (src/index.ts)
   - Remove import.meta.url conditional check that fails on Windows
   - Path separator differences (forward slash vs backslash) cause
     the file:// URL comparison to fail
   - Server now runs main() unconditionally as intended
   - Impact: Reliable server startup on Windows

Changes:
- src/logger.ts: Use console.error() for all log levels
- src/index.ts: Remove 'if (import.meta.url === ...)' check
- src/index.ts: Add explanatory comment about Windows issue

Tested on Windows 11 with KiCAD 9.0.6.
Integration tests confirm 36KB logs to stderr, 0 bytes to stdout.

Fixes: MCP protocol corruption, Windows startup failures
This commit is contained in:
ByteBard
2025-11-18 17:29:21 -05:00
parent bb1c7a0883
commit 70c0be6fd0
2 changed files with 10 additions and 22 deletions

View File

@@ -107,13 +107,12 @@ async function shutdownServer(server: KiCADMcpServer) {
}
}
// Run the main function if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch((error) => {
logger.error(`Unhandled error in main: ${error}`);
// Run the main function - always run when imported as module entry point
// The import.meta.url check was failing on Windows due to path separators
main().catch((error) => {
console.error(`Unhandled error in main: ${error}`);
process.exit(1);
});
}
});
// For testing and programmatic usage
export { KiCADMcpServer };

View File

@@ -87,20 +87,9 @@ class Logger {
const timestamp = new Date().toISOString();
const formattedMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
// Log to console
switch (level) {
case 'error':
// Log to console.error (stderr) only - stdout is reserved for MCP protocol
// All log levels go to stderr to avoid corrupting STDIO MCP transport
console.error(formattedMessage);
break;
case 'warn':
console.warn(formattedMessage);
break;
case 'info':
case 'debug':
default:
console.log(formattedMessage);
break;
}
// Log to file
try {