Animation Blueprint logo

Animation Blueprint

Community
kevinpbuckley
animation-blueprint

Navigate, inspect, and author Animation Blueprints — state machines, states, transitions, and transition rules (AnimGraphService). Use when the user asks to create or edit an Animation Blueprint/AnimBP, add a state machine or states, wire transitions between states, set a state's animation, or inspect AnimGraph structure.

Overview

Publisherkevinpbuckley
RepositoryVibeUE
Skill nameanimation-blueprint
Stars
735
Forks
161
Bundled files
1
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 1 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by kevinpbuckley on GitHub. Read the source before you install it.

Installation

Install the Animation Blueprint AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/animation-blueprint
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git /tmp/VibeUE
mkdir -p .claude/skills
cp -r /tmp/VibeUE/Content/Skills/animation-blueprint .claude/skills/animation-blueprint
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Animation Blueprint in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Animation Blueprint on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Animation Blueprint is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

🧠 Brains complement: IF an unreal-engine-skills-manager tool (external MCP) exists in this session, call it with {action: "load", skill: "animation-system"} for UE domain knowledge on this topic — correct APIs, architecture, best practices — and treat it as the rubric for any review / "best practices" question. If no such tool is available (e.g. running under Claude Code or Codex without that MCP), skip this line entirely and proceed with this skill alone — do NOT attempt the call.

Animation Blueprint Skill

Loading skills: skills load through the engine's AgentSkillToolset (ListSkills/GetSkills) — there is no vibeue-skills-manager tool. Run VibeUE services with execute_python_code (unreal.AnimGraphService.<method>()); reach engine toolsets with call_tool.

An AnimBP is a Blueprint. The state-machine/AnimGraph authoring here is VibeUE AnimGraphService (intact). For its variables and compile, note VibeUE's BlueprintService was trimmed: variable creation and blueprint compile moved to the engine toolset editor_toolset.toolsets.blueprint.BlueprintTools (add_variable, compile_blueprint), called via call_tool. BlueprintService still has list_variables, get_variable_info, set_variable_default_value, variable_exists, components, and overridable functions. Bool fields on info structs drop the C++ b prefix in Python — use is_pure, is_output, already_overridden (NOT b_is_pure); call discover_python_class to confirm field names rather than guessing.

⚠️ #1 GOTCHA — Transitions need a RULE or they NEVER fire

add_transition() only draws the arrow between two states. The transition's rule graph starts empty, which evaluates to false, so the transition is inert — the state machine will never move. You MUST set a rule on every transition:

python
import unreal
abp = "/Game/ABP_Character"
BT  = "editor_toolset.toolsets.blueprint.BlueprintTools"

# 1) Add the bool/float variable the rule reads, then COMPILE so it resolves.
#    Variable creation + compile are ENGINE BlueprintTools (call_tool), not VibeUE:
call_tool(BT, "add_variable", {"blueprint": {"refPath": abp}, "variable_name": "bIsDead", "variable_type": "bool"})
call_tool(BT, "compile_blueprint", {"blueprint": {"refPath": abp}})
# (Run describe_toolset(BT) for exact arg names.)

# 2) Draw the transition (VibeUE AnimGraphService)
unreal.AnimGraphService.add_transition(abp, "Locomotion", "Idle", "Dead", 0.2)

# 3) Give it a rule — THIS is what makes it fire
unreal.AnimGraphService.set_transition_rule_from_bool(abp, "Locomotion", "Idle", "Dead", "bIsDead")

Rule options:

  • set_transition_rule_from_bool(abp, machine, src, dst, bool_var, invert=False)
  • set_transition_rule_comparison(abp, machine, src, dst, float_var, op, value) — op ∈ greater/less/greater_equal/less_equal/equal/not_equal
  • set_transition_rule_automatic(abp, machine, src, dst, trigger_time=-1.0) — fires when the source state's animation is (almost) finished; perfect for one-shots (attack→idle)
  • clear_transition_rule(...) — non-destructively reset a rule

After authoring, always run validate_state_machine() (see below) and compile.

Critical Rules

Opening Animation States

Use AnimGraphService to navigate directly to states and graphs:

python
import unreal

# Open an AnimBP's main AnimGraph
unreal.AnimGraphService.open_anim_graph("/Game/ABP_Character", "AnimGraph")

# Open a specific state inside a state machine
unreal.AnimGraphService.open_anim_state("/Game/ABP_Character", "Locomotion", "IdleLoop")

# Open a transition rule
unreal.AnimGraphService.open_transition("/Game/ABP_Character", "Locomotion", "Idle", "Walk")

⚠️ State Machine Names

State machine names come from the node title, not the graph name. Use list_state_machines() to get the correct names:

python
machines = unreal.AnimGraphService.list_state_machines("/Game/ABP_Character")
for m in machines:
    print(f"Machine: {m.machine_name}")  # Use THIS name for open_anim_state

⚠️ Case Sensitivity

All name lookups are case-insensitive, but prefer using exact names from introspection:

python
# Both work:
unreal.AnimGraphService.open_anim_state(path, "State Controller", "In Air Loop")
unreal.AnimGraphService.open_anim_state(path, "state controller", "in air loop")

Workflows

Create Animation Blueprint

CRITICAL: AnimBlueprints require a skeleton reference. Always find the skeleton first.

python
import unreal

# Step 1: Find skeleton from reference blueprint
ref_bp_path = "/Game/Blueprints/SandboxCharacter_CMC_ABP"
if unreal.EditorAssetLibrary.does_asset_exist(ref_bp_path):
    ref_bp = unreal.load_asset(ref_bp_path)
    skeleton = ref_bp.get_editor_property('target_skeleton')
    skeleton_path = skeleton.get_path_name()
    print(f"Using skeleton: {skeleton_path}")
else:
    # Or load directly if you know the path
    skeleton_path = "/Game/Characters/UEFN_Mannequin/Meshes/SK_UEFN_Mannequin"
    skeleton = unreal.load_asset(skeleton_path)

# Step 2: Delete existing if needed
asset_path = "/Game/Tests/ABP_TestCharacter"
if unreal.EditorAssetLibrary.does_asset_exist(asset_path):
    unreal.EditorAssetLibrary.delete_asset(asset_path)

# Step 3: Create AnimBlueprint with skeleton
asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
blueprint_factory = unreal.AnimBlueprintFactory()
blueprint_factory.set_editor_property("target_skeleton", skeleton)
blueprint_factory.set_editor_property("parent_class", unreal.AnimInstance)

animation_blueprint = asset_tools.create_asset(
    "ABP_TestCharacter",
    "/Game/Tests",
    unreal.AnimBlueprint,
    blueprint_factory
)

# Step 4: Save
if animation_blueprint:
    unreal.EditorAssetLibrary.save_asset(asset_path, only_if_is_dirty=False)
    print(f"Created: {asset_path}")

Opening in Editor:

python
# Use open_editor_for_assets (plural) with list
editor_subsystem = unreal.get_editor_subsystem(unreal.AssetEditorSubsystem)
opened = editor_subsystem.open_editor_for_assets([animation_blueprint])

⚠️ DO NOT use AssetEditorSubsystem.open_editor_for_asset() (singular) - it will cause AttributeError.

Discover Animation Blueprint Structure

python
import unreal

abp_path = "/Game/Blueprints/SandboxCharacter_CMC_ABP"

# Get overview
parent = unreal.AnimGraphService.get_parent_class(abp_path)
skeleton = unreal.AnimGraphService.get_skeleton(abp_path)
print(f"Parent: {parent}, Skeleton: {skeleton}")

# List all graphs
graphs = unreal.AnimGraphService.list_graphs(abp_path)
for g in graphs:
    print(f"Graph: {g.graph_name} ({g.graph_type}), Nodes: {g.node_count}")

List State Machines and States

python
import unreal

abp_path = "/Game/ABP_Character"

# Find all state machines
machines = unreal.AnimGraphService.list_state_machines(abp_path)
for machine in machines:
    print(f"\nState Machine: {machine.machine_name} ({machine.state_count} states)")

    # List states in this machine
    states = unreal.AnimGraphService.list_states_in_machine(abp_path, machine.machine_name)
    for state in states:
        end_marker = " [END]" if state.is_end_state else ""
        print(f"  - {state.state_name} ({state.state_type}){end_marker}")

Navigate to Specific State

python
import unreal

abp_path = "/Game/Blueprints/SandboxCharacter_CMC_ABP"

# Open the AnimBP and navigate to a specific state
unreal.AnimGraphService.open_anim_state(
    abp_path,
    "State Controller",  # State machine name
    "In Air Loop"        # State name
)

Inspect Transitions

python
import unreal

abp_path = "/Game/ABP_Character"
machine_name = "Locomotion"

# Get all transitions in a state machine
transitions = unreal.AnimGraphService.get_state_transitions(abp_path, machine_name)
for t in transitions:
    auto = " [AUTO]" if t.is_automatic else ""
    print(f"{t.source_state} -> {t.dest_state} (blend: {t.blend_duration}s){auto}")

# Get transitions for a specific state
idle_transitions = unreal.AnimGraphService.get_state_transitions(abp_path, machine_name, "Idle")

Authoring State Machines (build / edit)

⭐ Fastest path: declarative build_state_machine

Build (or extend) a whole machine from one JSON spec in a single atomic, idempotent call. Re-running it never duplicates existing states/transitions. It sets animations, rules, the entry state, then compiles — and returns a JSON report.

python
import unreal, json

abp = "/Game/ABP_Character"
BT  = "editor_toolset.toolsets.blueprint.BlueprintTools"

# Add the variables the rules read FIRST, then compile so the rules can resolve them.
# Variable creation + compile are ENGINE BlueprintTools (call_tool), not VibeUE:
call_tool(BT, "add_variable", {"blueprint": {"refPath": abp}, "variable_name": "Speed",   "variable_type": "float"})
call_tool(BT, "add_variable", {"blueprint": {"refPath": abp}, "variable_name": "bAttack", "variable_type": "bool"})
call_tool(BT, "compile_blueprint", {"blueprint": {"refPath": abp}})

spec = {
    "states": [
        {"name": "Idle",   "animation": "/Game/Anims/Idle",   "loop": True,  "pos": [0, 0]},
        {"name": "Walk",   "animation": "/Game/Anims/Walk",   "loop": True,  "pos": [350, 0]},
        {"name": "Attack", "animation": "/Game/Anims/Attack", "loop": False, "pos": [350, 250]},
    ],
    "transitions": [
        {"from": "Idle",   "to": "Walk",   "rule": {"type": "comparison", "variable": "Speed", "op": "greater", "value": 10}, "blend": 0.15},
        {"from": "Walk",   "to": "Idle",   "rule": {"type": "comparison", "variable": "Speed", "op": "less_equal", "value": 10}},
        {"from": "Idle",   "to": "Attack", "rule": {"type": "bool", "variable": "bAttack"}},
        {"from": "Attack", "to": "Idle",   "rule": {"type": "automatic"}},  # when the attack anim ends
    ],
    "entry": "Idle",
}

report = json.loads(unreal.AnimGraphService.build_state_machine(abp, "Locomotion", json.dumps(spec)))
print(report)  # {"success":true,"states_created":3,"transitions_created":4,"errors":[]}

rule.type ∈ bool (variable, optional invert), comparison (variable,op,value), automatic (optional trigger_time), always (always-true), or omit rule to leave it inert.

Manual / incremental authoring

python
import unreal
abp = "/Game/ABP_Character"

# State machine + states
unreal.AnimGraphService.add_state_machine(abp, "Locomotion", 0, 0)
unreal.AnimGraphService.add_state(abp, "Locomotion", "Idle", 0, 0)
unreal.AnimGraphService.add_state(abp, "Locomotion", "Walk", 350, 0)

# One call: create+assign the sequence player inside the state AND wire it to Output Pose
unreal.AnimGraphService.set_state_animation(abp, "Locomotion", "Idle", "/Game/Anims/Idle", True)
unreal.AnimGraphService.set_state_animation(abp, "Locomotion", "Walk", "/Game/Anims/Walk", True)

# Default/entry state
unreal.AnimGraphService.set_entry_state(abp, "Locomotion", "Idle")

# Transitions + rules (rules are mandatory — see top gotcha)
unreal.AnimGraphService.add_transition(abp, "Locomotion", "Idle", "Walk", 0.15)
unreal.AnimGraphService.set_transition_rule_comparison(abp, "Locomotion", "Idle", "Walk", "Speed", "greater", 10.0)
unreal.AnimGraphService.set_transition_priority(abp, "Locomotion", "Idle", "Walk", 1)

# Compile via engine BlueprintTools:
call_tool("editor_toolset.toolsets.blueprint.BlueprintTools", "compile_blueprint", {"blueprint": {"refPath": abp}})

Verify before claiming success — validate_state_machine

python
result = unreal.AnimGraphService.validate_state_machine(abp, "Locomotion")
print(f"valid={result.is_valid}  states={result.state_count}  transitions={result.transition_count}")
for e in result.errors:   print("ERROR:", e)    # inert transitions, no entry state
for w in result.warnings: print("WARN :", w)    # unreachable states, states with no animation

Treat any errors as a build failure. The most common error is an inert transition (a transition with no rule) — fix it with one of the set_transition_rule_* calls.


Find Used Animation Sequences

python
import unreal

abp_path = "/Game/ABP_Character"

sequences = unreal.AnimGraphService.get_used_anim_sequences(abp_path)
for seq in sequences:
    print(f"{seq.sequence_name}")
    print(f"  Path: {seq.sequence_path}")
    print(f"  Used in: {seq.used_in_graph}")

Focus on Node by ID

python
import unreal

abp_path = "/Game/ABP_Character"

# If you have a node GUID from get_nodes_in_graph
node_id = "ABC123-DEF456-..."
unreal.AnimGraphService.focus_node(abp_path, node_id)

Data Structures

Python Naming Convention: C++ types like FAnimStateMachineInfo are exposed as AnimStateMachineInfo in Python (no F prefix).

AnimStateMachineInfo

PropertyTypeDescription
machine_namestringDisplay name of the state machine
node_idstringNode GUID
state_countintNumber of states
parent_graph_namestringGraph containing this machine

AnimStateInfo

PropertyTypeDescription
state_namestringDisplay name of the state
node_idstringNode GUID
state_typestring"State", "Conduit", "Entry"
is_end_stateboolTrue if no outgoing transitions
pos_xfloatX position in graph
pos_yfloatY position in graph

AnimTransitionInfo

PropertyTypeDescription
transition_namestringDisplay name
node_idstringNode GUID
source_statestringSource state name
dest_statestringDestination state name
priorityintPriority (lower = higher)
blend_durationfloatCrossfade time in seconds
is_automaticboolAuto-transition based on sequence
rule_typestringNone (inert), Bool, Comparison, Automatic, Custom
rule_variablestringBound variable name (for Bool/Comparison rules)
rule_summarystringHuman-readable rule, e.g. Speed > 150, bIsDead == true
has_ruleboolFalse = inert (never fires). True = transition can fire

AnimStateMachineValidationResult

Returned by validate_state_machine().

PropertyTypeDescription
is_validboolTrue when there are no blocking errors
state_countintNumber of states
transition_countintNumber of transitions
errors[string]Blocking problems (inert transitions, no entry state)
warnings[string]Non-blocking issues (unreachable states, states with no animation)

Driving bones directly — skeletal controls, no state machine

Not every AnimBP is a state machine. A spinning rotor, a windmill sail, a turret yaw, a rudder that follows a variable — all are a pose piped through Modify Bone nodes, which is a different graph shape and has its own traps.

The chain is always: a pose source → Local To Component → one Modify Bone per bone → Component To Local → Output. Skeletal controls only operate in component space, and connect_anim_nodes does not insert the space conversions for you.

python
import unreal
AG, BS = unreal.AnimGraphService, unreal.BlueprintService
PATH, G = "/Game/ABP_Windmill", "AnimGraph"

REF = "SPAWN AnimGraphNode_LocalRefPose|Local Space Ref Pose"   # no sequence needed
L2C = "SPAWN AnimGraphNode_LocalToComponentSpace|Local To Component"
C2L = "SPAWN AnimGraphNode_ComponentToLocalSpace|Component To Local"

ref = BS.create_node_by_key(PATH, G, REF, -900, -80)
l2c = BS.create_node_by_key(PATH, G, L2C, -640, -80)
AG.connect_anim_nodes(PATH, G, ref, "Pose", l2c, "LocalPose")

mb = AG.add_modify_bone_node(PATH, G, "sails", -340, -80)
AG.connect_anim_nodes(PATH, G, l2c, "ComponentPose", mb, "ComponentPose")
getter = BS.create_node_by_key(PATH, G, "SPAWN K2Node_VariableGet|Get SailRotation", -400, 200)
BS.connect_nodes(PATH, G, getter, "SailRotation", mb, "Rotation")

c2l = BS.create_node_by_key(PATH, G, C2L, 0, -80)
AG.connect_anim_nodes(PATH, G, mb, "Pose", c2l, "ComponentPose")
AG.connect_to_output_pose(PATH, G, c2l, "Pose")

Pin names to remember: LocalPose in / ComponentPose out on Local To Component; ComponentPose in / Pose out on Modify Bone and Component To Local.

  • Reconnecting a pose input replaces the old link. Pose inputs are 1:1, so connect_anim_nodes (and connect_to_output_pose) to an already-wired single-link input now breaks the existing link and wires the new source in its place — no need to disconnect_anim_node(node, "Pose") first — and returns False (logging a Warning with the schema's reason) when the schema refuses. Previously it stacked an illegal second link that compiled the AnimBP to BS_ERROR with an empty error list.

⚠️ Modify Bone ignores its Rotation pin until you set the mode

add_modify_bone_node creates the node with rotation_mode, translation_mode and scale_mode all set to Ignore. You can connect the Rotation pin, compile clean, and see absolutely nothing move — there is no warning. Set the mode on the node's inner node struct after creating it:

python
for i in range(0, 12):
    o = unreal.find_object(None, f"{PATH}.{name}:{G}.AnimGraphNode_ModifyBone_{i}")
    if not o:
        continue
    n = o.get_editor_property("node")
    n.set_editor_property("rotation_mode", unreal.BoneModificationMode.BMM_ADDITIVE)
    n.set_editor_property("rotation_space", unreal.BoneControlSpace.BCS_COMPONENT_SPACE)
    n.set_editor_property("translation_mode", unreal.BoneModificationMode.BMM_IGNORE)
    n.set_editor_property("scale_mode", unreal.BoneModificationMode.BMM_IGNORE)
    o.set_editor_property("node", n)      # write the struct back, or the change is lost

BMM_ADDITIVE and BMM_REPLACE behave identically when the bone is at identity in the ref pose.

⚠️ Variable getter names differ between BP variables and C++ properties

create_node_by_key needs the spawner key, which embeds the node's display name, and the two kinds of variable are spelled differently:

Variable lives onDisplay nameSpawner key
The AnimBP itself (add_member_variable)Get SailRotationSPAWN K2Node_VariableGet|Get SailRotation
A C++ UAnimInstance subclassGet Sail Rotation (spaced)SPAWN K2Node_VariableGet|Get Sail Rotation

Never hard-code either — discover_nodes(PATH, "SailRotation", "", 20) and match on display_name, which works for both.

Continuous motion without an animation asset

Put the accumulator in the AnimBP's EventGraph on Event Blueprint Update Animation (its DeltaTimeX pin), write a float, and convert it to the Rotator the Modify Bone reads:

DeltaTimeX ─┐
            ├─ float * float ─ float * float ─┐        (RPM → deg/sec is × 6)
SpinRPM ────┘                    6.0 ─────────┤
                                              ├─ float + float ─→ SET SailAngle
SailAngle (get) ──────────────────────────────┘
SailAngle (get) ─→ MakeRotator(Roll=) ─→ SET SailRotation

Float maths nodes are FUNC KismetMathLibrary::Multiply_DoubleDouble and ::Add_DoubleDouble (display names float * float / float + float) — Blueprint "float" is a double in UE5. MakeRotator is FUNC KismetMathLibrary::MakeRotator with pins Roll, Pitch, Yaw.

Verify it is actually running rather than trusting the compile: in PIE read the variable off the live instance, twice, in separate execute_python_code calls (see the pie-testing skill — Python blocks the game thread, so a sampling loop inside one call returns the same value every time).

python
comp = actor.get_components_by_class(unreal.SkeletalMeshComponent)[0]
ai = comp.get_anim_instance()
print(ai.get_editor_property("SailAngle"), comp.get_socket_rotation("sails").roll)

Common Patterns

Check if Asset is AnimBP

python
import unreal

if unreal.AnimGraphService.is_anim_blueprint("/Game/SomeAsset"):
    # It's an AnimBP, safe to use AnimGraphService
    machines = unreal.AnimGraphService.list_state_machines("/Game/SomeAsset")

Iterate All States Across All Machines

python
import unreal

abp_path = "/Game/ABP_Character"

machines = unreal.AnimGraphService.list_state_machines(abp_path)
for machine in machines:
    states = unreal.AnimGraphService.list_states_in_machine(abp_path, machine.machine_name)
    for state in states:
        print(f"{machine.machine_name}/{state.state_name}")

Sample scripts (run via execute_python_code)

  • scripts/build_state_machine.txt — add a state machine with two states, set state animations, add a transition, compile.

Additional gotchas

  • connect_anim_nodes replaces an existing pose link on the target input rather than erroring; it returns False if the schema refuses the connection, so check the return instead of hunting for a BS_ERROR with an empty error list.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Animation Blueprint AI skill do?

Navigate, inspect, and author Animation Blueprints — state machines, states, transitions, and transition rules (AnimGraphService). Use when the user asks to create or edit an Animation Blueprint/AnimBP, add a state machine or states, wire transitions between states, set a state's animation, or inspect AnimGraph structure.

Why use Animation Blueprint on TypingMind?

Because you install it once and use it with any model. Animation Blueprint is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Animation Blueprint in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/kevinpbuckley/VibeUE/tree/master/Content/Skills/animation-blueprint. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Animation Blueprint?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Animation Blueprint?

As many as you like. As long as a model supports skills, you can use Animation Blueprint with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Animation Blueprint AI skill free?

Yes. It is published on GitHub by kevinpbuckley under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇