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

120 lines (119 loc) 4.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatCommandResult = formatCommandResult; const formatter_util_js_1 = require("../utils/formatter.util.js"); const aws_sso_util_js_1 = require("../utils/aws.sso.util.js"); /** * Formats the result of an executed command into Markdown * * @param command The command that was executed (used for context, not displayed directly) * @param result The execution result containing stdout, stderr, and exit code * @param options Optional context like account, role, region, and suggested roles * @returns Formatted Markdown string */ function formatCommandResult(_command, result, options) { const defaultRegion = (0, aws_sso_util_js_1.getDefaultAwsRegion)(); const isSuccess = result.exitCode === 0; const isPermissionError = options?.suggestedRoles && options.suggestedRoles.length > 0; // Title with error indicator if needed const title = isSuccess ? 'AWS SSO: Command Result' : '❌ AWS SSO: Command Error'; // Build context properties as a single string per line const contextProps = {}; if (options?.accountId && options?.roleName) { contextProps['Account/Role'] = `${options.accountId}/${options.roleName}`; } if (options?.region || defaultRegion) { contextProps['Region'] = options?.region || defaultRegion; // Add default region info if different if (options?.region && defaultRegion && options.region !== defaultRegion) { contextProps['Region'] = `${options.region} (Default: ${defaultRegion})`; } } // Generate output sections based on command result const outputSections = []; // Always add the command that was executed outputSections.push({ heading: 'Command', content: _command, isCodeBlock: true, language: 'bash', }); if (isSuccess) { // Success case outputSections.push({ heading: 'Output', content: result.stdout && result.stdout.trim() ? result.stdout : '*Command completed successfully with no output.*', isCodeBlock: !!(result.stdout && result.stdout.trim()), }); // Show stderr as warnings if present, even on success if (result.stderr && result.stderr.trim()) { outputSections.push({ heading: 'Warnings (stderr)', content: result.stderr, isCodeBlock: true, }); } } else { // Error case - Customize error title based on the specific error let errorTitle = 'Error'; let errorDescription = 'The command failed to execute.'; if (isPermissionError) { errorTitle = 'Error: Permission Denied'; errorDescription = `The role \`${options?.roleName}\` does not have permission to execute this command.`; } else if (result.stderr && result.stderr.includes('not found')) { errorTitle = 'Error: Command Not Found'; } else if (result.exitCode) { errorTitle = `Error: Command Failed (Exit Code ${result.exitCode})`; } outputSections.push({ heading: errorTitle, content: errorDescription, }); // Add stderr if available if (result.stderr && result.stderr.trim()) { outputSections.push({ heading: 'Error Details', content: result.stderr, isCodeBlock: true, }); } else if (result.stdout && result.stdout.trim()) { // Sometimes errors go to stdout outputSections.push({ heading: 'Command Output', content: result.stdout, isCodeBlock: true, }); } // Add troubleshooting section if (isPermissionError && options?.suggestedRoles?.length) { const troubleshootingContent = [ '### Available Roles', ...options.suggestedRoles.map((role) => `- ${role.roleName}`), '', 'Try executing the command again using one of the roles listed above that has appropriate permissions.', ]; outputSections.push({ heading: 'Troubleshooting', content: troubleshootingContent, }); } } // Add simple footer with timestamp const footerInfo = [`*Executed: ${(0, formatter_util_js_1.formatDate)(new Date())}*`]; return (0, formatter_util_js_1.baseCommandFormatter)(title, contextProps, outputSections, footerInfo, // We no longer need the identity info section as we've incorporated // this information directly in the contextProps undefined); }