Skip to main content
Glama
ambivo-corp

Ambivo MCP Server

Official
by ambivo-corp
main.js9.12 kB
const { app, BrowserWindow, ipcMain, dialog } = require('electron'); const path = require('path'); const fs = require('fs'); const { exec } = require('child_process'); const os = require('os'); let mainWindow; let detectedPythonCommand = null; function createWindow() { mainWindow = new BrowserWindow({ width: 600, height: 700, webPreferences: { nodeIntegration: true, contextIsolation: false }, icon: path.join(__dirname, 'assets', 'icon.png'), resizable: false }); mainWindow.loadFile('index.html'); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); // Get Claude config path function getClaudeConfigPath() { if (process.platform === 'darwin') { return path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'); } else if (process.platform === 'win32') { return path.join(process.env.APPDATA, 'Claude', 'claude_desktop_config.json'); } } // Check if Python is installed and version ipcMain.handle('check-python', async () => { return new Promise((resolve) => { let debugInfo = []; // First, let's gather diagnostic information const diagnosticCommands = []; if (process.platform === 'darwin') { diagnosticCommands.push( 'which python3', 'which python', 'ls /usr/bin/python*', 'ls /usr/local/bin/python*', 'ls /opt/homebrew/bin/python*', 'ls /Library/Frameworks/Python.framework/Versions/*/bin/python*' ); } else if (process.platform === 'win32') { diagnosticCommands.push( 'where python', 'where python3', 'py -0' ); } // Run diagnostics first let diagnosticCount = 0; const runDiagnostics = () => { if (diagnosticCount >= diagnosticCommands.length) { // Now try actual Python commands tryPythonCommands(); return; } const diagCmd = diagnosticCommands[diagnosticCount]; diagnosticCount++; exec(diagCmd, { timeout: 2000 }, (error, stdout, stderr) => { if (!error && stdout.trim()) { debugInfo.push(`${diagCmd}: ${stdout.trim()}`); } runDiagnostics(); }); }; const tryPythonCommands = () => { const pythonCommands = []; if (process.platform === 'win32') { pythonCommands.push( 'python', 'python3', 'py -3', 'py -3.12', 'py -3.11', '"C:\\Program Files\\Python312\\python.exe"', '"C:\\Program Files\\Python311\\python.exe"', '"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Python\\Python312\\python.exe"', '"C:\\Users\\%USERNAME%\\AppData\\Local\\Programs\\Python\\Python311\\python.exe"' ); } else if (process.platform === 'darwin') { // Prioritize newer Python versions first pythonCommands.push( '/Library/Frameworks/Python.framework/Versions/3.12/bin/python3', '/opt/homebrew/bin/python3.12', '/usr/local/bin/python3.12', '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3', '/opt/homebrew/bin/python3.11', '/usr/local/bin/python3.11', '/Library/Frameworks/Python.framework/Versions/Current/bin/python3', '/opt/homebrew/bin/python3', '/usr/local/bin/python3', '/usr/bin/python3', 'python3', 'python' ); // Add any python3 executables found in diagnostics debugInfo.forEach(info => { if (info.includes('python3') && info.includes('/')) { const paths = info.split(':')[1]?.trim().split('\n') || []; paths.forEach(path => { if (path.trim() && !pythonCommands.includes(path.trim())) { pythonCommands.push(path.trim()); } }); } }); } else { pythonCommands.push('python3', 'python'); } const timeout = setTimeout(() => { resolve({ installed: false, version: null, error: 'timeout checking all Python locations', debugInfo: debugInfo }); }, 15000); // 15 second timeout let attemptIndex = 0; function tryNextCommand() { if (attemptIndex >= pythonCommands.length) { clearTimeout(timeout); resolve({ installed: false, version: null, error: 'no valid Python found in any location', debugInfo: debugInfo, triedCommands: pythonCommands }); return; } const cmd = pythonCommands[attemptIndex]; attemptIndex++; exec(`${cmd} --version`, { timeout: 3000 }, (error, stdout, stderr) => { if (error) { debugInfo.push(`FAILED: ${cmd} (${error.message})`); tryNextCommand(); } else { const versionMatch = stdout.match(/Python (\d+)\.(\d+)\.(\d+)/); if (versionMatch) { const major = parseInt(versionMatch[1]); const minor = parseInt(versionMatch[2]); detectedPythonCommand = cmd; clearTimeout(timeout); debugInfo.push(`SUCCESS: ${cmd} -> ${stdout.trim()}`); resolve({ installed: true, version: `${major}.${minor}`, versionString: stdout.trim(), isValid: major === 3 && minor >= 11, command: cmd, debugInfo: debugInfo }); } else { debugInfo.push(`INVALID VERSION: ${cmd} -> ${stdout.trim()}`); tryNextCommand(); } } }); } tryNextCommand(); }; runDiagnostics(); }); }); // Install the MCP server ipcMain.handle('install-server', async () => { return new Promise((resolve, reject) => { // Use the Python command that was detected during the check let pythonCmd = detectedPythonCommand || (process.platform === 'win32' ? 'python' : 'python3'); const installCmd = `${pythonCmd} -m pip install ambivo-mcp-server`; exec(installCmd, (error, stdout, stderr) => { if (error) { reject(`Installation failed with ${pythonCmd}: ${error.message}`); } else { resolve('Installation successful'); } }); }); }); // Configure Claude ipcMain.handle('configure-claude', async (event, token) => { try { const configPath = getClaudeConfigPath(); const configDir = path.dirname(configPath); // Create directory if it doesn't exist if (!fs.existsSync(configDir)) { fs.mkdirSync(configDir, { recursive: true }); } // Read existing config or create new one let config = {}; if (fs.existsSync(configPath)) { try { config = JSON.parse(fs.readFileSync(configPath, 'utf8')); } catch (e) { // Invalid JSON, start fresh config = {}; } } // Add our server configuration if (!config.mcpServers) { config.mcpServers = {}; } // Configure for local server config.mcpServers.ambivo = { command: detectedPythonCommand || (process.platform === 'win32' ? 'python' : 'python3'), args: ['-m', 'ambivo_mcp_server'], env: { AMBIVO_AUTH_TOKEN: token } }; // Write the config fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); return 'Configuration successful'; } catch (error) { throw error.message; } }); // Get app version ipcMain.handle('get-version', async () => { const packageJson = require('./package.json'); return packageJson.version; }); // Restart the app ipcMain.handle('restart-app', async () => { app.relaunch(); app.exit(); }); // Open external links ipcMain.handle('open-external', async (event, url) => { require('electron').shell.openExternal(url); }); // Download and install Python ipcMain.handle('install-python', async () => { return new Promise((resolve, reject) => { const platform = process.platform; let downloadUrl; if (platform === 'darwin') { // Mac - download universal installer for Python 3.12 downloadUrl = 'https://www.python.org/ftp/python/3.12.7/python-3.12.7-macos11.pkg'; } else if (platform === 'win32') { // Windows - download 64-bit installer for Python 3.12 downloadUrl = 'https://www.python.org/ftp/python/3.12.7/python-3.12.7-amd64.exe'; } else { reject('Unsupported platform for auto-install'); return; } // Open the download URL require('electron').shell.openExternal(downloadUrl); resolve(`Python 3.12 installer downloaded. Please run it, then click "Recheck Python" below. IMPORTANT: After installing Python, you may need to restart this installer or your terminal for the new Python version to be detected.`); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ambivo-corp/ambivo-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server