diff --git a/mcp-server/src/Tool.ts b/mcp-server/src/Tool.ts index 8ffc6a4..4a8fc2e 100644 --- a/mcp-server/src/Tool.ts +++ b/mcp-server/src/Tool.ts @@ -31,14 +31,12 @@ export abstract class Tool { * Executes the tool with automatic validation and type safety. * * This method handles the unknown args from the MCP protocol, - * validates them, and delegates to the type-safe implementation. + * delegating to the type-safe implementation. */ async execute(args: unknown): Promise { try { - this.logger.info("Executing tool: %s", this.getToolName()); - let argsInstance: TArgs = args as TArgs; - this.logger.debug("Tool args: %o", argsInstance); + this.logger.info("Executing tool: %s; arguments: %s", this.getToolName(), this.formatArgs(argsInstance)); // execute the actual tool logic let result = await this.executeCore(argsInstance); @@ -51,6 +49,46 @@ export abstract class Tool { } } + /** + * Formats tool arguments for readable logging. + * + * Multi-line strings are preserved with proper indentation. + */ + protected formatArgs(args: TArgs): string { + const formatted: string[] = []; + + for (const [key, value] of Object.entries(args)) { + if (typeof value === "string" && value.includes("\n")) { + // multi-line string - preserve formatting with indentation + const indentedValue = value + .split("\n") + .map((line, index) => (index === 0 ? line : " " + line)) + .join("\n"); + formatted.push(` ${key}: ${indentedValue}`); + } else if (typeof value === "string") { + // single-line string + formatted.push(` ${key}: "${value}"`); + } else if (value === null || value === undefined) { + formatted.push(` ${key}: ${value}`); + } else { + // other types (numbers, booleans, objects, arrays) + const stringified = JSON.stringify(value, null, 2); + if (stringified.includes("\n")) { + // multi-line JSON - indent it + const indented = stringified + .split("\n") + .map((line, index) => (index === 0 ? line : " " + line)) + .join("\n"); + formatted.push(` ${key}: ${indented}`); + } else { + formatted.push(` ${key}: ${stringified}`); + } + } + } + + return formatted.length > 0 ? "\n" + formatted.join("\n") : "{}"; + } + public getInputSchema() { return this.inputSchema; }