mcp-cisco-support
Version:
MCP server for Cisco Support APIs including Bug Search and future tools
806 lines (767 loc) • 35.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ENABLED_APIS = exports.apiRegistry = exports.logger = exports.setLogging = exports.mcpServer = exports.createProgressTracker = exports.sendProgress = exports.createElicitationRequest = exports.ElicitationSchemas = void 0;
exports.getAvailablePrompts = getAvailablePrompts;
exports.generatePrompt = generatePrompt;
exports.createMCPServer = createMCPServer;
exports.getAvailableTools = getAvailableTools;
exports.executeTool = executeTool;
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
const dotenv_1 = __importDefault(require("dotenv"));
const fs_1 = require("fs");
const path_1 = require("path");
// Import modular API system
const index_js_2 = require("./apis/index.js");
const formatting_js_1 = require("./utils/formatting.js");
const logger_js_1 = require("./utils/logger.js");
Object.defineProperty(exports, "setLogging", { enumerable: true, get: function () { return logger_js_1.setLogging; } });
Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_js_1.logger; } });
const icon_js_1 = require("./utils/icon.js");
const progress_js_1 = require("./utils/progress.js");
const cisco_prompts_js_1 = require("./prompts/cisco-prompts.js");
// Load environment variables
dotenv_1.default.config();
// Get version from package.json (handle different working directories)
function findPackageJson() {
const possiblePaths = [
(0, path_1.join)(__dirname, '../../package.json'), // When compiled to dist/src/
(0, path_1.join)(__dirname, '../package.json'), // When running from src/
(0, path_1.join)(process.cwd(), 'package.json'), // When running from project root
];
for (const path of possiblePaths) {
try {
return (0, fs_1.readFileSync)(path, 'utf8');
}
catch (error) {
// Continue to next path
}
}
// Fallback version
return JSON.stringify({ version: '1.5.0' });
}
const packageJson = JSON.parse(findPackageJson());
const VERSION = packageJson.version;
// Initialize API registry (will be created fresh each time for dynamic config)
let apiRegistry;
let ENABLED_APIS;
// Initialize or refresh the API registry
function initializeApiRegistry() {
exports.ENABLED_APIS = ENABLED_APIS = (0, index_js_2.getEnabledAPIs)();
exports.apiRegistry = apiRegistry = (0, index_js_2.createApiRegistry)();
}
// Initialize at module load
initializeApiRegistry();
// Prompts are now imported from ./prompts/cisco-prompts.js
// Elicitation schemas are now imported from ./elicitation/schemas.js
// Get available prompts (filtered by enabled APIs)
function getAvailablePrompts() {
return (0, cisco_prompts_js_1.getFilteredPrompts)(ENABLED_APIS);
}
// Generate prompt content based on prompt name and arguments
function generatePrompt(name, args) {
switch (name) {
case 'cisco-high-severity-search':
const maxSev = args.max_severity ? parseInt(args.max_severity) : 3;
const versionText = args.version ? ` version ${args.version}` : '';
return [
{
role: 'user',
content: {
type: 'text',
text: `Search for high-severity bugs for ${args.product_keyword}${versionText}:
**Search Requirements:**
- Product: ${args.product_keyword}${versionText}
- Severity: ${maxSev} or higher (1 = highest severity)
- Status: Open bugs only
**Important:** The Cisco Bug API only accepts ONE severity level per search. You must search each severity individually:
1. First search: severity="1", status="O", keyword="${args.product_keyword}${versionText}"
2. Second search: severity="2", status="O", keyword="${args.product_keyword}${versionText}"
${maxSev >= 3 ? `3. Third search: severity="3", status="O", keyword="${args.product_keyword}${versionText}"` : ''}
Please execute these searches sequentially and combine the results. Do NOT use comma-separated values like "1,2,3" for severity as this will cause a 500 error.`
}
}
];
case 'cisco-incident-investigation':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me investigate this Cisco incident:
**Incident Details:**
- Symptom/Error: ${args.symptom}
- Product: ${args.product}
${args.severity ? `- Severity: Level ${args.severity}` : ''}
${args.software_version ? `- Software Version: ${args.software_version}` : ''}
**Investigation Plan:**
1. Search for bugs matching the symptom keywords
2. Check product-specific bugs ${args.software_version ? `for version ${args.software_version}` : ''}
3. Focus on ${args.severity ? `severity ${args.severity} and higher` : 'high severity'} issues
4. Look for workarounds and fixes
Please start by searching for bugs related to "${args.symptom}" and then narrow down by product specifics.`
}
}
];
case 'cisco-upgrade-planning':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me plan a Cisco software upgrade:
**Upgrade Details:**
- Current Version: ${args.current_version}
- Target Version: ${args.target_version}
- Product: ${args.product}
${args.environment ? `- Environment: ${args.environment}` : ''}
**Pre-Upgrade Analysis Needed:**
1. Find bugs fixed between ${args.current_version} and ${args.target_version}
2. Identify new bugs introduced in ${args.target_version}
3. Check for upgrade-blocking issues
4. Look for known upgrade procedures and considerations
Please search for bugs related to both versions and provide an upgrade risk assessment.`
}
}
];
case 'cisco-maintenance-prep':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me prepare for Cisco maintenance:
**Maintenance Details:**
- Type: ${args.maintenance_type}
- Product: ${args.product}
${args.software_version ? `- Software Version: ${args.software_version}` : ''}
${args.timeline ? `- Timeline: ${args.timeline}` : ''}
**Pre-Maintenance Checklist:**
1. Search for bugs related to ${args.maintenance_type.toLowerCase()}
2. Check for product-specific issues ${args.software_version ? `in version ${args.software_version}` : ''}
3. Identify potential failure scenarios
4. Find recommended procedures and precautions
5. Look for rollback considerations
Please help me identify risks and create a maintenance plan with appropriate safeguards.`
}
}
];
case 'cisco-security-advisory':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me research security issues for Cisco products:
**Security Assessment:**
- Product: ${args.product}
${args.software_version ? `- Version: ${args.software_version}` : ''}
${args.security_focus ? `- Focus Area: ${args.security_focus}` : ''}
**Security Analysis Needed:**
1. Search for security-related bugs and vulnerabilities
2. Focus on high-severity security issues
3. Check for recent security advisories
4. Look for patches and mitigation strategies
${args.security_focus ? `5. Specific research on: ${args.security_focus}` : ''}
Please search for security bugs using relevant keywords like "security", "vulnerability", "CVE", "DoS", "authentication", "authorization", etc.`
}
}
];
case 'cisco-known-issues':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me research known issues in Cisco software:
**Research Target:**
- Product: ${args.product}
- Software Version: ${args.software_version}
${args.issue_type ? `- Issue Focus: ${args.issue_type}` : ''}
**Known Issues Analysis:**
1. Search for bugs in ${args.software_version}
2. Focus on ${args.issue_type || 'all types of'} issues
3. Check bug status (open vs. fixed)
4. Look for workarounds and solutions
5. Identify upgrade recommendations
Please search comprehensively for bugs affecting this version and provide a summary of major known issues.`
}
}
];
case 'cisco-case-investigation':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me investigate Cisco support cases:
**Investigation Target:**
${args.case_id ? `- Case ID: ${args.case_id}` : ''}
${args.contract_id ? `- Contract ID: ${args.contract_id}` : ''}
${args.user_id ? `- User ID: ${args.user_id}` : ''}
${args.status ? `- Status Filter: ${args.status}` : ''}
**Case Investigation Plan:**
${args.case_id ? '1. Get detailed case information' : ''}
${args.contract_id ? '1. Search cases by contract ID' : ''}
${args.user_id ? '1. Search cases by user ID' : ''}
2. Analyze case status and severity
3. Look for related cases or patterns
4. Check for associated bugs or known issues
Please use the appropriate Case API tools to gather comprehensive case information.`
}
}
];
case 'cisco-lifecycle-planning':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me plan for Cisco product lifecycle management:
**Lifecycle Planning Target:**
${args.product_ids ? `- Product IDs: ${args.product_ids}` : ''}
${args.serial_numbers ? `- Serial Numbers: ${args.serial_numbers}` : ''}
${args.date_range_start && args.date_range_end ? `- Date Range: ${args.date_range_start} to ${args.date_range_end}` : ''}
**Lifecycle Analysis Plan:**
1. Check end-of-life and end-of-sale dates for specified products
2. Identify upcoming maintenance and support end dates
3. Analyze end-of-software maintenance dates
4. Review product bulletins and migration information
5. Plan replacement timeline and budget considerations
**Key Dates to Monitor:**
- End of Sale Date (when product stops being sold)
- End of Software Maintenance (when software updates stop)
- Last Date of Support (when all support ends)
- End of Service Contract Renewal (when new contracts stop)
Please use the EoX API tools to gather comprehensive lifecycle information for planning purposes.`
}
}
];
case 'cisco-eox-research':
return [
{
role: 'user',
content: {
type: 'text',
text: `Help me research Cisco end-of-life information:
**Research Focus:** ${args.product_focus}
**Search Values:** ${args.search_values}
**EoX Research Plan:**
${args.product_focus === 'product_ids' ? '1. Search EoX information by Product IDs' : ''}
${args.product_focus === 'serial_numbers' ? '1. Search EoX information by Serial Numbers' : ''}
${args.product_focus === 'software_releases' ? '1. Search EoX information by Software Releases' : ''}
${args.product_focus === 'date_range' ? '1. Search EoX information by Date Range' : ''}
2. Analyze end-of-life timeline and critical dates
3. Review product bulletins and migration guides
4. Identify replacement products and upgrade paths
5. Assess impact on current operations
**Important EoX Milestones:**
- **End of Life Announcement:** When Cisco announces the product's retirement
- **End of Sale:** Last date to order the product
- **End of Software Maintenance:** Last software updates and bug fixes
- **End of Support:** All technical support ends
Please use the appropriate EoX API tools based on the research focus area.`
}
}
];
case 'cisco-smart-search':
const includeWebGuidance = args.include_web_guidance !== 'false';
return [
{
role: 'user',
content: {
type: 'text',
text: `Please perform an intelligent search analysis for: "${args.search_query}"
**Search Strategy Request:**
${args.search_context ? `- Context: ${args.search_context}` : ''}
- Query: ${args.search_query}
- Include web search guidance: ${includeWebGuidance}
**Recommended Approach:**
1. **Start with Smart Search Strategy**: Use \`smart_search_strategy\` tool to analyze the query and get optimal search recommendations
2. **Execute Comprehensive Analysis**: Use \`comprehensive_analysis\` tool with the product identifier and version detected
3. **Apply Progressive Search**: If initial results are limited, the system will automatically try broader search terms
4. **Multi-Severity Coverage**: For high-priority searches, automatically search multiple severity levels
${includeWebGuidance ? '5. **Web Search Guidance**: Get specific web search queries for additional research on Cisco.com' : ''}
**Enhanced Features Available:**
- **Product ID Resolution**: Converts technical product codes (ISR4431/K9) to full product names
- **Version Normalization**: Tries multiple version formats (17.09.06 → 17.09 → 17)
- **Automatic Refinement**: Broadens search scope when specific queries return no results
- **Parallel Severity Search**: Searches multiple severity levels simultaneously
- **Lifecycle Integration**: Includes end-of-life status and upgrade recommendations
Please execute this intelligent search strategy using the enhanced tools to provide comprehensive results.`
}
}
];
case 'cisco-interactive-search':
const useElicitation = args.use_elicitation !== 'false';
return [
{
role: 'user',
content: {
type: 'text',
text: `Please perform an interactive search that demonstrates the elicitationRequest feature:
**Interactive Search Configuration:**
${args.initial_query ? `- Initial Query: ${args.initial_query}` : '- No initial query provided'}
- Use Elicitation: ${useElicitation}
**Demonstration Approach:**
1. **Start with Basic Search**: Use the provided initial query or ask for one
2. **Elicitation Demo**: Use elicitationRequest to gather additional search parameters:
- Ask for search refinement (severity, status, date range)
- Request user confirmation for search strategy
- Collect product selection if multiple matches found
3. **Interactive Refinement**: Based on initial results, use elicitation to:
- Refine search scope if too many results
- Request confirmation before broad searches
- Ask for product-specific details if needed
4. **Enhanced Results**: Provide comprehensive results with context
**Available Elicitation Schemas:**
- \`searchRefinement\`: Request severity, status, and date range parameters
- \`userConfirmation\`: Request confirmation for search strategy
- \`productSelection\`: Request specific product selection from options
**Example Elicitation Flow:**
1. If no initial query: "What would you like to search for in Cisco bugs?"
2. If broad results: "I found many results. Would you like to refine by severity level?"
3. If multiple products: "I found several products. Which specific one interests you?"
4. If potentially impactful: "This search will query multiple APIs. Proceed?"
This interactive approach showcases how elicitationRequest can make tools more user-friendly and context-aware.`
}
}
];
default:
throw new Error(`Unknown prompt: ${name}`);
}
}
// ============================================================================
// ELICITATION REQUEST SUPPORT - FUTURE/EXPERIMENTAL
// ============================================================================
// Note: ElicitationRequest is part of MCP spec (2025-06-18) but client support
// is limited as of January 2025. No major MCP clients (including Claude Desktop)
// have confirmed full implementation yet.
//
// Current Status:
// - ❌ Claude Desktop: No confirmed support
// - ❌ MCP Inspector: Unknown support
// - ✅ Spec compliant: Code follows MCP 2025-06-18 specification
//
// Alternative: Claude Desktop handles missing parameters through natural
// conversational follow-up questions, which works better than rigid schemas.
//
// This code is kept for:
// - Future client support (when available)
// - Custom MCP client implementations
// - HTTP mode with custom UI
// - Reference implementation
//
// Last Updated: January 2025 (v1.11.3)
// ============================================================================
// Elicitation request utilities are now exported from ./elicitation/schemas.js
// Re-export for backward compatibility
var schemas_js_1 = require("./elicitation/schemas.js");
Object.defineProperty(exports, "ElicitationSchemas", { enumerable: true, get: function () { return schemas_js_1.ElicitationSchemas; } });
Object.defineProperty(exports, "createElicitationRequest", { enumerable: true, get: function () { return schemas_js_1.createElicitationRequest; } });
// Format results based on API type
function formatResults(result, apiName, toolName, args) {
const searchContext = { toolName, args };
if (apiName === 'Bug' || toolName.includes('bug')) {
return (0, formatting_js_1.formatBugResults)(result, searchContext);
}
else if (apiName === 'Case' || toolName.includes('case')) {
return (0, formatting_js_1.formatCaseResults)(result, searchContext);
}
else if (apiName === 'EoX' || toolName.includes('eox')) {
return (0, formatting_js_1.formatEoxResults)(result, searchContext);
}
else {
// For placeholder APIs, the result already contains formatted error message
return (0, formatting_js_1.formatBugResults)(result, searchContext);
}
}
// Re-export progress utilities for backward compatibility
var progress_js_2 = require("./utils/progress.js");
Object.defineProperty(exports, "sendProgress", { enumerable: true, get: function () { return progress_js_2.sendProgress; } });
Object.defineProperty(exports, "createProgressTracker", { enumerable: true, get: function () { return progress_js_2.createProgressTracker; } });
// Create MCP server
function createMCPServer() {
const server = new index_js_1.Server({
name: 'mcp-cisco-support',
version: VERSION,
icon: icon_js_1.SERVER_ICON,
}, {
capabilities: {
tools: {},
prompts: {},
resources: {},
elicitation: {},
},
});
// Initialize progress notification system
(0, progress_js_1.initializeProgressNotifications)(server);
// Reinitialize API registry with server instance for sampling support
exports.ENABLED_APIS = ENABLED_APIS = (0, index_js_2.getEnabledAPIs)(); // Refresh enabled APIs list
exports.apiRegistry = apiRegistry = (0, index_js_2.createApiRegistry)(server);
// Ping handler
server.setRequestHandler(types_js_1.PingRequestSchema, async () => {
logger_js_1.logger.info('Ping request received');
return {};
});
// Elicitation request handler
server.setRequestHandler(types_js_1.ElicitRequestSchema, async (request) => {
const { message, requestedSchema } = request.params;
try {
logger_js_1.logger.info('Elicitation request received', {
message: message?.substring(0, 100) + (message?.length > 100 ? '...' : ''),
schemaProperties: Object.keys(requestedSchema?.properties || {})
});
// For demonstration purposes, we'll create a sample elicitation request
// In a real implementation, this would interact with the client
const result = {
action: 'accept',
content: {
// This is a placeholder - in practice, the client would provide this data
sample: 'This is a sample elicitation response'
}
};
logger_js_1.logger.info('Elicitation request completed', {
action: result.action,
hasContent: !!result.content
});
return result;
}
catch (error) {
logger_js_1.logger.error('Elicitation request failed', {
error: error instanceof Error ? error.message : error
});
return {
action: 'cancel'
};
}
});
// List tools handler
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
return {
tools: apiRegistry.getAvailableTools(),
};
});
// Call tool handler
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const meta = request.params._meta;
try {
logger_js_1.logger.info('Tool call started', { name, args, hasProgressToken: !!meta?.progressToken });
const { result, apiName } = await apiRegistry.executeTool(name, args || {}, meta);
logger_js_1.logger.info('Tool call completed', {
name,
apiName,
resultCount: ('bugs' in result && Array.isArray(result.bugs)) ? result.bugs.length :
('cases' in result && Array.isArray(result.cases)) ? result.cases.length :
('EOXRecord' in result && Array.isArray(result.EOXRecord)) ? result.EOXRecord.length : 0
});
const content = {
type: 'text',
text: formatResults(result, apiName, name, args || {})
};
return {
content: [content],
isError: false,
};
}
catch (error) {
logger_js_1.logger.error('Tool call failed', {
name,
error: error instanceof Error ? error.message : error
});
// Provide helpful error messages for common issues
let errorMessage = error instanceof Error ? error.message : 'Unknown error';
if (errorMessage.includes('Unknown tool')) {
errorMessage += '\n\nℹ️ Currently available tools:\n' +
apiRegistry.getAvailableTools().map(t => `• ${t.name}: ${t.description}`).join('\n');
errorMessage += `\n\nℹ️ Enabled APIs: ${ENABLED_APIS.join(', ')}`;
}
if (errorMessage.includes('Tool implementation not found')) {
errorMessage += '\n\nℹ️ This tool may require an API that is not yet implemented or enabled.';
errorMessage += `\nCurrently enabled APIs: ${ENABLED_APIS.join(', ')}`;
errorMessage += `\nTo enable more APIs, set SUPPORT_API environment variable (e.g., SUPPORT_API=bug,case)`;
}
const errorContent = {
type: 'text',
text: `Error: ${errorMessage}`
};
return {
content: [errorContent],
isError: true,
};
}
});
// List prompts handler
server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => {
logger_js_1.logger.info('List prompts request received');
return {
prompts: getAvailablePrompts(),
};
});
// Get prompt handler
server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
logger_js_1.logger.info('Get prompt request', { name, args });
const messages = generatePrompt(name, args || {});
logger_js_1.logger.info('Prompt generated', { name, messageCount: messages.length });
return {
messages,
};
}
catch (error) {
logger_js_1.logger.error('Prompt generation failed', {
name,
error: error instanceof Error ? error.message : error
});
throw error;
}
});
// Helper function to get resource templates
function getResourceTemplates() {
const resourceTemplates = [];
// Bug resources (if bug API is enabled)
if (ENABLED_APIS.includes('bug')) {
resourceTemplates.push({
uriTemplate: 'cisco://bugs/{bug_id}',
name: 'Cisco Bug Report',
description: 'Access any Cisco bug by its ID (e.g., CSCvi12345)',
mimeType: 'application/json'
});
}
// Product resources (if product API is enabled)
if (ENABLED_APIS.includes('product')) {
resourceTemplates.push({
uriTemplate: 'cisco://products/{product_id}',
name: 'Cisco Product Information',
description: 'Get product details by product ID (e.g., C9300-24P, ISR4431)',
mimeType: 'application/json'
});
}
// Security resources (if PSIRT API is enabled)
if (ENABLED_APIS.includes('psirt')) {
resourceTemplates.push({
uriTemplate: 'cisco://security/advisories/{advisory_id}',
name: 'Cisco Security Advisory',
description: 'Get security advisory by ID (e.g., cisco-sa-20180221-ucdm)',
mimeType: 'application/json'
}, {
uriTemplate: 'cisco://security/cve/{cve_id}',
name: 'Security Advisory by CVE',
description: 'Get security advisory by CVE identifier (e.g., CVE-2018-0101)',
mimeType: 'application/json'
});
}
return resourceTemplates;
}
// List resources handler
server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async () => {
logger_js_1.logger.info('List resources request received');
const resources = [];
// Bug resources (if bug API is enabled)
if (ENABLED_APIS.includes('bug')) {
resources.push({
uri: 'cisco://bugs/recent/critical',
name: 'Recent Critical Bugs',
description: 'High-severity bugs from the last 7 days',
mimeType: 'application/json'
}, {
uri: 'cisco://bugs/recent/high',
name: 'Recent High-Severity Bugs',
description: 'Severity 1-3 bugs from the last 30 days',
mimeType: 'application/json'
});
}
// Product resources (if product API is enabled)
if (ENABLED_APIS.includes('product')) {
resources.push({
uri: 'cisco://products/catalog',
name: 'Product Catalog',
description: 'Product catalog overview',
mimeType: 'application/json'
});
}
// Security resources (if PSIRT API is enabled)
if (ENABLED_APIS.includes('psirt')) {
resources.push({
uri: 'cisco://security/advisories/recent',
name: 'Recent Security Advisories',
description: 'Latest 20 security advisories from Cisco PSIRT',
mimeType: 'application/json'
}, {
uri: 'cisco://security/advisories/critical',
name: 'Critical Security Advisories',
description: 'Critical severity security advisories',
mimeType: 'application/json'
});
}
logger_js_1.logger.info('Returning resources', { resourceCount: resources.length });
return { resources };
});
// List resource templates handler (separate method per MCP spec 2025-06-18)
server.setRequestHandler(types_js_1.ListResourceTemplatesRequestSchema, async () => {
logger_js_1.logger.info('List resource templates request received');
const resourceTemplates = getResourceTemplates();
logger_js_1.logger.info('Returning resource templates', {
templateCount: resourceTemplates.length
});
return { resourceTemplates };
});
// Read resource handler
server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
const { uri } = request.params;
logger_js_1.logger.info('Read resource request', { uri });
try {
let result;
let description = '';
// Bug resources
if (uri === 'cisco://bugs/recent/critical') {
description = 'Recent critical bugs (severity 1-2) from last 7 days';
const bugs1 = await apiRegistry.executeTool('search_bugs_by_keyword', {
keyword: 'cisco',
severity: '1',
modified_date: '1'
});
const bugs2 = await apiRegistry.executeTool('search_bugs_by_keyword', {
keyword: 'cisco',
severity: '2',
modified_date: '1'
});
result = {
description,
severity1: bugs1.result,
severity2: bugs2.result
};
}
else if (uri === 'cisco://bugs/recent/high') {
description = 'Recent high-severity bugs (severity 1-3) from last 30 days';
const bugs1 = await apiRegistry.executeTool('search_bugs_by_keyword', {
keyword: 'bug',
severity: '1',
modified_date: '2'
});
const bugs2 = await apiRegistry.executeTool('search_bugs_by_keyword', {
keyword: 'bug',
severity: '2',
modified_date: '2'
});
const bugs3 = await apiRegistry.executeTool('search_bugs_by_keyword', {
keyword: 'bug',
severity: '3',
modified_date: '2'
});
result = {
description,
severity1: bugs1.result,
severity2: bugs2.result,
severity3: bugs3.result
};
}
else if (uri.startsWith('cisco://bugs/')) {
// Dynamic bug lookup: cisco://bugs/{bug_id}
const bugId = uri.replace('cisco://bugs/', '');
description = `Bug details for ${bugId}`;
const bugResult = await apiRegistry.executeTool('get_bug_details', {
bug_ids: bugId
});
result = bugResult.result;
}
else if (uri.startsWith('cisco://products/')) {
// Dynamic product lookup: cisco://products/{product_id}
const productId = uri.replace('cisco://products/', '');
if (productId === 'catalog') {
result = {
description: 'Use cisco://products/{product_id} to access specific product information',
examples: [
'cisco://products/C9300-24P',
'cisco://products/ISR4431',
'cisco://products/ASA5516-X'
]
};
}
else {
description = `Product information for ${productId}`;
const productResult = await apiRegistry.executeTool('get_product_info_by_product_ids', {
product_ids: productId
});
result = productResult.result;
}
}
else if (uri === 'cisco://security/advisories/recent') {
description = 'Latest 20 security advisories';
const advisories = await apiRegistry.executeTool('get_latest_security_advisories', {
number: 20,
summary_details: true
});
result = advisories.result;
}
else if (uri === 'cisco://security/advisories/critical') {
description = 'Critical severity security advisories';
const advisories = await apiRegistry.executeTool('get_security_advisories_by_severity', {
severity: 'critical',
page_size: 20,
summary_details: true
});
result = advisories.result;
}
else if (uri.startsWith('cisco://security/advisories/')) {
// Dynamic advisory lookup: cisco://security/advisories/{advisory_id}
const advisoryId = uri.replace('cisco://security/advisories/', '');
description = `Security advisory ${advisoryId}`;
const advisory = await apiRegistry.executeTool('get_security_advisory_by_id', {
advisory_id: advisoryId,
summary_details: true
});
result = advisory.result;
}
else if (uri.startsWith('cisco://security/cve/')) {
// CVE lookup: cisco://security/cve/{cve_id}
const cveId = uri.replace('cisco://security/cve/', '');
description = `Security advisory for ${cveId}`;
const advisory = await apiRegistry.executeTool('get_security_advisory_by_cve', {
cve_id: cveId,
summary_details: true
});
result = advisory.result;
}
else {
throw new Error(`Unknown resource URI: ${uri}`);
}
logger_js_1.logger.info('Resource read completed', { uri });
return {
contents: [{
uri,
mimeType: 'application/json',
text: JSON.stringify({ description, data: result }, null, 2)
}]
};
}
catch (error) {
logger_js_1.logger.error('Resource read failed', {
uri,
error: error instanceof Error ? error.message : error
});
throw error;
}
});
return server;
}
// Export the main server instance and utilities
exports.mcpServer = createMCPServer();
// Export functions for backward compatibility with tests
function getAvailableTools() {
// Reinitialize registry to pick up any environment changes
initializeApiRegistry();
return apiRegistry.getAvailableTools();
}
async function executeTool(name, args) {
// Reinitialize registry to pick up any environment changes
initializeApiRegistry();
const { result } = await apiRegistry.executeTool(name, args);
return result;
}
//# sourceMappingURL=mcp-server.js.map