Skip to main content
Glama
ogbm77

Cisco CX Cloud MCP Server

by ogbm77
index.ts12 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, } from "@modelcontextprotocol/sdk/types.js"; import axios from "axios"; import { CiscoAuthClient } from "./auth.js"; import { logger } from "./logger.js"; // Load environment variables logger.info('Cisco CX Cloud MCP Server starting...'); logger.debug('Environment loaded', { logLevel: process.env.LOG_LEVEL || 'INFO', logToFile: process.env.LOG_TO_FILE || 'false', hasClientId: !!process.env.CISCO_CLIENT_ID, hasClientSecret: !!process.env.CISCO_CLIENT_SECRET }); const CX_CLOUD_BASE_URL = "https://apix.cisco.com/cs/api/v2"; // Initialize auth client const authClient = new CiscoAuthClient( process.env.CISCO_CLIENT_ID || "", process.env.CISCO_CLIENT_SECRET || "" ); // Helper function to make authenticated API calls async function makeApiCall(endpoint: string, customerId?: string): Promise<any> { const token = await authClient.getAccessToken(); let url = `${CX_CLOUD_BASE_URL}${endpoint}`; if (customerId) { url += `${endpoint.includes('?') ? '&' : '?'}customerId=${customerId}`; } logger.debug(`Making API call to: ${url}`); try { logger.apiRequest('GET', url, { Authorization: 'Bearer ***', }); const startTime = Date.now(); const response = await axios.get(url, { headers: { Authorization: `Bearer ${token}`, }, }); const duration = Date.now() - startTime; logger.apiResponse('GET', url, response.status, response.data); logger.debug(`API call completed in ${duration}ms`); return response.data; } catch (error) { logger.apiError('GET', url, error); if (axios.isAxiosError(error)) { throw new Error( `API call failed: ${error.response?.status} - ${error.response?.data?.message || error.message}` ); } throw error; } } const server = new Server( { name: "cisco-cx-cloud-mcp", version: "1.0.0", }, { capabilities: { tools: {}, }, } ); // Define the tools const tools: Tool[] = [ { name: "get_customer_accounts", description: "Get all accessible CX Cloud customer accounts and their IDs. Use this first to get customer IDs for other operations.", inputSchema: { type: "object", properties: {}, }, }, { name: "get_hardware_inventory", description: "Get hardware inventory for a specific customer. Returns details about all hardware assets.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID (get from get_customer_accounts first)", }, }, required: ["customerId"], }, }, { name: "get_network_elements", description: "Get network elements inventory for a specific customer. Returns network devices and their details.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_contracts", description: "Get all contracts for a specific customer. Returns contract details including coverage periods.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_covered_assets", description: "Get all assets covered by contracts for a specific customer.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_uncovered_assets", description: "Get all assets NOT covered by contracts for a specific customer. Useful for identifying coverage gaps.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_field_notices", description: "Get field notices for a specific customer. Returns important product notifications and bulletins.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_hardware_eol", description: "Get hardware end-of-life information for a specific customer. Shows which hardware is reaching end-of-life.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_software_eol", description: "Get software end-of-life information for a specific customer. Shows which software versions are reaching end-of-life.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, { name: "get_security_advisories", description: "Get security advisories for a specific customer. Returns security alerts and recommendations.", inputSchema: { type: "object", properties: { customerId: { type: "string", description: "The customer ID", }, }, required: ["customerId"], }, }, ]; // List tools handler server.setRequestHandler(ListToolsRequestSchema, async () => { logger.debug('ListTools request received'); return { tools, }; }); // Call tool handler server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; const startTime = Date.now(); logger.toolInvoked(name, args); try { switch (name) { case "get_customer_accounts": { const data = await makeApiCall("/customer-info/customer-details"); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_hardware_inventory": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/inventory/hardware", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_network_elements": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/inventory/network-elements", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_contracts": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/contracts/contract-details", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_covered_assets": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/contracts/coverage", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_uncovered_assets": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/contracts/not-covered", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_field_notices": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/product-alerts/field-notices", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_hardware_eol": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/product-alerts/hardware-eol", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_software_eol": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/product-alerts/software-eol", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } case "get_security_advisories": { const customerId = args?.customerId as string; if (!customerId) { throw new Error("customerId is required"); } const data = await makeApiCall("/product-alerts/security-advisories", customerId); return { content: [ { type: "text", text: JSON.stringify(data, null, 2), }, ], }; } default: logger.warn(`Unknown tool requested: ${name}`); throw new Error(`Unknown tool: ${name}`); } // Log successful completion const duration = Date.now() - startTime; logger.toolCompleted(name, true, duration); } catch (error) { const duration = Date.now() - startTime; logger.toolCompleted(name, false, duration); if (error instanceof Error) { logger.error(`Tool execution failed: ${name}`, error); return { content: [ { type: "text", text: `Error: ${error.message}`, }, ], isError: true, }; } throw error; } }); // Start the server async function main() { // Validate required environment variables if (!process.env.CISCO_CLIENT_ID || !process.env.CISCO_CLIENT_SECRET) { logger.error("Missing required environment variables: CISCO_CLIENT_ID and CISCO_CLIENT_SECRET"); console.error("Error: CISCO_CLIENT_ID and CISCO_CLIENT_SECRET must be set in .env file"); process.exit(1); } logger.info('Connecting to MCP transport...'); const transport = new StdioServerTransport(); await server.connect(transport); logger.info('Cisco CX Cloud MCP Server running on stdio'); logger.info('Server ready to accept requests'); console.error("Cisco CX Cloud MCP Server running on stdio"); } main().catch((error) => { logger.error("Fatal server error", error); console.error("Server error:", error); process.exit(1); });

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ogbm77/cisco-cx-cloud-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server