setLayerKeyframe
Set keyframes for specific layer properties in After Effects compositions at precise times using AI-driven automation. Define composition, layer, property, time, and value for accurate animation control.
Instructions
Set a keyframe for a specific layer property at a given time.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| compIndex | Yes | 1-based index of the target composition in the project panel. | |
| layerIndex | Yes | 1-based index of the target layer within the composition. | |
| propertyName | Yes | Name of the property to keyframe (e.g., 'Position', 'Scale', 'Rotation', 'Opacity'). | |
| timeInSeconds | Yes | The time (in seconds) for the keyframe. | |
| value | No | The value for the keyframe (e.g., [x,y] for Position, [w,h] for Scale, angle for Rotation, percentage for Opacity) |
Implementation Reference
- src/index.ts:489-524 (registration)MCP tool registration for 'setLayerKeyframe', including description, input schema (layer/comp indices, property name, time, value), and handler that queues the command via writeCommandFile.server.tool( "setLayerKeyframe", // Corresponds to the function name in ExtendScript "Set a keyframe for a specific layer property at a given time.", { ...LayerIdentifierSchema, // Reuse common identifiers propertyName: z.string().describe("Name of the property to keyframe (e.g., 'Position', 'Scale', 'Rotation', 'Opacity')."), timeInSeconds: z.number().describe("The time (in seconds) for the keyframe."), value: KeyframeValueSchema }, async (parameters) => { try { // Queue the command for After Effects writeCommandFile("setLayerKeyframe", parameters); return { content: [ { type: "text", text: `Command to set keyframe for "${parameters.propertyName}" on layer ${parameters.layerIndex} in comp ${parameters.compIndex} has been queued.\n` + `Use the "get-results" tool after a few seconds to check for confirmation.` } ] }; } catch (error) { return { content: [ { type: "text", text: `Error queuing setLayerKeyframe command: ${String(error)}` } ], isError: true }; } } );
- src/index.ts:498-523 (handler)The handler function for the setLayerKeyframe tool. It writes the command and parameters to a temporary file ('ae_command.json') for the After Effects MCP Bridge Auto panel to detect and execute the corresponding ExtendScript.async (parameters) => { try { // Queue the command for After Effects writeCommandFile("setLayerKeyframe", parameters); return { content: [ { type: "text", text: `Command to set keyframe for "${parameters.propertyName}" on layer ${parameters.layerIndex} in comp ${parameters.compIndex} has been queued.\n` + `Use the "get-results" tool after a few seconds to check for confirmation.` } ] }; } catch (error) { return { content: [ { type: "text", text: `Error queuing setLayerKeyframe command: ${String(error)}` } ], isError: true }; } }
- src/index.ts:479-482 (schema)Shared Zod schema for identifying target composition and layer by 1-based indices, reused in setLayerKeyframe and other layer tools.const LayerIdentifierSchema = { compIndex: z.number().int().positive().describe("1-based index of the target composition in the project panel."), layerIndex: z.number().int().positive().describe("1-based index of the target layer within the composition.") };
- src/index.ts:486-486 (schema)Zod schema for the keyframe value input, using z.any() for flexibility across different property types.const KeyframeValueSchema = z.any().describe("The value for the keyframe (e.g., [x,y] for Position, [w,h] for Scale, angle for Rotation, percentage for Opacity)");
- src/index.ts:156-170 (helper)Core helper function used by all command-queuing tools, including setLayerKeyframe, to write the command name and parameters to ae_command.json in TEMP dir for polling by After Effects bridge.function writeCommandFile(command: string, args: Record<string, any> = {}): void { try { const commandFile = path.join(process.env.TEMP || process.env.TMP || '', 'ae_command.json'); const commandData = { command, args, timestamp: new Date().toISOString(), status: "pending" // pending, running, completed, error }; fs.writeFileSync(commandFile, JSON.stringify(commandData, null, 2)); console.error(`Command "${command}" written to ${commandFile}`); } catch (error) { console.error("Error writing command file:", error); } }