UNPKG

@guillehr2/excel-mcp-server

Version:

Excel MCP Server - Manipulate Excel files without Microsoft Excel. Model Context Protocol server for reading, writing XLSX XLSM files with Claude AI LLM integration

125 lines (107 loc) 3.32 kB
#!/usr/bin/env node /* * Excel MCP Server - NPM Wrapper * Author: Guillem Hermida (https://github.com/guillehr2) * License: MIT */ const spawn = require('cross-spawn'); const path = require('path'); const fs = require('fs'); const os = require('os'); // Path to the Python script const pythonScript = path.join(__dirname, 'master_excel_mcp.py'); // Check if Python script exists if (!fs.existsSync(pythonScript)) { console.error('Error: master_excel_mcp.py not found'); process.exit(1); } // Determine Python command based on OS const pythonCmd = process.platform === 'win32' ? 'python' : 'python3'; // Check if uv is installed, otherwise use pip const checkCommand = (cmd) => { try { const result = spawn.sync(cmd, ['--version'], { stdio: 'pipe' }); return result.status === 0; } catch (e) { return false; } }; const hasUv = checkCommand('uv'); // Function to install dependencies silently const installDependencies = () => { const deps = [ 'fastmcp', 'openpyxl', 'pandas', 'numpy', 'xlsxwriter', 'xlrd', 'xlwt', 'matplotlib' ]; if (hasUv) { // Use uv for faster installation with --system flag const result = spawn.sync('uv', ['pip', 'install', '--system', '--quiet', ...deps], { stdio: 'ignore' }); return result.status === 0; } else { // Fallback to pip const pipCmd = process.platform === 'win32' ? 'pip' : 'pip3'; const result = spawn.sync(pipCmd, ['install', '--quiet', ...deps], { stdio: 'ignore' }); return result.status === 0; } }; // Check if this is the first run by checking for a marker file const markerFile = path.join(os.homedir(), '.excel-mcp-server-installed-v3'); if (!fs.existsSync(markerFile)) { // Install dependencies silently if (installDependencies()) { // Create marker file fs.writeFileSync(markerFile, new Date().toISOString()); } } // Run the Python script directly without extra logging const args = process.argv.slice(2); if (hasUv) { // Use uv run for better dependency management (without --system flag) const uvArgs = [ 'run', '--with', 'matplotlib', '--with', 'mcp[cli]', '--with', 'numpy', '--with', 'openpyxl', '--with', 'pandas', '--with', 'xlsxwriter', '--with', 'xlrd', '--with', 'xlwt', 'mcp', 'run', pythonScript, ...args ]; const child = spawn('uv', uvArgs, { stdio: 'inherit' }); child.on('error', (err) => { console.error('Failed to start server:', err); process.exit(1); }); child.on('exit', (code) => { process.exit(code || 0); }); } else { // Fallback to direct Python execution const child = spawn(pythonCmd, [pythonScript, ...args], { stdio: 'inherit' }); child.on('error', (err) => { console.error('Failed to start server:', err); process.exit(1); }); child.on('exit', (code) => { process.exit(code || 0); }); }