mcp-cisco-support
Version:
MCP server for Cisco Support APIs including Bug Search and future tools
332 lines • 15.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatBugResults = formatBugResults;
exports.formatCaseResults = formatCaseResults;
exports.formatEoxResults = formatEoxResults;
// Format bug results with hyperlinks (existing functionality)
function formatBugResults(data, searchContext) {
// Handle special error responses (like Case API placeholder)
if (data && typeof data === 'object' && 'error' in data && 'message' in data) {
let formatted = `# ⚠️ ${data.error}\n\n`;
formatted += `**${data.message}**\n\n`;
if (data.alternatives && Array.isArray(data.alternatives)) {
formatted += `## Alternative Approaches:\n\n`;
data.alternatives.forEach((alt, index) => {
formatted += `${index + 1}. ${alt}\n`;
});
formatted += `\n`;
}
if (data.example) {
formatted += `## Example:\n${data.example}\n\n`;
}
if (data.available_apis) {
formatted += `**Currently Available APIs:** ${data.available_apis.join(', ')}\n\n`;
}
if (data.planned_apis) {
formatted += `**Planned APIs:** ${data.planned_apis.join(', ')}\n\n`;
}
return formatted;
}
if (!data.bugs || data.bugs.length === 0) {
return JSON.stringify(data, null, 2);
}
let formatted = `# Cisco Bug Search Results\n\n`;
// Add search context if available
if (searchContext) {
formatted += formatSearchContext(searchContext);
}
if (data.total_results) {
formatted += `**Total Results:** ${data.total_results}\n\n`;
}
data.bugs.forEach((bug, index) => {
const bugUrl = `https://bst.cisco.com/bugsearch/bug/${bug.bug_id}`;
formatted += `## ${index + 1}. [${bug.bug_id}](${bugUrl})\n\n`;
formatted += `**Headline:** ${bug.headline}\n\n`;
formatted += `**Status:** ${bug.status}\n\n`;
formatted += `**Severity:** ${bug.severity}\n\n`;
formatted += `**Last Modified:** ${bug.last_modified_date}\n\n`;
// Add additional fields if they exist
Object.keys(bug).forEach(key => {
if (!['bug_id', 'headline', 'status', 'severity', 'last_modified_date'].includes(key)) {
const value = bug[key];
if (value && value !== '' && value !== null && value !== undefined) {
const fieldName = key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
formatted += `**${fieldName}:** ${value}\n\n`;
}
}
});
formatted += `**Bug URL:** ${bugUrl}\n\n`;
formatted += `---\n\n`;
});
return formatted;
}
// Format case results with hyperlinks
function formatCaseResults(data, searchContext) {
// Handle special error responses
if (data && typeof data === 'object' && 'error' in data && 'message' in data) {
let formatted = `# ⚠️ ${data.error}\n\n`;
formatted += `**${data.message}**\n\n`;
if (data.alternatives && Array.isArray(data.alternatives)) {
formatted += `## Alternative Approaches:\n\n`;
data.alternatives.forEach((alt, index) => {
formatted += `${index + 1}. ${alt}\n`;
});
formatted += `\n`;
}
return formatted;
}
if (!data.cases || data.cases.length === 0) {
return JSON.stringify(data, null, 2);
}
let formatted = `# Cisco Case Search Results\n\n`;
// Add search context if available
if (searchContext) {
formatted += formatSearchContext(searchContext);
}
if (data.total_results) {
formatted += `**Total Results:** ${data.total_results}\n\n`;
}
data.cases.forEach((caseItem, index) => {
// Note: Cisco Case Manager URL format may need adjustment based on actual Cisco portal
const caseUrl = `https://mycase.cloudapps.cisco.com/case/${caseItem.case_id}`;
formatted += `## ${index + 1}. [${caseItem.case_id}](${caseUrl})\n\n`;
formatted += `**Title:** ${caseItem.title}\n\n`;
formatted += `**Status:** ${caseItem.status}\n\n`;
formatted += `**Severity:** ${caseItem.severity}\n\n`;
formatted += `**Created:** ${caseItem.created_date}\n\n`;
formatted += `**Last Modified:** ${caseItem.last_modified_date}\n\n`;
// Add additional fields if they exist
Object.keys(caseItem).forEach(key => {
if (!['case_id', 'title', 'status', 'severity', 'created_date', 'last_modified_date'].includes(key)) {
const value = caseItem[key];
if (value && value !== '' && value !== null && value !== undefined) {
const fieldName = key.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
formatted += `**${fieldName}:** ${value}\n\n`;
}
}
});
formatted += `**Case URL:** ${caseUrl}\n\n`;
formatted += `---\n\n`;
});
return formatted;
}
// Format EoX results with hyperlinks
function formatEoxResults(data, searchContext) {
// Handle special error responses
if (data && typeof data === 'object' && 'error' in data && 'message' in data) {
let formatted = `# ⚠️ ${data.error}\n\n`;
formatted += `**${data.message}**\n\n`;
if (data.alternatives && Array.isArray(data.alternatives)) {
formatted += `## Alternative Approaches:\n\n`;
data.alternatives.forEach((alt, index) => {
formatted += `${index + 1}. ${alt}\n`;
});
formatted += `\n`;
}
return formatted;
}
if (!data.EOXRecord || data.EOXRecord.length === 0) {
return JSON.stringify(data, null, 2);
}
let formatted = `# Cisco End-of-Life (EoX) Results\n\n`;
// Add search context if available
if (searchContext) {
formatted += formatEoxSearchContext(searchContext);
}
// Add pagination info if available
if (data.PaginationResponseRecord) {
const pagination = data.PaginationResponseRecord;
formatted += `**Page:** ${pagination.PageIndex} of ${pagination.LastIndex}\n\n`;
formatted += `**Records:** ${pagination.PageRecords} of ${pagination.TotalRecords} total\n\n`;
}
data.EOXRecord.forEach((eoxItem, index) => {
// Check for errors first
const eoxError = eoxItem.EOXError;
if (eoxError && eoxError.ErrorID) {
formatted += `## ${index + 1}. ⚠️ EoX Lookup Error\n\n`;
formatted += `**Error ID:** ${eoxError.ErrorID}\n\n`;
formatted += `**Error Description:** ${eoxError.ErrorDescription}\n\n`;
formatted += `**Search Input:** ${eoxItem.EOXInputValue || 'N/A'} (${eoxItem.EOXInputType || 'Unknown Type'})\n\n`;
if (eoxError.ErrorDataType && eoxError.ErrorDataValue) {
formatted += `**Failed Lookup:** ${eoxError.ErrorDataType} = ${eoxError.ErrorDataValue}\n\n`;
}
formatted += `---\n\n`;
return; // Skip normal processing for error records
}
// Extract product ID (handle object structure)
const productId = extractValue(eoxItem.EOLProductID) || 'Unknown Product';
formatted += `## ${index + 1}. ${productId}\n\n`;
// Extract and format core fields
const description = extractValue(eoxItem.ProductIDDescription);
if (description) {
formatted += `**Product Description:** ${description}\n\n`;
}
// Format all date fields consistently
const dateFields = [
{ key: 'EOXExternalAnnouncementDate', label: 'End of Life Announcement' },
{ key: 'EndOfSaleDate', label: 'End of Sale Date' },
{ key: 'LastDateOfSupport', label: 'Last Date of Support' },
{ key: 'EndOfSWMaintenanceReleases', label: 'End of SW Maintenance' },
{ key: 'EndOfRoutineFailureAnalysisDate', label: 'End of Failure Analysis' },
{ key: 'EndOfServiceContractRenewal', label: 'End of Service Contract Renewal' },
{ key: 'UpdatedTimeStamp', label: 'Updated' }
];
dateFields.forEach(({ key, label }) => {
const dateValue = formatDate(eoxItem[key]);
if (dateValue && dateValue !== 'Not specified') {
formatted += `**${label}:** ${dateValue}\n\n`;
}
});
// Handle bulletin information
const bulletinNumber = extractValue(eoxItem.ProductBulletinNumber);
const bulletinURL = extractValue(eoxItem.LinkToProductBulletinURL);
if (bulletinNumber || bulletinURL) {
if (bulletinNumber) {
formatted += `**Product Bulletin:** ${bulletinNumber}\n\n`;
}
if (bulletinURL) {
formatted += `**Bulletin URL:** [${bulletinNumber || 'View Bulletin'}](${bulletinURL})\n\n`;
}
}
// Show additional fields that aren't explicitly handled
const handledKeys = [
'EOLProductID', 'ProductIDDescription', 'ProductBulletinNumber',
'LinkToProductBulletinURL', 'EOXExternalAnnouncementDate', 'EndOfSaleDate',
'EndOfSWMaintenanceReleases', 'EndOfRoutineFailureAnalysisDate',
'EndOfServiceContractRenewal', 'LastDateOfSupport', 'EndOfSvcAttachDate',
'UpdatedTimeStamp'
];
Object.keys(eoxItem).forEach(key => {
if (!handledKeys.includes(key)) {
const value = extractValue(eoxItem[key]);
if (value) {
const fieldName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());
formatted += `**${fieldName}:** ${value}\n\n`;
}
}
});
formatted += `---\n\n`;
});
return formatted;
}
// Helper function to format EoX search context
function formatEoxSearchContext(searchContext) {
let formatted = '';
if (searchContext.toolName === 'get_eox_by_date') {
formatted += `**Date Range:** ${searchContext.args.start_date} to ${searchContext.args.end_date}\n\n`;
if (searchContext.args.eox_attrib && searchContext.args.eox_attrib !== 'UPDATED_TIMESTAMP') {
formatted += `**EoX Attribute Filter:** ${searchContext.args.eox_attrib}\n\n`;
}
}
else if (searchContext.toolName === 'get_eox_by_product_id') {
formatted += `**Product IDs:** ${searchContext.args.product_ids}\n\n`;
}
else if (searchContext.toolName === 'get_eox_by_serial_number') {
formatted += `**Serial Numbers:** ${searchContext.args.serial_numbers}\n\n`;
}
else if (searchContext.toolName === 'get_eox_by_software_release') {
const inputs = [];
['input1', 'input2', 'input3', 'input4', 'input5'].forEach(inputKey => {
if (searchContext.args[inputKey]) {
inputs.push(searchContext.args[inputKey]);
}
});
formatted += `**Software Releases:** ${inputs.join(', ')}\n\n`;
}
return formatted;
}
// Helper function to extract values from EoX API object structures
function extractValue(value) {
if (!value) {
return null;
}
if (typeof value === 'string') {
return value.trim() || null;
}
if (typeof value === 'object') {
// Try common object properties
const valueKeys = ['value', '#text', 'text'];
for (const key of valueKeys) {
if (value[key]) {
const extracted = String(value[key]).trim();
return extracted || null;
}
}
return null;
}
return String(value).trim() || null;
}
// Helper function to format EoX date objects
function formatDate(dateValue) {
const extracted = extractValue(dateValue);
return extracted || 'Not specified';
}
// Helper function to format search context
function formatSearchContext(searchContext) {
let formatted = '';
if (searchContext.toolName === 'search_bugs_by_keyword' && searchContext.args.keyword) {
formatted += `**Search Keywords:** "${searchContext.args.keyword}"\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_id' && searchContext.args.base_pid) {
formatted += `**Product ID:** ${searchContext.args.base_pid}\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_and_release') {
formatted += `**Product ID:** ${searchContext.args.base_pid}\n\n`;
formatted += `**Software Releases:** ${searchContext.args.software_releases}\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_series_affected') {
formatted += `**Product Series:** ${searchContext.args.product_series}\n\n`;
formatted += `**Affected Releases:** ${searchContext.args.affected_releases}\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_series_fixed') {
formatted += `**Product Series:** ${searchContext.args.product_series}\n\n`;
formatted += `**Fixed Releases:** ${searchContext.args.fixed_releases}\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_name_affected') {
formatted += `**Product Name:** ${searchContext.args.product_name}\n\n`;
formatted += `**Affected Releases:** ${searchContext.args.affected_releases}\n\n`;
}
else if (searchContext.toolName === 'search_bugs_by_product_name_fixed') {
formatted += `**Product Name:** ${searchContext.args.product_name}\n\n`;
formatted += `**Fixed Releases:** ${searchContext.args.fixed_releases}\n\n`;
}
else if (searchContext.toolName.startsWith('get_case') || searchContext.toolName.includes('case')) {
// Case API context formatting
if (searchContext.args.case_id || searchContext.args.case_ids) {
formatted += `**Case ID(s):** ${searchContext.args.case_id || searchContext.args.case_ids}\n\n`;
}
if (searchContext.args.contract_id) {
formatted += `**Contract ID:** ${searchContext.args.contract_id}\n\n`;
}
if (searchContext.args.user_id) {
formatted += `**User ID:** ${searchContext.args.user_id}\n\n`;
}
}
// Add filters if specified
if (searchContext.args.status) {
const statusMap = {
'O': 'Open',
'F': 'Fixed',
'T': 'Terminated',
'C': 'Closed',
'W': 'Waiting',
'I': 'In Progress'
};
formatted += `**Status Filter:** ${statusMap[searchContext.args.status] || searchContext.args.status}\n\n`;
}
if (searchContext.args.severity) {
formatted += `**Severity Filter:** Severity ${searchContext.args.severity}\n\n`;
}
if (searchContext.args.modified_date && searchContext.args.modified_date !== '5') {
const dateMap = {
'1': 'Last Week',
'2': 'Last 30 Days',
'3': 'Last 6 Months',
'4': 'Last Year',
'5': 'All'
};
formatted += `**Modified Date Filter:** ${dateMap[searchContext.args.modified_date] || searchContext.args.modified_date}\n\n`;
}
return formatted;
}
//# sourceMappingURL=formatting.js.map