In multi-user mode, disable file system access in tools #20

This commit is contained in:
Dominik Jain 2025-12-16 22:50:10 +01:00
parent 02da2b4b19
commit 445cf728b8
2 changed files with 33 additions and 7 deletions

View File

@ -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<any>[] = [
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();

View File

@ -45,7 +45,13 @@ export class ExportShapeTool extends Tool<ExportShapeArgs> {
* @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<ExportShapeArgs> {
}
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<ToolResponse> {
@ -89,6 +95,10 @@ export class ExportShapeTool extends Tool<ExportShapeArgs> {
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));