UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

230 lines (229 loc) 8.58 kB
"use strict"; /** * @moduleName: Advanced MCP Tool Registry * @version: 2.0.0 * @since: 2025-07-25 * @lastUpdated: 2025-07-25 * @projectSummary: Enhanced MCP Quiz Server - Modular Architecture * @techStack: TypeScript, JSON-RPC 2.0, MCP Protocol * @dependency: None (registry module) * @interModuleDependency: All tool modules (quiz/, web/), types, security * @requirementsTraceability: * {@link Requirements.REQ_MCP_002} (Dynamic Tool Registry) * @briefDescription: Centralized registry for all MCP tools with logical organization and discovery * @methods: getAllTools, getToolsByCategory, getToolHandler, registerTool * @contributors: GitHub Copilot, Claude Code Agent * @examples: * - registry.getToolsByCategory('quiz') - Get all quiz-related tools * - registry.getToolHandler('create_quiz') - Get specific tool handler * @vulnerabilitiesAssessment: Tool validation prevents registration of malformed tools, category-based access control */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getRegistryStats = exports.executeTool = exports.getToolsByCategory = exports.getToolHandler = exports.getAllTools = exports.toolRegistry = exports.AdvancedToolRegistry = void 0; // Import quiz tools from index const index_1 = require("../tools/quiz/index"); // Import web tools const server_management_1 = require("../tools/web/server-management"); /** * Enhanced tool registry with logical organization */ class AdvancedToolRegistry { constructor() { this.categories = new Map(); this.toolHandlers = new Map(); this.allTools = []; this.initializeCategories(); this.registerAllTools(); } /** * Initialize tool categories with logical grouping */ initializeCategories() { // Quiz Management Category this.categories.set('quiz', { name: 'Quiz Management', description: 'Tools for creating, managing, and analyzing quizzes', tools: [], handlers: {}, }); // Quiz Analytics Category this.categories.set('analytics', { name: 'Quiz Analytics', description: 'Tools for quiz results, analytics, and URL generation', tools: [], handlers: {}, }); // Web Server Category this.categories.set('web', { name: 'Web Server Management', description: 'Tools for web server lifecycle and monitoring', tools: [], handlers: {}, }); console.log('🏗️ Tool categories initialized'); } /** * Register all tools in their appropriate categories */ registerAllTools() { var _a, _b, _c; // Register all quiz tools (including analytics) index_1.allQuizTools.forEach(tool => { const handler = index_1.allQuizHandlers[tool.name]; if (handler) { // Categorize tools based on their names if (tool.name.includes('submit_quiz_result') || tool.name.includes('get_quiz_analytics') || tool.name.includes('generate_quiz_urls')) { this.registerTool('analytics', tool, handler); } else { this.registerTool('quiz', tool, handler); } } }); // Register web server tools server_management_1.webServerTools.forEach(tool => { const handler = server_management_1.webServerHandlers[tool.name]; if (handler) { this.registerTool('web', tool, handler); } }); console.log('📋 All tools registered successfully'); console.log(` • Quiz tools: ${((_a = this.categories.get('quiz')) === null || _a === void 0 ? void 0 : _a.tools.length) || 0}`); console.log(` • Analytics tools: ${((_b = this.categories.get('analytics')) === null || _b === void 0 ? void 0 : _b.tools.length) || 0}`); console.log(` • Web tools: ${((_c = this.categories.get('web')) === null || _c === void 0 ? void 0 : _c.tools.length) || 0}`); console.log(` • Total tools: ${this.allTools.length}`); } /** * Register a tool in a specific category */ registerTool(categoryName, tool, handler) { const category = this.categories.get(categoryName); if (!category) { throw new Error(`Unknown category: ${categoryName}`); } // Validate tool definition if (!tool.name || !tool.description || !tool.inputSchema) { throw new Error(`Invalid tool definition for ${tool.name}`); } // Add to category category.tools.push(tool); category.handlers[tool.name] = handler; // Add to global registry this.allTools.push(tool); this.toolHandlers.set(tool.name, handler); console.log(`🔧 Registered tool '${tool.name}' in category '${categoryName}'`); } /** * Get all tools across all categories */ getAllTools() { return [...this.allTools]; } /** * Get tools by category */ getToolsByCategory(categoryName) { const category = this.categories.get(categoryName); return category ? [...category.tools] : []; } /** * Get all categories with their tools */ getAllCategories() { return Array.from(this.categories.entries()).map(([name, category]) => ({ name: category.name, description: category.description, toolCount: category.tools.length, tools: category.tools.map(tool => tool.name), })); } /** * Get tool handler by name */ getToolHandler(toolName) { return this.toolHandlers.get(toolName); } /** * Check if a tool exists */ hasTool(toolName) { return this.toolHandlers.has(toolName); } /** * Get tool definition by name */ getToolDefinition(toolName) { return this.allTools.find(tool => tool.name === toolName); } /** * Get registry statistics */ getStats() { const categoriesBreakdown = {}; for (const [name, category] of this.categories) { categoriesBreakdown[name] = category.tools.length; } return { totalTools: this.allTools.length, totalCategories: this.categories.size, categoriesBreakdown, toolNames: this.allTools.map(tool => tool.name), }; } /** * Search tools by name or description */ searchTools(query) { const searchTerm = query.toLowerCase(); return this.allTools.filter(tool => tool.name.toLowerCase().includes(searchTerm) || tool.description.toLowerCase().includes(searchTerm)); } /** * Get tools that match MCP list format */ getMCPToolsList() { return { tools: this.getAllTools(), }; } /** * Execute a tool by name with arguments */ async executeTool(toolName, args) { const handler = this.getToolHandler(toolName); if (!handler) { throw new Error(`Tool '${toolName}' not found`); } try { console.log(`🚀 Executing tool: ${toolName}`); const result = await handler(args); console.log(`✅ Tool execution completed: ${toolName}`); return result; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown execution error'; console.log(`❌ Tool execution failed: ${toolName} - ${errorMessage}`); throw new Error(`Tool execution failed: ${errorMessage}`); } } } exports.AdvancedToolRegistry = AdvancedToolRegistry; /** * Global registry instance */ exports.toolRegistry = new AdvancedToolRegistry(); /** * Export convenience functions */ const getAllTools = () => exports.toolRegistry.getAllTools(); exports.getAllTools = getAllTools; const getToolHandler = (name) => exports.toolRegistry.getToolHandler(name); exports.getToolHandler = getToolHandler; const getToolsByCategory = (category) => exports.toolRegistry.getToolsByCategory(category); exports.getToolsByCategory = getToolsByCategory; const executeTool = (name, args) => exports.toolRegistry.executeTool(name, args); exports.executeTool = executeTool; const getRegistryStats = () => exports.toolRegistry.getStats(); exports.getRegistryStats = getRegistryStats;