generate_svg_animation
Create SVG animations from static images by defining motion through natural language prompts. Specify input and output paths to generate dynamic animations with MCP-powered AI.
Instructions
Generate an SVG animation from a source file and prompt
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| output_path | Yes | Local file path to the output file, must be the absolute path (e.g., '/path/to/animated-svg.tsx') | |
| prompt | Yes | Description of what animation to generate (e.g., 'Make the character wave their hand', 'Add bouncing motion to the ball') | |
| svg_path | Yes | Local file path to the source file to animate, must be the absolute path (e.g., '/Users/username/image.png') |
Implementation Reference
- index.js:105-236 (handler)Implements the generate_svg_animation tool by reading the input SVG file from svg_path, constructing form data with the file and prompt, sending POST request to Allyson API (/mcp) with API key auth, receiving the animated SVG response, writing it to output_path, and returning structured JSON result with success/error details.async handleGenerateAnimation(args) { const { prompt, svg_path, output_path } = args; if (!prompt) { throw new Error("Prompt is required"); } if (!svg_path) { throw new Error("SVG file path is required"); } if (!output_path) { throw new Error("Output file path is required"); } try { // Read the file from the local path console.error(`[Allyson] Reading file from: ${svg_path}`); const fileBuffer = readFileSync(svg_path); const fileName = basename(svg_path); // Create form data for file upload const FormData = (await import('form-data')).default; const formData = new FormData(); formData.append('file', fileBuffer, fileName); formData.append('prompt', prompt); const url = `${this.baseUrl}/mcp`; console.error(`[Allyson] Uploading ${fileName} with prompt: "${prompt}"`); const response = await fetch(url, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'User-Agent': 'Allyson-MCP-Server/1.0.0', ...formData.getHeaders() }, body: formData }); const responseText = await response.text(); let responseData; try { responseData = JSON.parse(responseText); } catch { responseData = responseText; } const result = { status: response.status, statusText: response.statusText, success: response.ok, message: "Animation file generated successfully", outputFile: output_path }; if (!response.ok) { console.error(`[Allyson] Error ${response.status}:`, responseData); result.message = `API Error ${response.status}: ${response.statusText}`; result.error = responseData; result.data = null; } else { console.error(`[Allyson] Success! Animation generated for "${prompt}"`); result.message = "Animation file generated successfully"; result.data = responseData; // Write the successful result to the output file try { writeFileSync(output_path, responseData); } catch (writeError) { console.error(`[Allyson] Failed to write output file:`, writeError); result.success = false; result.message = `Failed to write output file: ${writeError.message}`; result.error = writeError.message; } } return { content: [ { type: "text", text: JSON.stringify(result, null, 2) } ] }; } catch (error) { console.error(`[Allyson] Request failed:`, error); // Create error result object to return detailed error info to AI const errorResult = { status: 500, statusText: 'Internal Error', success: false, outputFile: output_path, prompt: prompt, sourceFile: svg_path ? basename(svg_path) : 'unknown', message: '', error: error.message, data: null }; // Handle specific file errors if (error.code === 'ENOENT') { errorResult.message = `File not found: ${svg_path}`; errorResult.error = `The specified file path does not exist: ${svg_path}`; } else if (error.code === 'EACCES') { errorResult.message = `Permission denied accessing file: ${svg_path}`; errorResult.error = `No permission to read the file: ${svg_path}`; } else if (error.code === 'ECONNREFUSED') { errorResult.message = 'Cannot connect to animation API server'; errorResult.error = `Connection refused to ${this.baseUrl}/mcp - make sure the server is running`; } else if (error.name === 'FetchError') { errorResult.message = 'Network error connecting to animation API'; errorResult.error = error.message; } else { errorResult.message = `Animation generation failed: ${error.message}`; errorResult.error = error.message; } // Return the error result instead of throwing, so AI gets the details return { content: [ { type: "text", text: JSON.stringify(errorResult, null, 2) } ] }; } }
- index.js:57-74 (schema)Defines the input schema for generate_svg_animation: object with required properties prompt (string description), svg_path (absolute local path to source SVG), output_path (absolute local path for output).inputSchema: { type: "object", properties: { prompt: { type: "string", description: "Description of what animation to generate (e.g., 'Make the character wave their hand', 'Add bouncing motion to the ball')" }, svg_path: { type: "string", description: "Local file path to the source file to animate, must be the absolute path (e.g., '/Users/username/image.svg')" }, output_path: { type: "string", description: "Local file path to the output file, must be the absolute path (e.g., '/path/to/animated-svg.tsx')" } }, required: ["prompt", "svg_path", "output_path"] }
- index.js:51-78 (registration)Tool list registration: returns the generate_svg_animation tool details (name, description, inputSchema) in ListToolsRequestSchema handler.this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "generate_svg_animation", description: "Generate an SVG animation from a source file and prompt", inputSchema: { type: "object", properties: { prompt: { type: "string", description: "Description of what animation to generate (e.g., 'Make the character wave their hand', 'Add bouncing motion to the ball')" }, svg_path: { type: "string", description: "Local file path to the source file to animate, must be the absolute path (e.g., '/Users/username/image.svg')" }, output_path: { type: "string", description: "Local file path to the output file, must be the absolute path (e.g., '/path/to/animated-svg.tsx')" } }, required: ["prompt", "svg_path", "output_path"] } } ] }; });
- index.js:81-94 (registration)Tool execution dispatch: CallToolRequestSchema handler with switch case for 'generate_svg_animation' invoking handleGenerateAnimation.this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case "generate_svg_animation": return await this.handleGenerateAnimation(args); default: throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${name}` ); }