UNPKG

@toolprint/hypertool-mcp

Version:

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

138 lines • 5.33 kB
/** * Base transformer for standard MCP configuration format */ import { ClaudeCodeTransformer } from "./claude-code.js"; /** * Base transformer for applications using standard mcpServers format */ export class StandardTransformer { /** * Convert from standard format to standard format (pass-through) */ toStandard(appConfig) { let mcpServers = {}; let metadata = appConfig._metadata; // If it already has mcpServers, use that if (appConfig.mcpServers && typeof appConfig.mcpServers === "object") { mcpServers = appConfig.mcpServers; } else if (typeof appConfig === "object" && !Array.isArray(appConfig)) { // If it's a bare object of servers, use it directly mcpServers = appConfig; } // Add missing type fields to servers for backward compatibility let hasAddedTypes = false; for (const [name, server] of Object.entries(mcpServers)) { if (server && typeof server === "object" && !server.type) { // Default to stdio if has command field if (server.command) { server.type = "stdio"; hasAddedTypes = true; } } } if (hasAddedTypes) { console.warn('Added missing "type" fields to server configurations. Please update your config files to include explicit type fields.'); } return { mcpServers, _metadata: metadata, }; } /** * Convert from standard format to standard format (pass-through) */ fromStandard(standardConfig, existingConfig) { return standardConfig; } /** * Validate standard MCP configuration format */ validate(config) { const errors = []; const warnings = []; // Check if config is an object if (typeof config !== "object" || config === null) { errors.push("Configuration must be an object"); return { valid: false, errors }; } // Check if mcpServers exists and is an object if (!config.mcpServers) { warnings.push("Configuration does not contain mcpServers field"); } else if (typeof config.mcpServers !== "object" || Array.isArray(config.mcpServers)) { errors.push("mcpServers must be an object"); } else { // Validate each server for (const [name, server] of Object.entries(config.mcpServers)) { if (typeof server !== "object" || server === null) { errors.push(`Server "${name}" must be an object`); continue; } const serverConfig = server; // Check required fields if (!serverConfig.type) { errors.push(`Server "${name}" missing required field: type`); } else if (!["stdio", "http", "websocket", "sse"].includes(serverConfig.type)) { errors.push(`Server "${name}" has invalid type: ${serverConfig.type}`); } // Check command/url based on transport type if (serverConfig.type === "stdio") { if (!serverConfig.command) { errors.push(`Server "${name}" with type 'stdio' missing required field: command`); } } else if (["http", "sse", "websocket"].includes(serverConfig.type)) { if (!serverConfig.url) { errors.push(`Server "${name}" with type '${serverConfig.type}' missing required field: url`); } if (serverConfig.command) { warnings.push(`Server "${name}" with type '${serverConfig.type}' should use 'url' instead of 'command'`); } } // Check optional fields if (serverConfig.args && !Array.isArray(serverConfig.args)) { errors.push(`Server "${name}" args must be an array`); } if (serverConfig.env && typeof serverConfig.env !== "object") { errors.push(`Server "${name}" env must be an object`); } } } return { valid: errors.length === 0, errors: errors.length > 0 ? errors : undefined, warnings: warnings.length > 0 ? warnings : undefined, }; } } /** * Registry of available transformers */ export class TransformerRegistry { static transformers = new Map([ ["standard", new StandardTransformer()], ["claude-code", new ClaudeCodeTransformer()], ]); /** * Get a transformer by name */ static getTransformer(name) { const transformer = this.transformers.get(name); if (!transformer) { // Default to standard transformer return this.transformers.get("standard"); } return transformer; } /** * Register a custom transformer */ static registerTransformer(name, transformer) { this.transformers.set(name, transformer); } } //# sourceMappingURL=base.js.map