UNPKG

@aurracloud/mcp-cli

Version:

A command-line tool to install, manage, and setup MCP (Model Context Protocol) servers with Docker support

192 lines 7.59 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loginCommand = loginCommand; const node_fetch_1 = __importDefault(require("node-fetch")); const logger_1 = require("../utils/logger"); const auth_1 = require("../utils/auth"); const child_process_1 = require("child_process"); const fs = __importStar(require("fs")); const path = __importStar(require("path")); /** * Save API key to config file */ function saveApiKey(registry, apiKey) { const configDir = (0, auth_1.getConfigDir)(); const configFile = path.join(configDir, 'config.json'); let config = {}; if (fs.existsSync(configFile)) { try { config = JSON.parse(fs.readFileSync(configFile, 'utf8')); } catch (error) { logger_1.logger.warn('Could not parse existing config file, creating new one'); } } if (!config.registries) { config.registries = {}; } config.registries[registry] = { apiKey, lastLogin: new Date().toISOString() }; fs.writeFileSync(configFile, JSON.stringify(config, null, 2)); logger_1.logger.debug(`API key saved to ${configFile}`); } /** * Open URL in the default browser */ function openUrl(url) { try { let command; switch (process.platform) { case 'darwin': command = 'open'; break; case 'win32': command = 'start'; break; default: command = 'xdg-open'; } (0, child_process_1.execSync)(`${command} "${url}"`, { stdio: 'ignore' }); logger_1.logger.info('Opened login URL in your default browser'); } catch (error) { logger_1.logger.warn('Could not automatically open browser. Please manually open the URL above.'); } } /** * Poll for authentication completion */ async function pollForAuth(registry, uuid) { const maxAttempts = 150; // 5 minutes let attempts = 0; logger_1.logger.info('Waiting for authentication...'); logger_1.logger.info('(This will timeout in 5 minutes)'); while (attempts < maxAttempts) { try { const response = await (0, node_fetch_1.default)(`${registry}/api/registry/login/${uuid}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (response.ok) { const data = await response.json(); if (data.success && data.apiKey) { return data.apiKey; } } else if (response.status === 408) { // Timeout from server const data = await response.json(); throw new Error(data.error || 'Login timeout'); } // Wait 2 seconds before next attempt await new Promise(resolve => setTimeout(resolve, 2000)); attempts++; // Show progress every 30 seconds if (attempts % 15 === 0) { const remainingMinutes = Math.ceil((maxAttempts - attempts) * 2 / 60); logger_1.logger.info(`Still waiting... (${remainingMinutes} minutes remaining)`); } } catch (error) { if (error.message.includes('timeout') || error.message.includes('expired')) { throw error; } // For network errors, continue polling logger_1.logger.debug(`Polling error: ${error.message}`); await new Promise(resolve => setTimeout(resolve, 2000)); attempts++; } } throw new Error('Login timeout - please try again'); } /** * Command to authenticate with the MCP registry */ async function loginCommand(options) { const registry = options.registry || 'https://aurracloud.com'; logger_1.logger.info('Initiating login to MCP registry...'); logger_1.logger.info(`Registry: ${registry}`); try { // Step 1: Initiate login and get UUID + login URL logger_1.logger.info('Generating login session...'); const initResponse = await (0, node_fetch_1.default)(`${registry}/api/registry/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (!initResponse.ok) { throw new Error(`Failed to initiate login: ${initResponse.status} ${initResponse.statusText}`); } const loginData = await initResponse.json(); logger_1.logger.info(''); logger_1.logger.info('🔗 Please open the following URL in your authenticated browser:'); logger_1.logger.info(''); logger_1.logger.info(` ${loginData.loginUrl}`); logger_1.logger.info(''); // Step 2: Try to open the URL automatically openUrl(loginData.loginUrl); // Step 3: Start polling for authentication const apiKey = await pollForAuth(registry, loginData.uuid); // Step 4: Save the API key saveApiKey(registry, apiKey); logger_1.logger.success('✅ Login successful!'); logger_1.logger.info(`API key has been saved to your local configuration.`); logger_1.logger.info('You can now use mcp-cli to install and manage MCP servers.'); } catch (error) { if (error.message.includes('ENOTFOUND') || error.message.includes('ECONNREFUSED')) { logger_1.logger.error(`Could not connect to registry at ${registry}`); logger_1.logger.info('Please check your internet connection and registry URL.'); } else if (error.message.includes('timeout') || error.message.includes('expired')) { logger_1.logger.error('Login session expired. Please try again.'); logger_1.logger.info('Make sure to complete the browser authentication within 5 minutes.'); } else { logger_1.logger.error('Login failed:', error.message); } process.exit(1); } } //# sourceMappingURL=login.js.map