PinePaper MCP Tools Specification

This document defines the MCP tools for PinePaper integration. These tools enable AI agents to create animated graphics and generate training data.

Tool Categories

  1. Canvas Tools - Set and get canvas dimensions (REQUIRED before creating items)
  2. Item Tools - Create, modify, delete canvas items
  3. Diagram Tools - Create flowcharts, UML diagrams, and network diagrams
  4. Relation Tools - Define behavior relationships (key for animation)
  5. Animation Tools - Apply and control animations
  6. Mask Tools - Apply clipping masks and animated reveal effects
  7. Generator Tools - Create procedural backgrounds
  8. Map Tools - Geographic visualizations (world maps, US states, choropleth)
  9. Text Design Tools - Create stylized text (Letter Collage with tile, magazine, gradient styles)
  10. Effect Tools - Apply visual effects (sparkle, blast)
  11. Query Tools - Find and inspect items
  12. Export Tools - Export graphics and training data

Canvas Tools

IMPORTANT: AI agents MUST set the canvas size before creating items. The canvas defines the output dimensions and items should be positioned within these bounds.

pinepaper_get_canvas_size

Get the current canvas dimensions.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "success": true,
  "width": 800,
  "height": 600,
  "preset": "default"
}

pinepaper_set_canvas_size

Set the canvas output dimensions. Agents SHOULD call this before creating items to ensure proper positioning.

Input Schema:

{
  "type": "object",
  "properties": {
    "preset": {
      "type": "string",
      "enum": [
        "youtube-thumbnail", "youtube-short", "tiktok",
        "instagram-story", "instagram-post", "instagram-landscape", "instagram-portrait",
        "facebook-post", "facebook-cover", "facebook-story",
        "twitter-post", "twitter-header",
        "linkedin-post", "linkedin-banner",
        "pinterest-pin",
        "presentation-16x9", "presentation-4x3",
        "hd-720p", "full-hd-1080p",
        "default"
      ],
      "description": "Predefined canvas size preset"
    },
    "width": {
      "type": "number",
      "description": "Custom canvas width in pixels (use with height for custom size)",
      "minimum": 100,
      "maximum": 7680
    },
    "height": {
      "type": "number",
      "description": "Custom canvas height in pixels (use with width for custom size)",
      "minimum": 100,
      "maximum": 4320
    }
  },
  "oneOf": [
    {"required": ["preset"]},
    {"required": ["width", "height"]}
  ]
}

Preset Dimensions:

Preset Dimensions Use Case
youtube-thumbnail 1280×720 YouTube video thumbnails
youtube-short 1080×1920 YouTube Shorts
tiktok 1080×1920 TikTok videos
instagram-story 1080×1920 Instagram Stories & Reels
instagram-post 1080×1080 Square Instagram posts
instagram-landscape 1080×566 Landscape Instagram posts
instagram-portrait 1080×1350 Portrait Instagram posts
facebook-post 1200×630 Facebook feed posts
facebook-cover 820×312 Facebook cover photos
facebook-story 1080×1920 Facebook Stories
twitter-post 1200×675 Twitter/X images
twitter-header 1500×500 Twitter/X profile headers
linkedin-post 1200×627 LinkedIn posts
linkedin-banner 1584×396 LinkedIn banners
pinterest-pin 1000×1500 Pinterest pins
presentation-16x9 1920×1080 16:9 presentations
presentation-4x3 1024×768 4:3 presentations
hd-720p 1280×720 HD video
full-hd-1080p 1920×1080 Full HD video
default 800×600 Default canvas

Output:

{
  "success": true,
  "width": 1080,
  "height": 1080,
  "preset": "instagram-post"
}

pinepaper_get_canvas_presets

List all available canvas presets with their dimensions.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "presets": [
    {
      "key": "instagram-post",
      "name": "Instagram Post (Square)",
      "width": 1080,
      "height": 1080,
      "aspectRatio": "1:1",
      "category": "social"
    }
  ]
}

Item Tools

pinepaper_create_item

Create an item on the canvas.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemType": {
      "type": "string",
      "enum": ["text", "circle", "star", "rectangle", "triangle", "polygon", "ellipse", "path", "line", "arc"],
      "description": "Type of item to create"
    },
    "position": {
      "type": "object",
      "properties": {
        "x": { "type": "number" },
        "y": { "type": "number" }
      },
      "description": "Position on canvas"
    },
    "properties": {
      "type": "object",
      "description": "Type-specific properties"
    },
    "data": {
      "type": "object",
      "description": "Item data flags for selection and behavior control",
      "properties": {
        "selectable": { "type": "boolean", "description": "Whether item can be selected (default: true for text layer items)" },
        "isDraggable": { "type": "boolean", "description": "Whether item can be dragged (default: true for text layer items)" },
        "isDecorative": { "type": "boolean", "description": "Mark as decorative/non-interactive (skipped by selection)" }
      }
    }
  },
  "required": ["itemType"]
}

Type-Specific Properties:

Type Properties
text content, fontSize, fontFamily, color
circle radius, color, strokeColor, strokeWidth
star radius1, radius2, color
rectangle width, height, color
polygon sides, radius, color
path segments or pathData, strokeColor, strokeWidth, closed, smooth
line from, to, strokeColor, strokeWidth
arc from, through, to, strokeColor

Data Flags for Selection Control:

Flag Type Description
selectable boolean Allow item to be selected (even in background layer). Default: true for text layer items
isDraggable boolean Allow item to be dragged when selected. Default: true for text layer items
isDecorative boolean Mark as non-interactive decoration (never selectable). Useful for orbit paths, guidelines, etc.

Layer and Selection Priority:

  1. Items in textItemGroup (text layer) are always selectable by default
  2. Items in patternGroup (background) are NOT selectable unless marked with selectable: true
  3. Items with isDecorative: true are never selectable (overrides all)
  4. Items with selectable: true can be selected even if in background layer

Output:

{
  "success": true,
  "itemId": "item_1",
  "type": "circle",
  "position": { "x": 400, "y": 300 }
}

pinepaper_modify_item

Modify an existing item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the item"
    },
    "properties": {
      "type": "object",
      "description": "Properties to update",
      "properties": {
        "x": { "type": "number", "description": "X position in pixels" },
        "y": { "type": "number", "description": "Y position in pixels" },
        "width": { "type": "number", "description": "Width in pixels (absolute sizing)" },
        "height": { "type": "number", "description": "Height in pixels (absolute sizing)" },
        "scale": { "type": "number", "description": "Uniform scale (1.0 = 100%)" },
        "scaleX": { "type": "number", "description": "Horizontal scale" },
        "scaleY": { "type": "number", "description": "Vertical scale" },
        "rotation": { "type": "number", "description": "Rotation in degrees" },
        "opacity": { "type": "number", "description": "Opacity (0-1)" },
        "color": { "type": "string", "description": "Fill color" },
        "strokeColor": { "type": "string", "description": "Stroke color" },
        "strokeWidth": { "type": "number", "description": "Stroke width in pixels" },
        "fontSize": { "type": "number", "description": "Font size (text items only)" },
        "content": { "type": "string", "description": "Text content (text items only)" },
        "animationType": { "type": "string", "description": "Animation type" },
        "animationSpeed": { "type": "number", "description": "Animation speed multiplier" }
      }
    },
    "data": {
      "type": "object",
      "description": "Update item data flags",
      "properties": {
        "selectable": { "type": "boolean" },
        "isDraggable": { "type": "boolean" },
        "isDecorative": { "type": "boolean" }
      }
    }
  },
  "required": ["itemId", "properties"]
}

Sizing: width/height vs scale:

Property Type Description
width pixels Set exact width in pixels (absolute, predictable)
height pixels Set exact height in pixels (absolute, predictable)
scale ratio Multiply current size (relative, compounds on repeated use)

Recommendation: Use width/height for precise sizing. Use scale only for proportional adjustments.

pinepaper_delete_item

Delete an item from the canvas.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the item to delete"
    }
  },
  "required": ["itemId"]
}

Diagram Tools

Tools for creating flowcharts, UML diagrams, network diagrams, and connecting any visual elements with smart arrows.

Key Capabilities:

  • Flowcharts & UML - Standard diagram shapes (process, decision, terminal, etc.)
  • Network Diagrams - Server, cloud, and infrastructure symbols
  • Visual Sequences - Connect any items (images, SVGs, shapes) with stylish arrows
  • Smart Connectors - Auto-routing with orthogonal, curved, or direct paths
  • Arrow Styles - Multiple head styles (classic, stealth, sharp, open, diamond, circle)
  • Animated Flow - Bolt effect shows connection direction

Works With Any Item: Diagram connectors aren’t limited to diagram shapes. Connect any canvas items:

  • Images and imported SVGs
  • Text elements
  • Custom paths and shapes
  • Generator-created elements

This enables creative visual storytelling, infographics, and animated sequences.

pinepaper_create_diagram_shape

Create a diagram shape (flowchart, UML, network, or basic shape).

Input Schema:

{
  "type": "object",
  "properties": {
    "shapeType": {
      "type": "string",
      "enum": [
        "process", "decision", "terminal", "data", "document", "database", "preparation",
        "uml-class", "uml-usecase", "uml-actor",
        "cloud", "server",
        "rectangle", "circle", "triangle", "star"
      ],
      "description": "Type of diagram shape to create"
    },
    "position": {
      "type": "object",
      "properties": {
        "x": { "type": "number" },
        "y": { "type": "number" }
      },
      "description": "Position on canvas"
    },
    "width": {
      "type": "number",
      "description": "Shape width in pixels (optional, uses default for shape type)"
    },
    "height": {
      "type": "number",
      "description": "Shape height in pixels (optional, uses default for shape type)"
    },
    "label": {
      "type": "string",
      "description": "Text label to display inside the shape"
    },
    "style": {
      "type": "object",
      "properties": {
        "fillColor": { "type": "string", "description": "Fill color (hex, rgb, or named)" },
        "strokeColor": { "type": "string", "description": "Border/stroke color" },
        "strokeWidth": { "type": "number", "description": "Border width in pixels" }
      }
    }
  },
  "required": ["shapeType"]
}

Shape Types by Category:

Category Shapes Description
Flowchart process, decision, terminal, data, document, database, preparation Standard flowchart symbols
UML uml-class, uml-usecase, uml-actor UML diagram elements
Network cloud, server Network architecture symbols
Basic rectangle, circle, triangle, star Basic geometric shapes

Default Sizes:

Shape Default Size
process 120 x 60
decision 100 x 100
terminal 120 x 50
data 120 x 60
document 120 x 70
database 80 x 100
uml-class 150 x 120
cloud 140 x 90
server 60 x 80

Output:

{
  "success": true,
  "itemId": "item_1",
  "shapeType": "process",
  "position": { "x": 400, "y": 300 }
}

pinepaper_connect

Connect two items with a smart connector.

Input Schema:

{
  "type": "object",
  "properties": {
    "sourceItemId": {
      "type": "string",
      "description": "Registry ID of the source item"
    },
    "targetItemId": {
      "type": "string",
      "description": "Registry ID of the target item"
    },
    "routing": {
      "type": "string",
      "enum": ["direct", "orthogonal", "curved"],
      "default": "orthogonal",
      "description": "Path routing style"
    },
    "lineColor": {
      "type": "string",
      "description": "Connector line color"
    },
    "lineWidth": {
      "type": "number",
      "description": "Line width in pixels"
    },
    "lineStyle": {
      "type": "string",
      "enum": ["solid", "dashed", "dotted"],
      "default": "solid"
    },
    "headStyle": {
      "type": "string",
      "enum": ["classic", "stealth", "sharp", "open", "diamond", "circle", "none"],
      "default": "classic",
      "description": "Arrowhead style at target"
    },
    "tailStyle": {
      "type": "string",
      "enum": ["classic", "stealth", "sharp", "open", "diamond", "circle", "none"],
      "default": "none",
      "description": "Arrowhead style at source"
    },
    "label": {
      "type": "string",
      "description": "Label text to display on the connector"
    },
    "curvature": {
      "type": "number",
      "minimum": 0.1,
      "maximum": 1.0,
      "default": 0.5,
      "description": "Curve intensity for curved routing"
    },
    "boltEnabled": {
      "type": "boolean",
      "default": true,
      "description": "Enable animated bolt effect along connector"
    },
    "boltColor": {
      "type": "string",
      "default": "#fbbf24",
      "description": "Bolt animation color"
    }
  },
  "required": ["sourceItemId", "targetItemId"]
}

Output:

{
  "success": true,
  "connectorId": "connector_1",
  "sourceItemId": "item_1",
  "targetItemId": "item_2",
  "routing": "orthogonal"
}

pinepaper_connect_ports

Connect specific ports on items for precise connector placement.

Input Schema:

{
  "type": "object",
  "properties": {
    "sourceItemId": {
      "type": "string"
    },
    "sourcePort": {
      "type": "string",
      "enum": ["top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right", "center", "start", "end"],
      "description": "Port position on source item"
    },
    "targetItemId": {
      "type": "string"
    },
    "targetPort": {
      "type": "string",
      "enum": ["top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right", "center", "start", "end"],
      "description": "Port position on target item"
    },
    "config": {
      "type": "object",
      "description": "Connector configuration (same as pinepaper_connect)"
    }
  },
  "required": ["sourceItemId", "sourcePort", "targetItemId", "targetPort"]
}

pinepaper_add_ports

Add connection ports to an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the item"
    },
    "portType": {
      "type": "string",
      "enum": ["standard", "line", "path", "custom"],
      "default": "standard",
      "description": "Port configuration type"
    },
    "ports": {
      "type": "array",
      "description": "Custom port definitions (for portType='custom')",
      "items": {
        "type": "object",
        "properties": {
          "position": {
            "type": "string",
            "enum": ["top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right", "center"]
          },
          "type": {
            "type": "string",
            "enum": ["input", "output", "both"],
            "default": "both",
            "description": "Port connection direction"
          }
        }
      }
    },
    "count": {
      "type": "number",
      "description": "Number of ports (for portType='path')"
    }
  },
  "required": ["itemId"]
}

Port Types:

Type Description Ports Created
standard 4-way configuration (default) top, bottom, left, right
line For paths/lines start, end
path Distributed along closed path Evenly spaced points
custom User-defined ports As specified in ports array

pinepaper_auto_layout

Apply automatic layout algorithm to arrange diagram items.

Input Schema:

{
  "type": "object",
  "properties": {
    "layoutType": {
      "type": "string",
      "enum": ["hierarchical", "force-directed", "tree", "radial", "grid"],
      "description": "Layout algorithm to apply"
    },
    "itemIds": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Items to include (default: all items with ports)"
    },
    "options": {
      "type": "object",
      "properties": {
        "direction": {
          "type": "string",
          "enum": ["TB", "BT", "LR", "RL"],
          "default": "TB",
          "description": "Flow direction (hierarchical/tree)"
        },
        "levelSpacing": {
          "type": "number",
          "default": 100,
          "description": "Vertical spacing between levels"
        },
        "nodeSpacing": {
          "type": "number",
          "default": 80,
          "description": "Horizontal spacing between nodes"
        },
        "iterations": {
          "type": "number",
          "default": 100,
          "description": "Iterations for force-directed layout"
        },
        "attraction": {
          "type": "number",
          "default": 0.01,
          "description": "Attraction force (force-directed)"
        },
        "repulsion": {
          "type": "number",
          "default": 1000,
          "description": "Repulsion force (force-directed)"
        },
        "columns": {
          "type": "number",
          "description": "Number of columns (grid layout)"
        },
        "cellWidth": {
          "type": "number",
          "default": 150,
          "description": "Cell width (grid layout)"
        },
        "cellHeight": {
          "type": "number",
          "default": 100,
          "description": "Cell height (grid layout)"
        },
        "centerX": {
          "type": "number",
          "description": "Center X position (radial layout)"
        },
        "centerY": {
          "type": "number",
          "description": "Center Y position (radial layout)"
        },
        "startRadius": {
          "type": "number",
          "default": 100,
          "description": "Starting radius (radial layout)"
        },
        "radiusStep": {
          "type": "number",
          "default": 80,
          "description": "Radius increment per level (radial layout)"
        }
      }
    }
  },
  "required": ["layoutType"]
}

Layout Types:

Layout Description Best For
hierarchical Layered top-to-bottom or left-to-right Flowcharts, org charts
force-directed Physics-based node positioning Network diagrams
tree Parent-child hierarchical layout Family trees, file structures
radial Concentric circles from center Mind maps, radial hierarchies
grid Regular grid arrangement Inventory, galleries

Output:

{
  "success": true,
  "layoutType": "hierarchical",
  "itemsLayouted": 5,
  "bounds": {
    "x": 100,
    "y": 50,
    "width": 400,
    "height": 500
  }
}

pinepaper_get_diagram_shapes

Get available diagram shapes.

Input Schema:

{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": ["flowchart", "uml", "network", "basic"],
      "description": "Filter by category (optional)"
    }
  }
}

Output:

{
  "shapes": [
    {
      "id": "process",
      "name": "Process",
      "category": "flowchart",
      "description": "Rectangle with rounded corners",
      "defaultSize": { "width": 120, "height": 60 }
    },
    {
      "id": "decision",
      "name": "Decision",
      "category": "flowchart",
      "description": "Diamond shape for conditions",
      "defaultSize": { "width": 100, "height": 100 }
    }
  ]
}

pinepaper_update_connector

Update an existing connector’s style or configuration.

Input Schema:

{
  "type": "object",
  "properties": {
    "connectorId": {
      "type": "string",
      "description": "Connector ID to update"
    },
    "style": {
      "type": "object",
      "properties": {
        "lineColor": { "type": "string" },
        "lineWidth": { "type": "number" },
        "headStyle": { "type": "string" },
        "routing": { "type": "string" }
      }
    },
    "label": {
      "type": "string",
      "description": "Update connector label"
    },
    "labelPosition": {
      "type": "number",
      "minimum": 0,
      "maximum": 1,
      "description": "Label position along path (0-1)"
    }
  },
  "required": ["connectorId"]
}

pinepaper_remove_connector

Remove a connector between items.

Input Schema:

{
  "type": "object",
  "properties": {
    "connectorId": {
      "type": "string",
      "description": "Connector ID to remove"
    }
  },
  "required": ["connectorId"]
}

pinepaper_diagram_mode

Control diagram mode activation and tool selection.

Input Schema:

{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": ["activate", "deactivate", "toggle", "setMode"],
      "description": "Diagram mode action"
    },
    "mode": {
      "type": "string",
      "enum": ["select", "connect", "shape", "pan"],
      "description": "Tool mode (for setMode action)"
    },
    "shapeType": {
      "type": "string",
      "description": "Shape to place (for mode='shape')"
    }
  },
  "required": ["action"]
}

Output:

{
  "success": true,
  "isActive": true,
  "currentMode": "connect"
}

Relation Tools

Relations are the primary mechanism for creating declarative animations.

pinepaper_add_relation

Create a behavior relationship between two items.

Input Schema:

{
  "type": "object",
  "properties": {
    "sourceId": {
      "type": "string",
      "description": "Registry ID of the source item (the item that will be affected)"
    },
    "targetId": {
      "type": "string",
      "description": "Registry ID of the target item (the item being related to, can be null for self-animations)"
    },
    "relationType": {
      "type": "string",
      "enum": [
        "orbits", "follows", "attached_to", "maintains_distance", "points_at", "mirrors", "parallax", "bounds_to", "animates",
        "grows_from", "staggered_with", "indicates", "circumscribes", "wave_through", "camera_follows", "camera_animates", "morphs_to"
      ],
      "description": "Type of relationship"
    },
    "params": {
      "type": "object",
      "description": "Relation-specific parameters"
    }
  },
  "required": ["sourceId", "relationType"]
}

Core Relation Parameters:

Relation Parameters
orbits radius (number), speed (number), direction (‘clockwise’/‘counterclockwise’), phase (number)
follows offset ([x, y]), smoothing (0-1), delay (seconds)
attached_to offset ([x, y]), inherit_rotation (boolean)
maintains_distance distance (pixels), strength (0-1)
points_at offset_angle (degrees), smoothing (0-1)
mirrors axis (‘vertical’/‘horizontal’/‘both’), center ([x, y])
parallax depth (0-1), origin ([x, y])
bounds_to padding (pixels), bounce (boolean)
animates keyframes (array), duration (seconds), loop (boolean)

Manim-Inspired Animation Relations:

Relation Description Parameters
grows_from Item scales from zero to full size (like Manim GrowFromPoint) origin (‘center’/‘top’/‘bottom’/‘left’/‘right’/‘topLeft’/‘topRight’/‘bottomLeft’/‘bottomRight’), duration (seconds), delay (seconds), easing
staggered_with Staggered animation timing for groups (like Manim LaggedStart) index (0-based position), stagger (delay between items in seconds), effect (‘fadeIn’/‘fadeOut’/‘growIn’/‘slideIn’/‘popIn’)
indicates Temporary highlight effect (like Manim Indicate) scale (max scale during indication), color (highlight color), duration (seconds), delay (seconds), repeat (number of times)
circumscribes Draw temporary shape around target (like Manim Circumscribe) shape (‘rectangle’/‘circle’/‘ellipse’), color (stroke color), strokeWidth, padding, duration (seconds), fadeOut (boolean)
wave_through Send wave distortion through item (like Manim ApplyWave) amplitude (pixels), frequency (cycles), direction (‘horizontal’/‘vertical’), duration (seconds), delay (seconds)
camera_follows View pans to follow target (like Manim MovingCameraScene) smoothing (0-1), offset ([x, y]), zoom (level), deadzone (pixels), bounds ({minX, maxX, minY, maxY})
camera_animates Keyframe-based camera zoom and pan animation keyframes (array of {time, zoom, center, easing}), duration (seconds), loop (boolean), delay (seconds)
morphs_to Shape morphing animation (like Manim Transform) duration (seconds), delay (seconds), easing, morphColor (boolean), morphSize (boolean), hideTarget (boolean), removeTargetOnComplete (boolean)

Output:

{
  "success": true,
  "sourceId": "item_1",
  "targetId": "item_2",
  "relationType": "orbits"
}

pinepaper_remove_relation

Remove a relationship between items.

Input Schema:

{
  "type": "object",
  "properties": {
    "sourceId": {
      "type": "string"
    },
    "targetId": {
      "type": "string"
    },
    "relationType": {
      "type": "string",
      "description": "Optional: specific relation type to remove"
    }
  },
  "required": ["sourceId", "targetId"]
}

pinepaper_query_relations

Query relationships for an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Item to query relations for"
    },
    "relationType": {
      "type": "string",
      "description": "Optional: filter by relation type"
    },
    "direction": {
      "type": "string",
      "enum": ["outgoing", "incoming"],
      "description": "outgoing = from item, incoming = to item"
    }
  },
  "required": ["itemId"]
}

Output:

{
  "relations": [
    {
      "sourceId": "item_1",
      "targetId": "item_2",
      "relationType": "orbits",
      "params": { "radius": 100, "speed": 0.5 }
    }
  ]
}

Animation Tools

pinepaper_animate

Apply a simple animation to an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string"
    },
    "animationType": {
      "type": "string",
      "enum": ["pulse", "rotate", "bounce", "fade", "wobble", "slide", "typewriter"]
    },
    "speed": {
      "type": "number",
      "description": "Animation speed multiplier (default: 1.0)"
    }
  },
  "required": ["itemId", "animationType"]
}

pinepaper_keyframe_animate

Apply keyframe-based animation.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string"
    },
    "keyframes": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "time": { "type": "number", "description": "Time in seconds" },
          "properties": { "type": "object", "description": "Property values at this keyframe" },
          "easing": { "type": "string", "enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"] }
        }
      }
    },
    "duration": {
      "type": "number",
      "description": "Total animation duration in seconds"
    },
    "loop": {
      "type": "boolean"
    }
  },
  "required": ["itemId", "keyframes"]
}

Keyframe Properties:

Property Type Description
position [x, y] Item position
x, y number Individual coordinates
width number Width in pixels (absolute sizing)
height number Height in pixels (absolute sizing)
scale number Uniform scale
scaleX, scaleY number Separate axis scaling
rotation number Rotation in degrees
opacity number Transparency (0-1)
fillColor string Fill color
strokeColor string Stroke color
fontSize number Text size

pinepaper_play_timeline

Control keyframe playback.

Input Schema:

{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": ["play", "stop", "seek"]
    },
    "duration": {
      "type": "number",
      "description": "Duration for play action"
    },
    "loop": {
      "type": "boolean"
    },
    "time": {
      "type": "number",
      "description": "Time to seek to"
    }
  },
  "required": ["action"]
}

Camera Tools

Animate camera zoom and pan for cinematic effects.

pinepaper_camera_animate

Animate camera with keyframe-based zoom and pan sequence.

Input Schema:

{
  "type": "object",
  "properties": {
    "keyframes": {
      "type": "array",
      "description": "Array of camera keyframes",
      "items": {
        "type": "object",
        "properties": {
          "time": { "type": "number", "description": "Time in seconds" },
          "zoom": { "type": "number", "description": "Zoom level (1=normal, 2=2x zoom in, 0.5=zoom out)" },
          "center": { "type": "array", "items": { "type": "number" }, "description": "View center [x, y]" },
          "easing": { "type": "string", "enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"] }
        }
      }
    },
    "duration": {
      "type": "number",
      "description": "Total animation duration in seconds"
    },
    "loop": {
      "type": "boolean",
      "description": "Loop the animation"
    },
    "delay": {
      "type": "number",
      "description": "Delay before animation starts"
    }
  },
  "required": ["keyframes", "duration"]
}

Example - Zoom in, pan right, zoom out:

{
  "duration": 6,
  "loop": true,
  "keyframes": [
    { "time": 0, "zoom": 1, "center": [400, 300] },
    { "time": 2, "zoom": 2, "center": [400, 300], "easing": "easeInOut" },
    { "time": 4, "zoom": 2, "center": [600, 300], "easing": "easeOut" },
    { "time": 6, "zoom": 1, "center": [400, 300], "easing": "easeInOut" }
  ]
}

Output:

{
  "success": true,
  "isAnimating": true
}

pinepaper_camera_zoom

Simple zoom animation.

Input Schema:

{
  "type": "object",
  "properties": {
    "direction": {
      "type": "string",
      "enum": ["in", "out"],
      "description": "Zoom direction"
    },
    "level": {
      "type": "number",
      "description": "Target zoom level (default: 2 for in, 0.5 for out)"
    },
    "duration": {
      "type": "number",
      "description": "Animation duration in seconds (default: 0.5)"
    }
  },
  "required": ["direction"]
}

Output:

{
  "success": true,
  "fromZoom": 1,
  "toZoom": 2
}

pinepaper_camera_pan

Pan camera in a direction or to specific coordinates.

Input Schema:

{
  "type": "object",
  "properties": {
    "direction": {
      "type": "string",
      "enum": ["left", "right", "up", "down"],
      "description": "Pan direction (use with amount)"
    },
    "amount": {
      "type": "number",
      "description": "Pixels to pan (default: 100)"
    },
    "x": {
      "type": "number",
      "description": "Target X coordinate (use with y for panTo)"
    },
    "y": {
      "type": "number",
      "description": "Target Y coordinate (use with x for panTo)"
    },
    "duration": {
      "type": "number",
      "description": "Animation duration in seconds (default: 0.5)"
    }
  }
}

Examples:

// Pan left 200 pixels
{ "direction": "left", "amount": 200 }

// Pan to specific coordinates
{ "x": 200, "y": 200, "duration": 1 }

Output:

{
  "success": true,
  "fromCenter": [400, 300],
  "toCenter": [200, 200]
}

pinepaper_camera_move_to

Combined zoom and pan to a specific location.

Input Schema:

{
  "type": "object",
  "properties": {
    "x": {
      "type": "number",
      "description": "Target X coordinate"
    },
    "y": {
      "type": "number",
      "description": "Target Y coordinate"
    },
    "zoom": {
      "type": "number",
      "description": "Target zoom level"
    },
    "duration": {
      "type": "number",
      "description": "Animation duration in seconds (default: 0.5)"
    }
  },
  "required": ["x", "y", "zoom"]
}

Output:

{
  "success": true,
  "toCenter": [200, 200],
  "toZoom": 2
}

pinepaper_camera_reset

Reset camera to default state (center of canvas, zoom 1).

Input Schema:

{
  "type": "object",
  "properties": {
    "duration": {
      "type": "number",
      "description": "Animation duration in seconds (default: 0.5)"
    }
  }
}

Output:

{
  "success": true,
  "toCenter": [400, 300],
  "toZoom": 1
}

pinepaper_camera_stop

Stop current camera animation.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "success": true,
  "wasAnimating": true
}

pinepaper_camera_state

Get current camera state.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "zoom": 1.5,
  "center": [400, 300],
  "isAnimating": false
}

Mask Tools

Apply clipping masks and animated reveal effects to items.

pinepaper_apply_animated_mask

Apply an animated mask reveal to an item. Supports three usage modes for maximum flexibility.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the item to mask"
    },
    "preset": {
      "type": "string",
      "enum": ["wipeLeft", "wipeRight", "wipeUp", "wipeDown", "iris", "irisOut", "star", "heart", "curtainHorizontal", "curtainVertical", "cinematic", "diagonalWipe", "revealUp", "revealDown"],
      "description": "Animation preset name (Mode 1 & 3)"
    },
    "maskType": {
      "type": "string",
      "enum": ["rectangle", "circle", "ellipse", "star", "triangle", "hexagon", "heart", "rounded"],
      "description": "Mask shape type (Mode 2 - full control)"
    },
    "keyframes": {
      "type": "array",
      "description": "Custom keyframes array (Mode 2 & 3)",
      "items": {
        "type": "object",
        "properties": {
          "time": { "type": "number", "description": "Normalized time (0-1)" },
          "properties": {
            "type": "object",
            "description": "Mask properties at this keyframe",
            "properties": {
              "x": { "type": "number" },
              "y": { "type": "number" },
              "width": { "type": "number" },
              "height": { "type": "number" },
              "radius": { "type": "number" },
              "scale": { "type": "number" },
              "rotation": { "type": "number" },
              "opacity": { "type": "number" }
            }
          },
          "easing": {
            "type": "string",
            "enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"]
          }
        },
        "required": ["time", "properties"]
      }
    },
    "options": {
      "type": "object",
      "description": "Animation options (Mode 1)",
      "properties": {
        "startTime": { "type": "number", "description": "Start time in seconds", "default": 0 },
        "duration": { "type": "number", "description": "Duration in seconds", "default": 0.8 },
        "easing": { "type": "string", "enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce"], "default": "easeOut" },
        "reversed": { "type": "boolean", "description": "Reverse animation (hide instead of reveal)", "default": false },
        "loop": { "type": "boolean", "description": "Loop the animation", "default": false }
      }
    },
    "maskOptions": {
      "type": "object",
      "description": "Mask shape options (for star, etc.)",
      "properties": {
        "points": { "type": "number", "description": "Number of points (star mask)" },
        "innerRadius": { "type": "number", "description": "Inner radius ratio (star mask)" }
      }
    }
  },
  "required": ["itemId"]
}

Usage Modes:

Mode Description Required Fields
1. Preset Use animation preset with options preset, options
2. Full Control Define exact keyframes maskType, keyframes
3. Hybrid Preset with keyframe override preset, keyframes

Animation Presets:

Preset Effect Mask Type
wipeLeft Reveals from left to right Rectangle
wipeRight Reveals from right to left Rectangle
wipeUp Reveals from bottom to top Rectangle
wipeDown Reveals from top to bottom Rectangle
iris Circle expands from center Circle
irisOut Circle shrinks to center Circle
star Star shape scales up Star
heart Heart shape scales up Heart
curtainHorizontal Opens from center horizontally Rectangle pair
curtainVertical Opens from center vertically Rectangle pair
cinematic Letterbox bars animate Rectangle pair
diagonalWipe Angled reveal from corner Rectangle
revealUp Text slides up within mask Rectangle
revealDown Text slides down within mask Rectangle

Examples:

Mode 1 - Preset with options:

{
  "itemId": "item_1",
  "preset": "wipeLeft",
  "options": {
    "startTime": 0,
    "duration": 0.5,
    "easing": "easeOut"
  }
}

Mode 2 - Full keyframe control:

{
  "itemId": "item_1",
  "maskType": "rectangle",
  "keyframes": [
    { "time": 0, "properties": { "x": 200, "y": 250, "width": 0, "height": 100 }, "easing": "linear" },
    { "time": 0.25, "properties": { "x": 200, "y": 250, "width": 50, "height": 100 }, "easing": "easeIn" },
    { "time": 0.75, "properties": { "x": 200, "y": 250, "width": 150, "height": 100 }, "easing": "easeOut" },
    { "time": 1, "properties": { "x": 200, "y": 250, "width": 200, "height": 100 } }
  ]
}

Mode 3 - Preset with keyframe override:

{
  "itemId": "item_1",
  "preset": "iris",
  "keyframes": [
    { "time": 0, "properties": { "scale": 0.01 }, "easing": "linear" },
    { "time": 0.3, "properties": { "scale": 0.3 }, "easing": "easeIn" },
    { "time": 0.6, "properties": { "scale": 0.7 }, "easing": "easeOut" },
    { "time": 1, "properties": { "scale": 1 }, "easing": "bounce" }
  ]
}

Output:

{
  "success": true,
  "itemId": "item_1",
  "maskType": "rectangle",
  "animated": true,
  "keyframeCount": 4
}

pinepaper_apply_custom_mask

Direct helper for applying custom keyframe-based masks.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the item to mask"
    },
    "maskType": {
      "type": "string",
      "enum": ["rectangle", "circle", "ellipse", "star", "triangle", "hexagon", "heart", "rounded"],
      "description": "Mask shape type"
    },
    "keyframes": {
      "type": "array",
      "description": "Keyframes defining the animation",
      "items": {
        "type": "object",
        "properties": {
          "time": { "type": "number" },
          "properties": { "type": "object" },
          "easing": { "type": "string" }
        }
      }
    },
    "maskOptions": {
      "type": "object",
      "description": "Mask shape options",
      "properties": {
        "points": { "type": "number" },
        "innerRadius": { "type": "number" }
      }
    }
  },
  "required": ["itemId", "maskType", "keyframes"]
}

Example:

{
  "itemId": "item_1",
  "maskType": "star",
  "keyframes": [
    { "time": 0, "properties": { "scale": 0 }, "easing": "linear" },
    { "time": 0.5, "properties": { "scale": 0.5 }, "easing": "easeIn" },
    { "time": 1, "properties": { "scale": 1 }, "easing": "easeOut" }
  ],
  "maskOptions": { "points": 6, "innerRadius": 0.4 }
}

pinepaper_remove_mask

Remove mask from an item, restoring original.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Registry ID of the masked item"
    }
  },
  "required": ["itemId"]
}

pinepaper_get_animatable_properties

Get animatable properties for each mask type. Useful for building custom keyframe animations.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "rectangle": {
    "properties": ["x", "y", "width", "height", "rotation", "opacity"],
    "description": "Rectangular mask with position and size"
  },
  "circle": {
    "properties": ["x", "y", "radius", "scale", "opacity"],
    "description": "Circular mask with center and radius"
  },
  "ellipse": {
    "properties": ["x", "y", "radiusX", "radiusY", "rotation", "scale", "opacity"],
    "description": "Elliptical mask with separate radii"
  },
  "star": {
    "properties": ["x", "y", "radius", "scale", "rotation", "opacity"],
    "description": "Star mask with configurable points"
  },
  "heart": {
    "properties": ["x", "y", "scale", "rotation", "opacity"],
    "description": "Heart-shaped mask"
  }
}

pinepaper_get_available_easings

Get list of available easing functions for mask animations.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "easings": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"],
  "descriptions": {
    "linear": "Constant speed",
    "easeIn": "Slow start, fast end",
    "easeOut": "Fast start, slow end",
    "easeInOut": "Slow start and end",
    "bounce": "Bouncing effect at end",
    "elastic": "Spring-like overshoot"
  }
}

pinepaper_get_mask_types

Get available mask types.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "maskTypes": ["rectangle", "circle", "ellipse", "star", "triangle", "hexagon", "heart", "rounded", "custom"]
}

pinepaper_get_mask_animations

Get available mask animation presets.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "animations": [
    "wipeLeft", "wipeRight", "wipeUp", "wipeDown",
    "iris", "irisOut",
    "star", "heart",
    "curtainHorizontal", "curtainVertical", "cinematic",
    "diagonalWipe",
    "revealUp", "revealDown"
  ]
}

Generator Tools

pinepaper_execute_generator

Execute a background generator.

Input Schema:

{
  "type": "object",
  "properties": {
    "generatorName": {
      "type": "string",
      "enum": ["drawSunburst", "drawSunsetScene", "drawGrid", "drawStackedCircles", "drawCircuit", "drawWaves", "drawPattern", "drawSolarSystem", "drawDayNightCycle"]
    },
    "params": {
      "type": "object",
      "description": "Generator-specific parameters"
    }
  },
  "required": ["generatorName"]
}

Generator Parameters:

Generator Key Parameters
drawSunburst rayCount, colors (array), bgColor
drawSunsetScene skyColors (array), cloudCount
drawGrid gridType (‘lines’/‘dots’/‘squares’), spacing, lineColor, bgColor
drawStackedCircles count, colors, distribution (‘poisson’/‘golden’/‘random’)
drawWaves waveCount, colors
drawSolarSystem sunSize, sunColor, showOrbits, orbitColor, speedMultiplier, showLabels, bgColor
drawDayNightCycle cycleEnabled, cycleDuration, startPhase, showSun, sunSize, showMoon, moonSize, showStars, starCount, showClouds, cloudCount

Solar System Generator Details:

The drawSolarSystem generator creates an interactive solar system with:

  • All 8 planets with real orbital eccentricity (elliptical orbits)
  • Kepler’s laws for realistic orbital motion (faster at perihelion, slower at aphelion)
  • Sun and planets are selectable and draggable
  • Moving the Sun moves the entire system (planets and orbits follow)
  • Orbit paths are decorative (non-selectable)

Planet Data Flags:

  • Planets have data.selectable = true and data.isDraggable = true
  • Orbits have data.isDecorative = true (not selectable)
  • Sun has data.isSun = true, planets have data.isPlanet = true

pinepaper_list_generators

Get available generators and their parameter schemas.

Output:

{
  "generators": [
    {
      "name": "drawSunburst",
      "displayName": "Sunburst",
      "category": "patterns",
      "params": {
        "rayCount": { "type": "number", "default": 16 },
        "colors": { "type": "array", "default": ["#FF6B6B", "#4ECDC4"] }
      }
    }
  ]
}

Map Tools

Create data-driven geographic visualizations with interactive maps.

pinepaper_load_map

Load a geographic map onto the canvas with specified projection and styling.

Input Schema:

{
  "type": "object",
  "properties": {
    "mapId": {
      "type": "string",
      "enum": ["world", "worldHighRes", "usa"],
      "description": "Map to load (world=110m, worldHighRes=50m professional quality, usa=US states)"
    },
    "projection": {
      "type": "string",
      "enum": ["mercator", "equalEarth", "naturalEarth", "orthographic", "albers", "stereographic"],
      "default": "naturalEarth",
      "description": "Map projection type"
    },
    "quality": {
      "type": "string",
      "enum": ["fast", "balanced", "professional"],
      "default": "balanced",
      "description": "Rendering quality (professional=no simplification, best for multi-polygon countries)"
    },
    "fillColor": {
      "type": "string",
      "default": "#e5e7eb",
      "description": "Default fill color for regions"
    },
    "strokeColor": {
      "type": "string",
      "default": "#9ca3af",
      "description": "Border/stroke color"
    },
    "strokeWidth": {
      "type": "number",
      "default": 0.5,
      "description": "Border width in pixels"
    },
    "scale": {
      "type": "number",
      "description": "Scale multiplier"
    },
    "center": {
      "type": "array",
      "items": { "type": "number" },
      "description": "Center coordinates [longitude, latitude]"
    },
    "rotate": {
      "type": "array",
      "items": { "type": "number" },
      "description": "Rotation angles [x, y, z]"
    },
    "enableHover": {
      "type": "boolean",
      "default": false,
      "description": "Enable hover effects on regions"
    },
    "enableClick": {
      "type": "boolean",
      "default": false,
      "description": "Enable click events on regions"
    },
    "hoverFill": {
      "type": "string",
      "description": "Fill color on hover"
    },
    "hoverStroke": {
      "type": "string",
      "description": "Stroke color on hover"
    }
  },
  "required": ["mapId"]
}

Output:

{
  "success": true,
  "mapId": "worldHighRes",
  "regionCount": 177,
  "bounds": { "x": 50, "y": 100, "width": 700, "height": 400 }
}

pinepaper_highlight_regions

Highlight specific regions on a loaded map.

Input Schema:

{
  "type": "object",
  "properties": {
    "regionIds": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Array of region IDs to highlight"
    },
    "fillColor": {
      "type": "string",
      "default": "#22c55e",
      "description": "Highlight fill color"
    },
    "strokeColor": {
      "type": "string",
      "description": "Highlight stroke color"
    },
    "strokeWidth": {
      "type": "number",
      "description": "Highlight stroke width"
    },
    "animate": {
      "type": "boolean",
      "default": false,
      "description": "Animate the highlight transition"
    }
  },
  "required": ["regionIds"]
}

Region ID Formats:

Map ID Format Examples
world, worldHighRes Full country names “United States of America”, “France”, “Japan”, “Russian Federation”
usa State codes “CA”, “TX”, “NY”, “FL”

Output:

{
  "success": true,
  "highlighted": ["United States of America", "Canada", "Mexico"],
  "notFound": []
}

pinepaper_unhighlight_regions

Remove highlights from specific regions.

Input Schema:

{
  "type": "object",
  "properties": {
    "regionIds": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Array of region IDs to unhighlight (omit for all)"
    }
  }
}

pinepaper_apply_data_colors

Apply data-driven coloring to map regions (choropleth visualization).

Input Schema:

{
  "type": "object",
  "properties": {
    "data": {
      "type": "object",
      "description": "Object mapping region IDs to numeric values",
      "additionalProperties": { "type": "number" }
    },
    "colorScale": {
      "type": "string",
      "enum": ["blues", "greens", "reds", "oranges", "purples", "heat", "viridis"],
      "default": "blues",
      "description": "Color scale to use"
    },
    "minValue": {
      "type": "number",
      "description": "Minimum value for color scale (auto-detected if omitted)"
    },
    "maxValue": {
      "type": "number",
      "description": "Maximum value for color scale (auto-detected if omitted)"
    },
    "showLegend": {
      "type": "boolean",
      "default": true,
      "description": "Show color legend"
    },
    "legendPosition": {
      "type": "string",
      "enum": ["top-left", "top-right", "bottom-left", "bottom-right"],
      "default": "bottom-right",
      "description": "Legend position"
    },
    "legendTitle": {
      "type": "string",
      "description": "Legend title text"
    }
  },
  "required": ["data"]
}

Example:

{
  "data": {
    "California": 39538223,
    "Texas": 29145505,
    "Florida": 21538187,
    "New York": 20201249
  },
  "colorScale": "blues",
  "showLegend": true,
  "legendTitle": "Population"
}

Output:

{
  "success": true,
  "regionsColored": 4,
  "valueRange": { "min": 20201249, "max": 39538223 }
}

pinepaper_add_marker

Add a marker to the map at specified coordinates.

Input Schema:

{
  "type": "object",
  "properties": {
    "lat": {
      "type": "number",
      "description": "Latitude (-90 to 90)"
    },
    "lon": {
      "type": "number",
      "description": "Longitude (-180 to 180)"
    },
    "label": {
      "type": "string",
      "description": "Marker label text"
    },
    "color": {
      "type": "string",
      "default": "#ef4444",
      "description": "Marker color"
    },
    "size": {
      "type": "number",
      "default": 8,
      "description": "Marker size in pixels"
    },
    "pulse": {
      "type": "boolean",
      "default": false,
      "description": "Enable pulse animation"
    },
    "icon": {
      "type": "string",
      "enum": ["circle", "pin", "star", "diamond"],
      "default": "circle",
      "description": "Marker icon shape"
    }
  },
  "required": ["lat", "lon"]
}

Output:

{
  "success": true,
  "markerId": "marker_1",
  "position": { "x": 234, "y": 156 }
}

pinepaper_add_map_labels

Add labels to map regions.

Input Schema:

{
  "type": "object",
  "properties": {
    "regions": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Specific regions to label (omit for all visible)"
    },
    "labelType": {
      "type": "string",
      "enum": ["name", "code", "value"],
      "default": "name",
      "description": "What to display as label"
    },
    "fontSize": {
      "type": "number",
      "default": 10,
      "description": "Font size in pixels"
    },
    "fontColor": {
      "type": "string",
      "default": "#374151",
      "description": "Label text color"
    },
    "fontFamily": {
      "type": "string",
      "default": "Inter, sans-serif",
      "description": "Font family"
    },
    "showBackground": {
      "type": "boolean",
      "default": false,
      "description": "Show background behind labels"
    }
  }
}

pinepaper_pan_map

Pan the map view to specific coordinates.

Input Schema:

{
  "type": "object",
  "properties": {
    "lat": {
      "type": "number",
      "description": "Target latitude"
    },
    "lon": {
      "type": "number",
      "description": "Target longitude"
    },
    "animate": {
      "type": "boolean",
      "default": true,
      "description": "Animate the pan"
    },
    "duration": {
      "type": "number",
      "default": 0.5,
      "description": "Animation duration in seconds"
    }
  },
  "required": ["lat", "lon"]
}

pinepaper_zoom_map

Set the map zoom level.

Input Schema:

{
  "type": "object",
  "properties": {
    "level": {
      "type": "number",
      "minimum": 0.5,
      "maximum": 10,
      "description": "Zoom level (1 = default)"
    },
    "center": {
      "type": "array",
      "items": { "type": "number" },
      "description": "Zoom center [lon, lat] (optional)"
    },
    "animate": {
      "type": "boolean",
      "default": true
    }
  },
  "required": ["level"]
}

pinepaper_export_map

Export the current map configuration for saving/loading.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "mapId": "worldHighRes",
  "projection": "naturalEarth",
  "quality": "professional",
  "highlightedRegions": ["United States of America", "Canada"],
  "dataColors": { "California": "#3b82f6" },
  "markers": [
    { "lat": 37.77, "lon": -122.42, "label": "San Francisco" }
  ],
  "viewState": {
    "center": [0, 0],
    "zoom": 1
  }
}

pinepaper_import_custom_map

Import a custom GeoJSON or TopoJSON map.

Input Schema:

{
  "type": "object",
  "properties": {
    "geoJson": {
      "type": "object",
      "description": "GeoJSON or TopoJSON data"
    },
    "sourceUrl": {
      "type": "string",
      "description": "URL to fetch GeoJSON from (alternative to geoJson)"
    },
    "idProperty": {
      "type": "string",
      "default": "id",
      "description": "Property to use as region ID"
    },
    "nameProperty": {
      "type": "string",
      "default": "name",
      "description": "Property to use as region name"
    },
    "projection": {
      "type": "string",
      "enum": ["mercator", "equalEarth", "naturalEarth", "albers"],
      "default": "naturalEarth"
    },
    "style": {
      "type": "object",
      "properties": {
        "fillColor": { "type": "string" },
        "strokeColor": { "type": "string" },
        "strokeWidth": { "type": "number" }
      }
    }
  }
}

Data Sources:

Source Description URL
GADM Detailed country/admin boundaries gadm.org
Natural Earth Public domain map data naturalearthdata.com
OpenStreetMap Community map data openstreetmap.org
Mapshaper GeoJSON simplification tool mapshaper.org

Recommended Workflow:

  1. Download detailed boundaries from GADM or Natural Earth
  2. Simplify with Mapshaper if needed
  3. Import via pinepaper_import_custom_map

pinepaper_get_region_at_point

Get the region at a specific canvas point (for hit testing).

Input Schema:

{
  "type": "object",
  "properties": {
    "x": { "type": "number" },
    "y": { "type": "number" }
  },
  "required": ["x", "y"]
}

Output:

{
  "found": true,
  "regionId": "California",
  "properties": {
    "name": "California",
    "code": "CA",
    "population": 39538223
  }
}

pinepaper_animate_map_regions

Animate specific map regions with timeline-integrated keyframe color animations.

Input Schema:

{
  "type": "object",
  "properties": {
    "duration": {
      "type": "number",
      "description": "Total animation duration in seconds",
      "default": 5
    },
    "loop": {
      "type": "boolean",
      "description": "Loop the animation",
      "default": true
    },
    "regions": {
      "type": "object",
      "description": "Object mapping region IDs to arrays of keyframes",
      "additionalProperties": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "time": { "type": "number", "description": "Time in seconds" },
            "fillColor": { "type": "string", "description": "Fill color at this keyframe" },
            "strokeColor": { "type": "string", "description": "Stroke color at this keyframe" },
            "opacity": { "type": "number", "description": "Opacity at this keyframe (0-1)" }
          },
          "required": ["time", "fillColor"]
        }
      }
    }
  },
  "required": ["regions"]
}

Example:

{
  "duration": 8,
  "loop": true,
  "regions": {
    "USA": [
      { "time": 0, "fillColor": "#ef4444" },
      { "time": 4, "fillColor": "#22c55e" },
      { "time": 8, "fillColor": "#ef4444" }
    ],
    "France": [
      { "time": 0, "fillColor": "#3b82f6" },
      { "time": 8, "fillColor": "#fbbf24" }
    ]
  }
}

Output:

{
  "success": true,
  "animatedRegions": ["USA", "France"],
  "duration": 8,
  "errors": []
}

pinepaper_animate_map_wave

Create a wave animation across all map regions based on geographic position.

Input Schema:

{
  "type": "object",
  "properties": {
    "duration": {
      "type": "number",
      "description": "Total wave duration in seconds",
      "default": 10
    },
    "loop": {
      "type": "boolean",
      "description": "Loop the animation",
      "default": true
    },
    "colors": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Array of colors for the wave",
      "default": ["#ef4444", "#fbbf24", "#22c55e", "#3b82f6"]
    },
    "waveDirection": {
      "type": "string",
      "enum": ["horizontal", "vertical", "radial"],
      "description": "Direction of the wave effect",
      "default": "horizontal"
    }
  }
}

Output:

{
  "success": true,
  "animatedRegions": ["USA", "Canada", "Mexico", "..."],
  "totalRegions": 177
}

pinepaper_stop_map_animations

Stop all or specific map region animations.

Input Schema:

{
  "type": "object",
  "properties": {
    "regions": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Specific region IDs to stop (omit for all)"
    },
    "resetColors": {
      "type": "boolean",
      "description": "Reset regions to default colors",
      "default": true
    }
  }
}

pinepaper_get_animated_map_regions

Get list of currently animated map regions with their animation data.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "animatedRegions": [
    {
      "regionId": "USA",
      "keyframes": [
        { "time": 0, "fillColor": "#ef4444" },
        { "time": 5, "fillColor": "#22c55e" }
      ],
      "duration": 5,
      "loop": true
    }
  ],
  "count": 1
}

pinepaper_export_map_region_csv

Export map region data as CSV including colors, highlight, and selection status.

Input Schema:

{
  "type": "object",
  "properties": {
    "includeHighlighted": {
      "type": "boolean",
      "description": "Include highlight status column",
      "default": true
    },
    "includeSelected": {
      "type": "boolean",
      "description": "Include selection status column",
      "default": true
    },
    "includeColors": {
      "type": "boolean",
      "description": "Include fill/stroke color columns",
      "default": true
    },
    "download": {
      "type": "boolean",
      "description": "Auto-download the CSV file",
      "default": false
    },
    "filename": {
      "type": "string",
      "description": "Filename for download",
      "default": "map-regions.csv"
    }
  }
}

Output:

{
  "success": true,
  "csv": "regionId,name,highlighted,selected,fillColor,strokeColor\nUSA,United States of America,1,0,#22c55e,#16a34a\n...",
  "regionCount": 177
}

pinepaper_import_map_region_csv

Import CSV data to update map region states (colors, highlight, selection).

Input Schema:

{
  "type": "object",
  "properties": {
    "csvText": {
      "type": "string",
      "description": "CSV text content to import"
    },
    "applyColors": {
      "type": "boolean",
      "description": "Apply fill/stroke colors from CSV",
      "default": true
    },
    "applyHighlight": {
      "type": "boolean",
      "description": "Update highlight status from CSV",
      "default": true
    },
    "applySelection": {
      "type": "boolean",
      "description": "Update selection status from CSV",
      "default": true
    }
  },
  "required": ["csvText"]
}

Output:

{
  "success": true,
  "updatedRegions": 50,
  "notFound": ["INVALID_ID"],
  "errors": []
}

pinepaper_select_map_regions

Programmatically select map regions.

Input Schema:

{
  "type": "object",
  "properties": {
    "regionIds": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Array of region IDs to select"
    }
  },
  "required": ["regionIds"]
}

pinepaper_deselect_map_regions

Programmatically deselect map regions.

Input Schema:

{
  "type": "object",
  "properties": {
    "regionIds": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Array of region IDs to deselect (omit for all)"
    }
  }
}

pinepaper_get_highlighted_map_regions

Get list of currently highlighted map regions.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "highlighted": ["USA", "Canada", "France"],
  "count": 3
}

pinepaper_export_map_geojson

Export the current map as GeoJSON (with current colors/modifications).

Input Schema:

{
  "type": "object",
  "properties": {
    "includeStyles": {
      "type": "boolean",
      "description": "Include fill/stroke colors as properties",
      "default": true
    },
    "includeMetadata": {
      "type": "boolean",
      "description": "Include region names and IDs",
      "default": true
    },
    "selectedOnly": {
      "type": "boolean",
      "description": "Only export selected regions",
      "default": false
    },
    "download": {
      "type": "boolean",
      "description": "Auto-download the file",
      "default": false
    },
    "filename": {
      "type": "string",
      "description": "Filename for download",
      "default": "map-export.geojson"
    }
  }
}

Output:

{
  "success": true,
  "geoJson": { "type": "FeatureCollection", "features": [...] },
  "regionCount": 177
}

pinepaper_export_original_map_geojson

Export the original source GeoJSON (unmodified boundaries). This returns the exact data that was used to load the map, allowing users to edit boundaries externally and re-import.

Input Schema:

{
  "type": "object",
  "properties": {
    "download": {
      "type": "boolean",
      "description": "Auto-download the file",
      "default": false
    },
    "filename": {
      "type": "string",
      "description": "Filename for download",
      "default": "map-source.geojson"
    }
  }
}

Output:

{
  "success": true,
  "geoJson": { "type": "FeatureCollection", "features": [...] },
  "source": "world",
  "regionCount": 177
}

pinepaper_import_custom_map

Import a custom GeoJSON or TopoJSON map. Supports URLs or inline data.

Input Schema:

{
  "type": "object",
  "properties": {
    "geoJson": {
      "type": "object",
      "description": "GeoJSON or TopoJSON object"
    },
    "sourceUrl": {
      "type": "string",
      "description": "URL to fetch GeoJSON from (alternative to geoJson)"
    },
    "projection": {
      "type": "string",
      "enum": ["mercator", "equalEarth", "naturalEarth", "orthographic", "albers"],
      "default": "naturalEarth",
      "description": "Map projection to use"
    },
    "quality": {
      "type": "string",
      "enum": ["draft", "standard", "professional"],
      "default": "standard"
    },
    "styles": {
      "type": "object",
      "properties": {
        "fill": { "type": "string", "default": "#e5e7eb" },
        "stroke": { "type": "string", "default": "#9ca3af" },
        "strokeWidth": { "type": "number", "default": 0.5 }
      }
    }
  }
}

Output:

{
  "success": true,
  "mapId": "custom_map_1",
  "regionCount": 50,
  "bounds": { "x": 50, "y": 100, "width": 700, "height": 400 }
}

pinepaper_get_map_source_info

Get information about the currently loaded map source.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "source": "world",
  "projection": "naturalEarth",
  "quality": "standard",
  "regionCount": 177,
  "hasOriginalGeoJSON": true,
  "isCustomImport": false
}

Map Events

The map system emits events that can be listened to via triggers:

Event Description Data
map:regionClick Region was clicked { regionId, properties, position }
map:regionHover Mouse entered region { regionId, properties }
map:regionLeave Mouse left region { regionId }
map:markerClick Marker was clicked { markerId, lat, lon, label }

Example Trigger:

{
  "itemId": "map_1",
  "event": "map:regionClick",
  "actions": [
    { "type": "show", "targetItemId": "info_panel" },
    { "type": "update_property", "targetItemId": "region_name", "property": "content", "value": "$event.regionId" }
  ]
}

Query Tools

pinepaper_get_items

Get all or filtered items.

Input Schema:

{
  "type": "object",
  "properties": {
    "filter": {
      "type": "object",
      "properties": {
        "type": { "type": "string", "description": "Filter by item type" },
        "source": { "type": "string", "enum": ["user", "generator", "import"] },
        "hasAnimation": { "type": "boolean" },
        "hasRelation": { "type": "boolean" }
      }
    }
  }
}

Output:

{
  "items": [
    {
      "id": "item_1",
      "type": "circle",
      "position": { "x": 400, "y": 300 },
      "hasAnimation": true,
      "relations": ["orbits"]
    }
  ],
  "count": 1
}

pinepaper_get_relation_stats

Get statistics about active relations.

Output:

{
  "activeItems": 5,
  "ruleCount": 8,
  "associationsByType": {
    "orbits": 2,
    "follows": 3,
    "attached_to": 1
  }
}

Export Tools

pinepaper_export_svg

Export the scene as animated SVG.

Output:

{
  "success": true,
  "svgString": "<svg>...</svg>",
  "hasAnimations": true
}

pinepaper_export_training_data

Export relations as training data for LLM fine-tuning.

Output:

{
  "trainingData": [
    {
      "instruction": "moon orbits earth at radius 100",
      "code": "app.addRelation('item_1', 'item_2', 'orbits', {\"radius\":100})",
      "relation": "orbits",
      "params": { "radius": 100 }
    }
  ],
  "count": 5
}

pinepaper_export_scene

Export the complete scene state.

Output:

{
  "items": [...],
  "relations": [...],
  "decorative": [...],
  "backgroundColor": "#1e293b"
}

Effect Tools

pinepaper_apply_effect

Apply a visual effect to an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string"
    },
    "effectType": {
      "type": "string",
      "enum": ["sparkle", "blast"]
    },
    "params": {
      "type": "object",
      "properties": {
        "color": { "type": "string" },
        "speed": { "type": "number" },
        "size": { "type": "number" }
      }
    }
  },
  "required": ["itemId", "effectType"]
}

Text Design Tools

pinepaper_create_letter_collage

Create stylized text with per-letter customization. Perfect for word games, ransom notes, gradient text, and creative typography.

Input Schema:

{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "The text to stylize"
    },
    "style": {
      "type": "string",
      "enum": ["tile", "magazine", "paperCut", "fold", "gradient", "image"],
      "default": "tile",
      "description": "Style type for the letter collage"
    },
    "palette": {
      "type": "string",
      "description": "Color palette name (e.g., 'wordle', 'candy', 'neon', 'ocean')"
    },
    "position": {
      "type": "object",
      "properties": {
        "x": { "type": "number" },
        "y": { "type": "number" }
      },
      "description": "Position on canvas (defaults to center)"
    },
    "fontSize": {
      "type": "number",
      "default": 48,
      "description": "Base font size in pixels"
    },
    "fontFamily": {
      "type": "string",
      "default": "Inter, sans-serif",
      "description": "Font family to use"
    },
    "spacing": {
      "type": "number",
      "default": 1.1,
      "description": "Letter spacing multiplier"
    },
    "gradientPalette": {
      "type": "string",
      "description": "Gradient palette name (for style='gradient')"
    },
    "gradientDirection": {
      "type": "string",
      "enum": ["vertical", "horizontal", "diagonal", "radial"],
      "default": "vertical",
      "description": "Gradient direction (for style='gradient')"
    },
    "cornerRadius": {
      "type": "number",
      "default": 4,
      "description": "Corner radius for tile backgrounds"
    },
    "shadowEnabled": {
      "type": "boolean",
      "default": true,
      "description": "Enable drop shadows"
    }
  },
  "required": ["text"]
}

Style Types:

Style Description Best For
tile Wordle/Scrabble colored backgrounds Word games, educational
magazine Mixed fonts/colors like cutouts Ransom notes, collage art
paperCut Shadow/depth like cut paper Craft aesthetics
fold Origami-style folded letters Paper crafts
gradient Each letter with gradient fill Modern, vibrant text
image Letters filled with image Photo effects

Available Tile Palettes:

Category Palettes
Game wordle, scrabble
Vibrant candy, neon, rainbow
Soft pastel, cotton
Natural earth, ocean, forest, sunset
Professional corporate, minimal, slate
Seasonal christmas, halloween, spring
Magazine magazine, newspaper, vintage
Paper Craft paperCraft, origami, craftPaper

Available Gradient Palettes: rainbow, sunset, ocean, fire, gold, rose, ice, cyberpunk, neonGlow, purplePink

Output:

{
  "success": true,
  "collageId": "collage_1",
  "itemId": "item_5",
  "text": "HELLO",
  "style": "tile",
  "letterCount": 5
}

pinepaper_animate_letter_collage

Apply animation to all letters in a collage with staggered timing.

Input Schema:

{
  "type": "object",
  "properties": {
    "collageId": {
      "type": "string",
      "description": "Collage ID from create_letter_collage"
    },
    "animationType": {
      "type": "string",
      "enum": ["pulse", "bounce", "fade", "wobble", "rotate"],
      "description": "Animation type to apply"
    },
    "staggerDelay": {
      "type": "number",
      "default": 0.1,
      "description": "Delay between each letter's animation start (seconds)"
    },
    "animationSpeed": {
      "type": "number",
      "default": 1,
      "description": "Animation speed multiplier"
    }
  },
  "required": ["collageId", "animationType"]
}

pinepaper_get_letter_collage_options

Get available styles, palettes, and gradient options for letter collages.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "styles": ["tile", "magazine", "paperCut", "fold", "gradient", "image"],
  "tilePalettes": {
    "game": ["wordle", "scrabble"],
    "vibrant": ["candy", "neon", "rainbow"],
    "soft": ["pastel", "cotton"],
    "natural": ["earth", "ocean", "forest", "sunset"],
    "professional": ["corporate", "minimal", "slate"],
    "seasonal": ["christmas", "halloween", "spring"],
    "magazine": ["magazine", "newspaper", "vintage"],
    "paperCraft": ["paperCraft", "origami", "craftPaper"]
  },
  "gradientPalettes": ["rainbow", "sunset", "ocean", "fire", "gold", "rose", "ice", "cyberpunk", "neonGlow", "purplePink"],
  "gradientDirections": ["vertical", "horizontal", "diagonal", "radial"]
}

Interactive Triggers (v1.5.0+)

Add click, hover, drag, and timeline-based interactions to items.

pinepaper_add_trigger

Add an interactive trigger to an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {
      "type": "string",
      "description": "Item to attach trigger to"
    },
    "event": {
      "type": "string",
      "enum": ["click", "hover_enter", "hover_exit", "drag_start", "drag_move", "drag_end", "timeline", "scene_enter", "scene_exit", "animation_end", "quiz_answer"],
      "description": "Event that fires the trigger"
    },
    "actions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": ["show", "hide", "toggle_visibility", "play_animation", "stop_animation", "navigate", "update_property", "set_variable", "submit_answer", "increment_score", "reset_quiz"]
          },
          "targetItemId": {"type": "string"},
          "animationType": {"type": "string"},
          "property": {"type": "string"},
          "value": {},
          "url": {"type": "string"},
          "points": {"type": "number"}
        },
        "required": ["type"]
      }
    },
    "condition": {
      "type": "string",
      "description": "Optional condition expression (e.g., \"$score > 10\")"
    }
  },
  "required": ["itemId", "event", "actions"]
}

Examples:

// Click to show panel
{"itemId": "button_1", "event": "click", "actions": [{"type": "show", "targetItemId": "panel_1"}]}

// Hover to animate
{"itemId": "star_1", "event": "hover_enter", "actions": [{"type": "play_animation", "targetItemId": "star_1", "animationType": "pulse"}]}

// Click to navigate
{"itemId": "next_btn", "event": "click", "actions": [{"type": "navigate", "url": "#scene2"}]}

pinepaper_remove_trigger

Remove triggers from an item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {"type": "string"},
    "event": {"type": "string", "enum": ["click", "hover_enter", "hover_exit", "drag_start", "drag_move", "drag_end", "timeline", "scene_enter", "scene_exit", "animation_end", "quiz_answer"]},
    "removeAll": {"type": "boolean"}
  },
  "required": ["itemId"]
}

pinepaper_query_triggers

List all triggers on the canvas or for a specific item.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemId": {"type": "string", "description": "Filter by item ID"},
    "event": {"type": "string", "description": "Filter by event type"}
  }
}

Quiz/LMS Integration (v1.5.0+)

Create interactive quizzes with SCORM/xAPI support.

pinepaper_create_quiz

Create an interactive quiz with questions, answers, and scoring.

Question Types:

  • multiple-choice: Single correct answer
  • multiple-select: Multiple correct answers
  • drag-drop: Drag items to zones
  • matching: Match pairs
  • sequencing: Order items correctly
  • hotspot: Click correct area
  • true-false: True/false question

Input Schema:

{
  "type": "object",
  "properties": {
    "title": {"type": "string"},
    "questions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {"type": "string", "enum": ["multiple-choice", "multiple-select", "drag-drop", "matching", "sequencing", "hotspot", "true-false"]},
          "prompt": {"type": "string"},
          "options": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {"type": "string"},
                "label": {"type": "string"},
                "isCorrect": {"type": "boolean"}
              }
            }
          },
          "points": {"type": "number"},
          "correctFeedback": {"type": "string"},
          "incorrectFeedback": {"type": "string"}
        },
        "required": ["type", "prompt", "points"]
      }
    },
    "passingScore": {"type": "number", "description": "Minimum percentage to pass (0-100)"},
    "showScore": {"type": "boolean"},
    "allowRetry": {"type": "boolean"},
    "shuffleQuestions": {"type": "boolean"},
    "shuffleOptions": {"type": "boolean"}
  },
  "required": ["questions"]
}

Example:

{
  "title": "Geography Quiz",
  "questions": [
    {
      "type": "multiple-choice",
      "prompt": "What is the capital of France?",
      "options": [
        {"id": "a", "label": "London"},
        {"id": "b", "label": "Paris", "isCorrect": true},
        {"id": "c", "label": "Berlin"}
      ],
      "points": 10,
      "correctFeedback": "Correct! Paris is the capital.",
      "incorrectFeedback": "Sorry, the correct answer is Paris."
    }
  ],
  "passingScore": 70,
  "showScore": true
}

pinepaper_get_quiz_state

Get the current state of an active quiz.

Output:

{
  "quizId": "quiz_1",
  "currentQuestion": 2,
  "totalQuestions": 5,
  "score": 20,
  "maxScore": 50,
  "answers": [{"questionId": "q1", "correct": true}],
  "passed": false,
  "complete": false
}

pinepaper_reset_quiz

Reset a quiz to its initial state.

Input Schema:

{
  "type": "object",
  "properties": {
    "quizId": {"type": "string", "description": "Quiz ID (optional, uses active quiz)"}
  }
}

Widget Export (v1.5.0+)

Export as embeddable widgets for websites and LMS.

pinepaper_export_widget

Export the current canvas as an embeddable widget.

Export Formats:

  • web-component: <pinepaper-widget> custom element
  • standalone-html: Complete HTML file
  • iframe-embed: Iframe embed code
  • react-component: React wrapper
  • vue-component: Vue wrapper

Input Schema:

{
  "type": "object",
  "properties": {
    "format": {
      "type": "string",
      "enum": ["web-component", "standalone-html", "iframe-embed", "react-component", "vue-component"]
    },
    "sizing": {
      "type": "string",
      "enum": ["fixed", "responsive", "fluid"],
      "description": "Widget sizing mode (default: responsive)"
    },
    "interactivity": {
      "type": "string",
      "enum": ["none", "view", "full"],
      "description": "Interactivity level (default: view)"
    },
    "autoplay": {"type": "boolean", "description": "Auto-play animations (default: true)"},
    "loop": {"type": "boolean", "description": "Loop animations (default: true)"},
    "lmsEnabled": {"type": "boolean", "description": "Enable LMS tracking (SCORM/xAPI)"},
    "width": {"type": "number", "description": "Fixed width in pixels"},
    "height": {"type": "number", "description": "Fixed height in pixels"}
  },
  "required": ["format"]
}

Output:

{
  "code": "// main widget code",
  "embedCode": "<pinepaper-widget src=\"...\"></pinepaper-widget>",
  "sceneData": "{...serialized scene...}",
  "metadata": {"width": 800, "height": 600, "interactivity": "view"}
}

Agent Flow Mode Tools

Agent mode is enforced by default (v1.5.0+). The browser auto-connects on first tool call with optimized settings for automation.

pinepaper_agent_start_job

Start a new agent job/session for optimized batch workflows.

Input Schema:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Optional job name for tracking"
    },
    "screenshotPolicy": {
      "type": "string",
      "enum": ["on_complete", "on_error", "never", "on_request"],
      "description": "When to take screenshots (default: on_complete)"
    },
    "canvasPreset": {
      "type": "string",
      "enum": ["instagram", "instagram-story", "tiktok", "youtube", "youtube-thumbnail", "twitter", "linkedin", "web", "print-a4", "print-letter"],
      "description": "Set canvas size to platform preset"
    },
    "clearCanvas": {
      "type": "boolean",
      "description": "Clear canvas when starting job (default: true)"
    }
  }
}

pinepaper_agent_end_job

End the current agent job and get summary with export recommendations.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "jobId": "job_12345",
  "duration": 5432,
  "itemsCreated": ["item_1", "item_2", "item_3"],
  "relationsCreated": ["rel_1"],
  "screenshot": "base64...",
  "recommendations": {
    "formats": ["mp4", "gif"],
    "platforms": ["instagram", "tiktok"],
    "hasAnimations": true
  }
}

pinepaper_agent_reset

Fast canvas reset without browser refresh (~200ms vs ~3000ms for page refresh).

Input Schema:

{
  "type": "object",
  "properties": {
    "canvasPreset": {
      "type": "string",
      "enum": ["instagram", "instagram-story", "tiktok", "youtube", "youtube-thumbnail", "twitter", "linkedin", "web", "print-a4", "print-letter"],
      "description": "Set canvas size after reset"
    },
    "backgroundColor": {
      "type": "string",
      "description": "Set background color after reset"
    },
    "preserveBackground": {
      "type": "boolean",
      "description": "Keep existing background"
    }
  }
}

pinepaper_agent_batch_execute

Execute multiple operations in a single browser call. Dramatically faster than individual tool calls.

Performance:

  • 10 individual creates: ~1450ms (10 browser round trips)
  • Batch execute 10 creates: ~300ms (1 browser round trip)

Input Schema:

{
  "type": "object",
  "properties": {
    "operations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": ["create", "modify", "animate", "relation", "delete"]
          },
          "itemType": {"type": "string"},
          "itemId": {"type": "string"},
          "position": {"type": "object"},
          "properties": {"type": "object"},
          "animationType": {"type": "string"},
          "animationOptions": {"type": "object"},
          "sourceId": {"type": "string"},
          "targetId": {"type": "string"},
          "relationType": {"type": "string"},
          "relationOptions": {"type": "object"}
        },
        "required": ["type"]
      }
    },
    "atomic": {
      "type": "boolean",
      "description": "All succeed or all fail (default: true)"
    }
  },
  "required": ["operations"]
}

Variable References:

Use $0, $1, etc. to reference items created in earlier operations:

{
  "operations": [
    {"type": "create", "itemType": "circle", "position": {"x": 400, "y": 300}, "properties": {"radius": 50}},
    {"type": "animate", "itemId": "$0", "animationType": "pulse"}
  ]
}

pinepaper_agent_export

Smart export with automatic format detection and platform optimization.

Input Schema:

{
  "type": "object",
  "properties": {
    "platform": {
      "type": "string",
      "enum": ["instagram", "instagram-story", "tiktok", "youtube", "youtube-thumbnail", "twitter", "linkedin", "web", "print-a4", "print-letter"],
      "description": "Target platform (auto-selects optimal format)"
    },
    "format": {
      "type": "string",
      "enum": ["png", "svg", "mp4", "webm", "gif", "pdf"],
      "description": "Override format selection"
    },
    "quality": {
      "type": "string",
      "enum": ["low", "medium", "high", "maximum"],
      "description": "Export quality (default: high)"
    },
    "duration": {
      "type": "number",
      "description": "Animation duration in seconds (default: 5)"
    },
    "fps": {
      "type": "number",
      "description": "Frames per second for video (default: 30)"
    }
  }
}

Platform Optimal Formats:

Platform Dimensions Static Animated
instagram 1080x1080 PNG MP4
instagram-story 1080x1920 PNG MP4
tiktok 1080x1920 PNG MP4@60fps
youtube 1920x1080 PNG MP4
twitter 1200x675 PNG GIF
linkedin 1200x627 PNG GIF
web flexible SVG SVG
print-a4 2480x3508 PDF PDF

pinepaper_agent_analyze

Analyze canvas content for export recommendations.

Input Schema:

{
  "type": "object",
  "properties": {}
}

Output:

{
  "hasAnimations": true,
  "animationTypes": ["pulse", "orbits"],
  "colorComplexity": "gradient",
  "itemCount": 5,
  "canvasSize": {"width": 1080, "height": 1080},
  "hasRelations": true,
  "relationTypes": ["orbits"],
  "hasGradients": true,
  "hasShadows": false,
  "hasText": true,
  "hasImages": false,
  "recommendations": {
    "formats": ["mp4", "gif"],
    "platforms": ["instagram", "tiktok"],
    "reason": "Content has animations - video formats recommended"
  }
}

Paper.js Direct Access

pinepaper_register_item

Register a Paper.js item created externally.

Input Schema:

{
  "type": "object",
  "properties": {
    "itemJson": {
      "type": "object",
      "description": "Paper.js item JSON (from item.exportJSON())"
    },
    "itemType": {
      "type": "string",
      "description": "Type name for registry"
    },
    "properties": {
      "type": "object",
      "description": "Custom properties to store"
    }
  },
  "required": ["itemJson", "itemType"]
}

Error Handling

All tools return errors in a consistent format:

{
  "success": false,
  "error": {
    "code": "ITEM_NOT_FOUND",
    "message": "Item with ID 'item_99' not found",
    "details": {}
  }
}

Error Codes:

Code Description
ITEM_NOT_FOUND Item ID doesn’t exist
INVALID_RELATION Unknown relation type
INVALID_PARAMS Missing or invalid parameters
GENERATOR_NOT_FOUND Unknown generator name
EXPORT_FAILED Export operation failed

Implementation Notes

  1. Item IDs: All items are referenced by item.data.registryId (e.g., “item_1”)
  2. Positions: Canvas coordinates, (0,0) is top-left
  3. Colors: Hex (#RRGGBB), RGB, or named colors
  4. Async Operations: Generators may be async, return promises
  5. State Management: Call historyManager.saveState() after batches
  6. Relations: Process automatically each frame, no manual updates needed