Spritesheet Forge
Game-dev sprite tools: PNG/GIF to spritesheet, split, trim, animate. OAuth-authenticated MCP server.
Sollte ich dies verwenden
Qualität und Sicherheit
Befunde (4)
- LOWin trim_png
- LOWin gif_to_frames
- LOWin frames_to_animation
- LOWin spritesheet_to_animation
Basierend auf einer automatisierten Analyse der Tool-Definitionen und der Einhaltung des Protokolls.
Kontextkosten
Dies ist die ungefähre Anzahl der Tokens, die jedes Mal verbraucht werden, wenn die Tools des Servers in den Kontext eines Modells geladen werden. Höhere Werte verringern die Aufmerksamkeit, die für andere Aufgaben verfügbar ist.
Installieren
Installation mit einem Klick
Fügen Sie dies Ihrer Datei `claude_desktop_config.json` hinzu:
{
"mcpServers": {
"spritesheet-forge": {
"url": "https://mcp.clawstudiouo.com/mcp"
}
}
}Remote-Endpunkte
https://mcp.clawstudiouo.com/mcpstreamable-httpWas es kann
Tool-Inventar
Tools (8)
🟢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.
Eingabe-Schema
{
"type": "object",
"properties": {},
"required": []
}Ausgabe-Schema
{
"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.
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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).
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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.
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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.
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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.
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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.
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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).
Eingabe-Schema
{
"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"
]
}Ausgabe-Schema
{
"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"
]
}Community
Nachweis