#!/usr/bin/env node
/**
* NPX wrapper for OHM MCP Python refactoring server
* Launches the Python MCP server from Node.js/npx
*/
import { spawn } from 'child_process';
import { existsSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
async function findPythonCommand() {
const candidates = ['python3', 'python', 'py'];
for (const cmd of candidates) {
try {
await new Promise((resolve, reject) => {
const child = spawn(cmd, ['--version'], { stdio: 'pipe' });
child.on('close', (code) => {
if (code === 0) {
resolve(cmd);
} else {
reject(new Error(`Command failed with code ${code}`));
}
});
child.on('error', reject);
});
return cmd;
} catch (error) {
continue;
}
}
throw new Error('Python interpreter not found. Please install Python 3.8+ and ensure it\'s in your PATH.');
}
async function checkAndInstallOhmMcp(pythonCmd) {
return new Promise((resolve, reject) => {
// First check if ohm-mcp is already installed
const checkProcess = spawn(pythonCmd, ['-c', 'import pkg_resources; pkg_resources.get_distribution("ohm-mcp")'], { stdio: 'pipe' });
checkProcess.on('close', (code) => {
if (code === 0) {
console.log('✓ OHM MCP Python package found');
resolve();
} else {
console.log('📦 Installing OHM MCP Python package...');
// Try to install via pip
const installProcess = spawn(pythonCmd, ['-m', 'pip', 'install', 'ohm-mcp'], {
stdio: 'inherit',
env: { ...process.env, PYTHONPATH: '' }
});
installProcess.on('close', (installCode) => {
if (installCode === 0) {
console.log('✓ OHM MCP Python package installed successfully');
resolve();
} else {
reject(new Error(
'Failed to install OHM MCP Python package.\n' +
'Please install it manually with:\n' +
' pip install ohm-mcp\n' +
'Or visit: https://github.com/your-username/ohm-mcp'
));
}
});
installProcess.on('error', (error) => {
reject(new Error(
`Installation failed: ${error.message}\n` +
'Please ensure pip is available and try installing manually:\n' +
' pip install ohm-mcp'
));
});
}
});
checkProcess.on('error', () => {
// pkg_resources not available, try direct import
const altCheckProcess = spawn(pythonCmd, ['-c', 'import ohm_mcp'], { stdio: 'pipe' });
altCheckProcess.on('close', (altCode) => {
if (altCode === 0) {
console.log('✓ OHM MCP Python package found');
resolve();
} else {
// Package not found, try to install
console.log('📦 Installing OHM MCP Python package...');
const installProcess = spawn(pythonCmd, ['-m', 'pip', 'install', 'ohm-mcp'], {
stdio: 'inherit',
env: { ...process.env, PYTHONPATH: '' }
});
installProcess.on('close', (installCode) => {
if (installCode === 0) {
resolve();
} else {
reject(new Error(
'Failed to install OHM MCP Python package.\n' +
'Please install it manually with:\n' +
' pip install ohm-mcp\n' +
'Or visit: https://github.com/your-username/ohm-mcp'
));
}
});
}
});
altCheckProcess.on('error', reject);
});
});
}
async function main() {
try {
console.log('🚀 Starting OHM MCP Refactoring Server via npx...');
// Find Python interpreter
const pythonCmd = await findPythonCommand();
console.log(`✓ Found Python: ${pythonCmd}`);
// Ensure OHM MCP is installed
await checkAndInstallOhmMcp(pythonCmd);
// Launch the MCP server
console.log('🔧 Launching MCP server...');
console.log('📡 Server ready for MCP connections');
const serverProcess = spawn(pythonCmd, ['-m', 'ohm_mcp.server'], {
stdio: 'inherit',
env: {
...process.env,
PYTHONPATH: process.env.PYTHONPATH || ''
}
});
// Handle process termination
process.on('SIGINT', () => {
console.log('\n🛑 Shutting down MCP server...');
serverProcess.kill('SIGINT');
process.exit(0);
});
process.on('SIGTERM', () => {
console.log('\n🛑 Shutting down MCP server...');
serverProcess.kill('SIGTERM');
process.exit(0);
});
serverProcess.on('close', (code) => {
if (code !== 0) {
console.error(`❌ MCP server exited with code ${code}`);
process.exit(code);
}
});
serverProcess.on('error', (error) => {
console.error(`❌ Failed to start MCP server: ${error.message}`);
process.exit(1);
});
} catch (error) {
console.error(`❌ Error: ${error.message}`);
process.exit(1);
}
}
main().catch((error) => {
console.error(`❌ Unexpected error: ${error.message}`);
process.exit(1);
});