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
JavaScript
;
/**
* @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;