Skip to main content
Glama
http-server.ts12 kB
/* * MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import express, { Request, Response, NextFunction } from 'express'; import cors from 'cors'; import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { IntersightApiService } from './services/intersightApi.js'; import { loadConfig, loadMCPServerConfig, isToolEnabled, getEnabledTools, MCPServerConfig } from './utils/config.js'; import { IntersightMCPServer } from './server.js'; const app = express(); const port = process.env.PORT || 3000; // Middleware app.use(cors()); app.use(express.json({ limit: '10mb' })); // Initialize API Service and MCP Configuration let apiService: IntersightApiService; let mcpConfig: MCPServerConfig; let mcpServer: IntersightMCPServer; let allTools: Tool[]; let enabledTools: Tool[]; try { const config = loadConfig(); mcpConfig = loadMCPServerConfig(); apiService = new IntersightApiService(config); mcpServer = new IntersightMCPServer(); // Get tools from the MCP server instance allTools = (mcpServer as any).getAllTools(); enabledTools = getEnabledTools(allTools, mcpConfig); console.log('✅ Intersight API Service initialized successfully'); console.log(`🔧 Configuration: ${mcpConfig.serverConfig.toolSelectionMode} mode`); console.log(`🛠️ Tools: ${enabledTools.length} of ${allTools.length} enabled`); } catch (error) { console.error('❌ Failed to initialize API Service:', error); process.exit(1); } // Tool execution function (uses the MCP server's handleToolCall) async function executeTool(name: string, args: Record<string, any>): Promise<any> { // Security check: verify tool is enabled const allToolNames = allTools.map(t => t.name); if (!isToolEnabled(name, mcpConfig, allToolNames)) { throw new Error(`Tool '${name}' is not enabled in current configuration. Use INTERSIGHT_TOOL_MODE=all to enable all tools.`); } // Use the MCP server's tool execution logic return (mcpServer as any).handleToolCall(name, args); } // Health check endpoint app.get('/health', (req: Request, res: Response) => { res.json({ status: 'healthy', timestamp: new Date().toISOString(), version: '1.0.16', configuration: { toolMode: mcpConfig.serverConfig.toolSelectionMode, enabledTools: enabledTools.length, totalTools: allTools.length, enableAllTools: mcpConfig.serverConfig.enableAllTools }, description: 'Intersight MCP HTTP Server - v1.0.16 with Tool Configuration' }); }); // API info endpoint app.get('/api/info', (req: Request, res: Response) => { res.json({ name: 'Intersight MCP Server', version: '1.0.16', description: 'HTTP API for Cisco Intersight MCP tools with configurable tool modes', configuration: { toolMode: mcpConfig.serverConfig.toolSelectionMode, enabledTools: enabledTools.length, totalTools: allTools.length, toolModeEnv: process.env.INTERSIGHT_TOOL_MODE || 'core (default)' }, endpoints: { health: '/health', tools: '/api/tools', execute: '/api/execute', search: '/api/tools/search', batch: '/api/batch', config: '/api/config' }, documentation: 'https://github.com/jim-coyne/Intersight_MCP' }); }); // Configuration endpoint app.get('/api/config', (req: Request, res: Response) => { res.json({ success: true, configuration: { serverName: mcpConfig.serverConfig.name, toolSelectionMode: mcpConfig.serverConfig.toolSelectionMode, enableAllTools: mcpConfig.serverConfig.enableAllTools, serverProfileFocus: mcpConfig.serverConfig.serverProfileFocus, enabledToolsCount: enabledTools.length, totalToolsCount: allTools.length, environmentVariable: process.env.INTERSIGHT_TOOL_MODE || 'not set (using default: core)' }, instructions: { coreMode: 'Set INTERSIGHT_TOOL_MODE=core for 65 safe, read-only tools', allMode: 'Set INTERSIGHT_TOOL_MODE=all for 199+ tools with full CRUD capabilities' } }); }); // List available tools app.get('/api/tools', async (req: Request, res: Response) => { try { res.json({ success: true, configuration: { toolMode: mcpConfig.serverConfig.toolSelectionMode, enabledTools: enabledTools.length, totalTools: allTools.length }, tools: enabledTools.map((tool: Tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema?.properties || {} })) }); } catch (error) { res.status(500).json({ success: false, error: 'Failed to retrieve tools', message: error instanceof Error ? error.message : String(error) }); } }); // Execute a tool app.post('/api/execute', async (req: Request, res: Response) => { try { const { tool, parameters = {} } = req.body; if (!tool) { return res.status(400).json({ success: false, error: 'Tool name is required', usage: 'POST /api/execute with { "tool": "tool_name", "parameters": {...} }' }); } // Check if tool exists in enabled tools const toolExists = enabledTools.some((t: Tool) => t.name === tool); if (!toolExists) { return res.status(400).json({ success: false, error: `Tool not available: ${tool}`, message: `Tool '${tool}' is not enabled in current configuration (${mcpConfig.serverConfig.toolSelectionMode} mode)`, availableTools: enabledTools.map((t: Tool) => t.name), hint: 'Use INTERSIGHT_TOOL_MODE=all to enable all tools' }); } // Execute the tool const result = await executeTool(tool, parameters); res.json({ success: true, tool: tool, parameters: parameters, result: result, timestamp: new Date().toISOString() }); } catch (error) { res.status(500).json({ success: false, error: 'Tool execution failed', message: error instanceof Error ? error.message : String(error), timestamp: new Date().toISOString() }); } }); // Batch tool execution app.post('/api/batch', async (req: Request, res: Response) => { try { const { operations } = req.body; if (!Array.isArray(operations)) { return res.status(400).json({ success: false, error: 'Operations must be an array', usage: 'POST /api/batch with { "operations": [{"tool": "tool_name", "parameters": {...}}, ...] }' }); } const results = []; for (const operation of operations) { try { const result = await executeTool(operation.tool, operation.parameters || {}); results.push({ success: true, tool: operation.tool, result: result }); } catch (error) { results.push({ success: false, tool: operation.tool, error: error instanceof Error ? error.message : String(error) }); } } res.json({ success: true, totalOperations: operations.length, results: results, timestamp: new Date().toISOString() }); } catch (error) { res.status(500).json({ success: false, error: 'Batch execution failed', message: error instanceof Error ? error.message : String(error) }); } }); // Search tools by name or description app.get('/api/tools/search', (req: Request, res: Response) => { try { const { query } = req.query; if (!query) { return res.status(400).json({ success: false, error: 'Search query is required', usage: 'GET /api/tools/search?query=search_term' }); } const searchTerm = (query as string).toLowerCase(); const matchingTools = enabledTools.filter((tool: Tool) => tool.name.toLowerCase().includes(searchTerm) || (tool.description && tool.description.toLowerCase().includes(searchTerm)) ); res.json({ success: true, query: query, totalMatches: matchingTools.length, tools: matchingTools.map((tool: Tool) => ({ name: tool.name, description: tool.description, parameters: tool.inputSchema?.properties || {} })) }); } catch (error) { res.status(500).json({ success: false, error: 'Search failed', message: error instanceof Error ? error.message : String(error) }); } }); // Get tool details app.get('/api/tools/:toolName', (req: Request, res: Response) => { try { const { toolName } = req.params; const tool = enabledTools.find((t: Tool) => t.name === toolName); if (!tool) { return res.status(404).json({ success: false, error: `Tool not found: ${toolName}`, availableTools: enabledTools.map((t: Tool) => t.name) }); } res.json({ success: true, tool: { name: tool.name, description: tool.description, parameters: tool.inputSchema?.properties || {}, required: tool.inputSchema?.required || [] } }); } catch (error) { res.status(500).json({ success: false, error: 'Failed to retrieve tool details', message: error instanceof Error ? error.message : String(error) }); } }); // Error handling middleware app.use((error: any, req: Request, res: Response, next: NextFunction) => { console.error('Express error:', error); res.status(500).json({ success: false, error: 'Internal server error', message: error.message }); }); // 404 handler app.use((req: Request, res: Response) => { res.status(404).json({ success: false, error: 'Endpoint not found', availableEndpoints: [ 'GET /health', 'GET /api/info', 'GET /api/tools', 'GET /api/tools/:toolName', 'GET /api/tools/search?query=term', 'POST /api/execute', 'POST /api/batch' ] }); }); // Start server app.listen(port, () => { console.log(`🚀 Intersight MCP HTTP Server v1.0.15 running on port ${port}`); console.log(`🔧 Configuration Mode: ${mcpConfig.serverConfig.toolSelectionMode.toUpperCase()}`); console.log(`⚡ Enabled Tools: ${enabledTools.length} tools available`); console.log(''); console.log(`� Health check: http://localhost:${port}/health`); console.log(`🔧 API info: http://localhost:${port}/api/info`); console.log(`🛠️ Tools list: http://localhost:${port}/api/tools`); console.log(`🔍 Search tools: http://localhost:${port}/api/tools/search?query=server`); console.log(`⚙️ Execute tool: POST http://localhost:${port}/api/execute`); console.log(''); console.log(`💡 To enable all tools, set: INTERSIGHT_TOOL_MODE=all`); console.log(`💡 To use core tools only, set: INTERSIGHT_TOOL_MODE=core`); }); // Graceful shutdown process.on('SIGTERM', () => { console.log('📝 SIGTERM received, shutting down gracefully'); process.exit(0); }); process.on('SIGINT', () => { console.log('📝 SIGINT received, shutting down gracefully'); process.exit(0); });

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/jim-coyne/Intersight_MCP'

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