Skip to main content
Glama

hypertool-mcp

manager.tsโ€ข6.79 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 { Tool } from "@modelcontextprotocol/sdk/types.js"; import { ToolsProvider } from "../../types.js"; import { ToolModule, ToolDependencies } from "../types.js"; import { createChildLogger } from "../../../utils/logging.js"; import { CONFIG_TOOL_FACTORIES } from "./registry.js"; import { IToolsetDelegate } from "../interfaces/toolset-delegate.js"; const logger = createChildLogger({ module: "config-tools" }); /** * Manager for configuration tools in HyperTool MCP * Implements ToolsProvider interface for polymorphic tool handling */ export class ConfigToolsManager implements ToolsProvider { private toolModules: Map<string, ToolModule> = new Map(); private dependencies: ToolDependencies; private onModeChangeRequest?: () => void; private dynamicConfigMenuEnabled: boolean; constructor( dependencies: ToolDependencies, onModeChangeRequest?: () => void ) { this.dependencies = dependencies; this.onModeChangeRequest = onModeChangeRequest; // Dynamic config menu is enabled when onModeChangeRequest is provided this.dynamicConfigMenuEnabled = !!onModeChangeRequest; this.registerTools(); } /** * Register all configuration tools */ private registerTools(): void { 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 */ public getMcpTools(): Tool[] { // Return all configuration tools - server decides when to call this const tools: Tool[] = []; 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 */ private getActiveToolsetDelegate(): IToolsetDelegate { const activePersona = this.dependencies.personaManager?.getActivePersona(); if (activePersona) { // PersonaManager will need to implement IToolsetDelegate interface return this.dependencies.personaManager as IToolsetDelegate; } else { // ToolsetManager will need to implement IToolsetDelegate interface return this.dependencies.toolsetManager as IToolsetDelegate; } } /** * Handle tool call - route to appropriate handler or delegate */ public async handleToolCall(name: string, args: any): Promise<any> { // 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) */ public getToolModules(): Map<string, ToolModule> { return this.toolModules; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/toolprint/hypertool-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server