UNPKG

@agentdb/mcpproxy

Version:

MCP proxy server for remote HTTP endpoints supporting JSON and Server-Sent Events

145 lines (119 loc) 4.2 kB
#!/usr/bin/env node import { createWriteStream, chmodSync, existsSync, mkdirSync } from 'fs'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; import { pipeline } from 'stream/promises'; import fetch from 'node-fetch'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Configuration const REPO = 'sutterhill/agentdb'; const BINARY_NAME = 'mcpproxy'; // Platform detection function getPlatform() { const platform = process.platform; const arch = process.arch; let platformName; let archName; switch (platform) { case 'darwin': platformName = 'apple-darwin'; break; case 'linux': platformName = 'unknown-linux-gnu'; break; case 'win32': platformName = 'pc-windows-msvc'; break; default: throw new Error(`Unsupported platform: ${platform}`); } switch (arch) { case 'x64': archName = 'x86_64'; break; case 'arm64': archName = 'aarch64'; break; default: throw new Error(`Unsupported architecture: ${arch}`); } return `${archName}-${platformName}`; } function getBinaryName() { const target = getPlatform(); const extension = process.platform === 'win32' ? '.exe' : ''; return `${BINARY_NAME}-${target}${extension}`; } function getLocalBinaryPath() { const extension = process.platform === 'win32' ? '.exe' : ''; return join(__dirname, '..', 'bin', `${BINARY_NAME}${extension}`); } async function downloadBinary() { const binaryName = getBinaryName(); const localPath = getLocalBinaryPath(); // Create bin directory if it doesn't exist const binDir = dirname(localPath); if (!existsSync(binDir)) { mkdirSync(binDir, { recursive: true }); } // Skip download if binary already exists if (existsSync(localPath)) { console.log('Binary already exists, skipping download'); return; } // Check if we're in development mode (local build available) const localBuildPath = join(__dirname, '..', '..', 'mcpproxy', 'target', 'release', 'mcpproxy'); if (existsSync(localBuildPath)) { console.log('Using local development build...'); const { copyFileSync } = await import('fs'); copyFileSync(localBuildPath, localPath); if (process.platform !== 'win32') { chmodSync(localPath, 0o755); } console.log(`✓ Copied local build to ${localPath}`); return; } const downloadUrl = `https://github.com/${REPO}/releases/latest/download/${binaryName}`; console.log(`Downloading mcpproxy binary for ${getPlatform()}...`); console.log(`URL: ${downloadUrl}`); try { const response = await fetch(downloadUrl); if (!response.ok) { throw new Error(`Failed to download binary: ${response.status} ${response.statusText}`); } const fileStream = createWriteStream(localPath); await pipeline(response.body, fileStream); // Make executable on Unix-like systems if (process.platform !== 'win32') { chmodSync(localPath, 0o755); } console.log(`✓ mcpproxy binary downloaded successfully to ${localPath}`); } catch (error) { console.warn('Failed to download mcpproxy binary:', error.message); console.warn(''); console.warn('This is expected during development before releases are published.'); console.warn(''); console.warn('To use this package:'); console.warn('1. Build the binary first:'); console.warn(' cd ../mcpproxy && cargo build --release'); console.warn('2. Then install this package'); console.warn(''); console.warn('Or download manually from:'); console.warn(`https://github.com/${REPO}/releases/latest`); // Don't exit with error during development if (process.env.NODE_ENV === 'development' || process.env.npm_config_optional === 'true') { console.warn('Continuing without binary (development mode)'); return; } process.exit(1); } } // Only run if this script is executed directly if (import.meta.url === `file://${process.argv[1]}`) { downloadBinary().catch(error => { console.error('Download failed:', error); process.exit(1); }); } export { downloadBinary, getLocalBinaryPath };