spine-anim-mcp
An MCP server that converts layered PSD characters into Spine 4.2 rigs with deterministic, parametric 2D/2.5D animations (idle, walk, run, jump, attack, hit) ready for the Spine editor and Unity.
README
spine-anim-mcp
An MCP server that turns a layered PSD character into a Spine 4.2 rig and generates deterministic, parametric 2D/2.5D animations — idle, walk, run, jump, attack, hit — ready for the Spine editor and Unity.
<!-- Real 2D character animated entirely by the procedural engine. --> <p align="center"> <img src="examples/adventurer/walk.gif" width="200" alt="walk"/> <img src="examples/adventurer/run.gif" width="200" alt="run"/> <img src="examples/adventurer/idle.gif" width="200" alt="idle"/> </p> <p align="center"><em>Walk, run, idle — same rig, generated procedurally, zero hand-keyed frames.</em></p>
Most PSD→Spine tools stop at rigging — they hand you a skeleton and leave the animation to you. This one generates the animations too, with pure math: same parameters in → byte-identical output. Reproducible, diffable, no broken AI-guessed poses.
PSD ──▶ rig (bones + slots + atlas) ──▶ procedural animations ──▶ .json + .atlas + .png
Why deterministic instead of AI?
Generative pose prediction produces anatomically broken results that cost more time to fix than to author by hand. Every animation here is a sampled mathematical function — a walk cycle is antiphase leg sines with opposing arm swing and a 2× vertical bob, not a guess. The trade-off is explicit: this tool owns locomotion and combat basics; expressive one-off animation stays in the Spine editor where an artist's eye belongs.
Features
- PSD → joint-correct rig. Layers named after body parts (
head,torso,arm_left,leg_right, …) become a topologically-ordered Spine 4.2 skeleton with anatomical pivots (upper-arm rotates at the shoulder, not the image center). - Six procedural generators, each fully parametric (see table below).
- Loop-correct cycles.
idle/walk/runare authored so frame 0 == frame N — seamless Spine looping, no popping. - Validated before write. Structural invariants the runtime reader assumes (single root, topological bone order, resolvable references, monotonic keyframe times) are checked at generation time, so failures are clear errors instead of silent import breakage.
- Idempotent output. Identical inputs overwrite with byte-identical content and touch no other file in the output directory.
- Unity-ready. Emits
.json+.atlas+.png; full import guide indocs/UNITY.md.
Validation status
Phase 1 — implemented and validated end-to-end on two PSDs: a synthetic
stick rig (examples/hero) and a real stylized 2D character
(examples/adventurer) — a shaded adventurer with tunic, pants, and boots, split
into 17 convention-named layers.
Real character, posed by the procedural engine
Live animations (looping GIFs), all from the same rig with no hand-keying:
<p align="center"> <img src="examples/adventurer/walk.gif" width="180" alt="walk"/> <img src="examples/adventurer/run.gif" width="180" alt="run"/> <img src="examples/adventurer/jump.gif" width="180" alt="jump"/> <img src="examples/adventurer/attack.gif" width="180" alt="attack"/> </p>
Source PSD → idle → walk (static reference):

Per-animation keyframe breakdowns: examples/adventurer/walk_cycle.png,
attack_sequence.png, jump_sequence.png.
Testing against a real character surfaced — and fixed — several issues that flat rectangles hid: limb parts must overlap at joints to avoid gaps when bent; a bone-hierarchy bug had the foot parented to the upper leg instead of the shin, so it tracked the wrong segment and detached when the knee bent; and the walk now uses 2-bone analytic IK foot-lock — the ankle is placed on a plant/swing path (planted on the ground through stance, arcing forward in swing) and the leg is solved to reach it. Because the foot is the IK target, it stays locked to the shin through the entire stride. No detachment.
Recommended before shipping art: open the generated
.jsonin the actual Spine 4.2 editor and import into spine-unity to confirm against the real runtime. The headless renderer (examples/render_posed.py) solves forward kinematics independently — useful, but it is not the Spine runtime itself.
Animation catalog
| Type | Loops | Method | Key parameters (defaults) |
|---|---|---|---|
idle |
✓ | sine breathing on chest/torso, half-freq head sway, arm drift | duration 2.0, breath_amp 2.0, sway_amp 1.0 |
walk |
✓ | antiphase leg sine, opposing arm swing, 2× bob, torso counter-rotate | duration 1.0, stride 28, arm_swing 22, bob 3 |
run |
✓ | walk with larger amplitudes + constant forward lean | duration 0.6, stride 45, arm_swing 40, bob 7, lean 8 |
jump |
✗ | crouch → launch → apex → land → settle pose keys, eased | duration 0.9, crouch 18, rise 40 |
attack |
✗ | windup → stepped strike → follow-through; hand picks arm |
duration 0.5, windup 35, swing 80, hand "right" |
hit |
✗ | sharp recoil on root/torso/head then settle | duration 0.35, knockback 14 |
Generators are rig-agnostic within the humanoid convention: a 4-bone stick figure and an 18-bone character both animate; roles the rig lacks are silently skipped.
Install
git clone https://github.com/K-ulucay/spine_anim_mcp.git
cd spine-anim-mcp
pip install -e . # pulls mcp, pydantic, Pillow, psd-tools
Requires Python 3.11+.
Run the tests
python3 tests/test_pipeline.py
Run the MCP server
spine-anim-mcp # or: python -m spine_anim_mcp.server
Then point an MCP client (Claude Desktop / Claude Code) at it.
Quickstart
Given hero.psd with layers named head, neck, chest, torso, hip,
arm_upper_left, arm_lower_left, leg_upper_right, … ask your MCP client to
call:
import_psd_to_spine(
psd_path = "hero.psd",
animations = [
{ "type": "idle" },
{ "type": "walk", "params": { "stride": 34, "bob": 4 } },
{ "type": "run" },
{ "type": "attack", "name": "slash", "params": { "hand": "left", "swing": 95 } }
]
)
Output (in hero_spine/):
hero.json # skeleton + idle, walk, run, slash animations
hero.atlas # texture atlas
hero.png # packed atlas page
Import into Unity per docs/UNITY.md (note: rename
hero.atlas → hero.atlas.txt, spine-unity requires the .txt extension).
MCP tools
| Tool | Purpose |
|---|---|
import_psd_to_spine(psd_path, animations?, out_dir?, name?) |
Full pipeline: PSD → rig + animations → files. Defaults to idle + walk. |
animate_existing(skeleton_json_path, animations, out_dir?) |
Add animations to an existing Spine skeleton (bones auto-mapped by name). |
list_animation_types() |
List available generators. |
describe_animation_type(type) |
Tunable parameters + defaults for one type. |
animations is a list of { type, name?, params? }. type selects the
generator; optional name renames the produced animation; params overrides
defaults from the catalog above.
Layer naming
Layer names are matched to roles flexibly (lowercased, separators normalised), so
Left Arm, arm_l, upperarm.L, and arm_upper_left all resolve to the same
role.
| Region | Roles |
|---|---|
| Spine | root, hip, torso, chest, neck, head |
| Left arm | arm_upper_left, arm_lower_left, hand_left |
| Right arm | arm_upper_right, arm_lower_right, hand_right |
| Left leg | leg_upper_left, leg_lower_left, foot_left |
| Right leg | leg_upper_right, leg_lower_right, foot_right |
Full alias table: src/spine_anim_mcp/psd/conventions.py.
Project layout
src/spine_anim_mcp/
server.py FastMCP server + tool definitions
pipeline.py orchestration; idempotent file writes
psd/parser.py PSD -> flat part list (+ spec fallback for tests)
psd/conventions.py hierarchy, name->role aliases, pivot fractions
spine/schema.py Pydantic models = source of truth for Spine 4.2 JSON
spine/builder.py parts -> bones/slots/attachments (world->local transform)
spine/writer.py JSON serialiser + structural validator
anim/generators.py the procedural animation engine
atlas/writer.py shelf packer -> .atlas text + composite PNG
docs/
SPECIFICATION.md architecture, Spine 4.2 contract, animation math, roadmap
UNITY.md spine-unity 4.2 import + scripting guide
tests/
test_pipeline.py end-to-end test on a synthetic 18-bone humanoid
Roadmap
- [x] Real-PSD round-trip through the pipeline with FK-verified rig (
examples/hero) - [x] 2-bone IK foot-lock on walk/run (
anim/ik.py) — feet stay planted - [ ] Confirm
examples/adventurer/adventurer.jsonin the live Spine 4.2 editor + spine-unity - [ ] Extract real per-part PNG pixels into the atlas (currently bounds-only)
- [ ]
<part>[pivot]marker-layer support for per-part pivot overrides - [ ] Bezier easing on cyclic anims (currently linear/stepped) for snappier feel
- [ ] Mesh-deform + skin-swap timelines (stronger 2.5D perspective)
- [ ] Emit Spine IK constraints directly (so the editor re-solves), not just baked angles
Contributing
PRs welcome — especially:
- Real-PSD test fixtures and Spine/Unity round-trip reports. This is the most valuable contribution right now.
- New generators (add
gen_<name>(rig, **params)toanim/generators.py, register inGENERATORS, document params inserver.PARAM_DOCS). - Non-humanoid rig conventions (vehicles, creatures).
Generators must stay deterministic — no randomness, no model calls.
License
MIT — see LICENSE.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.