@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
176 lines (175 loc) • 6.96 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatAccountsAndRoles = formatAccountsAndRoles;
exports.formatNoAccounts = formatNoAccounts;
exports.formatAuthRequired = formatAuthRequired;
exports.formatAccountRoles = formatAccountRoles;
const formatter_util_js_1 = require("../utils/formatter.util.js");
/**
* Calculate the approximate duration from now until the expiration time
* @param expirationDate The date when the session expires
* @returns Formatted duration string like "approximately 12 hours"
*/
function calculateDuration(expirationDate) {
try {
const now = new Date();
const diffMs = expirationDate.getTime() - now.getTime();
// Convert to hours
const diffHours = Math.round(diffMs / (1000 * 60 * 60));
if (diffHours < 1) {
return 'less than an hour';
}
else if (diffHours === 1) {
return 'approximately 1 hour';
}
else {
return `approximately ${diffHours} hours`;
}
}
catch {
return 'unknown duration';
}
}
/**
* Format accounts and roles information
* @param expiresDate Formatted expiration date
* @param accountsWithRoles List of accounts with roles
* @returns Formatted markdown content
*/
function formatAccountsAndRoles(expiresDate, accountsWithRoles) {
// Parse the expiration date to calculate the duration
let durationText = 'unknown duration';
try {
const expirationDate = new Date(expiresDate);
durationText = calculateDuration(expirationDate);
}
catch {
// Keep the default text if parsing fails
}
const headerLines = [
(0, formatter_util_js_1.formatHeading)('AWS SSO: Accounts and Roles', 1),
'',
`**Session Status**: Valid until ${expiresDate} (${durationText} remaining)`,
];
if (accountsWithRoles.length === 0) {
return formatNoAccounts(true);
}
const accountLines = [];
accountLines.push((0, formatter_util_js_1.formatHeading)('Available Accounts', 2));
accountsWithRoles.forEach((account) => {
accountLines.push('');
accountLines.push((0, formatter_util_js_1.formatHeading)(`Account: ${account.accountName || 'Unnamed Account'} (${account.accountId})`, 3));
const accountDetails = {};
if (account.accountEmail) {
accountDetails['Email'] = account.accountEmail;
}
// Add other potential details here if needed
accountLines.push((0, formatter_util_js_1.formatBulletList)(accountDetails));
if (account.roles.length === 0) {
accountLines.push('- **Roles**: No roles available');
}
else {
accountLines.push('- **Roles**:');
account.roles.forEach((role) => {
accountLines.push(` - ${role.roleName}`);
});
}
});
const usageLines = [
'',
(0, formatter_util_js_1.formatHeading)('Next Steps', 2),
'To execute a command in an account, run:',
(0, formatter_util_js_1.formatCodeBlock)('mcp-aws-sso exec-command --account-id <ACCOUNT_ID> --role-name <ROLE_NAME> --command "aws s3 ls"', 'bash'),
'',
'**Tip**: Use `mcp-aws-sso login` if you need to re-authenticate.',
];
const footerLines = [
'',
(0, formatter_util_js_1.formatSeparator)(),
`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`,
];
return [
...headerLines,
...accountLines,
...usageLines,
...footerLines,
].join('\n');
}
/**
* Format no accounts message
* @param addFooter Flag to indicate if the standard footer should be added
* @returns Formatted markdown content
*/
function formatNoAccounts(addFooter = true) {
const lines = [
(0, formatter_util_js_1.formatHeading)('AWS SSO: Accounts and Roles', 1),
'',
(0, formatter_util_js_1.formatHeading)('No Accounts Found', 2),
'',
'Your AWS SSO user has no assigned accounts.',
'',
(0, formatter_util_js_1.formatHeading)('Possible Causes', 3),
'* Your user lacks account assignments in AWS IAM Identity Center.',
'* Your SSO permissions are restricted.',
'* There may be a configuration issue with your AWS SSO setup.',
'',
(0, formatter_util_js_1.formatHeading)('Suggested Actions', 3),
'1. Contact your AWS administrator to verify account assignments.',
'2. Re-authenticate to refresh your session:',
(0, formatter_util_js_1.formatCodeBlock)('mcp-aws-sso login', 'bash'),
];
if (addFooter) {
lines.push('');
lines.push((0, formatter_util_js_1.formatSeparator)());
lines.push(`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`);
}
return lines.join('\n');
}
/**
* Format auth required message
* @returns Formatted markdown content
*/
function formatAuthRequired() {
const lines = [
(0, formatter_util_js_1.formatHeading)('AWS SSO Authentication Required', 1),
'',
'You need to authenticate with AWS SSO to view accounts and roles.',
'',
(0, formatter_util_js_1.formatHeading)('How to Authenticate', 2),
'Run the following command to start the login process:',
(0, formatter_util_js_1.formatCodeBlock)('mcp-aws-sso login', 'bash'),
'',
'This will open a browser window for AWS SSO authentication. Follow the prompts to complete the process.',
'',
(0, formatter_util_js_1.formatSeparator)(),
`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`,
];
return lines.join('\n');
}
/**
* Format roles listing for an account
* @param accountId AWS account ID
* @param roles List of roles for the account
* @returns Formatted markdown content
*/
function formatAccountRoles(accountId, roles) {
const rolesList = roles.length === 0
? 'No roles are available for this account with your SSO credentials.'
: roles
.map((role) => `- **${role.roleName || 'Unnamed Role'}**${role.roleArn ? ` (${role.roleArn})` : ''}`)
.join('\n');
const lines = [
(0, formatter_util_js_1.formatHeading)(`AWS SSO: Roles for Account ${accountId}`, 1),
'',
(0, formatter_util_js_1.formatHeading)('Available Roles', 2),
rolesList,
'',
(0, formatter_util_js_1.formatHeading)('Usage Example', 2),
'To use a role for executing AWS CLI commands:',
(0, formatter_util_js_1.formatCodeBlock)(`mcp-aws-sso exec-command --account-id ${accountId} --role-name <ROLE_NAME> --command "aws s3 ls"`, 'bash'),
'',
(0, formatter_util_js_1.formatSeparator)(),
`*Information retrieved at: ${(0, formatter_util_js_1.formatDate)(new Date())}*`,
];
return lines.join('\n');
}