UNPKG

@houmak/minerva-mcp-server

Version:

Minerva Model Context Protocol (MCP) Server for Microsoft 365 and Azure integrations

302 lines (301 loc) 13.6 kB
import { z } from "zod"; import { logger } from "./logger.js"; import { RouterIntegrationManager } from "./router/router-integration-manager.js"; export function registerRouterTools(server, powershellExecutor, graphClient) { // Initialize router integration manager const routerConfig = { enabled: process.env.ENABLE_INTELLIGENT_ROUTER === 'true', enableFallback: process.env.ENABLE_ROUTER_FALLBACK !== 'false', enablePerformanceTracking: process.env.ENABLE_PERFORMANCE_TRACKING !== 'false', enableUserPreferences: process.env.ENABLE_USER_PREFERENCES !== 'false', maxRetries: parseInt(process.env.ROUTER_MAX_RETRIES || '3'), retryDelay: parseInt(process.env.ROUTER_RETRY_DELAY || '1000') }; const routerManager = new RouterIntegrationManager(routerConfig, powershellExecutor, graphClient); // Set default scopes (these would normally come from authentication) routerManager.setAvailableScopes([ 'users.read', 'sites.read', 'lists.read', 'permissions.read', 'content.read', 'admin.read', 'teams.read', 'files.read', 'groups.read', 'flows.read', 'azure.read' ]); // Tool: Set User Preference server.tool("setUserPreference", "Set user preference for provider selection for a specific action", { action: z.string().describe("The action name to set preference for"), provider: z.enum(["graph", "pnp", "cli"]).describe("Preferred provider for this action") }, async ({ action, provider }) => { try { logger.info(`Setting user preference for action '${action}' to provider '${provider}'`); routerManager.setUserPreference(action, provider); return { success: true, message: `User preference set for action '${action}' to provider '${provider}'`, action, provider }; } catch (error) { logger.error(`Error setting user preference: ${error}`); return { success: false, error: `Failed to set user preference: ${error}` }; } }); // Tool: Get Router Statistics server.tool("getRouterStats", "Get comprehensive statistics about the intelligent router including provider health, performance metrics, and usage patterns", {}, async () => { try { logger.info("Getting router statistics"); const stats = routerManager.getRouterStats(); return { success: true, message: "Router statistics retrieved successfully", data: stats }; } catch (error) { logger.error(`Error getting router stats: ${error}`); return { success: false, error: `Failed to get router stats: ${error}` }; } }); // Tool: Get Provider Recommendations server.tool("getProviderRecommendations", "Get provider recommendations for a specific action based on current capabilities and performance", { action: z.string().describe("The action to get recommendations for") }, async ({ action }) => { try { logger.info(`Getting provider recommendations for action '${action}'`); const recommendations = routerManager.getProviderRecommendations(action); return { success: true, message: `Provider recommendations retrieved for action '${action}'`, action, recommendations }; } catch (error) { logger.error(`Error getting provider recommendations: ${error}`); return { success: false, error: `Failed to get provider recommendations: ${error}` }; } }); // Tool: Validate Action server.tool("validateAction", "Validate if an action is supported by the intelligent router", { action: z.string().describe("The action to validate") }, async ({ action }) => { try { logger.info(`Validating action '${action}'`); const validation = routerManager.validateAction(action); return { success: true, message: `Action validation completed for '${action}'`, action, isValid: validation.isValid, errors: validation.errors }; } catch (error) { logger.error(`Error validating action: ${error}`); return { success: false, error: `Failed to validate action: ${error}` }; } }); // Tool: Execute Action with Intelligent Routing server.tool("executeWithRouting", "Execute an action using intelligent routing with automatic provider selection and fallback", { action: z.string().describe("The action to execute"), parameters: z.record(z.any()).describe("Parameters for the action"), priority: z.enum(["high", "medium", "low"]).optional().default("medium").describe("Execution priority"), complexity: z.enum(["low", "medium", "high"]).optional().default("medium").describe("Expected complexity"), userPreference: z.enum(["graph", "pnp", "cli"]).optional().describe("User's preferred provider") }, async ({ action, parameters, priority, complexity, userPreference }) => { try { logger.info(`Executing action '${action}' with intelligent routing`); const context = { availableScopes: [ 'users.read', 'sites.read', 'lists.read', 'permissions.read', 'content.read', 'admin.read', 'teams.read', 'files.read', 'groups.read', 'flows.read', 'azure.read' ], currentRateLimits: {}, complexity, priority, userPreference }; const result = await routerManager.executeAction(action, parameters, context); return { success: result.success, message: result.success ? `Action '${action}' executed successfully using ${result.provider}` : `Action '${action}' failed: ${result.error}`, action, provider: result.provider, data: result.data, error: result.error, executionTime: result.executionTime, retries: result.retries, fallbackUsed: result.fallbackUsed }; } catch (error) { logger.error(`Error executing action with routing: ${error}`); return { success: false, error: `Failed to execute action with routing: ${error}` }; } }); // Tool: Test Provider Performance server.tool("testProviderPerformance", "Test the performance of different providers for a specific action", { action: z.string().describe("The action to test"), parameters: z.record(z.any()).describe("Parameters for the action"), providers: z.array(z.enum(["graph", "pnp", "cli"])).optional().describe("Specific providers to test (default: all available)") }, async ({ action, parameters, providers }) => { try { logger.info(`Testing provider performance for action '${action}'`); const availableProviders = providers || ["pnp"]; // Default to PnP for now const results = []; for (const provider of availableProviders) { const startTime = Date.now(); try { // Create context for each provider const context = { availableScopes: [ 'users.read', 'sites.read', 'lists.read', 'permissions.read', 'content.read', 'admin.read', 'teams.read', 'files.read', 'groups.read', 'flows.read', 'azure.read' ], currentRateLimits: {}, complexity: "medium", priority: "medium" }; const result = await routerManager.executeAction(action, parameters, context); const executionTime = Date.now() - startTime; results.push({ provider, success: result.success, executionTime, error: result.error, data: result.data }); } catch (error) { const executionTime = Date.now() - startTime; results.push({ provider, success: false, executionTime, error: error.message }); } } return { success: true, message: `Provider performance test completed for action '${action}'`, action, results }; } catch (error) { logger.error(`Error testing provider performance: ${error}`); return { success: false, error: `Failed to test provider performance: ${error}` }; } }); // Tool: Get Supported Actions server.tool("getSupportedActions", "Get list of all actions supported by the intelligent router", { provider: z.enum(["graph", "pnp", "cli"]).optional().describe("Filter by specific provider") }, async ({ provider }) => { try { logger.info("Getting supported actions"); if (provider) { const actions = routerManager.getRouterStats().actionsForProvider?.[provider] || []; return { success: true, message: `Supported actions for provider '${provider}'`, provider, actions }; } else { const stats = routerManager.getRouterStats(); return { success: true, message: "All supported actions retrieved", totalActions: stats.totalActions, actionsByProvider: { graph: routerManager.getRouterStats().actionsForProvider?.graph || [], pnp: routerManager.getRouterStats().actionsForProvider?.pnp || [], cli: routerManager.getRouterStats().actionsForProvider?.cli || [] } }; } } catch (error) { logger.error(`Error getting supported actions: ${error}`); return { success: false, error: `Failed to get supported actions: ${error}` }; } }); // Tool: Update Provider Health server.tool("updateProviderHealth", "Update the health status of a provider (for testing purposes)", { provider: z.enum(["graph", "pnp", "cli"]).describe("The provider to update"), status: z.enum(["healthy", "degraded", "unhealthy"]).describe("New health status") }, async ({ provider, status }) => { try { logger.info(`Updating provider health for '${provider}' to '${status}'`); // This would normally be called by the router manager internally // For testing, we'll simulate the update const router = routerManager.router; router.updateProviderHealth(provider, status); return { success: true, message: `Provider health updated for '${provider}' to '${status}'`, provider, status }; } catch (error) { logger.error(`Error updating provider health: ${error}`); return { success: false, error: `Failed to update provider health: ${error}` }; } }); // Tool: Simulate Rate Limiting server.tool("simulateRateLimiting", "Simulate rate limiting for a provider (for testing purposes)", { provider: z.enum(["graph", "pnp", "cli"]).describe("The provider to simulate rate limiting for"), requestCount: z.number().describe("Number of requests to simulate") }, async ({ provider, requestCount }) => { try { logger.info(`Simulating rate limiting for '${provider}' with ${requestCount} requests`); // This would normally be called by the router manager internally // For testing, we'll simulate the update const router = routerManager.router; router.updateRateLimitCounter(provider, requestCount); return { success: true, message: `Rate limiting simulated for '${provider}' with ${requestCount} requests`, provider, requestCount }; } catch (error) { logger.error(`Error simulating rate limiting: ${error}`); return { success: false, error: `Failed to simulate rate limiting: ${error}` }; } }); console.error("Router tools registered successfully"); }