Skip to main content
Glama
definitions.ts26.3 kB
/** * PinePaper MCP Tool Definitions * * This file contains all the tool definitions for the MCP server. * Each tool has a name, description, and JSON schema for inputs. * * Note: Tool descriptions remain in English for optimal AI/LLM understanding. * User-facing messages (errors, success) are translated via i18n. */ import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { I18nManager } from '../i18n/index.js'; // ============================================================================= // TOOL DEFINITIONS // ============================================================================= export const PINEPAPER_TOOLS: Tool[] = [ // --------------------------------------------------------------------------- // ITEM TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_create_item', description: `Create an item on the PinePaper canvas. Returns an itemId (e.g., "item_1") that you MUST save to reference this item later. USE WHEN: - User wants to add text, shapes, or graphics to the canvas - Creating new visual elements (circles, stars, rectangles, etc.) - Starting a new scene or composition IMPORTANT: - Save the returned itemId! You need it for pinepaper_add_relation, pinepaper_modify_item, pinepaper_delete_item, etc. - If there's a welcome template on the canvas, use pinepaper_clear_canvas first - Position defaults to canvas center (400, 300). Use position: {x, y} to place elsewhere. ITEM TYPES: - text: Text content with font styling (properties: content, fontSize, color, fontFamily) - circle: Circular shape (properties: radius, color, strokeColor, strokeWidth) - star: Star shape (properties: radius1, radius2, points, color) - rectangle: Rectangle (properties: width, height, color, cornerRadius) - triangle: Triangular shape (properties: color) - polygon: Regular polygon with N sides (properties: sides, radius, color) - ellipse: Oval shape (properties: color) - path: Custom path with segments or SVG data (properties: segments, pathData, strokeColor) - line: Line between two points (properties: from, to, strokeColor, strokeWidth) - arc: Curved arc through three points (properties: from, through, to, strokeColor) EXAMPLES: - "Create red text saying HELLO" → itemType: "text", properties: {content: "HELLO", color: "#ef4444", fontSize: 48} - "Add a blue circle" → itemType: "circle", properties: {radius: 50, color: "#3b82f6"} - "Create a 5-pointed gold star" → itemType: "star", properties: {radius1: 60, radius2: 30, points: 5, color: "#fbbf24"} WORKFLOW TIP: After creating items, use pinepaper_add_relation to animate them (e.g., orbits, follows, attached_to).`, inputSchema: { 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', description: 'X coordinate (default: 400)' }, y: { type: 'number', description: 'Y coordinate (default: 300)' }, }, description: 'Position on canvas', }, properties: { type: 'object', description: 'Type-specific properties (content, radius, color, fontSize, etc.)', additionalProperties: true, }, }, required: ['itemType'], }, }, { name: 'pinepaper_modify_item', description: `Modify an existing item's properties. USE WHEN: - Changing color, size, position of an existing item - Updating text content - Adjusting styling properties MODIFIABLE PROPERTIES: - position: {x, y} or separate x, y - color/fillColor: Fill color - strokeColor: Outline color - strokeWidth: Outline thickness - fontSize: Text size - content: Text content - opacity: Transparency (0-1) - rotation: Rotation in degrees - scale: Size multiplier`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Registry ID of the item (e.g., "item_1")', }, properties: { type: 'object', description: 'Properties to update', additionalProperties: true, }, }, required: ['itemId', 'properties'], }, }, { name: 'pinepaper_delete_item', description: `Delete a single item from the canvas by its registry ID. USE WHEN: - Removing a specific unwanted item - Cleaning up individual elements - Undoing a creation mistake HOW TO FIND ITEM IDs: 1. The itemId is returned when you create an item (e.g., "item_1", "item_2") 2. Use pinepaper_get_items to list all items and their IDs 3. Items are typically named sequentially: item_1, item_2, item_3, etc. IF DELETION FAILS: - Verify the itemId exists with pinepaper_get_items first - If the item is part of the welcome template, use pinepaper_clear_canvas instead - For stubborn items, try pinepaper_refresh_page to reset the entire canvas TO DELETE ALL ITEMS: Use pinepaper_clear_canvas instead of deleting items one by one.`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Registry ID of the item to delete (e.g., "item_1")', }, }, required: ['itemId'], }, }, // --------------------------------------------------------------------------- // RELATION TOOLS (KEY FOR ANIMATION) // --------------------------------------------------------------------------- { name: 'pinepaper_add_relation', description: `Create a behavior relationship between two items. Relations are the PRIMARY way to add animation in PinePaper - they describe HOW items should behave relative to each other. USE WHEN: - "moon orbits earth" → relationType: orbits - "label follows player" → relationType: follows - "hat attached to character" → relationType: attached_to - "keep satellite 200px from station" → relationType: maintains_distance - "arrow points at target" → relationType: points_at - "reflection mirrors original" → relationType: mirrors - "background moves with parallax" → relationType: parallax - "player stays in arena" → relationType: bounds_to - Creating physics-based or behavioral animations RELATION TYPES: - orbits: Circular motion around target (params: radius, speed, direction, phase) - follows: Move toward target with smoothing (params: offset, smoothing, delay) - attached_to: Fixed offset from target (params: offset, inherit_rotation) - maintains_distance: Stay fixed distance from target (params: distance, strength) - points_at: Rotate to face target (params: offset_angle, smoothing) - mirrors: Mirror position across axis (params: axis, center) - parallax: Move relative by depth (params: depth, origin) - bounds_to: Stay within bounds (params: padding, bounce) VERIFYING ANIMATION WORKS: After adding a relation, verify the animation is running: 1. Use pinepaper_browser_screenshot to see the canvas 2. Wait 1-2 seconds and take another screenshot - items should have moved 3. Use pinepaper_query_relations to confirm the relation was added Relations are COMPOSITIONAL - an item can have multiple relations that work together!`, inputSchema: { 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)', }, relationType: { type: 'string', enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to'], description: 'Type of relationship', }, params: { type: 'object', description: 'Relation-specific parameters', additionalProperties: true, }, }, required: ['sourceId', 'targetId', 'relationType'], }, }, { name: 'pinepaper_remove_relation', description: `Remove a relationship between items. USE WHEN: - Stopping an orbital animation - Detaching items from each other - Removing behavioral connections`, inputSchema: { type: 'object', properties: { sourceId: { type: 'string', description: 'Source item ID' }, targetId: { type: 'string', description: 'Target item ID' }, relationType: { type: 'string', enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to'], description: 'Specific relation type to remove (optional - removes all if not specified)', }, }, required: ['sourceId', 'targetId'], }, }, { name: 'pinepaper_query_relations', description: `Query relationships for an item. USE WHEN: - Finding what items orbit a central object - Checking existing relations before adding new ones - Debugging animation behaviors`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Item to query relations for' }, relationType: { type: 'string', enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to'], description: 'Filter by relation type (optional)', }, direction: { type: 'string', enum: ['outgoing', 'incoming'], description: 'outgoing = relations FROM item, incoming = relations TO item', }, }, required: ['itemId'], }, }, // --------------------------------------------------------------------------- // ANIMATION TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_animate', description: `Apply a simple LOOP animation to an item. These are continuous animations that repeat infinitely. USE WHEN: - "make it pulse" → animationType: pulse - "rotating logo" → animationType: rotate - "bouncing text" → animationType: bounce - "fading effect" → animationType: fade - "wobbling button" → animationType: wobble - "sliding header" → animationType: slide - "typewriter effect" → animationType: typewriter (text only) DO NOT USE WHEN: - User specifies exact timing ("fade in over 3 seconds") → Use keyframe animation - User wants sequential animations ("first fade, then rotate") → Use keyframe animation - User describes relationships ("orbit around") → Use relations ANIMATION TYPES: - pulse: Scale up/down rhythmically - rotate: Continuous rotation - bounce: Vertical bouncing motion - fade: Opacity cycling - wobble: Side-to-side wobbling - slide: Horizontal sliding - typewriter: Character-by-character reveal`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Registry ID of the item' }, animationType: { type: 'string', enum: ['pulse', 'rotate', 'bounce', 'fade', 'wobble', 'slide', 'typewriter'], description: 'Type of animation', }, speed: { type: 'number', description: 'Animation speed multiplier (default: 1.0)', }, }, required: ['itemId', 'animationType'], }, }, { name: 'pinepaper_keyframe_animate', description: `Apply keyframe-based animation with precise timing and property control. USE WHEN: - "fade in over 3 seconds" - "move from left to right in 2 seconds" - "change color from red to blue" - "first fade in, then rotate, then fade out" - Any animation with specific timing or sequential stages ANIMATABLE PROPERTIES: - position: [x, y] array - x, y: Individual coordinates - scale: Uniform scale - scaleX, scaleY: Axis scaling - rotation: Degrees - opacity: 0-1 - fillColor: Color string - strokeColor: Color string - fontSize: Number EASING OPTIONS: - linear: Constant speed - easeIn: Slow start - easeOut: Slow end - easeInOut: Slow start and end - bounce: Bounce effect - elastic: Elastic overshoot`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Registry ID of the item' }, keyframes: { type: 'array', items: { type: 'object', properties: { time: { type: 'number', description: 'Time in seconds' }, properties: { type: 'object', description: 'Property values at this keyframe', additionalProperties: true, }, easing: { type: 'string', enum: ['linear', 'easeIn', 'easeOut', 'easeInOut', 'bounce', 'elastic'], }, }, required: ['time', 'properties'], }, description: 'Array of keyframes', }, duration: { type: 'number', description: 'Total animation duration in seconds', }, loop: { type: 'boolean', description: 'Whether to loop the animation', }, }, required: ['itemId', 'keyframes'], }, }, { name: 'pinepaper_play_timeline', description: `Control keyframe animation playback. USE WHEN: - Starting/stopping timeline playback - Seeking to specific time - Controlling animation state`, inputSchema: { type: 'object', properties: { action: { type: 'string', enum: ['play', 'stop', 'seek'], description: 'Playback action', }, duration: { type: 'number', description: 'Duration for play action', }, loop: { type: 'boolean', description: 'Whether to loop', }, time: { type: 'number', description: 'Time to seek to (for seek action)', }, }, required: ['action'], }, }, // --------------------------------------------------------------------------- // GENERATOR TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_execute_generator', description: `Execute a background generator to create procedural patterns. USE WHEN: - "add a sunburst background" - "create wave pattern" - "grid background" - "circuit board pattern" - Creating dynamic procedural backgrounds GENERATORS: - drawSunburst: Radial rays from center (rayCount, colors, bgColor) - drawSunsetScene: Animated sunset with clouds (sunColor, skyColors, cloudCount) - drawGrid: Lines, dots, or squares (gridType, spacing, lineColor) - drawStackedCircles: Overlapping circles (count, colors, distribution) - drawCircuit: Tech circuit board (lineColor, nodeColor, density) - drawWaves: Layered wave pattern (waveCount, colors, amplitude) - drawPattern: Geometric shapes in orbit`, inputSchema: { type: 'object', properties: { generatorName: { type: 'string', enum: ['drawSunburst', 'drawSunsetScene', 'drawGrid', 'drawStackedCircles', 'drawCircuit', 'drawWaves', 'drawPattern'], description: 'Generator name', }, params: { type: 'object', description: 'Generator-specific parameters', additionalProperties: true, }, }, required: ['generatorName'], }, }, { name: 'pinepaper_list_generators', description: `Get a list of all available background generators with their parameters. USE WHEN: - User asks "what backgrounds are available?" - Need to show generator options - Discovering generator capabilities`, inputSchema: { type: 'object', properties: {}, }, }, // --------------------------------------------------------------------------- // EFFECT TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_apply_effect', description: `Apply a visual effect to an item. USE WHEN: - Adding sparkle/glitter effects - Creating burst/explosion effects - Enhancing visual impact EFFECTS: - sparkle: Glitter/sparkle particles (color, speed, size) - blast: Explosion burst effect (color, radius, count)`, inputSchema: { type: 'object', properties: { itemId: { type: 'string', description: 'Registry ID of the item' }, effectType: { type: 'string', enum: ['sparkle', 'blast'], description: 'Type of effect', }, params: { type: 'object', description: 'Effect parameters', additionalProperties: true, }, }, required: ['itemId', 'effectType'], }, }, // --------------------------------------------------------------------------- // QUERY TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_get_items', description: `Get all or filtered items from the canvas. USE WHEN: - Listing what's on the canvas - Finding items by type - Checking animated items - Scene inspection`, inputSchema: { type: 'object', properties: { filter: { type: 'object', properties: { type: { type: 'string', enum: ['text', 'circle', 'star', 'rectangle', 'triangle', 'polygon', 'ellipse', 'path', 'line', 'arc'], description: 'Filter by item type', }, source: { type: 'string', enum: ['user', 'generator', 'import'], description: 'Filter by item source', }, hasAnimation: { type: 'boolean', description: 'Filter by animation status', }, hasRelation: { type: 'boolean', description: 'Filter by relation status', }, }, }, }, }, }, { name: 'pinepaper_get_relation_stats', description: `Get statistics about active relations in the scene. USE WHEN: - Debugging relation system - Understanding scene complexity - Analytics and reporting`, inputSchema: { type: 'object', properties: {}, }, }, // --------------------------------------------------------------------------- // CANVAS TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_set_background_color', description: `Set the canvas background color. USE WHEN: - Changing scene background - Setting up canvas before adding items`, inputSchema: { type: 'object', properties: { color: { type: 'string', description: 'Background color (hex, rgb, or named)', }, }, required: ['color'], }, }, { name: 'pinepaper_set_canvas_size', description: `Change the canvas dimensions. IMPORTANT: Call this BEFORE creating items if you need a specific canvas size. The default canvas is 800x600 which may be too small for complex designs. USE WHEN: - Starting a new design - SET SIZE FIRST before adding items - Setting up for specific format (Instagram, YouTube, etc.) - Custom canvas size requirements - Design elements extend beyond current canvas bounds COMMON PRESETS: - instagram-square: 1080x1080 - instagram-story: 1080x1920 - youtube-thumbnail: 1280x720 - twitter-post: 1200x675 - hd-landscape: 1920x1080 - hd-portrait: 1080x1920 For wedding invitations, event cards, or detailed designs, use at least 1080x1080 or larger.`, inputSchema: { type: 'object', properties: { width: { type: 'number', description: 'Canvas width in pixels' }, height: { type: 'number', description: 'Canvas height in pixels' }, preset: { type: 'string', description: 'Optional preset name', }, }, required: ['width', 'height'], }, }, { name: 'pinepaper_get_canvas_size', description: `Get the current canvas dimensions. USE WHEN: - Need to know current canvas size before positioning items - Checking if canvas needs to be resized - Calculating positions relative to canvas bounds`, inputSchema: { type: 'object', properties: {}, }, }, { name: 'pinepaper_clear_canvas', description: `Clear all items from the canvas, removing everything including any welcome template items. USE WHEN: - User wants to start fresh with an empty canvas - Need to remove all existing items before creating new ones - Clearing the welcome template that appears for first-time visitors - User says "clear everything", "start over", "reset canvas", "remove all items" IMPORTANT NOTES: - This removes ALL items from the canvas permanently - The welcome template (shown to first-time visitors) will be cleared - After clearing, use pinepaper_get_items to verify the canvas is empty - If items persist after clearing, try pinepaper_refresh_page instead`, inputSchema: { type: 'object', properties: {}, }, }, { name: 'pinepaper_refresh_page', description: `Refresh the PinePaper Studio page in the browser. This is the most reliable way to get a completely clean canvas. USE WHEN: - pinepaper_clear_canvas didn't fully remove all items - Need a guaranteed clean slate - Want to remove the welcome template completely - Troubleshooting issues with the canvas state - User explicitly asks to "refresh" or "reload" IMPORTANT NOTES: - This reloads the entire page, which resets everything - The welcome template will NOT appear after refresh (only shows for first-time visitors) - After refresh, the canvas will be completely empty - All unsaved work will be lost - You may need to wait a moment after refresh before executing other commands`, inputSchema: { type: 'object', properties: {}, }, }, // --------------------------------------------------------------------------- // EXPORT TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_export_svg', description: `Export the scene as animated SVG. USE WHEN: - Saving work as SVG file - Generating shareable graphics - Final export`, inputSchema: { type: 'object', properties: { animated: { type: 'boolean', description: 'Include CSS animations (default: true)', }, }, }, }, { name: 'pinepaper_export_training_data', description: `Export relation data as training pairs for LLM fine-tuning. This generates instruction/code pairs from the current scene's relations. USE WHEN: - Generating training data for fine-tuning - Creating examples from current scene - Building custom animation model training sets OUTPUT FORMAT: - json: Array of {instruction, code, relation, params} - jsonl: JSONL format with messages array for chat fine-tuning`, inputSchema: { type: 'object', properties: { format: { type: 'string', enum: ['json', 'jsonl'], description: 'Output format (default: json)', }, includeMetadata: { type: 'boolean', description: 'Include relation metadata (default: true)', }, }, }, }, // --------------------------------------------------------------------------- // BROWSER CONTROL TOOLS // --------------------------------------------------------------------------- { name: 'pinepaper_browser_connect', description: `Connect to PinePaper Studio Editor in a browser. This launches a browser window and navigates to the PinePaper Editor. USE WHEN: - Starting a new PinePaper session - Need to execute commands in the actual application - User wants to see changes live in the browser IMPORTANT: Call this FIRST before using any other pinepaper tools. Without connecting, tools only generate code but don't execute it. The browser will open and navigate to https://pinepaper.studio/editor where the code console and JavaScript API are available.`, inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Custom PinePaper Studio URL (default: https://pinepaper.studio/editor)', }, headless: { type: 'boolean', description: 'Run browser in headless mode - no visible window (default: false)', }, }, }, }, { name: 'pinepaper_browser_disconnect', description: `Disconnect from the browser and close PinePaper Studio. USE WHEN: - Done working with PinePaper - Need to clean up browser resources - Switching to a different project`, inputSchema: { type: 'object', properties: {}, }, }, { name: 'pinepaper_browser_screenshot', description: `Take a screenshot of the current PinePaper canvas. USE WHEN: - User wants to see the current state - Verifying that changes were applied correctly - Debugging visual issues Returns a base64-encoded PNG image of the canvas.`, inputSchema: { type: 'object', properties: {}, }, }, { name: 'pinepaper_browser_status', description: `Check the current browser connection status. USE WHEN: - Need to verify if connected to PinePaper - Debugging connection issues - Before executing commands`, inputSchema: { type: 'object', properties: {}, }, }, ]; /** * Get a tool definition by name */ export function getToolByName(name: string): Tool | undefined { return PINEPAPER_TOOLS.find((t) => t.name === name); } /** * Get all tool names */ export function getToolNames(): string[] { return PINEPAPER_TOOLS.map((t) => t.name); } /** * Get tools with localized descriptions from i18n manager * Tool descriptions remain in English for AI, but names can be localized for UI */ export function getLocalizedTools(i18n: I18nManager): Tool[] { return PINEPAPER_TOOLS.map((tool) => ({ ...tool, // Tool descriptions intentionally kept in English for AI understanding // The i18n manager provides translated tool names for UI purposes description: i18n.getToolDescription(tool.name) || tool.description, })); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pinepaper/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server