{"ok":true,"site":{"host":"pixelforge-webmcp.netlify.app","url":"https://pixelforge-webmcp.netlify.app/","type":"live","desc":"PixelForge — an agent-native pixel art studio where humans and AI agents collaborate on the same canvas via WebMCP.","tools":[{"name":"get_editor_state","kind":"answer","impl":"imperative","description":"Inspect the PixelForge pixel-art editor: canvas size, frames, layers, active selections, palette, and per-layer pixel counts. Call this first before any editing to understand the current artwork.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_region","kind":"answer","impl":"imperative","description":"Read the pixel colors of a rectangular region of the active frame. Returns a compact legend + row grid of palette indexes (0 = transparent). Use this to inspect existing artwork before modifying it.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"x":{"type":"integer","description":"Left edge (0-based)"},"y":{"type":"integer","description":"Top edge (0-based)"},"width":{"type":"integer","description":"Width in pixels"},"height":{"type":"integer","description":"Height in pixels"},"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."},"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}},"required":["x","y","width","height"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"draw_pixels","kind":"act","impl":"imperative","description":"Draw one or many pixels at once on the pixel canvas. Each pixel is {x, y, color} where color is a hex string like '#38b764'. Coordinates outside the canvas are rejected. Batch all pixels of a shape into one call.","inputSchema":{"type":"object","properties":{"pixels":{"type":"array","description":"Pixels to draw (batch in one call)","items":{"type":"object","properties":{"x":{"type":"integer"},"y":{"type":"integer"},"color":{"type":"string","description":"Hex color, e.g. '#38b764'"}},"required":["x","y","color"]}},"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."},"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}},"required":["pixels"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"erase_pixels","kind":"act","impl":"imperative","description":"Erase (make transparent) one or many pixels at once. Each point is {x, y}.","inputSchema":{"type":"object","properties":{"pixels":{"type":"array","description":"Pixels to erase","items":{"type":"object","properties":{"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y"]}},"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."},"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}},"required":["pixels"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"fill_region","kind":"act","impl":"imperative","description":"Flood fill: starting at (x, y), replace the contiguous region of identical color with the given hex color (like the paint-bucket tool).","inputSchema":{"type":"object","properties":{"x":{"type":"integer","description":"Start pixel x"},"y":{"type":"integer","description":"Start pixel y"},"color":{"type":"string","description":"Hex fill color, e.g. '#38b764'"},"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."},"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}},"required":["x","y","color"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"replace_color","kind":"act","impl":"imperative","description":"Recolor existing artwork: replace every pixel of hex color `from` with hex color `to`. Defaults to the active layer; use scope 'all-layers' for the whole frame or 'all-frames' to recolor an animation at once. Idempotent — repeating the call affects zero pixels.","inputSchema":{"type":"object","properties":{"from":{"type":"string","description":"Hex color to replace"},"to":{"type":"string","description":"Replacement hex color"},"scope":{"type":"string","enum":["active-layer","all-layers","all-frames"],"description":"How far the replacement reaches (default: active layer)"}},"required":["from","to"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"create_layer","kind":"act","impl":"imperative","description":"Create a new empty layer on the active frame (e.g. 'Eyes', 'Outline') and make it active. New layers stack on top.","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Layer name, e.g. 'Eyes'"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"select_layer","kind":"act","impl":"imperative","description":"Make a layer active by id or exact name (case-insensitive). Subsequent pixel operations default to this layer.","inputSchema":{"type":"object","properties":{"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."}},"required":["layer"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_layer_visibility","kind":"act","impl":"imperative","description":"Show or hide a layer by id or name, on the active frame.","inputSchema":{"type":"object","properties":{"layer":{"type":"string","description":"Target layer. Accepts the layer id (e.g. \"layer-ab12cd\") OR the layer name (e.g. \"Eyes\", case-insensitive). Defaults to the active layer."},"visible":{"type":"boolean","description":"true to show, false to hide"}},"required":["layer","visible"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"create_frame","kind":"act","impl":"imperative","description":"Append a new empty frame to the animation timeline (same layer structure) and make it active.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"duplicate_frame","kind":"act","impl":"imperative","description":"Duplicate a frame (copying all of its artwork) and insert the copy right after it. Target defaults to the active frame.","inputSchema":{"type":"object","properties":{"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"select_frame","kind":"act","impl":"imperative","description":"Make a frame active by 1-based number or id. Subsequent operations default to this frame.","inputSchema":{"type":"object","properties":{"frame":{"type":"integer","description":"Target frame as a 1-based frame number (1 = first frame). Defaults to the active frame."}},"required":["frame"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"select_region","kind":"act","impl":"imperative","description":"Select a rectangular region on the active layer. The selection is used by move_region, flip_region and clear_region.","inputSchema":{"type":"object","properties":{"x":{"type":"integer","description":"Left edge, pixels, 0-based from top-left"},"y":{"type":"integer","description":"Top edge, pixels, 0-based from top-left"},"width":{"type":"integer","description":"Width in pixels (min 1)"},"height":{"type":"integer","description":"Height in pixels (min 1)"}},"required":["x","y","width","height"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_region","kind":"act","impl":"imperative","description":"Shift the selected region's pixels by (dx, dy) on the active layer. Select a region with select_region first.","inputSchema":{"type":"object","properties":{"dx":{"type":"integer","description":"Horizontal shift (+right / -left)"},"dy":{"type":"integer","description":"Vertical shift (+down / -up)"}},"required":["dx","dy"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"flip_region","kind":"act","impl":"imperative","description":"Mirror the selected region horizontally or vertically on the active layer. Select a region with select_region first.","inputSchema":{"type":"object","properties":{"direction":{"type":"string","enum":["horizontal","vertical"]}},"required":["direction"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"clear_region","kind":"act","impl":"imperative","description":"Erase every pixel inside the selected region on the active layer (make them transparent). Select a region with select_region first.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_palette","kind":"act","impl":"imperative","description":"Replace the editor's color palette with a list of hex colors. Also updates the palette swatches shown to the human.","inputSchema":{"type":"object","properties":{"colors":{"type":"array","description":"Hex colors, e.g. ['#1a1c2c', '#38b764']","items":{"type":"string"}}},"required":["colors"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"export_sprite_sheet","kind":"act","impl":"imperative","description":"Export all animation frames as a single sprite-sheet PNG (row-major, N columns) and trigger a browser download. Returns sheet metadata and a data URL of the generated image.","inputSchema":{"type":"object","properties":{"columns":{"type":"integer","description":"Frames per row in the sheet (default: all frames in one row)"},"scale":{"type":"integer","description":"Output scale factor per pixel (default 8)"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"export_animation_gif","kind":"act","impl":"imperative","description":"Export the whole animation as an animated GIF file and trigger a browser download. Frames play at their configured durations. Returns file metadata.","inputSchema":{"type":"object","properties":{"scale":{"type":"integer","description":"Output scale factor per pixel (default 4)"},"background":{"type":"string","description":"Hex background color the animation is flattened onto (default '#ffffff')"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"Media & Personal","favicon":"/favicons/pixelforge-webmcp.netlify.app.png","apiSurface":"spec","toolCount":19}}