diff --git a/mcp-server/src/ToolResponse.ts b/mcp-server/src/ToolResponse.ts index 748d637..2c31c12 100644 --- a/mcp-server/src/ToolResponse.ts +++ b/mcp-server/src/ToolResponse.ts @@ -4,10 +4,22 @@ type CallToolContent = CallToolResult["content"][number]; type TextItem = Extract; type ImageItem = Extract; -class TextContent implements TextItem { +export class TextContent implements TextItem { [x: string]: unknown; readonly type = "text" as const; constructor(public text: string) {} + + /** + * @param data - Text data as string or as object (from JSON representation where indices are mapped to character codes) + */ + public static textData(data: string | object): string { + if (typeof data === "object") { + // convert object containing character codes (as obtained from JSON conversion of string) back to string + return String.fromCharCode(...(Object.values(data) as number[])); + } else { + return data; + } + } } class ImageContent implements ImageItem { @@ -58,6 +70,16 @@ export class TextResponse extends ToolResponse { constructor(text: string) { super([new TextContent(text)]); } + + /** + * Creates a TextResponse from text data given as string or as object (from JSON representation where indices are mapped to + * character codes). + * + * @param data - Text data as string or as object (from JSON representation where indices are mapped to character codes) + */ + public static fromData(data: string | object): TextResponse { + return new TextResponse(TextContent.textData(data)); + } } export class PNGResponse extends ToolResponse { diff --git a/mcp-server/src/tools/ExportShapeTool.ts b/mcp-server/src/tools/ExportShapeTool.ts index edbae54..1315614 100644 --- a/mcp-server/src/tools/ExportShapeTool.ts +++ b/mcp-server/src/tools/ExportShapeTool.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { Tool } from "../Tool"; -import { PNGImageContent, PNGResponse, TextResponse, ToolResponse } from "../ToolResponse"; +import { PNGImageContent, PNGResponse, TextContent, TextResponse, ToolResponse } from "../ToolResponse"; import "reflect-metadata"; import { PenpotMcpServer } from "../PenpotMcpServer"; import { ExecuteCodePluginTask } from "../tasks/ExecuteCodePluginTask"; @@ -86,14 +86,14 @@ export class ExportShapeTool extends Tool { if (args.format === "png") { return new PNGResponse(imageData); } else { - return new TextResponse(imageData); + return TextResponse.fromData(imageData); } } else { // save image to file if (args.format === "png") { FileUtils.writeBinaryFile(args.filePath, PNGImageContent.byteData(imageData)); } else { - FileUtils.writeTextFile(args.filePath, imageData); + FileUtils.writeTextFile(args.filePath, TextContent.textData(imageData)); } return new TextResponse(`The shape has been exported to ${args.filePath}`); } diff --git a/mcp-server/src/utils/FileUtils.ts b/mcp-server/src/utils/FileUtils.ts index b20bd1a..8da7c7d 100644 --- a/mcp-server/src/utils/FileUtils.ts +++ b/mcp-server/src/utils/FileUtils.ts @@ -1,3 +1,6 @@ +import * as path from "path"; +import * as fs from "fs"; + export class FileUtils { /** * Checks whether the given file path is absolute and raises an error if not. @@ -5,16 +8,15 @@ export class FileUtils { * @param filePath - The file path to check */ public static checkPathIsAbsolute(filePath: string): void { - if (!require("path").isAbsolute(filePath)) { + if (!path.isAbsolute(filePath)) { throw new Error(`The specified file path must be absolute: ${filePath}`); } } public static createParentDirectories(filePath: string): void { - const path = require("path"); const dir = path.dirname(filePath); - if (!require("fs").existsSync(dir)) { - require("fs").mkdirSync(dir, { recursive: true }); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); } } @@ -26,7 +28,7 @@ export class FileUtils { */ public static writeBinaryFile(filePath: string, bytes: Uint8Array): void { this.createParentDirectories(filePath); - require("fs").writeFileSync(filePath, Buffer.from(bytes)); + fs.writeFileSync(filePath, Buffer.from(bytes)); } /** @@ -37,6 +39,6 @@ export class FileUtils { */ public static writeTextFile(filePath: string, text: string): void { this.createParentDirectories(filePath); - require("fs").writeFileSync(filePath, text, { encoding: "utf-8" }); + fs.writeFileSync(filePath, text, { encoding: "utf-8" }); } }