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
- Canvas Tools - Set and get canvas dimensions (REQUIRED before creating items)
- Item Tools - Create, modify, delete canvas items
- Diagram Tools - Create flowcharts, UML diagrams, and network diagrams
- Relation Tools - Define behavior relationships (key for animation)
- Animation Tools - Apply and control animations
- Mask Tools - Apply clipping masks and animated reveal effects
- Generator Tools - Create procedural backgrounds
- Map Tools - Geographic visualizations (world maps, US states, choropleth)
- Font Tools - Create custom hand-drawn fonts with glyph management
- Text Design Tools - Create stylized text (Letter Collage with tile, magazine, gradient styles)
- Effect Tools - Apply visual effects (sparkle, blast)
- Query Tools - Find and inspect items
- Export Tools - Export graphics, training data, widget JSON, and standalone HTML
- Rigging Tools - Skeletal animation with bones, FK/IK solvers, and poses (v0.4)
- Blending Tools - Per-item and per-group compositing presets and transitions (v0.4)
- Image Filter Tools - GPU-accelerated image filters (grayscale, HSL, posterize, etc.)
- Lasso Tools - Freehand lasso selection for image region extraction
- Cutout Style Tools - Apply visual style presets to image cutouts
- View Tools - Zoom, pan, and fit canvas view
- Selection Tools - Select, deselect, and manage item selection
- Transform Tools - Nudge, flip, and reorder items in stacking order
- Background Tools - Set background color, pattern, or procedural generator
- History Tools - Undo, redo, and manage edit history
- Advanced Query Tools - Query items by name, type, or custom matcher
- Precomp Tools - Create and manage nested compositions
- Playback Tools - Control keyframe timeline playback
- 3D Projection Tools - Create and configure 3D objects with projection, camera, and lighting
- Deformation Tools - Apply vertex-level geometric deformation presets (fold, twist, wave, etc.)
- Sprite Sheet Tools - Generate, play, and export sprite sheet atlases from rigged skeletons
- Shape Key Tools - Save, load, and animate per-item blend shapes for facial animation (v0.4.3)
- Procedural Animation Tools - One-call breathing, idle, walk, and jump animations (v0.4.3)
- Bone Physics Tools - Verlet physics simulation on bones with impulses and colliders (v0.4.3)
- Physics World Tools - Rigid body physics for canvas items via Planck.js (v0.4.3)
- Character Controller Tools - Composable character movement and test mode (v0.4.3)
- Scene Sequencer Tools - Timeline-based multi-character action choreography (v0.4.3)
- Advanced Rigging Tools - Guided rig builder, bone management, path skinning, secondary motion (v0.4.3)
- Scene Tools - Scene baking, part system, and animation suggestions (v0.4.3)
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)" }
}
},
"animationType": {
"type": "string",
"description": "Animation type to apply on creation (e.g., 'pulse', 'bounce', 'keyframe')"
},
"animationSpeed": {
"type": "number",
"description": "Animation speed multiplier (for simple animations)"
},
"keyframes": {
"type": "array",
"description": "Keyframe array for inline keyframe animation (requires animationType: 'keyframe')",
"items": {
"type": "object",
"properties": {
"time": { "type": "number", "description": "Time in seconds" },
"properties": { "type": "object", "description": "Animatable properties (x, y, scale, opacity, rotation, fillColor, etc.)" },
"easing": { "type": "string", "description": "Easing function: linear, easeIn, easeOut, easeInOut, bounce, elastic" }
}
}
}
},
"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:
- Items in
textItemGroup(text layer) are always selectable by default - Items in
patternGroup(background) are NOT selectable unless marked withselectable: true - Items with
isDecorative: trueare never selectable (overrides all) - Items with
selectable: truecan 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",
"bone_attached", "ik_target", "blend_reacts_to", "blend_transition"
],
"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) |
| All relations | startTime (seconds), endTime (seconds), autoRemove (boolean) — time-scoping parameters |
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, pan, and 3D tilt animation | mode (‘keyframes’/‘fly_to’/‘orbit’), keyframes (array of {time, zoom, focus, pitch, yaw, easing, pathOut, pathIn, pathMode, pivot, arcDirection, path} — focus accepts [x,y], an item id, or {item, offset} and is resolved live against the scene graph so the camera tracks items as they move; legacy center: [x,y] still honored when focus is absent; inter-keyframe path defaults to linear but can curve via pathOut/pathIn bezier handles, pathMode: 'arc' with pivot + optional `arcDirection: ‘ccw’ |
morphs_to |
Shape morphing animation (like Manim Transform) | duration (seconds), delay (seconds), easing, morphColor (boolean), morphSize (boolean), hideTarget (boolean), removeTargetOnComplete (boolean) |
Rigging Relations (v0.4):
| Relation | Description | Parameters |
|---|---|---|
bone_attached |
Item follows a bone’s world transform (priority -10, runs before standard relations) | skeletonId (string), boneId (string), offset ([x, y]), inheritRotation (boolean), attachPoint (0=joint, 1=tip) |
ik_target |
Item acts as IK solver target pulling a bone chain (priority -20) | skeletonId (string), chainId (string), strength (0-1, FK/IK blend) |
Blending Relations (v0.4):
| Relation | Description | Parameters |
|---|---|---|
blend_reacts_to |
Proximity-based blend mode/opacity changes | proximityRadius (pixels), activeMode (blend mode), inactiveMode (blend mode), activeOpacity (0-1), inactiveOpacity (0-1), smoothing (0-1) |
blend_transition |
Automatic time-based blend mode cycling | modes (string[]), opacities (number[]), cycleDuration (seconds), easing |
Output:
{
"success": true,
"sourceId": "item_1",
"targetId": "item_2",
"relationType": "orbits"
}
pinepaper_replace_relation
Atomically replace a relation (remove + add with fresh params). Unlike pinepaper_add_relation which merges params, this fully replaces them.
Input Schema:
Same as pinepaper_add_relation.
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", "shake", "swing", "jelly", "glow"]
},
"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"
},
"timeOffset": {
"type": "number",
"description": "Offset in seconds — delays this item's keyframe start relative to global timeline"
},
"relationBehavior": {
"type": "string",
"enum": ["override", "keyframeFirst"],
"description": "How relations interact with keyframes. 'keyframeFirst' pauses relations during playback."
}
},
"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, pan, and 3D tilt sequence. Supports three modes: keyframes (manual control), fly_to (shorthand pan+zoom), and orbit (revolve around point). Keyframes can include pitch and yaw for cinematic 3D perspective using PinePaper’s equirectangular projection pipeline.
Input Schema:
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["keyframes", "fly_to", "orbit"],
"default": "keyframes",
"description": "Camera mode: keyframes (manual array), fly_to (shorthand target+zoom), orbit (revolve)"
},
"keyframes": {
"type": "array",
"description": "Array of camera keyframes (mode=keyframes)",
"items": {
"type": "object",
"properties": {
"time": { "type": "number", "description": "Time in seconds" },
"zoom": { "type": "number", "description": "Zoom level (1=normal, 2=2x zoom in)" },
"center": { "type": "array", "items": { "type": "number" }, "description": "View center [x, y]" },
"pitch": { "type": "number", "description": "Camera tilt in degrees (0=flat, positive=tilt forward). Uses 3D projection" },
"yaw": { "type": "number", "description": "Camera rotation in degrees. Uses 3D projection" },
"easing": { "type": "string", "enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"] }
}
}
},
"target": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"description": "Target position for fly_to mode"
},
"pitch": {
"type": "number",
"default": 0,
"description": "Global camera tilt in degrees. Applied when not using per-keyframe pitch"
},
"yaw": {
"type": "number",
"default": 0,
"description": "Global camera rotation in degrees. Applied when not using per-keyframe yaw"
},
"fov": {
"type": "number",
"default": 60,
"description": "Field of view in degrees for 3D perspective projection"
},
"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": ["duration"]
}
Example - Cinematic zoom with 3D tilt:
{
"duration": 6,
"loop": true,
"keyframes": [
{ "time": 0, "zoom": 1, "center": [400, 300], "pitch": 0, "yaw": 0 },
{ "time": 2, "zoom": 2.5, "center": [200, 350], "pitch": 15, "yaw": -8, "easing": "easeInOut" },
{ "time": 4, "zoom": 2.5, "center": [200, 350], "pitch": 15, "yaw": -8 },
{ "time": 6, "zoom": 1, "center": [400, 300], "pitch": 0, "yaw": 0, "easing": "easeInOut" }
]
}
Example - fly_to mode (shorthand):
{
"mode": "fly_to",
"target": { "x": 200, "y": 350 },
"zoom": 3,
"pitch": 12,
"duration": 1.5
}
Output:
{
"success": true,
"isAnimating": true
}
Notes:
- Pitch/yaw use CSS
perspective+rotateX/rotateYfor GPU-accelerated 3D compositing - Routes through PinePaper’s own equirectangular 3D projection pipeline (not Three.js)
- Pitch 0° = flat canvas, 90° = top-down view
- When pitch/yaw return to 0, the 3D transform is removed (pure 2D)
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 = trueanddata.isDraggable = true - Orbits have
data.isDecorative = true(not selectable) - Sun has
data.isSun = true, planets havedata.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:
- Download detailed boundaries from GADM or Natural Earth
- Simplify with Mapshaper if needed
- 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" }
]
}
Font Tools
Create custom hand-drawn fonts by drawing glyphs on a dedicated canvas. Font Studio converts Paper.js paths to OpenType glyphs.
pinepaper_font_show_studio
Open the Font Studio UI for interactive font creation.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"message": "Font Studio opened"
}
pinepaper_font_set_name
Set the font name.
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Font family name (e.g., 'MyHandwriting')"
}
},
"required": ["name"]
}
Output:
{
"success": true,
"fontName": "MyHandwriting"
}
pinepaper_font_get_required_chars
Get the list of characters needed for a complete font.
Input Schema:
{
"type": "object",
"properties": {
"set": {
"type": "string",
"enum": ["minimum", "standard"],
"default": "minimum",
"description": "minimum: A-Z, a-z, 0-9, space (63 chars). standard: adds punctuation (90+ chars)"
}
}
}
Output:
{
"characters": ["A", "B", "C", "..."],
"count": 63,
"set": "minimum"
}
pinepaper_font_get_status
Get font completion status.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"fontName": "MyHandwriting",
"total": 63,
"completed": 26,
"pending": 37,
"percentage": 41,
"completedChars": ["A", "B", "C", "..."],
"pendingChars": ["a", "b", "c", "..."],
"isComplete": false
}
pinepaper_font_create_glyph
Create a glyph from a Paper.js path. Used programmatically when drawing paths for characters.
Input Schema:
{
"type": "object",
"properties": {
"character": {
"type": "string",
"description": "Single character (e.g., 'A', 'a', '1', ' ')"
},
"pathId": {
"type": "string",
"description": "Registry ID of the Paper.js path to use as glyph shape"
}
},
"required": ["character", "pathId"]
}
Output:
{
"success": true,
"character": "A",
"glyphName": "A",
"advanceWidth": 450
}
pinepaper_font_create_space
Create the space glyph (no visible shape, just advance width).
Input Schema:
{
"type": "object",
"properties": {
"width": {
"type": "number",
"default": 250,
"description": "Space width in font units"
}
}
}
Output:
{
"success": true,
"character": " ",
"advanceWidth": 250
}
pinepaper_font_remove_glyph
Remove a glyph from the font.
Input Schema:
{
"type": "object",
"properties": {
"character": {
"type": "string",
"description": "Character to remove"
}
},
"required": ["character"]
}
Output:
{
"success": true,
"removed": "A"
}
pinepaper_font_set_metrics
Set font metrics (advanced).
Input Schema:
{
"type": "object",
"properties": {
"unitsPerEm": {
"type": "number",
"default": 1000,
"description": "Coordinate grid size"
},
"ascender": {
"type": "number",
"default": 800,
"description": "Height above baseline"
},
"descender": {
"type": "number",
"default": -200,
"description": "Depth below baseline (negative)"
},
"xHeight": {
"type": "number",
"default": 500,
"description": "Lowercase letter height"
},
"capHeight": {
"type": "number",
"default": 700,
"description": "Capital letter height"
}
}
}
Output:
{
"success": true,
"metrics": {
"unitsPerEm": 1000,
"ascender": 800,
"descender": -200,
"xHeight": 500,
"capHeight": 700
}
}
pinepaper_font_export
Export the font as OTF file.
Input Schema:
{
"type": "object",
"properties": {
"download": {
"type": "boolean",
"default": true,
"description": "Trigger browser download"
}
}
}
Output:
{
"success": true,
"fontName": "MyHandwriting",
"format": "otf",
"downloaded": true,
"glyphCount": 63
}
pinepaper_font_load_into_document
Load the custom font into the document for immediate use in PinePaper.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"fontName": "MyHandwriting",
"message": "Font 'MyHandwriting' loaded and ready to use"
}
pinepaper_font_export_data
Export font data as JSON for saving progress.
Input Schema:
{
"type": "object",
"properties": {
"download": {
"type": "boolean",
"default": true,
"description": "Trigger browser download"
}
}
}
Output:
{
"success": true,
"data": {
"version": "1.0",
"fontName": "MyHandwriting",
"metrics": { "..." },
"glyphs": { "..." }
},
"downloaded": true
}
pinepaper_font_import_data
Import font data from previously saved JSON.
Input Schema:
{
"type": "object",
"properties": {
"data": {
"type": "object",
"description": "Font data object from pinepaper_font_export_data"
}
},
"required": ["data"]
}
Output:
{
"success": true,
"fontName": "MyHandwriting",
"glyphCount": 26
}
pinepaper_font_clear
Clear all glyphs and reset the font.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"message": "Font cleared"
}
pinepaper_font_remove_overlap
Remove overlapping areas from a path (like FontForge’s RemoveOverlap). Merges multiple overlapping paths into a single clean outline.
Input Schema:
{
"type": "object",
"properties": {
"pathId": {
"type": "string",
"description": "Registry ID of the Paper.js path to process"
}
},
"required": ["pathId"]
}
Output:
{
"success": true,
"pathId": "item_42",
"message": "Overlaps removed from path"
}
pinepaper_font_correct_direction
Correct path winding direction for proper fill rendering (like FontForge’s CorrectDirection). Ensures outer contours are clockwise and inner holes are counter-clockwise.
Input Schema:
{
"type": "object",
"properties": {
"pathId": {
"type": "string",
"description": "Registry ID of the Paper.js path to process"
}
},
"required": ["pathId"]
}
Output:
{
"success": true,
"pathId": "item_42",
"message": "Path direction corrected"
}
pinepaper_font_cleanup_path
Apply all path cleanup operations in the correct order: removeOverlap → correctDirection → smooth.
Input Schema:
{
"type": "object",
"properties": {
"pathId": {
"type": "string",
"description": "Registry ID of the Paper.js path to process"
},
"removeOverlap": {
"type": "boolean",
"default": true,
"description": "Merge overlapping strokes"
},
"correctDirection": {
"type": "boolean",
"default": true,
"description": "Fix winding direction for fills"
},
"smooth": {
"type": "boolean",
"default": true,
"description": "Apply path smoothing"
},
"smoothTolerance": {
"type": "number",
"default": 2.5,
"description": "Smoothing tolerance (higher = more simplification)"
}
},
"required": ["pathId"]
}
Output:
{
"success": true,
"pathId": "item_42",
"operations": ["removeOverlap", "correctDirection", "smooth"],
"message": "Path cleanup complete"
}
Font Studio Typography Guide
When using Font Studio interactively, guide lines help with consistent glyph drawing:
| Guide Line | Color | Description |
|---|---|---|
| Cap Height | Red (#ff6b6b) | Top of capital letters (H, T, A) |
| x-Height | Cyan (#4ecdc4) | Top of lowercase letters (a, e, x) |
| Baseline | Green (#95e1d3) | Where letters “sit” |
| Descender | Purple (#dda0dd) | Below baseline for g, p, y, j |
Best Practices:
- Keep stroke width consistent across all characters
- Uppercase letters should touch the cap height line
- Lowercase (except b, d, f, h, k, l, t) stay within x-height
- Letters g, j, p, q, y extend below baseline to descender
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"
}
pinepaper_export_widget
Export scene as embeddable widget JSON format using the pp:PinePaper ontology. The output contains scene data that can be loaded by PineWidget.js or embedded in any website.
Input Schema:
{
"type": "object",
"properties": {
"includeInteractions": {
"type": "boolean",
"default": true,
"description": "Include interaction triggers in export"
},
"minify": {
"type": "boolean",
"default": false,
"description": "Minify JSON output"
}
}
}
Output:
{
"success": true,
"data": {
"ontology": "pp:PinePaper",
"ontologyVersion": "0.4.3",
"version": "1.0",
"width": 1080,
"height": 1080,
"background": "#1e293b",
"items": [],
"relations": [],
"metadata": {
"itemCount": 5,
"relationCount": 3,
"hasAnimations": true,
"ontologyTokens": 55
}
},
"embedCode": "<div id=\"my-widget\">...</div><script>...</script>"
}
pinepaper_export_widget_html
Export scene as a standalone self-contained HTML file. The output includes only the runtime code needed for this specific scene — item renderers, relation handlers, and features are tree-shaken based on actual scene content. Zero external dependencies, no CDN links, no API calls. Opens directly in any browser.
Input Schema:
{
"type": "object",
"properties": {
"title": {
"type": "string",
"default": "PinePaper Widget",
"description": "HTML page title"
}
}
}
Output:
{
"success": true,
"html": "<!DOCTYPE html><html>...</html>",
"analysis": {
"itemTypes": ["circle", "text"],
"relationTypes": ["orbits", "follows"],
"hasSimpleAnimations": true,
"hasKeyframeAnimations": false,
"hasMasks": false,
"hasCameraRelation": false
},
"estimatedSize": 12400
}
Notes:
- Output HTML is self-contained — no
<script src>tags, nofetch()calls - Scene data is inlined as JSON within the HTML
- Supports transparent backgrounds for overlay use cases
- Canvas is responsive and scales to container size
- All pp:PinePaper ontology relation types are supported
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 answermultiple-select: Multiple correct answersdrag-drop: Drag items to zonesmatching: Match pairssequencing: Order items correctlyhotspot: Click correct areatrue-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)"}
}
}
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 |
|---|---|---|---|
| 1080x1080 | PNG | MP4 | |
| instagram-story | 1080x1920 | PNG | MP4 |
| tiktok | 1080x1920 | PNG | MP4@60fps |
| youtube | 1920x1080 | PNG | MP4 |
| 1200x675 | PNG | GIF | |
| 1200x627 | PNG | GIF | |
| web | flexible | SVG | SVG |
| print-a4 | 2480x3508 |
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 |
Rigging Tools (v0.4)
Skeletal animation with bones, FK/IK solvers, poses, and character presets.
pinepaper_create_skeleton
Create a new skeleton for character rigging.
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Skeleton name"
},
"rootPosition": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"description": "World position of skeleton root (default: canvas center)"
}
},
"required": ["name"]
}
Output:
{
"success": true,
"skeletonId": "skeleton_1"
}
pinepaper_add_bone
Add a bone to an existing skeleton.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to add bone to"
},
"name": {
"type": "string",
"description": "Bone name (e.g., 'upperArm_L')"
},
"parentBoneId": {
"type": "string",
"description": "Parent bone ID (null for root bone)"
},
"length": {
"type": "number",
"description": "Bone length in pixels",
"default": 80
},
"angle": {
"type": "number",
"description": "Local rotation angle in radians",
"default": 0
},
"constraint": {
"type": "object",
"properties": {
"minAngle": { "type": "number", "description": "Minimum angle in radians" },
"maxAngle": { "type": "number", "description": "Maximum angle in radians" },
"fixed": { "type": "boolean", "description": "Lock joint rotation" }
},
"description": "Joint angle constraints"
}
},
"required": ["skeletonId", "name"]
}
Output:
{
"success": true,
"boneId": "bone_1"
}
pinepaper_attach_item_to_bone
Attach a canvas item to a bone so it follows bone transforms.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"boneId": { "type": "string" },
"itemId": {
"type": "string",
"description": "Item registry ID to attach"
},
"attachPoint": {
"type": "number",
"description": "Position along bone: 0=joint, 0.5=middle, 1=tip",
"default": 0.5
},
"offset": {
"type": "array",
"items": { "type": "number" },
"description": "Local offset from attach point [x, y]",
"default": [0, 0]
},
"inheritRotation": {
"type": "boolean",
"description": "Whether item rotates with bone",
"default": true
}
},
"required": ["skeletonId", "boneId", "itemId"]
}
Output:
{
"success": true,
"skeletonId": "skeleton_1",
"boneId": "bone_3",
"itemId": "item_5"
}
pinepaper_set_bone_angle
Set the local rotation angle of a bone (respects joint constraints).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"boneId": { "type": "string" },
"angle": {
"type": "number",
"description": "Angle in radians"
}
},
"required": ["skeletonId", "boneId", "angle"]
}
pinepaper_create_ik_chain
Create an Inverse Kinematics chain for drag-based posing.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"name": { "type": "string" },
"boneIds": {
"type": "array",
"items": { "type": "string" },
"description": "Ordered bone IDs from root to effector (minimum 2)",
"minItems": 2
},
"strength": {
"type": "number",
"description": "IK influence: 0=FK only, 1=full IK",
"default": 1,
"minimum": 0,
"maximum": 1
},
"iterations": {
"type": "number",
"description": "FABRIK solver iterations",
"default": 10
},
"tolerance": {
"type": "number",
"description": "Convergence tolerance in pixels",
"default": 0.5
}
},
"required": ["skeletonId", "boneIds"]
}
Output:
{
"success": true,
"chainId": "ikchain_1"
}
pinepaper_set_ik_target
Set the IK target item for a chain. The solver will pull the bone chain toward this item’s position.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"chainId": { "type": "string" },
"targetItemId": {
"type": "string",
"description": "Item registry ID to use as IK target (draggable handle)"
}
},
"required": ["skeletonId", "chainId", "targetItemId"]
}
pinepaper_apply_rig_preset
Apply a pre-built character rig preset to a skeleton.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"preset": {
"type": "string",
"enum": ["humanoid", "quadruped", "spider", "simple_arm", "snake", "chain"],
"description": "Character rig preset name"
}
},
"required": ["skeletonId", "preset"]
}
Preset Details:
| Preset | Bones | IK Chains | Description |
|---|---|---|---|
humanoid |
16 | 4 | Spine + head + arms(L/R) + legs(L/R) |
quadruped |
13 | 4 | Horizontal spine + 4 legs + tail |
spider |
19 | 8 | Body + head + 8 legs |
simple_arm |
3 | 1 | Upper arm + lower arm + hand |
snake |
10 | 1 | Spine chain for serpentine motion |
chain |
5 | 1 | Generic pendulum/rope |
Output:
{
"success": true,
"skeletonId": "skeleton_1",
"boneMap": {
"hip": "bone_1",
"spine": "bone_2",
"chest": "bone_3"
},
"chainIds": ["ikchain_1", "ikchain_2"]
}
pinepaper_save_pose
Save current bone angles as a named pose for later recall or animation.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": { "type": "string" },
"name": {
"type": "string",
"description": "Pose name (e.g., 'idle', 'walk_frame1')"
}
},
"required": ["skeletonId", "name"]
}
Output:
{
"success": true,
"poseId": "pose_1"
}
pinepaper_load_pose
Load a saved pose onto its skeleton.
Input Schema:
{
"type": "object",
"properties": {
"poseId": { "type": "string" }
},
"required": ["poseId"]
}
pinepaper_interpolate_poses
Blend between two poses. Useful for keyframe animation of character rigs.
Input Schema:
{
"type": "object",
"properties": {
"poseIdA": { "type": "string" },
"poseIdB": { "type": "string" },
"t": {
"type": "number",
"description": "Interpolation factor: 0=pose A, 1=pose B",
"minimum": 0,
"maximum": 1
},
"apply": {
"type": "boolean",
"description": "Apply interpolated angles to skeleton immediately",
"default": true
}
},
"required": ["poseIdA", "poseIdB", "t"]
}
Output:
{
"success": true,
"boneAngles": {
"bone_1": 0.35,
"bone_2": -0.15,
"bone_3": 0.22
}
}
pinepaper_create_chain_from_items
Auto-create a skeleton by inferring bone hierarchy from a sequence of existing items.
Input Schema:
{
"type": "object",
"properties": {
"itemIds": {
"type": "array",
"items": { "type": "string" },
"description": "Ordered item IDs — bones created between consecutive items",
"minItems": 2
},
"name": { "type": "string", "description": "Skeleton name" },
"createIKChain": {
"type": "boolean",
"description": "Auto-create IK chain for the full bone sequence",
"default": false
}
},
"required": ["itemIds"]
}
Output:
{
"success": true,
"skeletonId": "skeleton_1",
"boneIds": ["bone_1", "bone_2"],
"chainId": "ikchain_1"
}
Blending Tools (v0.4)
Per-item and per-group compositing with presets, transitions, and interactive modes.
pinepaper_apply_blend_preset
Apply a named blend preset (mode + opacity combo) to an item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID"
},
"preset": {
"type": "string",
"enum": [
"ghost", "neon", "shadow", "silhouette", "glow", "highlight",
"darkroom", "xray", "dreamy", "vintage",
"multiply", "screen", "overlay", "dodge", "burn",
"hardLight", "softLight", "difference", "exclusion"
],
"description": "Blend preset name"
}
},
"required": ["itemId", "preset"]
}
Preset Details:
| Preset | Blend Mode | Opacity | Effect |
|---|---|---|---|
ghost |
screen | 0.5 | Ghostly translucent overlay |
neon |
color-dodge | 0.85 | Bright neon glow |
shadow |
multiply | 0.7 | Dark shadow overlay |
silhouette |
darken | 1.0 | Dark silhouette cutout |
glow |
screen | 0.8 | Bright additive glow |
highlight |
lighten | 0.9 | Light highlight overlay |
darkroom |
color-burn | 0.6 | Deep color burn |
xray |
difference | 0.8 | X-ray inversion |
dreamy |
soft-light | 0.9 | Soft dreamy haze |
vintage |
overlay | 0.7 | Warm vintage overlay |
Output:
{
"success": true,
"itemId": "item_1",
"preset": "ghost",
"blendMode": "screen",
"opacity": 0.5
}
pinepaper_remove_blend_preset
Remove blend preset and reset item to normal blending.
Input Schema:
{
"type": "object",
"properties": {
"itemId": { "type": "string" }
},
"required": ["itemId"]
}
pinepaper_transition_blend_mode
Smoothly transition an item’s blend mode using opacity cross-fade with mode snap at midpoint.
Input Schema:
{
"type": "object",
"properties": {
"itemId": { "type": "string" },
"targetMode": {
"type": "string",
"description": "Target blend mode (e.g., 'multiply', 'screen', 'overlay')"
},
"duration": {
"type": "number",
"description": "Transition duration in seconds",
"default": 0.5
},
"easing": {
"type": "string",
"enum": ["linear", "easeIn", "easeOut", "easeInOut", "bounce", "elastic"],
"default": "easeOut"
},
"targetOpacity": {
"type": "number",
"description": "Final opacity (defaults to current)",
"minimum": 0,
"maximum": 1
}
},
"required": ["itemId", "targetMode"]
}
pinepaper_add_interactive_blend
Add interactive blend mode cycling triggered by mouse events.
Input Schema:
{
"type": "object",
"properties": {
"itemId": { "type": "string" },
"event": {
"type": "string",
"enum": ["hover", "click"],
"description": "Trigger event type",
"default": "hover"
},
"modes": {
"type": "array",
"items": { "type": "string" },
"description": "Blend modes to cycle through",
"default": ["normal", "screen"]
},
"opacities": {
"type": "array",
"items": { "type": "number" },
"description": "Opacity for each mode",
"default": [1.0, 0.8]
}
},
"required": ["itemId"]
}
pinepaper_set_group_blend_mode
Set blend mode for all items in a group with optional cascading opacity.
Input Schema:
{
"type": "object",
"properties": {
"groupId": {
"type": "string",
"description": "Group ID or item ID of a Paper.js Group"
},
"mode": {
"type": "string",
"description": "Blend mode to apply to all children"
},
"opacity": {
"type": "number",
"description": "Group opacity",
"minimum": 0,
"maximum": 1
},
"cascadeOpacity": {
"type": "boolean",
"description": "Multiply child opacity by group opacity",
"default": false
}
},
"required": ["groupId", "mode"]
}
pinepaper_set_opacity_reaction
Configure automatic blend mode switching based on item opacity thresholds.
Input Schema:
{
"type": "object",
"properties": {
"itemId": { "type": "string" },
"thresholds": {
"type": "array",
"items": {
"type": "object",
"properties": {
"opacity": {
"type": "number",
"description": "Opacity threshold (blend mode activates when item opacity <= this value)"
},
"blendMode": {
"type": "string",
"description": "Blend mode to apply at this threshold"
}
},
"required": ["opacity", "blendMode"]
},
"description": "Opacity thresholds sorted from lowest to highest"
}
},
"required": ["itemId", "thresholds"]
}
Example:
{
"itemId": "item_1",
"thresholds": [
{ "opacity": 0.2, "blendMode": "screen" },
{ "opacity": 0.5, "blendMode": "multiply" }
]
}
When item_1’s opacity drops below 0.2, blend mode switches to “screen”. Between 0.2 and 0.5, it uses “multiply”.
Image Filter Tools
GPU-accelerated image filters for raster items. Filters run on the GPU via WebGL shaders for real-time performance.
pinepaper_apply_image_filter
Apply a single GPU filter to a raster item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID of the raster item"
},
"filterName": {
"type": "string",
"enum": [
"grayscale", "sepia", "brightness", "contrast", "saturation",
"invert", "posterize", "hsl", "colorTint", "vignette",
"edgeDetect", "blur"
],
"description": "Filter to apply"
},
"params": {
"type": "object",
"description": "Filter-specific parameters (e.g., { \"amount\": 1.5 } for brightness, { \"hue\": 30, \"saturation\": 0.5, \"lightness\": 0.1 } for hsl)"
}
},
"required": ["itemId", "filterName"]
}
Output:
{
"success": true
}
pinepaper_apply_filter_chain
Apply multiple filters in a single GPU pass for efficient composited effects.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID of the raster item"
},
"filters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"enum": [
"grayscale", "sepia", "brightness", "contrast", "saturation",
"invert", "posterize", "hsl", "colorTint", "vignette",
"edgeDetect", "blur"
],
"description": "Filter name"
},
"params": {
"type": "object",
"description": "Filter-specific parameters"
}
},
"required": ["name"]
},
"description": "Ordered list of filters to apply in sequence"
}
},
"required": ["itemId", "filters"]
}
Output:
{
"success": true
}
Lasso Tools
Freehand lasso selection for extracting regions from raster images on the canvas.
pinepaper_lasso_activate
Activate lasso mode on an image, enabling freehand selection drawing.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID of the raster item to select from"
}
},
"required": ["itemId"]
}
Output:
{
"success": true,
"message": "Lasso mode activated"
}
pinepaper_lasso_apply
Apply the current lasso selection to extract the selected region as a new cutout item.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"cutoutId": "item_5"
}
Cutout Style Tools
Apply visual style presets to image cutouts for creative effects.
pinepaper_apply_cutout_style
Apply a visual style preset to a cutout item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID of the cutout item"
},
"preset": {
"type": "string",
"enum": [
"papercut", "postcard", "sticker", "poster",
"monochromeCut", "edgeSketch", "warmGlow", "coolTone"
],
"description": "Style preset to apply"
},
"options": {
"type": "object",
"description": "Optional preset-specific overrides (e.g., { \"borderWidth\": 4, \"shadowColor\": \"#000\" })"
}
},
"required": ["itemId", "preset"]
}
Output:
{
"success": true
}
pinepaper_get_cutout_styles
List all available cutout style presets with their descriptions.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"presets": [
{ "name": "papercut", "displayName": "Paper Cut", "description": "Rough-edge paper cutout with drop shadow" },
{ "name": "postcard", "displayName": "Postcard", "description": "Rounded corners with white border and stamp texture" },
{ "name": "sticker", "displayName": "Sticker", "description": "Thick white outline with slight tilt and shadow" },
{ "name": "poster", "displayName": "Poster", "description": "High-contrast posterized colors with halftone dots" },
{ "name": "monochromeCut", "displayName": "Monochrome Cut", "description": "Grayscale cutout with sharp edges" },
{ "name": "edgeSketch", "displayName": "Edge Sketch", "description": "Pencil-sketch outline extracted from edges" },
{ "name": "warmGlow", "displayName": "Warm Glow", "description": "Warm color tint with soft vignette" },
{ "name": "coolTone", "displayName": "Cool Tone", "description": "Cool blue-tinted desaturated look" }
]
}
View Tools
Control canvas zoom, pan, and viewport fitting.
pinepaper_zoom
Zoom the canvas in or out.
Input Schema:
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["in", "out", "reset", "set"],
"description": "Zoom action"
},
"level": {
"type": "number",
"description": "Zoom level (only for action='set'). 1.0 = 100%"
}
},
"required": ["action"]
}
Output:
{
"success": true,
"zoomLevel": 1.5
}
pinepaper_pan
Pan the canvas view.
Input Schema:
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["by", "to"],
"description": "'by' pans by offset, 'to' pans to absolute coordinates"
},
"x": { "type": "number", "description": "X offset or coordinate" },
"y": { "type": "number", "description": "Y offset or coordinate" }
},
"required": ["action", "x", "y"]
}
Output:
{
"success": true
}
pinepaper_fit_view
Fit canvas content into the viewport.
Input Schema:
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["content", "canvas"],
"description": "'content' fits all items, 'canvas' fits the canvas bounds"
},
"padding": {
"type": "number",
"description": "Optional padding in pixels around the content"
}
}
}
Output:
{
"success": true,
"zoomLevel": 0.85
}
pinepaper_get_view_state
Get current view state (zoom level, scroll position).
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"zoomLevel": 1.2,
"center": { "x": 400, "y": 300 },
"bounds": { "x": 0, "y": 0, "width": 800, "height": 600 }
}
Selection Tools
Manage item selection programmatically.
pinepaper_select
Select items by ID, name, or type.
Input Schema:
{
"type": "object",
"properties": {
"itemIds": {
"type": "array",
"items": { "type": "string" },
"description": "Array of item IDs to select"
},
"mode": {
"type": "string",
"enum": ["replace", "add", "remove"],
"default": "replace",
"description": "'replace' clears existing selection, 'add' adds to it, 'remove' removes from it"
}
},
"required": ["itemIds"]
}
Output:
{
"success": true,
"selectedCount": 3
}
pinepaper_select_all
Select all items on the canvas.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"selectedCount": 12
}
pinepaper_deselect_all
Clear all selection.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true
}
pinepaper_get_selection
Get currently selected items.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"items": [
{ "id": "item_1", "type": "text", "name": "Title" },
{ "id": "item_3", "type": "circle", "name": null }
]
}
pinepaper_delete_selected
Delete all currently selected items.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"deletedCount": 2
}
Transform Tools
Transform items: nudge, flip, and reorder in stacking order.
pinepaper_nudge
Move selected items by a pixel offset.
Input Schema:
{
"type": "object",
"properties": {
"dx": { "type": "number", "description": "Horizontal offset in pixels" },
"dy": { "type": "number", "description": "Vertical offset in pixels" }
},
"required": ["dx", "dy"]
}
Output:
{
"success": true
}
pinepaper_flip
Flip selected items horizontally or vertically.
Input Schema:
{
"type": "object",
"properties": {
"direction": {
"type": "string",
"enum": ["horizontal", "vertical"],
"description": "Flip direction"
}
},
"required": ["direction"]
}
Output:
{
"success": true
}
pinepaper_reorder
Change stacking order of selected items.
Input Schema:
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["bringToFront", "sendToBack", "moveUp", "moveDown"],
"description": "Stacking order action"
}
},
"required": ["action"]
}
Output:
{
"success": true
}
Background Tools
Control canvas background color, pattern, or procedural generator.
pinepaper_set_background
Set the canvas background.
Input Schema:
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["color", "pattern", "generator"],
"description": "Background mode"
},
"color": {
"type": "string",
"description": "Background color (hex). Used when mode='color'"
},
"pattern": {
"type": "string",
"description": "Pattern type name. Used when mode='pattern'"
},
"generator": {
"type": "string",
"description": "Generator name. Used when mode='generator'"
},
"generatorParams": {
"type": "object",
"description": "Generator parameters. Used when mode='generator'"
}
},
"required": ["mode"]
}
Output:
{
"success": true,
"mode": "color",
"value": "#1a1a2e"
}
pinepaper_clear_background
Clear the canvas background to transparent.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true
}
pinepaper_get_background
Get current background state.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"mode": "generator",
"generator": "starfield",
"params": { "starCount": 200, "twinkle": true }
}
History Tools
Manage undo/redo and edit history.
pinepaper_undo
Undo the last action.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"canUndo": true,
"canRedo": true
}
pinepaper_redo
Redo the last undone action.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"canUndo": true,
"canRedo": false
}
pinepaper_get_history_state
Get current history state.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"canUndo": true,
"canRedo": false,
"historyLength": 15,
"currentIndex": 14
}
pinepaper_clear_canvas
Clear the entire canvas (all items, drawings, and background).
Input Schema:
{
"type": "object",
"properties": {
"keepBackground": {
"type": "boolean",
"default": false,
"description": "If true, preserves the background setting"
}
}
}
Output:
{
"success": true
}
Advanced Query Tools
Query items by name, type, position, or custom matchers.
pinepaper_query_items
Query items using flexible matchers.
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Filter by item name (exact or partial match)"
},
"type": {
"type": "string",
"description": "Filter by item type (e.g., 'text', 'circle', 'Raster')"
},
"withinBounds": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" },
"width": { "type": "number" },
"height": { "type": "number" }
},
"description": "Filter items within a bounding rectangle"
},
"hasAnimation": {
"type": "boolean",
"description": "Filter by whether item is animated"
},
"limit": {
"type": "number",
"description": "Maximum number of results"
}
}
}
Output:
{
"success": true,
"items": [
{
"id": "item_1",
"type": "text",
"name": "Title",
"position": { "x": 400, "y": 100 },
"bounds": { "x": 320, "y": 80, "width": 160, "height": 40 }
}
],
"count": 1
}
pinepaper_get_item_by_id
Get detailed information about a specific item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Item registry ID"
}
},
"required": ["itemId"]
}
Output:
{
"success": true,
"item": {
"id": "item_5",
"type": "text",
"name": "Heading",
"position": { "x": 400, "y": 200 },
"bounds": { "x": 300, "y": 180, "width": 200, "height": 40 },
"rotation": 0,
"opacity": 1,
"visible": true,
"hasAnimation": true,
"hasRelations": false,
"isMasked": false
}
}
pinepaper_hit_test
Find items at a specific canvas point.
Input Schema:
{
"type": "object",
"properties": {
"x": { "type": "number", "description": "X coordinate" },
"y": { "type": "number", "description": "Y coordinate" },
"all": {
"type": "boolean",
"default": false,
"description": "If true, return all items at point (not just topmost)"
},
"tolerance": {
"type": "number",
"default": 5,
"description": "Hit test tolerance in pixels"
}
},
"required": ["x", "y"]
}
Output:
{
"success": true,
"items": [
{ "id": "item_3", "type": "circle" }
]
}
pinepaper_is_empty
Check if the canvas has any content.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"empty": false,
"itemCount": 8
}
Precomp Tools
Create and manage nested compositions (precomps) with independent local timelines.
pinepaper_create_precomp
Group items into a precomp with an independent timeline.
Input Schema:
{
"type": "object",
"properties": {
"itemIds": {
"type": "array",
"items": { "type": "string" },
"description": "Array of item IDs to include in the precomp"
},
"name": {
"type": "string",
"description": "Optional name for the precomp"
},
"loop": {
"type": "boolean",
"default": true,
"description": "Whether the precomp timeline loops"
},
"duration": {
"type": "number",
"description": "Precomp timeline duration in seconds"
}
},
"required": ["itemIds"]
}
Output:
{
"success": true,
"precompId": "item_20"
}
pinepaper_add_to_precomp
Add an item to an existing precomp.
Input Schema:
{
"type": "object",
"properties": {
"precompId": { "type": "string", "description": "Precomp item ID" },
"itemId": { "type": "string", "description": "Item to add" }
},
"required": ["precompId", "itemId"]
}
Output:
{
"success": true
}
pinepaper_remove_from_precomp
Remove an item from a precomp.
Input Schema:
{
"type": "object",
"properties": {
"precompId": { "type": "string", "description": "Precomp item ID" },
"itemId": { "type": "string", "description": "Item to remove" }
},
"required": ["precompId", "itemId"]
}
Output:
{
"success": true
}
Playback Tools
Control keyframe timeline playback.
pinepaper_play_timeline
Start or resume keyframe timeline playback.
Input Schema:
{
"type": "object",
"properties": {
"duration": {
"type": "number",
"description": "Timeline duration in seconds. If omitted, uses existing duration."
},
"loop": {
"type": "boolean",
"default": false,
"description": "Whether to loop playback"
}
}
}
Output:
{
"success": true,
"playing": true
}
pinepaper_stop_timeline
Stop timeline playback and reset to start.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"playing": false
}
pinepaper_pause_timeline
Pause timeline playback at current position.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"playing": false
}
pinepaper_seek_timeline
Seek to a specific time position.
Input Schema:
{
"type": "object",
"properties": {
"time": {
"type": "number",
"description": "Time position in seconds (0 to duration)"
}
},
"required": ["time"]
}
Output:
{
"success": true,
"currentTime": 1.5
}
3D Projection Tools
Create and manipulate 3D objects on the 2D canvas using PinePaper’s standalone 3D projection library. Objects are rendered as depth-sorted, lit polygons projected through configurable camera and projection systems.
Architecture: The 3D library (js/3d/) is zero-dependency and outputs renderer-agnostic polygon descriptors. GPU acceleration (WebGPU/WebGL2) is automatic for scenes above 150 faces.
pinepaper_create_3d_object
Create a 3D primitive projected onto the 2D canvas with simulated lighting and depth-sorted face rendering.
Input Schema:
{
"type": "object",
"properties": {
"objectType": {
"type": "string",
"enum": ["cube", "sphere", "cylinder", "torus", "cone"],
"description": "Type of 3D primitive to create"
},
"x": {
"type": "number",
"description": "World X position (default: 0)"
},
"y": {
"type": "number",
"description": "World Y position (default: 0)"
},
"z": {
"type": "number",
"description": "World Z position (default: 0)"
},
"color": {
"type": "string",
"description": "Face color as hex string (default: '#cccccc')"
},
"size": {
"type": "number",
"description": "Cube size (cube only, default: 1)"
},
"radius": {
"type": "number",
"description": "Radius (sphere, cylinder, torus, cone; default: 0.5)"
},
"height": {
"type": "number",
"description": "Height (cylinder, cone; default: 1)"
},
"tube": {
"type": "number",
"description": "Tube radius (torus only; default: 0.2)"
},
"rotationX": {
"type": "number",
"description": "X rotation in degrees (default: 0)"
},
"rotationY": {
"type": "number",
"description": "Y rotation in degrees (default: 0)"
},
"rotationZ": {
"type": "number",
"description": "Z rotation in degrees (default: 0)"
},
"scale": {
"type": "number",
"description": "Uniform scale factor (default: 1)"
},
"animationType": {
"type": "string",
"enum": ["rotate"],
"description": "Animation type (optional)"
},
"animationSpeed": {
"type": "number",
"description": "Rotation speed multiplier (default: 1)"
}
},
"required": ["objectType"]
}
Output:
{
"success": true,
"itemId": "item_42",
"objectType": "cube",
"faces": 6,
"message": "Created 3D cube with 6 faces"
}
Face Counts by Primitive:
| Primitive | Default Faces | Key Parameters |
|---|---|---|
cube |
6 quads | size |
sphere |
~96 triangles | radius, widthSegments (12), heightSegments (8) |
cylinder |
~34 | radius, height, segments (16) |
torus |
~192 | radius, tube, radialSegments (12), tubularSegments (16) |
cone |
~17 | radius, height, segments (16) |
pinepaper_create_glossy_sphere
Create a glossy 2D sphere effect using layered radial gradients with shadow. This is a purely 2D effect (no 3D projection) that simulates a shiny sphere appearance.
Input Schema:
{
"type": "object",
"properties": {
"x": {
"type": "number",
"description": "X position on canvas (default: center)"
},
"y": {
"type": "number",
"description": "Y position on canvas (default: center)"
},
"radius": {
"type": "number",
"description": "Sphere radius in pixels (default: 50)"
},
"color": {
"type": "string",
"description": "Base sphere color as hex (default: '#4a9eff')"
},
"lightDirection": {
"type": "string",
"enum": ["top-left", "top-right", "top", "left", "right", "bottom-left", "bottom-right"],
"description": "Direction of the light source (default: 'top-left')"
},
"glossiness": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Glossiness level from 0 to 1 (default: 0.7)"
},
"castShadow": {
"type": "boolean",
"description": "Whether to cast a shadow (default: true)"
},
"shadowBlur": {
"type": "number",
"description": "Shadow blur amount in pixels (default: 15)"
}
}
}
Output:
{
"success": true,
"itemId": "item_43",
"message": "Created glossy sphere with radius 60"
}
pinepaper_set_3d_projection
Set the 3D scene projection type. Affects how 3D objects are rendered on the 2D canvas.
Input Schema:
{
"type": "object",
"properties": {
"projectionType": {
"type": "string",
"enum": ["perspective", "orthographic", "isometric", "cabinet", "cavalier"],
"description": "Projection type"
},
"fov": {
"type": "number",
"description": "Field of view in degrees (perspective only; default: 60)"
},
"aspect": {
"type": "number",
"description": "Aspect ratio (perspective only; default: 1)"
},
"near": {
"type": "number",
"description": "Near clipping plane (perspective/orthographic; default: 0.1 or -500)"
},
"far": {
"type": "number",
"description": "Far clipping plane (perspective/orthographic; default: 1000 or 500)"
},
"width": {
"type": "number",
"description": "View width (orthographic only; default: 400)"
},
"height": {
"type": "number",
"description": "View height (orthographic only; default: 400)"
},
"scale": {
"type": "number",
"description": "Scale factor (isometric only; default: 1)"
},
"angle": {
"type": "number",
"description": "Shear angle in degrees (cabinet/cavalier; default: 45)"
},
"depthScale": {
"type": "number",
"description": "Depth scale factor (cabinet only; default: 0.5)"
}
},
"required": ["projectionType"]
}
Output:
{
"success": true,
"projectionType": "isometric",
"message": "Set 3D projection to isometric"
}
Projection Comparison:
| Projection | Depth Reduction | Parallel Lines | Use Case |
|---|---|---|---|
perspective |
Yes (1/z) | No | Realistic visualization |
orthographic |
No | Yes | Technical drawings |
isometric |
No | Yes | Games, infographics |
cabinet |
Half (0.5) | Yes | Technical illustration |
cavalier |
No | Yes | Simple 3D diagrams |
pinepaper_set_3d_camera
Set the 3D camera position and look-at target. Defines the viewpoint from which 3D objects are rendered.
Input Schema:
{
"type": "object",
"properties": {
"positionX": {
"type": "number",
"description": "Camera X position in world space (default: 0)"
},
"positionY": {
"type": "number",
"description": "Camera Y position in world space (default: 0)"
},
"positionZ": {
"type": "number",
"description": "Camera Z position in world space (default: 5)"
},
"targetX": {
"type": "number",
"description": "Look-at target X (default: 0)"
},
"targetY": {
"type": "number",
"description": "Look-at target Y (default: 0)"
},
"targetZ": {
"type": "number",
"description": "Look-at target Z (default: 0)"
},
"upX": {
"type": "number",
"description": "Up vector X (default: 0)"
},
"upY": {
"type": "number",
"description": "Up vector Y (default: 1)"
},
"upZ": {
"type": "number",
"description": "Up vector Z (default: 0)"
}
}
}
Output:
{
"success": true,
"position": { "x": 3, "y": 2, "z": 5 },
"target": { "x": 0, "y": 0, "z": 0 },
"message": "Camera positioned at (3, 2, 5) looking at origin"
}
28. Deformation Tools
Apply vertex-level geometric deformation presets to items. Deformation manipulates actual path geometry per frame, creating effects like eye blinks, jelly wobble, and traveling waves.
pinepaper_apply_deform
Apply a looping deformation to an item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Target item registry ID"
},
"preset": {
"type": "string",
"enum": ["fold", "squeeze", "squash", "pinch", "bulge", "twist", "ripple", "wave", "breathe", "melt", "shear", "inflate", "wobble"],
"description": "Deformation preset name"
},
"frequency": {
"type": "number",
"description": "Oscillation speed in cycles/sec (default: 1)",
"minimum": 0.1,
"maximum": 10
},
"amplitude": {
"type": "number",
"description": "Deformation strength 0-1 (default: 1)",
"minimum": 0,
"maximum": 1
},
"phase": {
"type": "string",
"enum": ["sin", "blink", "linear", "pingpong", "once", "elastic", "heartbeat", "stepped"],
"description": "Phase driver controlling when deformation cycles (default: sin)"
},
"axis": {
"type": "string",
"enum": ["horizontal", "vertical"],
"description": "Axis for fold preset (default: horizontal)"
},
"waves": {
"type": "number",
"description": "Wave count for ripple/wave presets (default: 3)"
},
"speed": {
"type": "number",
"description": "Travel speed for wave preset (default: 1)"
},
"maxDisplacement": {
"type": "number",
"description": "Max pixel displacement for ripple/wave/wobble (default: 10)"
},
"turns": {
"type": "number",
"description": "Rotation amount for twist preset (default: 0.5)"
}
},
"required": ["itemId", "preset"]
}
Output:
{
"success": true,
"message": "Applied 'fold' deformation to item_1"
}
pinepaper_remove_deform
Remove deformation from an item, restoring original geometry.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Target item registry ID"
}
},
"required": ["itemId"]
}
pinepaper_trigger_deform
Apply a one-shot deformation that plays once and auto-removes.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Target item registry ID"
},
"preset": {
"type": "string",
"enum": ["fold", "squeeze", "squash", "pinch", "bulge", "twist", "ripple", "wave", "breathe", "melt", "shear", "inflate", "wobble"],
"description": "Deformation preset name"
},
"frequency": {
"type": "number",
"description": "Playback speed (default: 1)"
},
"amplitude": {
"type": "number",
"description": "Deformation strength 0-1 (default: 1)"
}
},
"required": ["itemId", "preset"]
}
29. Sprite Sheet Tools
pinepaper_generate_sprite_sheet
Generate a sprite sheet from a rigged skeleton’s poses. Captures each pose as a frame, packs into a texture atlas, and returns TexturePacker-compatible metadata.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to generate sprite sheet from"
},
"mode": {
"type": "string",
"enum": ["poses", "transition", "cycle", "baked"],
"description": "Generation mode: explicit poses, interpolated transition, multi-pose cycle, or baked animation"
},
"poses": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"poseId": { "type": "string" }
}
},
"description": "Explicit pose list (for mode=poses)"
},
"transition": {
"type": "object",
"properties": {
"poseIdA": { "type": "string" },
"poseIdB": { "type": "string" },
"frameCount": { "type": "number", "default": 8 },
"name": { "type": "string", "default": "transition" }
},
"description": "Transition config (for mode=transition)"
},
"cycle": {
"type": "object",
"properties": {
"poseIds": { "type": "array", "items": { "type": "string" } },
"framesPerTransition": { "type": "number", "default": 4 },
"name": { "type": "string", "default": "cycle" },
"loop": { "type": "boolean", "default": true }
},
"description": "Pose cycle config (for mode=cycle)"
},
"bakedAnimation": {
"type": "object",
"properties": {
"duration": { "type": "number", "default": 2 },
"fps": { "type": "number", "default": 12 },
"name": { "type": "string", "default": "animation" }
},
"description": "Baked animation config (for mode=baked)"
},
"padding": { "type": "number", "default": 1, "description": "Padding between frames in atlas" },
"framePadding": { "type": "number", "default": 4, "description": "Padding around character in each frame" },
"allowRotation": { "type": "boolean", "default": false, "description": "Allow 90-deg rotation for tighter packing" },
"maxAtlasSize": { "type": "number", "default": 4096, "description": "Maximum atlas dimension" },
"fps": { "type": "number", "default": 12, "description": "Default animation FPS" }
},
"required": ["skeletonId", "mode"]
}
Output:
{
"success": true,
"spriteSheetId": "spritesheet_1",
"atlasSize": { "w": 512, "h": 256 },
"frameCount": 12,
"animations": ["walk"],
"metadata": { "frames": {}, "animations": {}, "meta": {} }
}
pinepaper_play_sprite_sheet
Play a sprite sheet animation on the canvas using a Paper.js Raster item.
Input Schema:
{
"type": "object",
"properties": {
"spriteSheetId": { "type": "string", "description": "ID of generated sprite sheet" },
"x": { "type": "number", "description": "Canvas X position" },
"y": { "type": "number", "description": "Canvas Y position" },
"animation": { "type": "string", "description": "Animation name to play" },
"fps": { "type": "number", "default": 12, "description": "Playback FPS" },
"loop": { "type": "boolean", "default": true },
"scale": { "type": "number", "default": 1, "description": "Render scale" },
"autoPlay": { "type": "boolean", "default": true }
},
"required": ["spriteSheetId"]
}
Output:
{
"success": true,
"playerId": "player_1",
"animation": "walk",
"playing": true
}
pinepaper_export_sprite_sheet
Export a sprite sheet as downloadable atlas image + metadata JSON files.
Input Schema:
{
"type": "object",
"properties": {
"spriteSheetId": { "type": "string", "description": "ID of generated sprite sheet" },
"format": { "type": "string", "enum": ["png", "webp"], "default": "png" },
"includeMetadata": { "type": "boolean", "default": true, "description": "Include TexturePacker JSON file" },
"download": { "type": "boolean", "default": true, "description": "Trigger browser download" }
},
"required": ["spriteSheetId"]
}
Output:
{
"success": true,
"atlasDataUrl": "data:image/png;base64,...",
"format": "png",
"metadataIncluded": true
}
30. Shape Key Tools
Shape keys capture per-item visual state (size, opacity, color, path segments) as named blend shapes. Used for facial animation (blink, smile, frown) with weighted interpolation between rest pose and target state.
pinepaper_save_shape_key
Capture the current visual state of all attached items as a named shape key (blend shape).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to save shape key for"
},
"name": {
"type": "string",
"description": "Shape key name (e.g., 'blink', 'smile', 'openMouth')"
}
},
"required": ["skeletonId", "name"]
}
Output:
{
"success": true,
"shapeKeyId": "sk_blink_1"
}
pinepaper_load_shape_key
Apply a saved shape key with weighted interpolation (0=rest pose, 1=full shape key).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to apply shape key to"
},
"shapeKeyId": {
"type": "string",
"description": "Shape key ID to load"
},
"weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 1,
"description": "Blend weight (0=rest, 1=full shape key)"
}
},
"required": ["skeletonId", "shapeKeyId"]
}
Output:
{
"success": true,
"shapeKeyId": "sk_blink_1",
"weight": 0.5
}
pinepaper_remove_shape_key
Delete a saved shape key.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton owning the shape key"
},
"shapeKeyId": {
"type": "string",
"description": "Shape key ID to remove"
}
},
"required": ["skeletonId", "shapeKeyId"]
}
Output:
{
"success": true
}
pinepaper_list_shape_keys
List all saved shape keys for a skeleton.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to list shape keys for"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"shapeKeys": [
{ "id": "sk_blink_1", "name": "blink" },
{ "id": "sk_smile_1", "name": "smile" },
{ "id": "sk_openMouth_1", "name": "openMouth" }
]
}
pinepaper_add_shape_key_keyframe
Add a keyframe for shape key animation on the timeline. Multiple shape keys can be active at the same time with additive blending.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to animate"
},
"time": {
"type": "number",
"description": "Keyframe time in seconds"
},
"keys": {
"type": "object",
"additionalProperties": { "type": "number" },
"description": "Shape key ID to weight map (e.g., { 'sk_blink_1': 1, 'sk_smile_1': 0.5 })"
},
"easing": {
"type": "string",
"default": "linear",
"description": "Easing function for this keyframe"
}
},
"required": ["skeletonId", "time", "keys"]
}
Output:
{
"success": true
}
pinepaper_remove_shape_key_keyframes
Remove all shape key keyframes from a skeleton’s timeline.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to clear keyframes for"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true
}
31. Procedural Animation Tools
One-call procedural animation helpers that create pose layers for common effects. These run automatically each frame using the skeleton’s saved poses.
pinepaper_auto_breath
Apply automatic breathing animation to a skeleton. Subtly rotates specified bones with a sine wave.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to animate"
},
"bones": {
"type": "array",
"items": { "type": "string" },
"description": "Bone names to affect (e.g., ['spine', 'chest'])"
},
"frequency": {
"type": "number",
"description": "Breathing cycles per second"
},
"amplitude": {
"type": "number",
"default": 0.03,
"description": "Max rotation delta in radians"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"layerId": "layer_breath_1"
}
pinepaper_auto_idle
Apply automatic idle sway animation to a skeleton.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to animate"
},
"bones": {
"type": "array",
"items": { "type": "string" },
"description": "Bone names to affect"
},
"frequency": {
"type": "number",
"description": "Oscillation frequency"
},
"intensity": {
"type": "number",
"default": 1,
"minimum": 0,
"maximum": 1,
"description": "Motion intensity (0-1)"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"layerId": "layer_idle_1"
}
pinepaper_auto_walk
Apply automatic walk cycle animation using pose interpolation. Requires saved walk poses in the skeleton’s pose library.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to animate"
},
"bones": {
"type": "array",
"items": { "type": "string" },
"description": "Bone names to affect"
},
"frequency": {
"type": "number",
"description": "Walk cycle frequency"
},
"cycleDistance": {
"type": "number",
"description": "Pixels traveled per walk cycle"
},
"poseIdMap": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "Pose name to ID map from loadPoseLibrary (e.g., { 'walk_contact_L': 'pose_1' })"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"layerId": "layer_walk_1",
"callbackId": "cb_walk_1"
}
pinepaper_auto_jump
Apply a physics-based jump with parabolic root arc, impact compression, and auto-cleanup.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to animate"
},
"height": {
"type": "number",
"default": 100,
"description": "Jump apex height in pixels"
},
"duration": {
"type": "number",
"default": 0.6,
"description": "Total jump duration in seconds"
},
"poseIdMap": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "Pose name to ID map for jump/land poses"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"layerId": "layer_jump_1",
"callbackId": "cb_jump_1"
}
32. Bone Physics Tools
Verlet physics simulation on bones with spring motors that blend between animation targets and physics simulation. Enables ragdoll, hit reactions, jiggle/secondary motion (hair, tails, cloth), and colliders.
pinepaper_enable_physics
Enable bone-level Verlet physics on a skeleton. Physics particles are created for each bone and spring motors pull them toward FK/IK animation targets.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to enable physics on"
},
"fromBone": {
"type": "string",
"description": "Start physics from this bone downward (null = all bones)"
},
"blendWeight": {
"type": "number",
"default": 0.3,
"minimum": 0,
"maximum": 1,
"description": "Default blend weight (0=pure animation, 1=full physics)"
},
"gravity": {
"type": "object",
"properties": {
"x": { "type": "number", "default": 0 },
"y": { "type": "number", "default": 980 }
},
"description": "Gravity vector in pixels/sec²"
},
"stiffness": {
"type": "number",
"default": 200,
"description": "Spring motor strength pulling toward animation targets"
},
"damping": {
"type": "number",
"default": 15,
"description": "Velocity damping factor"
},
"iterations": {
"type": "number",
"default": 3,
"description": "Constraint solver iterations per step"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"skeletonId": "skeleton_1",
"boneCount": 15
}
pinepaper_disable_physics
Disable Verlet physics on a skeleton, returning to pure animation control.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to disable physics on"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true
}
pinepaper_set_physics_blend_weight
Set the blend weight between animation and physics for specific bones or all bones.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to configure"
},
"boneId": {
"type": "string",
"description": "Bone ID, or 'all' for every bone"
},
"weight": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Blend weight (0=animation, 1=full physics)"
}
},
"required": ["skeletonId", "boneId", "weight"]
}
Output:
{
"success": true
}
pinepaper_apply_physics_impulse
Apply an instantaneous force impulse to a bone (for hit reactions, explosions, etc.).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the bone"
},
"boneId": {
"type": "string",
"description": "Bone to receive the impulse"
},
"impulse": {
"type": "object",
"properties": {
"x": { "type": "number", "description": "Horizontal force in pixels/sec" },
"y": { "type": "number", "description": "Vertical force in pixels/sec" }
},
"required": ["x", "y"],
"description": "Force vector"
}
},
"required": ["skeletonId", "boneId", "impulse"]
}
Output:
{
"success": true
}
pinepaper_set_jiggle
Configure per-bone jiggle for secondary motion (hair, tails, accessories). Jiggle creates independent spring-damper oscillation.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the bone"
},
"boneId": {
"type": "string",
"description": "Bone to add jiggle to"
},
"stiffness": {
"type": "number",
"default": 5,
"description": "Spring stiffness"
},
"damping": {
"type": "number",
"default": 0.8,
"description": "Damping factor (0-1)"
},
"gravity": {
"type": "number",
"default": 980,
"description": "Gravity influence in pixels/sec²"
}
},
"required": ["skeletonId", "boneId"]
}
Output:
{
"success": true
}
pinepaper_add_physics_collider
Add a collision object for bone physics (ground plane, circle, or rect obstacle).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to add collider for"
},
"collider": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["ground", "circle", "rect"],
"description": "Collider shape type"
},
"y": { "type": "number", "description": "Y position (for ground plane)" },
"x": { "type": "number", "description": "X position (for circle/rect)" },
"radius": { "type": "number", "description": "Radius (for circle)" },
"width": { "type": "number", "description": "Width (for rect)" },
"height": { "type": "number", "description": "Height (for rect)" }
},
"required": ["type"]
}
},
"required": ["skeletonId", "collider"]
}
Output:
{
"success": true,
"colliderIndex": 0
}
33. Physics World Tools
Rigid body physics for canvas items using Planck.js (Box2D). Simulates gravity, collision, friction, and restitution. Static bodies are immovable, dynamic bodies respond to forces, kinematic bodies follow animation and push dynamic bodies.
pinepaper_init_physics_world
Initialize the physics world. Must be called before adding bodies.
Input Schema:
{
"type": "object",
"properties": {
"gravity": {
"type": "object",
"properties": {
"x": { "type": "number", "default": 0 },
"y": { "type": "number", "default": 980 }
},
"description": "Gravity vector in pixels/sec²"
}
}
}
Output:
{
"success": true
}
pinepaper_add_physics_body
Add a physics body to a canvas item. The item will be simulated by the physics engine.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Canvas item registry ID"
},
"type": {
"type": "string",
"enum": ["static", "dynamic", "kinematic"],
"default": "dynamic",
"description": "Body type: static (immovable), dynamic (full physics), kinematic (animation-driven, pushes dynamic)"
},
"mass": { "type": "number", "default": 1, "description": "Body mass" },
"friction": { "type": "number", "default": 0.3, "description": "Surface friction (0-1)" },
"restitution": { "type": "number", "default": 0.3, "description": "Bounciness (0-1)" },
"density": { "type": "number", "default": 1, "description": "Body density" },
"fixedRotation": { "type": "boolean", "default": false, "description": "Prevent rotation" },
"shape": {
"type": "string",
"enum": ["auto", "circle", "rect"],
"default": "auto",
"description": "Collision shape (auto detects from item geometry)"
}
},
"required": ["itemId"]
}
Output:
{
"success": true,
"itemId": "item_1",
"type": "dynamic"
}
pinepaper_remove_physics_body
Remove a physics body from a canvas item.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Canvas item registry ID"
}
},
"required": ["itemId"]
}
Output:
{
"success": true
}
pinepaper_create_physics_ground
Create a static ground plane for physics objects to land on.
Input Schema:
{
"type": "object",
"properties": {
"y": {
"type": "number",
"description": "Y position of the ground plane in pixels"
},
"width": {
"type": "number",
"default": 2000,
"description": "Ground plane width in pixels"
}
},
"required": ["y"]
}
Output:
{
"success": true,
"groundId": "ground_1"
}
pinepaper_create_physics_joint
Create a joint connecting two physics bodies.
Input Schema:
{
"type": "object",
"properties": {
"itemIdA": {
"type": "string",
"description": "First body's item ID"
},
"itemIdB": {
"type": "string",
"description": "Second body's item ID"
},
"type": {
"type": "string",
"enum": ["revolute", "distance", "weld", "prismatic"],
"default": "revolute",
"description": "Joint type"
},
"anchor": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"description": "Anchor point in canvas pixels"
},
"enableMotor": { "type": "boolean", "default": false },
"motorSpeed": { "type": "number", "default": 0 },
"maxMotorTorque": { "type": "number", "default": 100 },
"lowerAngle": { "type": "number", "description": "Lower angle limit in radians" },
"upperAngle": { "type": "number", "description": "Upper angle limit in radians" }
},
"required": ["itemIdA", "itemIdB"]
}
Output:
{
"success": true,
"jointType": "revolute"
}
pinepaper_apply_physics_force
Apply a continuous force to a physics body (persists until removed or countered).
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Canvas item registry ID"
},
"force": {
"type": "object",
"properties": {
"x": { "type": "number", "description": "Horizontal force in pixels/sec²" },
"y": { "type": "number", "description": "Vertical force in pixels/sec²" }
},
"required": ["x", "y"]
}
},
"required": ["itemId", "force"]
}
Output:
{
"success": true
}
pinepaper_get_physics_body_state
Get the current physics state of an item (position, velocity, angle).
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Canvas item registry ID"
}
},
"required": ["itemId"]
}
Output:
{
"success": true,
"x": 400,
"y": 300,
"angle": 0.15,
"vx": 50,
"vy": -120,
"type": "dynamic"
}
34. Character Controller Tools
Composable movement functions for rigged characters. Input-agnostic — can be triggered by AI, timeline, physics, or keyboard. Test mode enables arrow key control for interactive verification.
pinepaper_start_character_test
Start keyboard-driven character test mode. Arrow keys control walk, up = jump, down = crouch.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to control"
},
"walkSpeed": {
"type": "number",
"default": 120,
"description": "Walk speed in pixels/second"
},
"jumpHeight": {
"type": "number",
"default": 100,
"description": "Jump height in pixels"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"skeletonId": "skeleton_1",
"controls": "Arrow keys: Left/Right=walk, Up=jump, Down=crouch"
}
pinepaper_stop_character_test
Stop keyboard-driven character test mode.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true
}
pinepaper_move_character_left
Move a character to the left using walk animation.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to move"
},
"speed": {
"type": "number",
"default": 120,
"description": "Movement speed in pixels/second"
},
"delta": {
"type": "number",
"default": 0.0167,
"description": "Time step in seconds (default: 1/60)"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"state": "walking",
"facingRight": false
}
pinepaper_move_character_right
Move a character to the right using walk animation.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to move"
},
"speed": {
"type": "number",
"default": 120,
"description": "Movement speed in pixels/second"
},
"delta": {
"type": "number",
"default": 0.0167,
"description": "Time step in seconds (default: 1/60)"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"state": "walking",
"facingRight": true
}
pinepaper_character_jump
Make a character jump with parabolic arc and landing squash.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to jump"
},
"height": {
"type": "number",
"default": 100,
"description": "Jump apex height in pixels"
},
"duration": {
"type": "number",
"default": 0.6,
"description": "Total jump duration in seconds"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"state": "jumping"
}
pinepaper_character_crouch
Make a character crouch.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to crouch"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"state": "crouching"
}
pinepaper_character_idle
Return a character to idle pose.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to idle"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"state": "idle"
}
35. Scene Sequencer Tools
Timeline-based multi-character action choreography. Schedule composable actions (walk, jump, crouch, custom) on a timeline for cinematic sequences. Supports LLM/AI script generation via buildScene.
pinepaper_create_scene
Create a new empty action sequence.
Input Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Optional sequence name"
}
}
}
Output:
{
"success": true,
"sequenceId": "seq_1"
}
pinepaper_add_scene_action
Schedule an action for a character at a specific time in a sequence.
Input Schema:
{
"type": "object",
"properties": {
"sequenceId": {
"type": "string",
"description": "Sequence to add action to"
},
"skeletonId": {
"type": "string",
"description": "Target character skeleton"
},
"startTime": {
"type": "number",
"description": "Action start time in seconds"
},
"actionType": {
"type": "string",
"enum": ["moveLeft", "moveRight", "jump", "crouch", "idle", "stand"],
"description": "Action type (or custom registered action name)"
},
"duration": {
"type": "number",
"default": 1,
"description": "Action duration in seconds"
},
"speed": {
"type": "number",
"description": "Movement speed for walk actions"
},
"height": {
"type": "number",
"description": "Jump height for jump actions"
}
},
"required": ["sequenceId", "skeletonId", "startTime", "actionType"]
}
Output:
{
"success": true,
"actionId": "act_1"
}
pinepaper_build_scene
Build a complete scene from a script array. Designed for LLM/AI scene generation — describe actions as a timeline of events.
Input Schema:
{
"type": "object",
"properties": {
"script": {
"type": "array",
"items": {
"type": "object",
"properties": {
"skeleton": { "type": "string", "description": "Skeleton ID" },
"time": { "type": "number", "description": "Start time in seconds" },
"action": { "type": "string", "description": "Action type" },
"params": {
"type": "object",
"description": "Action parameters (duration, speed, height, etc.)"
}
},
"required": ["skeleton", "time", "action"]
},
"description": "Array of timed actions forming the scene script"
},
"name": {
"type": "string",
"description": "Scene name"
},
"loop": {
"type": "boolean",
"default": false,
"description": "Loop the scene"
}
},
"required": ["script"]
}
Example script:
{
"script": [
{ "skeleton": "skeleton_1", "time": 0, "action": "idle", "params": { "duration": 1 } },
{ "skeleton": "skeleton_1", "time": 1, "action": "moveRight", "params": { "duration": 2, "speed": 150 } },
{ "skeleton": "skeleton_2", "time": 1.5, "action": "moveLeft", "params": { "duration": 1.5 } },
{ "skeleton": "skeleton_1", "time": 3, "action": "jump", "params": { "height": 120 } }
],
"name": "encounter",
"loop": false
}
Output:
{
"success": true,
"sequenceId": "seq_2",
"duration": 3.6,
"actionCount": 4
}
pinepaper_play_scene
Play a scene sequence.
Input Schema:
{
"type": "object",
"properties": {
"sequenceId": {
"type": "string",
"description": "Sequence to play"
},
"speed": {
"type": "number",
"default": 1,
"description": "Playback speed multiplier"
},
"startTime": {
"type": "number",
"default": 0,
"description": "Start time in seconds"
}
},
"required": ["sequenceId"]
}
Output:
{
"success": true,
"playing": true
}
pinepaper_stop_scene
Stop scene playback and reset to start.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true
}
pinepaper_pause_scene
Pause scene playback at the current position.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"time": 2.5
}
pinepaper_resume_scene
Resume paused scene playback.
Input Schema:
{
"type": "object",
"properties": {}
}
Output:
{
"success": true,
"playing": true
}
36. Advanced Rigging Tools
Extended rigging operations: guided rig builder, bone management, pole vectors, secondary motion chains, animation baking, and path skinning.
pinepaper_start_guided_rig
Start the step-by-step guided rigging wizard. Walks through bone placement with visual highlights, auto-scales skeleton to selection bounds, and supports symmetry mirroring.
Input Schema:
{
"type": "object",
"properties": {
"itemIds": {
"type": "array",
"items": { "type": "string" },
"description": "Pre-selected item IDs to rig"
},
"preset": {
"type": "string",
"enum": ["humanoid", "quadruped", "bird", "simple_arm"],
"description": "Skeleton preset to use"
}
}
}
Output:
{
"success": true,
"wizardActive": true,
"preset": "humanoid"
}
pinepaper_remove_bone
Remove a bone from a skeleton with child reparenting, IK chain cleanup, and item detachment.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the bone"
},
"boneId": {
"type": "string",
"description": "Bone to remove"
}
},
"required": ["skeletonId", "boneId"]
}
Output:
{
"success": true
}
pinepaper_set_bone_length
Adjust the length of a bone.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the bone"
},
"boneId": {
"type": "string",
"description": "Bone to resize"
},
"length": {
"type": "number",
"minimum": 0,
"description": "New bone length in pixels"
}
},
"required": ["skeletonId", "boneId", "length"]
}
Output:
{
"success": true
}
pinepaper_set_pole_vector
Set a pole vector constraint to control IK joint bend direction (e.g., knees forward, elbows back).
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the IK chain"
},
"chainId": {
"type": "string",
"description": "IK chain ID"
},
"position": {
"type": "object",
"properties": {
"x": { "type": "number" },
"y": { "type": "number" }
},
"required": ["x", "y"],
"description": "Pole vector target position in canvas coordinates"
}
},
"required": ["skeletonId", "chainId", "position"]
}
Output:
{
"success": true
}
pinepaper_clear_pole_vector
Remove a pole vector constraint from an IK chain.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the IK chain"
},
"chainId": {
"type": "string",
"description": "IK chain ID"
}
},
"required": ["skeletonId", "chainId"]
}
Output:
{
"success": true
}
pinepaper_add_secondary_motion
Add spring-based secondary motion to a chain of bones (tail, hair, cloth). Creates spring_follow relations with stagger delay.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton containing the bones"
},
"boneNames": {
"type": "array",
"items": { "type": "string" },
"description": "Ordered bone names forming the chain (e.g., ['tail_1', 'tail_2', 'tail_3'])"
},
"stiffness": {
"type": "number",
"description": "Spring stiffness"
},
"damping": {
"type": "number",
"description": "Spring damping"
},
"gravity": {
"type": "number",
"description": "Gravity influence"
},
"delay": {
"type": "number",
"default": 0.05,
"description": "Stagger delay per bone in seconds"
}
},
"required": ["skeletonId", "boneNames"]
}
Output:
{
"success": true,
"relationKeys": ["rel_1", "rel_2", "rel_3"]
}
pinepaper_bake_animation
Convert bone-driven animation to plain item keyframes at configurable FPS. Useful for exporting rigged animation to formats that don’t support skeletons.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to bake animation from"
},
"includeRelations": {
"type": "boolean",
"default": true,
"description": "Also bake spring_follow and other relation animations"
}
},
"required": ["skeletonId"]
}
Output:
{
"success": true,
"itemCount": 8,
"keyframeCount": 120
}
pinepaper_skin_path
Bind a path item’s vertices to nearby bones for per-vertex deformation (2D Linear Blend Skinning). Auto-computes bone weights based on vertex proximity.
Input Schema:
{
"type": "object",
"properties": {
"skeletonId": {
"type": "string",
"description": "Skeleton to bind to"
},
"itemId": {
"type": "string",
"description": "Path item to skin"
},
"maxInfluences": {
"type": "number",
"description": "Max bone influences per vertex"
},
"maxDistance": {
"type": "number",
"description": "Max distance for bone influence in pixels"
},
"falloff": {
"type": "number",
"default": 2,
"description": "Distance falloff exponent"
}
},
"required": ["skeletonId", "itemId"]
}
Output:
{
"success": true,
"vertexCount": 24,
"boneInfluences": 3
}
pinepaper_unskin_path
Remove path skinning from an item, returning it to normal transform behavior.
Input Schema:
{
"type": "object",
"properties": {
"itemId": {
"type": "string",
"description": "Path item to unskin"
}
},
"required": ["itemId"]
}
Output:
{
"success": true
}
37. Scene Tools
Scene-level operations: part system for semantic grouping, scene baking for export, and animation suggestions.
pinepaper_add_parts
Batch-create part_of relations from a role map. Used for semantic grouping (e.g., face parts: eye_left, eye_right, mouth).
Input Schema:
{
"type": "object",
"properties": {
"parentId": {
"type": "string",
"description": "Parent item ID"
},
"roleMap": {
"type": "object",
"additionalProperties": { "type": "string" },
"description": "Role name to child item ID map (e.g., { 'eye_left': 'item_3', 'mouth': 'item_7' })"
}
},
"required": ["parentId", "roleMap"]
}
Output:
{
"success": true,
"relationsCreated": 3
}
pinepaper_bake_scene
Sample all animation systems (relations, rigging, callbacks) frame-by-frame into exportable keyframes with RDP path optimization. Used for Lottie export and other formats that need pre-baked animation.
Input Schema:
{
"type": "object",
"properties": {
"duration": {
"type": "number",
"description": "Scene duration in seconds"
},
"fps": {
"type": "number",
"description": "Sample rate (frames per second)"
},
"tolerance": {
"type": "number",
"description": "RDP simplification tolerance for keyframe reduction"
},
"includeCallbacks": {
"type": "boolean",
"default": true,
"description": "Include onFrame callback animations"
}
}
}
Output:
{
"success": true,
"itemCount": 12,
"duration": 5,
"fps": 30,
"stats": {
"totalKeyframes": 1500,
"optimizedKeyframes": 340
}
}
pinepaper_suggest_animations
Read-only analysis that returns per-item animation suggestions based on canvas content and mood. Does NOT modify the canvas.
Input Schema:
{
"type": "object",
"properties": {
"mood": {
"type": "string",
"description": "Target mood for suggestions (e.g., 'energetic', 'calm', 'dramatic')"
}
}
}
Output:
{
"success": true,
"suggestions": [
{
"itemId": "item_1",
"itemType": "text",
"suggestedAnimation": "fadeIn",
"reasoning": "Title text works well with a subtle entrance"
},
{
"itemId": "item_2",
"itemType": "circle",
"suggestedAnimation": "pulse",
"reasoning": "Shape complements energetic mood with rhythmic scaling"
}
]
}
Implementation Notes
- Item IDs: All items are referenced by
item.data.registryId(e.g., “item_1”) - Positions: Canvas coordinates, (0,0) is top-left
- Colors: Hex (#RRGGBB), RGB, or named colors
- Async Operations: Generators may be async, return promises
- State Management: Call
historyManager.saveState()after batches - Relations: Process automatically each frame, no manual updates needed
- Rigging: FK/IK solving runs automatically in the update loop before relations; bone transforms are pre-computed
- Blending: Transitions process automatically each frame; blend mode snaps at transition midpoint while opacity cross-fades smoothly
- View Tools: Zoom level is relative (1.0 = 100%); pan coordinates are in canvas space
- Selection: Selection changes dispatch
selectionChangedevents; usedeselect_allbefore batch operations to avoid side effects - History: Undo/redo automatically saves/restores all canvas state including relations and animations
- 3D Projection: 3D objects are rendered as 2D polygons via a 5-stage pipeline (transform → cull → shade → project → sort). GPU acceleration (WebGPU/WebGL2) is automatic above 150 faces. Scene budget: ~500 faces max.
- Shape Keys: Multiple shape keys can be active simultaneously with additive blending. Save shape keys from the current visual state, then animate between them via keyframes or direct weight control.
- Bone Physics: Verlet physics runs in the update loop after FK/IK.
blendWeightcontrols the mix — 0 = pure animation, 1 = full physics. Spring motors automatically pull bones back toward animation targets. - Physics World: Must call
init_physics_worldbefore adding bodies. Kinematic bodies follow animation transforms and push dynamic bodies. Fixed-timestep accumulator prevents tunneling. - Character Controller: Movement functions are composable and input-agnostic. Walk cycle interpolates between saved poses. Test mode binds arrow keys for interactive verification.
- Scene Sequencer: Actions execute based on elapsed time. Multiple characters can act in parallel on the same timeline.
buildSceneis the primary LLM/AI entry point for choreography. - Path Skinning: Per-vertex bone weights are auto-computed from proximity. Works with any Paper.js path — curved paths get per-segment deformation. Call
unskinPathbefore deleting the skeleton. - Widget Export:
export_widgetproduces pp:PinePaper ontology JSON.export_widget_htmlproduces a self-contained HTML file with scene-specific tree-shaken code — only the item renderers and relation handlers used in the scene are included. Zero external dependencies. WCAG 2.1 AA accessible. Supports transparent backgrounds for overlays. - 3D Camera:
camera_animatessupportspitch(tilt) andyaw(rotation) params for cinematic 3D perspective. Uses CSSperspective+rotateX/rotateYfor GPU-accelerated compositing via PinePaper’s equirectangular projection pipeline. Three modes:keyframes(manual),fly_to(shorthand),orbit(revolve). Pitch/yaw interpolate between keyframes with easing.