UNPKG

@toolprint/hypertool-mcp

Version:

HyperTool MCP proxy server for routing requests between clients and multiple underlying MCP servers

170 lines • 7.08 kB
/** * Configuration Tools Manager * * Manages all configuration-related tools for HyperTool MCP. * This component is responsible for exposing tools in configuration mode * separate from the operational tools managed by ToolsetManager. */ import { createChildLogger } from "../../../utils/logging.js"; import { CONFIG_TOOL_FACTORIES } from "./registry.js"; const logger = createChildLogger({ module: "config-tools" }); /** * Manager for configuration tools in HyperTool MCP * Implements ToolsProvider interface for polymorphic tool handling */ export class ConfigToolsManager { toolModules = new Map(); dependencies; onModeChangeRequest; dynamicConfigMenuEnabled; constructor(dependencies, onModeChangeRequest) { this.dependencies = dependencies; this.onModeChangeRequest = onModeChangeRequest; // Dynamic config menu is enabled when onModeChangeRequest is provided this.dynamicConfigMenuEnabled = !!onModeChangeRequest; this.registerTools(); } /** * Register all configuration tools */ registerTools() { logger.debug("Registering configuration tools"); // Create and register each configuration tool module from the registry for (const factory of CONFIG_TOOL_FACTORIES) { const module = factory(this.dependencies, this.onModeChangeRequest); this.toolModules.set(module.toolName, module); } logger.info(`Registered ${this.toolModules.size} configuration tools`); } /** * Get MCP tools for configuration mode * Implements ToolsProvider interface */ getMcpTools() { // Return all configuration tools - server decides when to call this const tools = []; const activePersona = this.dependencies.personaManager?.getActivePersona(); logger.debug(`Getting MCP tools - persona manager exists: ${!!this.dependencies.personaManager}, active persona: ${activePersona ? activePersona.persona.config.name : "none"}`); for (const [toolName, module] of this.toolModules) { // When dynamic config menu is disabled, skip mode-switching tools if (!this.dynamicConfigMenuEnabled && toolName === "exit-configuration-mode") { logger.debug("Skipping exit-configuration-mode tool when dynamic menu disabled"); continue; } // Only show list-personas tool when persona IS active // (to see available personas for switching/viewing) if (toolName === "list-personas") { if (!activePersona) { logger.debug(`Skipping list-personas tool - no persona active, persona system not in use`); continue; } } // Hide build-toolset and delete-toolset when persona is active // (persona toolsets are managed by the persona system) if (toolName === "build-toolset" || toolName === "delete-toolset") { if (activePersona) { logger.debug(`Skipping ${toolName} tool - not available in persona mode with persona: ${activePersona.persona.config.name}`); continue; } } logger.debug(`Including tool: ${toolName}`); tools.push(module.definition); } logger.debug(`Returning ${tools.length} configuration tools (active persona: ${activePersona ? activePersona.persona.config.name : "none"})`); return tools; } /** * Determine which toolset delegate to use based on persona activation state */ getActiveToolsetDelegate() { const activePersona = this.dependencies.personaManager?.getActivePersona(); if (activePersona) { // PersonaManager will need to implement IToolsetDelegate interface return this.dependencies.personaManager; } else { // ToolsetManager will need to implement IToolsetDelegate interface return this.dependencies.toolsetManager; } } /** * Handle tool call - route to appropriate handler or delegate */ async handleToolCall(name, args) { // Check if this is a toolset operation that needs routing const toolsetOperations = [ "list-saved-toolsets", "equip-toolset", "get-active-toolset", ]; if (toolsetOperations.includes(name)) { // Route to appropriate delegate based on persona activation state const delegate = this.getActiveToolsetDelegate(); const delegateType = delegate.getDelegateType(); logger.debug(`Routing ${name} to ${delegateType} delegate`); switch (name) { case "list-saved-toolsets": { const result = await delegate.listSavedToolsets(); return { content: [ { type: "text", text: JSON.stringify(result), }, ], structuredContent: result, }; } case "equip-toolset": { const result = await delegate.equipToolset(args?.name); return { content: [ { type: "text", text: JSON.stringify(result), }, ], structuredContent: result, }; } case "get-active-toolset": { const result = await delegate.getActiveToolset(); return { content: [ { type: "text", text: JSON.stringify(result), }, ], structuredContent: result, }; } default: throw new Error(`Unhandled toolset operation: ${name}`); } } // Handle regular configuration tools const module = this.toolModules.get(name); if (!module) { throw new Error(`Configuration tool not found: ${name}`); } logger.debug(`Handling configuration tool call: ${name}`, { args }); try { const result = await module.handler(args); logger.debug(`Configuration tool call completed: ${name}`); return result; } catch (error) { logger.error(`Configuration tool call failed: ${name}`, error); throw error; } } /** * Get all registered tool modules (for testing) */ getToolModules() { return this.toolModules; } } //# sourceMappingURL=manager.js.map