{"ok":true,"site":{"host":"pixel-art-tutor.thomasjvu.com","url":"https://pixel-art-tutor.thomasjvu.com/","type":"live","desc":"Pixel Art Tutor — a WebMCP-powered pixel art studio where AI agents and humans co-create sprites, characters, animations and tilemaps together.","tools":[{"name":"get_project_state","kind":"answer","impl":"imperative","description":"Overview of the whole pixel art project: palette with indices, all sprites (ids, names, sizes, kinds, frame counts), which sprite/frame is on the human's screen, and tilemap info. Call this first to ground yourself.","title":"Get project state","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"read_sprite","kind":"answer","impl":"imperative","description":"Read one frame of a sprite as ASCII art rows plus a color legend, so you can see exactly what the human is drawing. '.' = transparent; other characters use the 64-symbol palette alphabet returned in the legend.","title":"Read sprite pixels","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"spriteId":{"type":"string","description":"Sprite id. Defaults to the active sprite."},"frameIndex":{"type":"number","description":"Zero-based frame index."},"layerId":{"type":"string","description":"Layer id. Defaults to the first layer."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_pixels","kind":"act","impl":"imperative","description":"Paint specific pixels on a sprite frame. Each valid requested pixel is applied in order, one cell at a time on the page. Use fill_region or flood_fill for bulk areas.","title":"Set pixels","inputSchema":{"type":"object","properties":{"pixels":{"type":"array","maxItems":4096,"description":"List of pixel changes, applied one cell at a time, e.g. [{\"x\":3,\"y\":4,\"color\":\"#38b764\"}]","items":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"color":{"description":"Color to paint. Use a palette index (number), a hex string like '#38b764' (auto-added to the palette), 'transparent', or null to erase.","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]}},"required":["x","y","color"]}},"spriteId":{"type":"string","description":"Defaults to the active sprite."},"frameIndex":{"type":"number","description":"Defaults to the active frame."},"allFrames":{"type":"boolean","description":"Apply the same change to every frame."},"layerId":{"type":"string","description":"Layer id. Defaults to the first layer."}},"required":["pixels"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"fill_region","kind":"act","impl":"imperative","description":"Fill a rectangular region of a sprite frame with one color. Great for blocking in base shapes quickly.","title":"Fill rectangle region","inputSchema":{"type":"object","properties":{"x":{"type":"number","minimum":-256,"maximum":256},"y":{"type":"number","minimum":-256,"maximum":256},"width":{"type":"number","minimum":-256,"maximum":256},"height":{"type":"number","minimum":-256,"maximum":256},"color":{"description":"Color to paint. Use a palette index (number), a hex string like '#38b764' (auto-added to the palette), 'transparent', or null to erase.","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]},"spriteId":{"type":"string"},"frameIndex":{"type":"number"},"allFrames":{"type":"boolean"},"layerId":{"type":"string"}},"required":["x","y","width","height","color"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"flood_fill","kind":"act","impl":"imperative","description":"Bucket-fill: starting at x,y, replace all connected pixels of the same color with the new color (transparent counts as a color). Fails clearly if the start pixel is out of bounds.","title":"Flood fill region","inputSchema":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"color":{"description":"Color to paint. Use a palette index (number), a hex string like '#38b764' (auto-added to the palette), 'transparent', or null to erase.","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]},"spriteId":{"type":"string"},"frameIndex":{"type":"number"},"layerId":{"type":"string"}},"required":["x","y","color"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"clear_frame","kind":"act","impl":"imperative","description":"Erase every pixel of one sprite frame, making it fully transparent.","title":"Clear frame","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string"},"frameIndex":{"type":"number"},"layerId":{"type":"string"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"transform_sprite","kind":"act","impl":"imperative","description":"Apply a geometric transform to a sprite. Ops: flip_h, flip_v, rotate_90 (clockwise), rotate (RotSprite-style nearest-neighbor angle in degrees), shift (wrap-around move by dx/dy), outline (adds outlineColor around silhouettes). Applies to all frames unless frameIndices given.","title":"Transform sprite","inputSchema":{"type":"object","properties":{"op":{"type":"string","enum":["flip_h","flip_v","rotate_90","rotate","shift","outline"]},"dx":{"type":"number","description":"shift only: horizontal offset"},"dy":{"type":"number","description":"shift only: vertical offset"},"angle":{"type":"number","description":"rotate only: clockwise angle in degrees; keeps the sprite dimensions"},"color":{"description":"outline only: outline color (defaults to palette index 0)","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]},"frameIndices":{"type":"array","items":{"type":"number"},"description":"Which frames; omit for all."},"spriteId":{"type":"string"},"layerId":{"type":"string"}},"required":["op"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"replace_color","kind":"act","impl":"imperative","description":"Swap every occurrence of one palette color for another across a sprite (or the whole project if no spriteId). Accepts palette indices or hex strings.","title":"Replace color everywhere","inputSchema":{"type":"object","properties":{"from":{"description":"Color to replace.","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]},"to":{"description":"Replacement color ('transparent'/null erases).","anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}]},"spriteId":{"type":"string","description":"Scope to one sprite; omit for all sprites."},"layerId":{"type":"string","description":"Scope to one layer; omit for all layers."}},"required":["from","to"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_palette_color","kind":"act","impl":"imperative","description":"Add a new hex color to the shared project palette and get its index back.","title":"Add palette color","inputSchema":{"type":"object","properties":{"hex":{"type":"string","description":"e.g. '#ffcd75'"}},"required":["hex"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_palette_alpha","kind":"act","impl":"imperative","description":"Set the selected palette entry's opacity from 0 to 1 without changing its color index.","title":"Set palette alpha","inputSchema":{"type":"object","properties":{"index":{"type":"number"},"alpha":{"type":"number","minimum":0,"maximum":1}},"required":["index","alpha"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_palette_color","kind":"act","impl":"imperative","description":"Reorder a palette entry while remapping all pixel indices so the artwork keeps its appearance.","title":"Move palette color","inputSchema":{"type":"object","properties":{"fromIndex":{"type":"number"},"toIndex":{"type":"number"}},"required":["fromIndex","toIndex"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_active_sprite","kind":"act","impl":"imperative","description":"Switch the human's editor view to a given sprite (and optionally frame). Use this to show them something you made or want them to review.","title":"Point human at a sprite","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string"},"frameIndex":{"type":"number"}},"required":["spriteId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_frame","kind":"act","impl":"imperative","description":"Add a new animation frame to a character sprite, copying an existing frame by default so it can be nudged into the next pose.","title":"Add animation frame","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string"},"copyFrameIndex":{"type":"number","description":"Frame to duplicate. Defaults to the last frame."},"layerId":{"type":"string","description":"Layer id. Defaults to the selected layer."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"delete_frame","kind":"transact","impl":"imperative","description":"Delete one animation frame from a sprite. Requires confirm:true. Refuses to delete a sprite's last remaining frame.","title":"Delete animation frame","inputSchema":{"type":"object","properties":{"frameIndex":{"type":"number","description":"Zero-based frame to delete"},"spriteId":{"type":"string"},"layerId":{"type":"string","description":"Layer id. Defaults to the selected layer."},"confirm":{"type":"boolean","description":"Must be true to perform the deletion"}},"required":["frameIndex","confirm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"link_frame","kind":"act","impl":"imperative","description":"Link two cels on one layer so future pixel edits stay synchronized across both frames.","title":"Link animation cels","inputSchema":{"type":"object","properties":{"frameIndex":{"type":"number","description":"Zero-based cel to link"},"targetIndex":{"type":"number","description":"Zero-based cel to link it with"},"spriteId":{"type":"string"},"layerId":{"type":"string","description":"Layer id. Defaults to the selected layer."}},"required":["frameIndex","targetIndex"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"unlink_frame","kind":"act","impl":"imperative","description":"Detach one cel from its linked group so it can be edited independently.","title":"Unlink animation cel","inputSchema":{"type":"object","properties":{"frameIndex":{"type":"number"},"spriteId":{"type":"string"},"layerId":{"type":"string","description":"Layer id. Defaults to the selected layer."}},"required":["frameIndex"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_layer","kind":"act","impl":"imperative","description":"Create an empty animation layer above the selected layer. It starts with matching cels so it can be painted immediately.","title":"Create layer","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string","description":"Sprite id; defaults to the active sprite."},"name":{"type":"string","description":"Layer name; defaults to Layer."},"aboveLayerId":{"type":"string","description":"Insert above this layer; defaults to the top."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"duplicate_layer","kind":"act","impl":"imperative","description":"Copy a layer, including every cel, and place the copy directly above it.","title":"Duplicate layer","inputSchema":{"type":"object","properties":{"layerId":{"type":"string"},"spriteId":{"type":"string"}},"required":["layerId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"delete_layer","kind":"transact","impl":"imperative","description":"Delete a layer after explicit confirmation. A sprite must keep at least one layer.","title":"Delete layer","inputSchema":{"type":"object","properties":{"layerId":{"type":"string"},"spriteId":{"type":"string"},"confirm":{"type":"boolean"}},"required":["layerId","confirm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_layer","kind":"act","impl":"imperative","description":"Move a layer one slot up or down in the stack. Direction 1 moves toward the top.","title":"Move layer","inputSchema":{"type":"object","properties":{"layerId":{"type":"string"},"direction":{"type":"number","enum":[-1,1]},"spriteId":{"type":"string"}},"required":["layerId","direction"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_layer_properties","kind":"act","impl":"imperative","description":"Update a layer name, visibility, lock, opacity, or blend mode.","title":"Set layer properties","inputSchema":{"type":"object","properties":{"layerId":{"type":"string"},"spriteId":{"type":"string"},"name":{"type":"string"},"visible":{"type":"boolean"},"locked":{"type":"boolean"},"opacity":{"type":"number","minimum":0,"maximum":1},"blendMode":{"type":"string","enum":["normal","multiply","screen","overlay"]}},"required":["layerId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_animation_preview","kind":"act","impl":"imperative","description":"Control playback mode, tagged range, speed, and onion-skin display without changing sprite pixels.","title":"Set animation preview","inputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["forward","reverse","ping_pong"]},"tagId":{"anyOf":[{"type":"string"},{"type":"null"}]},"fps":{"type":"number","minimum":1,"maximum":30},"playing":{"type":"boolean"},"onion":{"type":"boolean"},"onionMode":{"type":"string","enum":["tint","red_blue"]}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_canvas_options","kind":"act","impl":"imperative","description":"Set zoom, grid, pixel-perfect stroke, shading ink, tiled preview, and dither brush options. The default canvas is a 256x256 logical grid displayed at 1px per cell; zoom in for detailed editing.","title":"Set canvas options","inputSchema":{"type":"object","properties":{"zoom":{"type":"number","minimum":1,"maximum":16},"showGrid":{"type":"boolean"},"pixelPerfect":{"type":"boolean"},"shadingMode":{"type":"boolean"},"tiledMode":{"type":"boolean"},"brushMode":{"type":"string","enum":["solid","checker","dots"]}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_frame_tag","kind":"act","impl":"imperative","description":"Create a named animation section over a range of frames, such as idle or walk.","title":"Tag animation frames","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string"},"name":{"type":"string"},"from":{"type":"number"},"to":{"type":"number"},"color":{"type":"string"}},"required":["name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"delete_frame_tag","kind":"transact","impl":"imperative","description":"Delete a named animation section after explicit confirmation.","title":"Delete frame tag","inputSchema":{"type":"object","properties":{"tagId":{"type":"string"},"spriteId":{"type":"string"},"confirm":{"type":"boolean"}},"required":["tagId","confirm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"rename_sprite","kind":"act","impl":"imperative","description":"Rename an existing sprite (e.g. after giving an untitled sprite an identity).","title":"Rename sprite","inputSchema":{"type":"object","properties":{"spriteId":{"type":"string"},"name":{"type":"string","maxLength":128,"description":"New name (non-empty)"}},"required":["spriteId","name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_sprite","kind":"act","impl":"imperative","description":"Create a new empty sprite (character, item, or tile for the tileset). It becomes the active sprite so the human sees it immediately. Character sprites default to 4 empty animation frames and items/tiles default to 1; pass frameCount to choose another count. Optionally copy dimensions/content from an existing sprite.","title":"Create sprite","inputSchema":{"type":"object","properties":{"name":{"type":"string","maxLength":128},"width":{"type":"number","description":"1-256 logical pixels, typically 16, 32, 64, 128, or 256"},"height":{"type":"number","description":"1-256 logical pixels, typically 16, 32, 64, 128, or 256"},"kind":{"type":"string","enum":["character","item","tile"],"description":"'tile' adds it to the tileset for map painting."},"copyFromId":{"type":"string","description":"Clone pixels from this sprite id if sizes match."},"frameCount":{"type":"number","minimum":1,"maximum":32,"description":"Animation frame count. Defaults to 4 for characters and 1 for items/tiles."}},"required":["name","width","height","kind"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_tilemap","kind":"answer","impl":"imperative","description":"Read the tilemap grid as ASCII rows where each token maps to a tileset sprite via the returned legend. Maps with more than 64 tiles use two-character tokens and return tokenWidth: 2.","title":"Read tilemap","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"ensure_tilemap","kind":"act","impl":"imperative","description":"Create the project tilemap (or resize it, preserving overlapping cells) so tiles can be placed. Cols/rows are clamped to 2-64; default to 12x9 when unsure. No-ops with ok:true if the map already has these dimensions.","title":"Create or resize tilemap","inputSchema":{"type":"object","properties":{"cols":{"type":"number","minimum":2,"maximum":64,"description":"Map width in tiles (2-64)"},"rows":{"type":"number","minimum":2,"maximum":64,"description":"Map height in tiles (2-64)"}},"required":["cols","rows"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"place_tile","kind":"act","impl":"imperative","description":"Put one tileset sprite at a map coordinate. Pass tileId=null or 'empty' to clear the cell.","title":"Place tile on map","inputSchema":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"tileId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["x","y"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"fill_tiles","kind":"act","impl":"imperative","description":"Fill a rectangular region of the tilemap with one tileset sprite. Pass tileId=null or 'empty' to clear the area.","title":"Fill map region with tile","inputSchema":{"type":"object","properties":{"x":{"type":"number","minimum":-64,"maximum":64},"y":{"type":"number","minimum":-64,"maximum":64},"width":{"type":"number","minimum":-64,"maximum":64},"height":{"type":"number","minimum":-64,"maximum":64},"tileId":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["x","y","width","height"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"critique_artwork","kind":"act","impl":"imperative","description":"Run the built-in pixel-art tutor analysis on a sprite: color discipline, value contrast, outline strength, noise, centering, symmetry, animation readiness. Returns a score, stats and findings with concrete tips. Use it to give the human structured feedback before/after you edit.","title":"Critique artwork","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"spriteId":{"type":"string","description":"Defaults to the active sprite."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"export_project","kind":"act","impl":"imperative","description":"Serialize the entire project (palette, sprites, frames, tilemap) as JSON that can be re-imported via the import_project tool, the Sprites > Project file > Import button, or a share permalink.","title":"Export project JSON","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"import_project","kind":"act","impl":"imperative","description":"Replace the current project with one previously exported via export_project (or a project file). The JSON is sanitized and validated; the human sees the imported project immediately.","title":"Import project JSON","inputSchema":{"type":"object","properties":{"json":{"type":"string","description":"Full project JSON string"}},"required":["json"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"new_canvas","kind":"act","impl":"imperative","description":"Replace the current project with a fresh blank 256x256 logical canvas (one empty character sprite, default palette, no tilemap). Defaults to 4 empty animation frames; pass frameCount to choose another count. Requires confirm:true. The human sees the blank canvas immediately; use this to start a new drawing together.","title":"New blank canvas","inputSchema":{"type":"object","properties":{"confirm":{"type":"boolean","description":"Must be true to clear the current project"},"frameCount":{"type":"number","minimum":1,"maximum":32,"description":"Optional animation frame count; defaults to 4."}},"required":["confirm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"start_tutorial","kind":"act","impl":"imperative","description":"Open the step-by-step guided tour overlay (shared with the room, so following humans see the same step) and jump to a step. Use it to walk the human through the whole app, then guide them to a first project together with your drawing tools.","title":"Start guided tutorial","inputSchema":{"type":"object","properties":{"step":{"type":"number","description":"Zero-based step index. Defaults to 0 (the beginning)."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"tutorial_goto","kind":"act","impl":"imperative","description":"Jump the shared guided-tour overlay to a given step (0-based). Pair each step with a live demo using your drawing tools.","title":"Go to tutorial step","inputSchema":{"type":"object","properties":{"step":{"type":"number","description":"Zero-based step index"}},"required":["step"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"end_tutorial","kind":"act","impl":"imperative","description":"Close the shared guided-tour overlay on this window (following humans keep their own copy until they close it). Call it when the tour is done so it never pops back up.","title":"End guided tutorial","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"rename_project","kind":"act","impl":"imperative","description":"Rename the current project (e.g. 'guided-tutorial-01' when starting a tutorial piece). The human sees the new title immediately.","title":"Rename project","inputSchema":{"type":"object","properties":{"name":{"type":"string","maxLength":128,"description":"New project name (non-empty)"}},"required":["name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"save_project","kind":"act","impl":"imperative","description":"Save the current project into the on-device library under a name (defaults to the project name), so it can be reopened later with open_project. Saved names are listed in get_project_state.","title":"Save named project","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Slot name, e.g. 'guided-tutorial-01'. Defaults to the project name."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"open_project","kind":"act","impl":"imperative","description":"Replace the current project with a saved one from the on-device library. Requires confirm:true. The human sees the opened project immediately.","title":"Open saved project","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Saved project name"},"confirm":{"type":"boolean","description":"Must be true to replace the current project"}},"required":["name","confirm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"save_palette","kind":"act","impl":"imperative","description":"Save the current shared palette into the on-device library under a name, so it can be merged into any project later with apply_palette. Saved names are listed in get_project_state.","title":"Save named palette","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Slot name. Defaults to '<project> palette'."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"apply_palette","kind":"act","impl":"imperative","description":"Merge a saved palette into the current project: missing colors are appended (up to 64), existing indices never move so artwork is untouched. Reports how many colors were added.","title":"Apply saved palette","inputSchema":{"type":"object","properties":{"name":{"type":"string","description":"Saved palette name"}},"required":["name"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"Media & Personal","favicon":"/favicons/pixel-art-tutor.thomasjvu.com.png","apiSurface":"spec","toolCount":43}}