@toolprint/hypertool-mcp
Version:
HyperTool MCP proxy server for routing requests between clients and multiple underlying MCP servers
170 lines • 7.08 kB
JavaScript
/**
* 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