Spritesheet Forge

Game-dev sprite tools: PNG/GIF to spritesheet, split, trim, animate. OAuth-authenticated MCP server.

¿Debería usar esto?

Calidad y seguridad

A
Calidad de la descripción
83%
Integridad del esquema
89%
Calidad de los nombres
80%
Riesgo de envenenamiento
100%
Coincidencia de permisos
100%
Cumplimiento del protocolo
100%

Hallazgos (4)

  • LOWTool 'trim_png' description lacks action verben trim_png
  • LOWTool 'gif_to_frames' description lacks action verben gif_to_frames
  • LOWTool 'frames_to_animation' description lacks action verben frames_to_animation
  • LOWTool 'spritesheet_to_animation' description lacks action verben spritesheet_to_animation

Basado en el análisis automatizado de las definiciones de herramientas y el cumplimiento del protocolo.

Costo de contexto

~4,628Tokens (definiciones de herramientas)
~6.4 KBTamaño de respuesta típico
Impacto significativo en la atención (3.62% del contexto de 128k)

Este es el número aproximado de tokens que se consumen cada vez que las herramientas del servidor se cargan en el contexto de un modelo. Los recuentos más altos reducen la atención disponible para otras tareas.

Instalar

Instalación con un clic

Agrega esto a tu archivo `claude_desktop_config.json`:

{
  "mcpServers": {
    "spritesheet-forge": {
      "url": "https://mcp.clawstudiouo.com/mcp"
    }
  }
}

Puntos de conexión remotos

https://mcp.clawstudiouo.com/mcpstreamable-http

Qué puede hacer

Inventario de herramientas

Herramientas (8)

🟢 Solo lectura🟡 Escritura🔴 Eliminación⚪ Desconocido
🟢server_info

Returns this server's runtime configuration: upload endpoint URL, output file TTL, file size limits, and base64 encoding rules. Call this before working with large files (≥ 4 MB) or when building multi-step workflows that chain tool outputs.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "required": []
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "upload_url": {
      "type": "string",
      "description": "URL for uploading files via multipart/form-data (Bearer token required)"
    },
    "output_ttl_seconds": {
      "type": "number",
      "description": "Seconds until output files expire"
    },
    "max_file_bytes": {
      "type": "number",
      "description": "Maximum accepted file size in bytes"
    },
    "base64_threshold_bytes": {
      "type": "number",
      "description": "Files smaller than this can be sent as base64 data URIs"
    },
    "file_input_rules": {
      "type": "object",
      "description": "Guidance for agents on how to pass file inputs",
      "properties": {
        "small_file": {
          "type": "string"
        },
        "large_file": {
          "type": "string"
        },
        "token_for_upload": {
          "type": "string"
        },
        "previous_output": {
          "type": "string"
        },
        "ttl_warning": {
          "type": "string"
        }
      }
    }
  },
  "required": [
    "upload_url",
    "output_ttl_seconds",
    "max_file_bytes",
    "base64_threshold_bytes",
    "file_input_rules"
  ]
}
🟢png_to_spritesheet(files, layout, columns, cell_mode, cell_width, ...)

Merge multiple PNG files into a single spritesheet. Supports grid, horizontal, vertical, and packed (bin-packed) layouts with optional TexturePacker-compatible JSON metadata. Returns a download URL.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "files": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "PNG files — HTTPS URLs, data URIs, or output URLs from previous tool calls (pass directly, no re-encoding needed). For local files < ~185 KB each: base64-encode the bytes and prepend \"data:image/png;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending (shell encoders like openssl insert newlines that cause INVALID_BASE64). For larger files or any file encoded via a shell command: call server_info to get the upload_url and token instructions, POST the file there (multipart/form-data, field \"file\", Bearer token required), and pass the returned URL."
    },
    "layout": {
      "type": "string",
      "enum": [
        "grid",
        "horizontal",
        "vertical",
        "packed"
      ],
      "description": "Frame arrangement. Default: grid"
    },
    "columns": {
      "type": "integer",
      "description": "Grid columns. Auto-calculated if omitted."
    },
    "cell_mode": {
      "type": "string",
      "enum": [
        "auto_max",
        "auto_uniform",
        "fixed"
      ],
      "description": "Cell sizing mode. Default: auto_max"
    },
    "cell_width": {
      "type": "integer",
      "description": "Required when cell_mode=fixed"
    },
    "cell_height": {
      "type": "integer",
      "description": "Required when cell_mode=fixed"
    },
    "fit_mode": {
      "type": "string",
      "enum": [
        "scale_fit",
        "scale_fill",
        "error"
      ]
    },
    "align": {
      "type": "string",
      "enum": [
        "center",
        "top_left"
      ]
    },
    "padding": {
      "type": "integer",
      "description": "Pixel gap between frames"
    },
    "bg_color": {
      "type": "string",
      "description": "\"transparent\" or hex \"#RRGGBB\""
    },
    "power_of_2": {
      "type": "boolean",
      "description": "Pad output to next power of 2"
    },
    "file_name_order": {
      "type": "boolean",
      "description": "Order frames by the numeric _N suffix in each filename (e.g. frame_00.png, frame_01.png) instead of by array order. REQUIRES every input filename to end with _N.<ext> — the name is taken from the URL's last path segment. IMPORTANT: this server's upload endpoint renames every file to output-<hex>.png (no _N suffix), and data URIs carry no filename, so file_name_order=true is REJECTED (422) for both — it only works for external URLs that already end in _N.<ext>. TO ORDER FRAMES, PREFER doing it manually: leave this false and pass `files` in the exact order you want (the server preserves array order). If order matters but your inputs are upload URLs / data URIs / local files, fetch the files locally, CONFIRM the intended order with the user, then pass `files` in that order with file_name_order=false. Default: false"
    },
    "trim_input": {
      "type": "boolean",
      "description": "Auto-trim transparent edges before compositing"
    },
    "extrude": {
      "type": "integer",
      "description": "Extrude outermost pixels by N px per frame"
    },
    "metadata_format": {
      "type": "string",
      "enum": [
        "none",
        "json_array",
        "json_hash",
        "css"
      ],
      "description": "Atlas metadata format. Required (non-none) when layout=packed"
    }
  },
  "required": [
    "files"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
⚪split_spritesheet(file, columns, rows, cell_width, cell_height, ...)

Slice a spritesheet PNG into individual frames, generate TexturePacker-compatible atlas JSON, or both. Provide columns+rows (grid mode) or cell_width+cell_height (cell mode).

Esquema de entrada

{
  "type": "object",
  "properties": {
    "file": {
      "type": "string",
      "description": "Spritesheet PNG — HTTPS URL, data URI, or output URL from a previous tool call (pass directly, no re-encoding needed). For local files < 4 MB: base64-encode the bytes and prepend \"data:image/png;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending. For files ≥ 4 MB: call server_info to get the upload_url, POST the file there (multipart/form-data, field \"file\", Bearer token), and pass the returned URL."
    },
    "columns": {
      "type": "integer",
      "description": "Grid columns (grid mode)"
    },
    "rows": {
      "type": "integer",
      "description": "Grid rows (grid mode)"
    },
    "cell_width": {
      "type": "integer",
      "description": "Cell width in px (cell mode)"
    },
    "cell_height": {
      "type": "integer",
      "description": "Cell height in px (cell mode)"
    },
    "padding": {
      "type": "integer"
    },
    "frame_count": {
      "type": "integer"
    },
    "column_range": {
      "type": "string",
      "description": "e.g. \"0-5\" or \"2\""
    },
    "row_range": {
      "type": "string"
    },
    "skip_empty": {
      "type": "boolean",
      "description": "Remove fully transparent frames. Default: true"
    },
    "trim_top": {
      "type": "integer"
    },
    "trim_right": {
      "type": "integer"
    },
    "trim_bottom": {
      "type": "integer"
    },
    "trim_left": {
      "type": "integer"
    },
    "output": {
      "type": "string",
      "enum": [
        "frames",
        "metadata",
        "both"
      ],
      "description": "Default: frames"
    },
    "metadata_format": {
      "type": "string",
      "enum": [
        "json_array",
        "json_hash",
        "css"
      ]
    }
  },
  "required": [
    "file"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
⚪trim_png(files, threshold, padding)

Crop transparent edges from one or more PNG files. Single file returns PNG; multiple files return a ZIP.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "files": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "PNG files — HTTPS URLs, data URIs, or output URLs from previous tool calls (pass directly, no re-encoding needed). For local files < ~185 KB each: base64-encode the bytes and prepend \"data:image/png;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending (shell encoders like openssl insert newlines that cause INVALID_BASE64). For larger files or any file encoded via a shell command: call server_info to get the upload_url and token instructions, POST the file there (multipart/form-data, field \"file\", Bearer token required), and pass the returned URL."
    },
    "threshold": {
      "type": "integer",
      "description": "Alpha threshold 0-255. Pixels with alpha ≤ threshold are trimmed. Default: 0"
    },
    "padding": {
      "type": "integer",
      "description": "Transparent margin to preserve around trimmed content. Default: 0"
    }
  },
  "required": [
    "files"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
🔴gif_to_spritesheet(file, columns, padding, remove_bg, bg_color, ...)

Convert a GIF animation into a spritesheet PNG with all frames arranged in a grid. Optionally remove the background.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "file": {
      "type": "string",
      "description": "GIF file — HTTPS URL, data URI, or output URL from a previous tool call (pass directly, no re-encoding needed). For local files < ~185 KB: base64-encode the bytes and prepend \"data:image/gif;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending (shell encoders like openssl insert newlines that cause INVALID_BASE64). For larger files or any file encoded via a shell command: call server_info to get the upload_url and token instructions, POST the file there (multipart/form-data, field \"file\", Bearer token required), and pass the returned URL."
    },
    "columns": {
      "type": "integer",
      "description": "Grid columns. Auto-calculated if omitted."
    },
    "padding": {
      "type": "integer",
      "description": "Pixel gap between frames. Default: 0"
    },
    "remove_bg": {
      "type": "boolean",
      "description": "Remove background from each frame. Default: false"
    },
    "bg_color": {
      "type": "string",
      "description": "\"auto\" or hex \"#RRGGBB\". Default: \"auto\""
    },
    "tolerance": {
      "type": "integer",
      "description": "Background removal threshold 0-255. Default: 30"
    }
  },
  "required": [
    "file"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
🟢gif_to_frames(file, remove_bg, bg_color, tolerance)

Extract all frames from a GIF and return them as individual PNGs in a ZIP archive.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "file": {
      "type": "string",
      "description": "GIF file — HTTPS URL, data URI, or output URL from a previous tool call (pass directly, no re-encoding needed). For local files < ~185 KB: base64-encode the bytes and prepend \"data:image/gif;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending (shell encoders like openssl insert newlines that cause INVALID_BASE64). For larger files or any file encoded via a shell command: call server_info to get the upload_url and token instructions, POST the file there (multipart/form-data, field \"file\", Bearer token required), and pass the returned URL."
    },
    "remove_bg": {
      "type": "boolean",
      "description": "Remove background from each frame. Default: false"
    },
    "bg_color": {
      "type": "string",
      "description": "\"auto\" or hex \"#RRGGBB\""
    },
    "tolerance": {
      "type": "integer",
      "description": "Background removal threshold 0-255. Default: 30"
    }
  },
  "required": [
    "file"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
⚪frames_to_animation(files, duration, loop, file_name_order, resize, ...)

Assemble multiple PNG files into an animated GIF or animated WebP.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "files": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "PNG frames — HTTPS URLs, data URIs, or output URLs from previous tool calls (pass directly, no re-encoding needed). For local files < 4 MB each: base64-encode the bytes and prepend \"data:image/png;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending. For files ≥ 4 MB each: call server_info to get the upload_url, POST the file there (multipart/form-data, field \"file\", Bearer token), and pass the returned URL."
    },
    "duration": {
      "type": "integer",
      "description": "Frame duration in ms (10-10000). Default: 100"
    },
    "loop": {
      "type": "integer",
      "description": "Loop count. 0 = infinite. Default: 0"
    },
    "file_name_order": {
      "type": "boolean",
      "description": "Order frames by the numeric _N suffix in each filename (e.g. frame_00.png, frame_01.png) instead of by array order. REQUIRES every input filename to end with _N.<ext> — the name is taken from the URL's last path segment. IMPORTANT: this server's upload endpoint renames every file to output-<hex>.png (no _N suffix), and data URIs carry no filename, so file_name_order=true is REJECTED (422) for both — it only works for external URLs that already end in _N.<ext>. TO ORDER FRAMES, PREFER doing it manually: leave this false and pass `files` in the exact order you want (the server preserves array order). If order matters but your inputs are upload URLs / data URIs / local files, fetch the files locally, CONFIRM the intended order with the user, then pass `files` in that order with file_name_order=false. Default: false"
    },
    "resize": {
      "type": "string",
      "enum": [
        "error",
        "fill",
        "transparent"
      ],
      "description": "Dimension mismatch handling. Default: transparent"
    },
    "bg_fill_color": {
      "type": "string",
      "description": "Fill color for resize=fill. Hex #RRGGBB. Default: #000000"
    },
    "output_format": {
      "type": "string",
      "enum": [
        "gif",
        "webp"
      ],
      "description": "Output format. Default: gif"
    },
    "quality": {
      "type": "integer",
      "description": "WebP lossy quality 0-100. Default: 80"
    },
    "lossless": {
      "type": "boolean",
      "description": "WebP lossless mode. Default: false"
    }
  },
  "required": [
    "files"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}
⚪spritesheet_to_animation(file, columns, rows, cell_width, cell_height, ...)

Slice a spritesheet PNG into frames and produce an animated GIF or WebP. Provide columns+rows (grid mode) or cell_width+cell_height (cell mode).

Esquema de entrada

{
  "type": "object",
  "properties": {
    "file": {
      "type": "string",
      "description": "Spritesheet PNG — HTTPS URL, data URI, or output URL from a previous tool call (pass directly, no re-encoding needed). For local files < ~185 KB: base64-encode the bytes and prepend \"data:image/png;base64,\" — you MUST strip ALL whitespace and newlines from the base64 string before prepending (shell encoders like openssl insert newlines that cause INVALID_BASE64). For larger files or any file encoded via a shell command: call server_info to get the upload_url and token instructions, POST the file there (multipart/form-data, field \"file\", Bearer token required), and pass the returned URL."
    },
    "columns": {
      "type": "integer",
      "description": "Grid columns (grid mode)"
    },
    "rows": {
      "type": "integer",
      "description": "Grid rows (grid mode)"
    },
    "cell_width": {
      "type": "integer",
      "description": "Cell width in px (cell mode)"
    },
    "cell_height": {
      "type": "integer",
      "description": "Cell height in px (cell mode)"
    },
    "frame_count": {
      "type": "integer",
      "description": "Actual frame count for incomplete last row"
    },
    "padding": {
      "type": "integer",
      "description": "Pixel gap between cells. Default: 0"
    },
    "column_range": {
      "type": "string",
      "description": "e.g. \"0-5\" or \"2\""
    },
    "row_range": {
      "type": "string"
    },
    "skip_empty": {
      "type": "boolean",
      "description": "Auto-remove fully transparent frames. Default: true"
    },
    "trim_top": {
      "type": "integer"
    },
    "trim_right": {
      "type": "integer"
    },
    "trim_bottom": {
      "type": "integer"
    },
    "trim_left": {
      "type": "integer"
    },
    "duration": {
      "type": "integer",
      "description": "Frame duration in ms. Default: 100"
    },
    "loop": {
      "type": "integer",
      "description": "Loop count. 0 = infinite. Default: 0"
    },
    "output_format": {
      "type": "string",
      "enum": [
        "gif",
        "webp"
      ],
      "description": "Default: gif"
    },
    "quality": {
      "type": "integer",
      "description": "WebP quality 0-100. Default: 80"
    },
    "lossless": {
      "type": "boolean",
      "description": "WebP lossless. Default: false"
    }
  },
  "required": [
    "file"
  ]
}

Esquema de salida

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Download URL for the output file (expires in 1 hour)"
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 expiry timestamp"
    },
    "content_type": {
      "type": "string",
      "description": "MIME type of the output file (image/png, image/gif, application/zip, etc.)"
    },
    "size_bytes": {
      "type": "number",
      "description": "Output file size in bytes"
    },
    "quota": {
      "type": "object",
      "properties": {
        "used": {
          "type": "number",
          "description": "Operations used this month"
        },
        "limit": {
          "type": "number",
          "description": "Monthly operation limit"
        },
        "reset_at": {
          "type": "string",
          "description": "Date quota resets (YYYY-MM-01)"
        }
      },
      "required": [
        "used",
        "limit",
        "reset_at"
      ]
    }
  },
  "required": [
    "url",
    "expires_at",
    "content_type",
    "size_bytes",
    "quota"
  ]
}

Comunidad

Califica este servidor

Evidencia

Observaciones recientes

verificadoversión no registrada8 herramientas
verificadoversión no registrada8 herramientas