Game-dev sprite tools: PNG/GIF to spritesheet, split, trim, animate. OAuth-authenticated MCP server.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Assemble multiple PNG files into an animated GIF or animated WebP.
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.
Loop count. 0 = infinite. Default: 0
Dimension mismatch handling. Default: transparent
WebP lossy quality 0-100. Default: 80
Frame duration in ms (10-10000). Default: 100
WebP lossless mode. Default: false
Fill color for resize=fill. Hex #RRGGBB. Default: #000000
Output format. Default: gif
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
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Assemble multiple PNG files into an animated GIF or animated WebP.
| Argument | Type | Description |
|---|---|---|
| loop | integer | Loop count. 0 = infinite. Default: 0 |
| files* | array | 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. |
| resize | string | Dimension mismatch handling. Default: transparent |
| quality | integer | WebP lossy quality 0-100. Default: 80 |
| duration | integer | Frame duration in ms (10-10000). Default: 100 |
| lossless | boolean | WebP lossless mode. Default: false |
| bg_fill_color | string | Fill color for resize=fill. Hex #RRGGBB. Default: #000000 |
| output_format | string | Output format. Default: gif |
| file_name_order | boolean | 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 |
{
"type": "object",
"required": [
"files"
],
"properties": {
"loop": {
"type": "integer",
"description": "Loop count. 0 = infinite. Default: 0"
},
"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."
},
"resize": {
"enum": [
"error",
"fill",
"transparent"
],
"type": "string",
"description": "Dimension mismatch handling. Default: transparent"
},
"quality": {
"type": "integer",
"description": "WebP lossy quality 0-100. Default: 80"
},
"duration": {
"type": "integer",
"description": "Frame duration in ms (10-10000). Default: 100"
},
"lossless": {
"type": "boolean",
"description": "WebP lossless mode. Default: false"
},
"bg_fill_color": {
"type": "string",
"description": "Fill color for resize=fill. Hex #RRGGBB. Default: #000000"
},
"output_format": {
"enum": [
"gif",
"webp"
],
"type": "string",
"description": "Output format. Default: gif"
},
"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"
}
}
}Extract all frames from a GIF and return them as individual PNGs in a ZIP archive.
| Argument | Type | Description |
|---|---|---|
| file* | string | 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. |
| bg_color | string | "auto" or hex "#RRGGBB" |
| remove_bg | boolean | Remove background from each frame. Default: false |
| tolerance | integer | Background removal threshold 0-255. Default: 30 |
{
"type": "object",
"required": [
"file"
],
"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."
},
"bg_color": {
"type": "string",
"description": "\"auto\" or hex \"#RRGGBB\""
},
"remove_bg": {
"type": "boolean",
"description": "Remove background from each frame. Default: false"
},
"tolerance": {
"type": "integer",
"description": "Background removal threshold 0-255. Default: 30"
}
}
}Convert a GIF animation into a spritesheet PNG with all frames arranged in a grid. Optionally remove the background.
| Argument | Type | Description |
|---|---|---|
| file* | string | 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 | integer | Grid columns. Auto-calculated if omitted. |
| padding | integer | Pixel gap between frames. Default: 0 |
| bg_color | string | "auto" or hex "#RRGGBB". Default: "auto" |
| remove_bg | boolean | Remove background from each frame. Default: false |
| tolerance | integer | Background removal threshold 0-255. Default: 30 |
{
"type": "object",
"required": [
"file"
],
"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"
},
"bg_color": {
"type": "string",
"description": "\"auto\" or hex \"#RRGGBB\". Default: \"auto\""
},
"remove_bg": {
"type": "boolean",
"description": "Remove background from each frame. Default: false"
},
"tolerance": {
"type": "integer",
"description": "Background removal threshold 0-255. Default: 30"
}
}
}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.
| Argument | Type | Description |
|---|---|---|
| align | string | |
| files* | array | 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 | string | Frame arrangement. Default: grid |
| columns | integer | Grid columns. Auto-calculated if omitted. |
| extrude | integer | Extrude outermost pixels by N px per frame |
| padding | integer | Pixel gap between frames |
| bg_color | string | "transparent" or hex "#RRGGBB" |
| fit_mode |
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.
No arguments.
{
"type": "object",
"required": [],
"properties": {}
}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).
| Argument | Type | Description |
|---|---|---|
| file* | string | 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. |
| rows | integer | Grid rows (grid mode) |
| output | string | Default: frames |
| columns | integer | Grid columns (grid mode) |
| padding | integer | |
| trim_top | integer | |
| row_range | string | |
| trim_left | integer | |
| cell_width | integer | Cell width in px (cell mode) |
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).
| Argument | Type | Description |
|---|---|---|
| file* | string | 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. |
| loop | integer | Loop count. 0 = infinite. Default: 0 |
| rows | integer | Grid rows (grid mode) |
| columns | integer | Grid columns (grid mode) |
| padding | integer | Pixel gap between cells. Default: 0 |
| quality | integer | WebP quality 0-100. Default: 80 |
| duration | integer | Frame duration in ms. Default: 100 |
| lossless | boolean |
Crop transparent edges from one or more PNG files. Single file returns PNG; multiple files return a ZIP.
| Argument | Type | Description |
|---|---|---|
| files* | array | 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. |
| padding | integer | Transparent margin to preserve around trimmed content. Default: 0 |
| threshold | integer | Alpha threshold 0-255. Pixels with alpha ≤ threshold are trimmed. Default: 0 |
{
"type": "object",
"required": [
"files"
],
"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."
},
"padding": {
"type": "integer",
"description": "Transparent margin to preserve around trimmed content. Default: 0"
},
"threshold": {
"type": "integer",
"description": "Alpha threshold 0-255. Pixels with alpha ≤ threshold are trimmed. Default: 0"
}
}
}| string |
| cell_mode | string | Cell sizing mode. Default: auto_max |
| cell_width | integer | Required when cell_mode=fixed |
| power_of_2 | boolean | Pad output to next power of 2 |
| trim_input | boolean | Auto-trim transparent edges before compositing |
| cell_height | integer | Required when cell_mode=fixed |
| file_name_order | boolean | 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 |
| metadata_format | string | Atlas metadata format. Required (non-none) when layout=packed |
{
"type": "object",
"required": [
"files"
],
"properties": {
"align": {
"enum": [
"center",
"top_left"
],
"type": "string"
},
"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": {
"enum": [
"grid",
"horizontal",
"vertical",
"packed"
],
"type": "string",
"description": "Frame arrangement. Default: grid"
},
"columns": {
"type": "integer",
"description": "Grid columns. Auto-calculated if omitted."
},
"extrude": {
"type": "integer",
"description": "Extrude outermost pixels by N px per frame"
},
"padding": {
"type": "integer",
"description": "Pixel gap between frames"
},
"bg_color": {
"type": "string",
"description": "\"transparent\" or hex \"#RRGGBB\""
},
"fit_mode": {
"enum": [
"scale_fit",
"scale_fill",
"error"
],
"type": "string"
},
"cell_mode": {
"enum": [
"auto_max",
"auto_uniform",
"fixed"
],
"type": "string",
"description": "Cell sizing mode. Default: auto_max"
},
"cell_width": {
"type": "integer",
"description": "Required when cell_mode=fixed"
},
"power_of_2": {
"type": "boolean",
"description": "Pad output to next power of 2"
},
"trim_input": {
"type": "boolean",
"description": "Auto-trim transparent edges before compositing"
},
"cell_height": {
"type": "integer",
"description": "Required when cell_mode=fixed"
},
"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"
},
"metadata_format": {
"enum": [
"none",
"json_array",
"json_hash",
"css"
],
"type": "string",
"description": "Atlas metadata format. Required (non-none) when layout=packed"
}
}
}| skip_empty | boolean | Remove fully transparent frames. Default: true |
| trim_right | integer |
| cell_height | integer | Cell height in px (cell mode) |
| frame_count | integer |
| trim_bottom | integer |
| column_range | string | e.g. "0-5" or "2" |
| metadata_format | string |
{
"type": "object",
"required": [
"file"
],
"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."
},
"rows": {
"type": "integer",
"description": "Grid rows (grid mode)"
},
"output": {
"enum": [
"frames",
"metadata",
"both"
],
"type": "string",
"description": "Default: frames"
},
"columns": {
"type": "integer",
"description": "Grid columns (grid mode)"
},
"padding": {
"type": "integer"
},
"trim_top": {
"type": "integer"
},
"row_range": {
"type": "string"
},
"trim_left": {
"type": "integer"
},
"cell_width": {
"type": "integer",
"description": "Cell width in px (cell mode)"
},
"skip_empty": {
"type": "boolean",
"description": "Remove fully transparent frames. Default: true"
},
"trim_right": {
"type": "integer"
},
"cell_height": {
"type": "integer",
"description": "Cell height in px (cell mode)"
},
"frame_count": {
"type": "integer"
},
"trim_bottom": {
"type": "integer"
},
"column_range": {
"type": "string",
"description": "e.g. \"0-5\" or \"2\""
},
"metadata_format": {
"enum": [
"json_array",
"json_hash",
"css"
],
"type": "string"
}
}
}| WebP lossless. Default: false |
| trim_top | integer |
| row_range | string |
| trim_left | integer |
| cell_width | integer | Cell width in px (cell mode) |
| skip_empty | boolean | Auto-remove fully transparent frames. Default: true |
| trim_right | integer |
| cell_height | integer | Cell height in px (cell mode) |
| frame_count | integer | Actual frame count for incomplete last row |
| trim_bottom | integer |
| column_range | string | e.g. "0-5" or "2" |
| output_format | string | Default: gif |
{
"type": "object",
"required": [
"file"
],
"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."
},
"loop": {
"type": "integer",
"description": "Loop count. 0 = infinite. Default: 0"
},
"rows": {
"type": "integer",
"description": "Grid rows (grid mode)"
},
"columns": {
"type": "integer",
"description": "Grid columns (grid mode)"
},
"padding": {
"type": "integer",
"description": "Pixel gap between cells. Default: 0"
},
"quality": {
"type": "integer",
"description": "WebP quality 0-100. Default: 80"
},
"duration": {
"type": "integer",
"description": "Frame duration in ms. Default: 100"
},
"lossless": {
"type": "boolean",
"description": "WebP lossless. Default: false"
},
"trim_top": {
"type": "integer"
},
"row_range": {
"type": "string"
},
"trim_left": {
"type": "integer"
},
"cell_width": {
"type": "integer",
"description": "Cell width in px (cell mode)"
},
"skip_empty": {
"type": "boolean",
"description": "Auto-remove fully transparent frames. Default: true"
},
"trim_right": {
"type": "integer"
},
"cell_height": {
"type": "integer",
"description": "Cell height in px (cell mode)"
},
"frame_count": {
"type": "integer",
"description": "Actual frame count for incomplete last row"
},
"trim_bottom": {
"type": "integer"
},
"column_range": {
"type": "string",
"description": "e.g. \"0-5\" or \"2\""
},
"output_format": {
"enum": [
"gif",
"webp"
],
"type": "string",
"description": "Default: gif"
}
}
}