@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
155 lines (154 loc) • 6.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const logger_util_js_1 = require("../utils/logger.util.js");
const error_handler_util_js_1 = require("../utils/error-handler.util.js");
const error_types_util_js_1 = require("../utils/error-types.util.js");
const vendor_aws_sso_auth_core_service_js_1 = require("../services/vendor.aws.sso.auth.core.service.js");
const vendor_aws_sso_accounts_service_js_1 = require("../services/vendor.aws.sso.accounts.service.js");
const aws_sso_cache_util_js_1 = require("../utils/aws.sso.cache.util.js");
const aws_sso_accounts_formatter_js_1 = require("./aws.sso.accounts.formatter.js");
// Removed unused imports for pagination, defaults, and ListAccountsParams
/**
* AWS SSO Accounts Controller Module
*
* Provides functionality for listing and managing AWS SSO accounts and roles.
* Handles retrieving account information, listing available roles, and formatting
* the results for display. All operations require valid AWS SSO authentication.
*/
// Create a module logger
const controllerLogger = logger_util_js_1.Logger.forContext('controllers/aws.sso.accounts.controller.ts');
// Log module initialization
controllerLogger.debug('AWS SSO accounts controller initialized');
/**
* List all AWS accounts and their roles (no pagination)
*
* Retrieves and formats all available AWS accounts and the roles the user
* can assume in each account via AWS SSO. Handles pagination internally.
*
* @async
* @returns {Promise<ControllerResponse>} Response with comprehensive formatted list of accounts and roles.
* @throws {Error} If account listing fails or authentication is required
*/
async function listAccounts() {
const listLogger = logger_util_js_1.Logger.forContext('controllers/aws.sso.accounts.controller.ts', 'listAccounts');
listLogger.debug('Listing ALL AWS SSO accounts');
try {
// --- Authentication Check ---
const cachedToken = await (0, vendor_aws_sso_auth_core_service_js_1.getCachedSsoToken)();
if (!cachedToken) {
return {
content: (0, aws_sso_accounts_formatter_js_1.formatAuthRequired)(),
};
}
if (!cachedToken.accessToken || cachedToken.accessToken.trim() === '') {
try {
await (0, aws_sso_cache_util_js_1.clearSsoToken)();
}
catch (e) {
listLogger.error('Error clearing invalid token', e);
}
return {
content: (0, aws_sso_accounts_formatter_js_1.formatAuthRequired)(),
};
}
const now = Math.floor(Date.now() / 1000);
if (cachedToken.expiresAt <= now) {
try {
await (0, aws_sso_cache_util_js_1.clearSsoToken)();
}
catch (e) {
listLogger.error('Error clearing expired token', e);
}
return {
content: (0, aws_sso_accounts_formatter_js_1.formatAuthRequired)(),
};
}
let expiresDate = 'Unknown';
try {
const expirationDate = new Date(cachedToken.expiresAt * 1000);
expiresDate = expirationDate.toLocaleString();
}
catch (error) {
listLogger.error('Error formatting expiration date', error);
}
// --- End Authentication Check ---
listLogger.debug('Fetching ALL AWS accounts with roles from service...');
try {
// Fetch the complete list from the service
const allAccountsData = await (0, vendor_aws_sso_accounts_service_js_1.getAllAccountsWithRoles)();
const totalAccountsFetched = allAccountsData.length;
listLogger.debug(`Fetched ${totalAccountsFetched} accounts in total.`);
// Handle case where no accounts are found
if (allAccountsData.length === 0) {
listLogger.debug('No accounts found after fetching.');
return {
content: (0, aws_sso_accounts_formatter_js_1.formatNoAccounts)(true),
};
}
// Format the accounts with roles
const formattedContent = (0, aws_sso_accounts_formatter_js_1.formatAccountsAndRoles)(expiresDate, allAccountsData);
// Return the content only
return {
content: formattedContent,
};
}
catch (error) {
// Handle API errors during account fetching (authentication check still applies)
if (error instanceof Error &&
(error.message.includes('invalid') ||
error.message.includes('expired') ||
error.message.includes('session'))) {
listLogger.debug('Token validation failed during API call', error);
return {
content: (0, aws_sso_accounts_formatter_js_1.formatAuthRequired)(),
};
}
throw error; // Rethrow other API errors
}
}
catch (error) {
// Handle broader errors
throw (0, error_handler_util_js_1.handleControllerError)(error, (0, error_types_util_js_1.buildErrorContext)('AWS SSO Accounts', 'listing all', 'controllers/aws.sso.accounts.controller.ts@listAccounts', undefined, {
hasToken: !!(await (0, vendor_aws_sso_auth_core_service_js_1.getCachedSsoToken)()),
}));
}
}
/**
* List roles available for a specified AWS account
*
* Retrieves and formats all IAM roles the authenticated user can assume
* in a specific AWS account via SSO.
*
* @async
* @param {ListRolesOptions} params - Role listing parameters
* @returns {Promise<ControllerResponse>} Response with formatted list of available roles
* @throws {Error} If role listing fails or authentication is invalid
* @example
* // List roles for account 123456789012
* const result = await listRoles({
* accessToken: "token-value",
* accountId: "123456789012"
* });
*/
async function listRoles(params) {
const listRolesLogger = logger_util_js_1.Logger.forContext('controllers/aws.sso.accounts.controller.ts', 'listRoles');
listRolesLogger.debug(`Listing roles for account ${params.accountId}`);
try {
// Get roles for account
const roles = await (0, vendor_aws_sso_accounts_service_js_1.listAccountRoles)({
accountId: params.accountId,
});
return {
content: (0, aws_sso_accounts_formatter_js_1.formatAccountRoles)(params.accountId, roles.roleList),
};
}
catch (error) {
throw (0, error_handler_util_js_1.handleControllerError)(error, (0, error_types_util_js_1.buildErrorContext)('AWS Account Roles', 'listing', 'controllers/aws.sso.accounts.controller.ts@listRoles', params.accountId, {
accountId: params.accountId,
}));
}
}
exports.default = {
listAccounts,
listRoles,
};