diff --git a/mcp-server/src/PenpotMcpServer.ts b/mcp-server/src/PenpotMcpServer.ts index 445d2eb..eb2c367 100644 --- a/mcp-server/src/PenpotMcpServer.ts +++ b/mcp-server/src/PenpotMcpServer.ts @@ -67,10 +67,23 @@ export class PenpotMcpServer { this.registerTools(); } + /** + * Indicates whether the server is running in multi-user mode, + * where user tokens are required for authentication. + */ public isMultiUserMode(): boolean { return this.isMultiUser; } + /** + * Indicates whether file system access is enabled for MCP tools. + * Access is enabled only in single-user mode, where the file system is assumed + * to belong to the user running the server locally. + */ + public isFileSystemAccessEnabled(): boolean { + return !this.isMultiUserMode(); + } + public getInitialInstructions(): string { let instructions = this.configLoader.getInitialInstructions(); instructions = instructions.replace("$api_types", this.apiDocs.getTypeNames().join(", ")); @@ -87,13 +100,16 @@ export class PenpotMcpServer { } private registerTools(): void { + // Create relevant tool instances (depending on file system access) const toolInstances: Tool[] = [ new ExecuteCodeTool(this), new HighLevelOverviewTool(this), new PenpotApiInfoTool(this, this.apiDocs), - new ExportShapeTool(this), - new ImportImageTool(this), + new ExportShapeTool(this), // tool adapts to file system access internally ]; + if (this.isFileSystemAccessEnabled()) { + toolInstances.push(new ImportImageTool(this)); + } for (const tool of toolInstances) { const toolName = tool.getToolName(); diff --git a/mcp-server/src/tools/ExportShapeTool.ts b/mcp-server/src/tools/ExportShapeTool.ts index 1315614..ae4577c 100644 --- a/mcp-server/src/tools/ExportShapeTool.ts +++ b/mcp-server/src/tools/ExportShapeTool.ts @@ -45,7 +45,13 @@ export class ExportShapeTool extends Tool { * @param mcpServer - The MCP server instance */ constructor(mcpServer: PenpotMcpServer) { - super(mcpServer, ExportShapeArgs.schema); + let schema: any = ExportShapeArgs.schema; + if (!mcpServer.isFileSystemAccessEnabled()) { + // remove filePath key from schema + schema = { ...schema }; + delete schema.filePath; + } + super(mcpServer, schema); } public getToolName(): string { @@ -53,11 +59,11 @@ export class ExportShapeTool extends Tool { } public getToolDescription(): string { - return ( + let description = "Exports a shape from the Penpot design to a PNG or SVG image, " + - "such that you can get an impression of what the shape looks like.\n" + - "Alternatively, you can save it to a file." - ); + "such that you can get an impression of what the shape looks like."; + if (this.mcpServer.isFileSystemAccessEnabled()) description += "\nAlternatively, you can save it to a file."; + return description; } protected async executeCore(args: ExportShapeArgs): Promise { @@ -89,6 +95,10 @@ export class ExportShapeTool extends Tool { return TextResponse.fromData(imageData); } } else { + // make sure file system access is enabled + if (!this.mcpServer.isFileSystemAccessEnabled()) { + throw new Error("File system access is not enabled on the MCP server!"); + } // save image to file if (args.format === "png") { FileUtils.writeBinaryFile(args.filePath, PNGImageContent.byteData(imageData));