Skip to main content
Glama

Export Image

photopea_export_image

Exports the active document from Photopea to a local file. Supports PNG, JPG, WebP, PSD, and SVG formats with optional JPEG quality control.

Instructions

Export the active document to a file and save it to the local filesystem. The entire document is flattened and exported in the chosen format. Use create_document or open_file to set up the document before exporting.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
formatYesOutput format: 'png' for lossless, 'jpg' for compressed photos, 'webp' for web, 'psd' for Photoshop, 'svg' for vector
qualityNoCompression quality for JPG format only (1 = smallest file, 100 = best quality). Ignored for other formats.
outputPathYesAbsolute local file path where the exported file will be saved (e.g. /Users/me/output.png)

Implementation Reference

  • The registerExportTools function registers the 'photopea_export_image' tool on the MCP server. The handler (lines 25-39) builds an export script via buildExportImage, sends it to the Photopea bridge, and writes the resulting file data to the local filesystem using writeLocalFile.
    export function registerExportTools(server: McpServer, bridge: PhotopeaBridge): void {
      // 30. photopea_export_image
      server.registerTool("photopea_export_image", {
        title: "Export Image",
        description: "Export the active document to a file and save it to the local filesystem. The entire document is flattened and exported in the chosen format. Use create_document or open_file to set up the document before exporting.",
        inputSchema: {
          format: z.enum(["png", "jpg", "webp", "psd", "svg"]).describe("Output format: 'png' for lossless, 'jpg' for compressed photos, 'webp' for web, 'psd' for Photoshop, 'svg' for vector"),
          quality: z.number().min(1).max(100).optional().describe("Compression quality for JPG format only (1 = smallest file, 100 = best quality). Ignored for other formats."),
          outputPath: z.string().describe("Absolute local file path where the exported file will be saved (e.g. /Users/me/output.png)"),
        },
        annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
      }, async (params) => {
        const script = buildExportImage(params);
        bridge.sendActivity({ type: "activity", id: "", tool: "export_image", summary: `Export as ${params.format} to ${params.outputPath}` });
        const rawResult = await bridge.executeScript(script, true);
        if (!rawResult.success) return { isError: true, content: [{ type: "text" as const, text: rawResult.error || "Failed to export image" }] };
    
        const fileResult = rawResult as BridgeFileResult;
        try {
          await writeLocalFile(params.outputPath, fileResult.data);
        } catch (err) {
          return { isError: true, content: [{ type: "text" as const, text: `Export succeeded but failed to write file: ${(err as Error).message}` }] };
        }
    
        return { content: [{ type: "text" as const, text: `Image exported to: ${params.outputPath}` }] };
      });
  • Registration of the tool 'photopea_export_image' on the MCP server via server.registerTool with title, description, inputSchema, and annotations.
    server.registerTool("photopea_export_image", {
      title: "Export Image",
      description: "Export the active document to a file and save it to the local filesystem. The entire document is flattened and exported in the chosen format. Use create_document or open_file to set up the document before exporting.",
      inputSchema: {
        format: z.enum(["png", "jpg", "webp", "psd", "svg"]).describe("Output format: 'png' for lossless, 'jpg' for compressed photos, 'webp' for web, 'psd' for Photoshop, 'svg' for vector"),
        quality: z.number().min(1).max(100).optional().describe("Compression quality for JPG format only (1 = smallest file, 100 = best quality). Ignored for other formats."),
        outputPath: z.string().describe("Absolute local file path where the exported file will be saved (e.g. /Users/me/output.png)"),
      },
      annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
    }, async (params) => {
  • Type definition for ExportImageParams used by the tool handler and script builder.
    export interface ExportImageParams {
      format: "png" | "jpg" | "webp" | "psd" | "svg";
      quality?: number;
      outputPath: string;
    }
  • buildExportImage generates the Photopea ExtendScript that calls app.activeDocument.saveToOE() to export the active document in the specified format.
    export function buildExportImage(params: ExportImageParams): string {
      const { format, quality } = params;
      const lines: string[] = [];
    
      let formatStr: string;
      if (format === "jpg" && quality !== undefined) {
        formatStr = `jpg:${quality}`;
      } else {
        formatStr = format;
      }
    
      lines.push(`app.activeDocument.saveToOE('${formatStr}');`);
      return lines.join("\n");
    }
  • writeLocalFile writes the exported Buffer data to the specified file path, creating directories if needed.
    export async function writeLocalFile(filePath: string, data: Buffer): Promise<void> {
      const dir = dirname(filePath);
      if (!existsSync(dir)) {
        await mkdir(dir, { recursive: true });
      }
      await writeFile(filePath, data);
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses that the entire document is flattened and exported to local filesystem. Annotations provide no extra safety info (all false), so description adds valuable context beyond them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The crucial detail (flattening) is front-loaded, and prerequisites are mentioned concisely.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple export tool with fully described parameters and no output schema needed (return value is implicit), the description covers all necessary context: what it does, what happens to the document, and prerequisites.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with detailed descriptions for each parameter (format enum, quality range and format, outputPath absolute path). Description repeats 'flattened' and 'save to local filesystem' but adds no new param-specific info beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it exports the active document to a file and flattens it. Distinguishes from siblings like open_file and create_document by noting they must be used first.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states to use create_document or open_file before exporting, providing clear prerequisite context. Does not specify when not to use or alternatives, but the guidance is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/attalla1/photopea-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server