@houmak/minerva-mcp-server
Version:
Minerva Model Context Protocol (MCP) Server for Microsoft 365 and Azure integrations
302 lines (301 loc) • 13.6 kB
JavaScript
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");
}