UNPKG

@aashari/mcp-server-aws-sso

Version:

Node.js/TypeScript MCP server for AWS Single Sign-On (SSO). Enables AI systems (LLMs) with tools to initiate SSO login (device auth flow), list accounts/roles, and securely execute AWS CLI commands using temporary credentials. Streamlines AI interaction w

121 lines (120 loc) 4.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executeCommand = executeCommand; const logger_util_js_1 = require("../utils/logger.util.js"); const child_process_1 = require("child_process"); const vendor_aws_sso_accounts_service_js_1 = require("./vendor.aws.sso.accounts.service.js"); const logger = logger_util_js_1.Logger.forContext('services/vendor.aws.sso.exec.service.ts'); /** * Execute AWS CLI command with temporary credentials * * Gets temporary credentials for the specified account and role, then executes * the AWS CLI command with those credentials in the environment. * * @param {string} accountId - AWS account ID to get credentials for * @param {string} roleName - AWS role name to assume via SSO * @param {string[]} command - AWS CLI command and arguments as array * @param {string} [region] - Optional AWS region override * @returns {Promise<CommandExecutionResult>} Command execution result with stdout, stderr, and exit code * @throws {Error} If credentials cannot be obtained or command execution fails */ async function executeCommand(accountId, roleName, command, region) { const methodLogger = logger.forMethod('executeCommand'); methodLogger.debug('Executing AWS CLI command', { accountId, roleName, command, region, }); // Validate parameters if (!accountId || !roleName) { throw new Error('Account ID and role name are required'); } if (!command || command.length === 0) { throw new Error('Command is required'); } try { // Get credentials for the account and role const credentials = await (0, vendor_aws_sso_accounts_service_js_1.getAwsCredentials)({ accountId, roleName, region, }); methodLogger.debug('Obtained temporary credentials', { accountId, roleName, expiration: credentials.expiration.toISOString(), }); // Set up environment variables for the command const processEnv = { ...process.env }; // Add AWS credentials to the environment processEnv.AWS_ACCESS_KEY_ID = credentials.accessKeyId; processEnv.AWS_SECRET_ACCESS_KEY = credentials.secretAccessKey; processEnv.AWS_SESSION_TOKEN = credentials.sessionToken; // Set region if provided if (region) { processEnv.AWS_REGION = region; processEnv.AWS_DEFAULT_REGION = region; } // Execute the command const result = await executeChildProcess(command[0], command.slice(1), processEnv); methodLogger.debug('Command execution completed', { exitCode: result.exitCode, stdoutBytes: result.stdout.length, stderrBytes: result.stderr.length, }); return result; } catch (error) { methodLogger.error('Failed to execute command', error); throw error; } } /** * Execute child process with the given command and arguments * * Helper function to spawn a child process and collect its output. * * @param {string} command - Command to execute * @param {string[]} args - Command arguments * @param {NodeJS.ProcessEnv} env - Environment variables for the process * @returns {Promise<CommandExecutionResult>} Command execution result */ async function executeChildProcess(command, args, env) { const methodLogger = logger.forMethod('executeChildProcess'); methodLogger.debug('Executing child process', { command, args, }); return new Promise((resolve, reject) => { const child = (0, child_process_1.spawn)(command, args, { env, stdio: 'pipe', shell: false, }); let stdout = ''; let stderr = ''; child.stdout.on('data', (data) => { stdout += data.toString(); }); child.stderr.on('data', (data) => { stderr += data.toString(); }); child.on('error', (error) => { methodLogger.error('Child process error', error); reject(error); }); child.on('close', (exitCode) => { methodLogger.debug('Child process completed', { exitCode, stdoutLength: stdout.length, stderrLength: stderr.length, }); resolve({ stdout, stderr, exitCode: exitCode ?? 1, }); }); }); }