Skip to main content
Glama
huikku

Kitsu MCP Server

by huikku

Kitsu MCP server

Connect any AI agent to Kitsu

A Model Context Protocol server that gives LLM agents (Claude Desktop, Claude Code, Cursor, …) access to Kitsu — CGWire's open-source production tracker — through its Zou API and the official Gazu SDK.

30 tools, one write family, a dry_run safety gate on every write. Tested live against a self-hosted Kitsu — including whole-project ShotGrid ↔ Kitsu and ftrack → Kitsu migrations carrying structure + statuses + casting + thumbnails + video version media (multiple versions) + notes + custom fields, verified by read-back and torn down with remove_project.

Part of a small tracker-MCP quintet — see Migrating projects between platforms.

The 30 tools

Generic power tools (full reach over the Zou REST API):

  • get — GET any Zou route (the escape hatch)

  • create · update · delete — write to any Zou model collection

  • remove_project — delete a project (Kitsu requires close→force; the generic delete can't)

Media / versions (a "version" = a preview file on a task; thumbnails derive from previews):

  • upload_preview — upload an image/movie as a version on a task (+ optionally set the entity thumbnail)

  • download_preview — pull a preview's media (image or movie) to disk

  • list_previews — versions on a task

  • log_time — log time on a task (the person must be assigned to it — a Kitsu rule)

Schema & discovery (Kitsu is configurable — learn the site first):

  • list_projects

  • list_asset_types · list_task_types · list_task_statuses (with workflow flags) · list_departments

  • list_metadata_descriptors · add_metadata_descriptor · set_metadata — Kitsu's schema-as-data custom fields (for_client + per-department); define a field and set values (migration carries custom fields)

Typed convenience (structure, creation + the review loop):

  • list_assets · list_shots · list_sequences · list_tasks

  • new_project · new_sequence · new_asset · new_shot · new_task (entity-aware type resolution)

  • set_task_status — post a comment that sets a task's status (the Kitsu review loop)

  • set_casting — cast assets into a shot (breakdown)

  • project_summary — a normalized project snapshot (counts + per-shot cast/status/thumbnail, canonical statuses) for cross-tracker verify/diff

  • whoami

The new_* + media + set_casting tools make Kitsu a viable migration target — read structure, statuses, casting, thumbnails and version media from another tracker (e.g. shotgrid-mcp) and recreate the project here. See Migrating projects between platforms.

Dry-run modes

Every write takes dry_run (default false = perform the write). create / update / delete / set_task_status support two preview levels:

  • dry_run="plan" (or true) — client-side echo of the intent. No server contact.

  • dry_run="preflight" — a real dry run: resolves every reference against live data, validates (does the parent exist? is the status name valid?), returns a before→after diff for updates, and a verdict of ok / would_failwithout writing anything.

Set MCP_PLAN_LOG=/path/plan.jsonl and every plan/preflight is appended as a line, so a whole dry-run migration produces a reviewable plan file. (Other write tools take dry_run as a plain boolean.)

Related MCP server: Kitsu MCP Server

Install

pip install -r requirements.txt        # fastmcp, gazu

Configure (credentials)

var

value

KITSU_URL

your Kitsu API base, including /api — e.g. https://your.kitsu.host/api

KITSU_EMAIL

a Kitsu user (a dedicated bot account is recommended)

KITSU_PASSWORD

that user's password

For local dev you can drop them in a .env next to server.py (gitignored — see .env.example).

Run / wire into a client

python3 server.py        # stdio transport

Claude Code:

claude mcp add kitsu \
  -e KITSU_URL=https://your.kitsu.host/api \
  -e KITSU_EMAIL=bot@studio.com -e KITSU_PASSWORD=•••• \
  -- python3 /path/to/kitsu-mcp/server.py

Examples (what the agent calls)

get("data/projects")                                   # raw route, full reach
list_shots("<project_id>")                             # typed convenience
list_task_statuses()                                   # workflow-as-data (is_done/for_client/…)
new_asset("<project_id>", "Character", "Hero")         # asset-type name resolved for you
set_task_status("<task_id>", "wip", "Starting blocking")
create("shots", {"project_id":"…","name":"sh010"}, dry_run=True)   # preview, commit nothing

Migrating projects between platforms

This is one of four sibling tracker MCPs, each exposing the same shape (generic CRUD + schema + typed convenience, with a dry_run gate):

Tracker

MCP

ShotGrid / Flow Production Tracking

huikku/shotgrid-mcp

ftrack Studio

huikku/ftrack-mcp

Kitsu (CGWire)

this repo

AYON (Ynput)

huikku/ayon-mcp

NIM (NIM Labs)

huikku/nim-mcp

📊 See COMPARISON.md for a side-by-side of the five trackers (data model, status vocabularies) and the migration incompatibilities to know about (casting can't round-trip through ftrack; statuses must be mapped; Kitsu projects need remove_project to delete; heavy publish bytes stay on storage — only references carry).

🧪 See TESTING.md for how these servers are validated — live round-trip tests, two-level dry-run checks, and the cross-tracker migration matrix (including what is not yet covered, stated plainly).

Because all four speak the same production model (Project → Sequence/Asset → Shot → Task → Version/Status) and present a uniform tool surface, an agent with two of them loaded can migrate a project from one platform to another — read the structure from the source tracker, map the schema, and recreate it in the target:

"Read every sequence, asset, shot and task from the ShotGrid project, then recreate them in Kitsu."

The agent calls find/list_* on the source MCP and create/new_* on the target — no bespoke migration script. (This trio grew out of exactly that exercise: a single project copied across ShotGrid, ftrack and Kitsu to prove the tracker-agnostic, agent-native approach.)

Kitsu migration gotchas (live-verified on a full 1,200-shot reverse sync)

  • Zou ignores client-supplied ids on create — it always mints its own UUID. If you're syncing from a system that shares ids with Kitsu, that only holds for rows that originated in Kitsu; anything you create must be re-fetched and mapped by a natural key (persons → email, entities → name+parent).

  • USER_LIMIT defaults to 100 — person creates fail with 400 "User limit reached" at the cap. Self-hosted: set the USER_LIMIT env for zou (or patch zou/app/config.py) and restart the zou processes (supervisorctl restart zou-processes:* in the all-in-one container — postgres keeps running, data intact).

  • Time-spent action route is method-restricted on some buildsPOST /actions/tasks/<id>/time-spents/<date> can 405; the generic POST /data/time-spents collection accepts {task_id, person_id, date, duration} (minutes). log_time falls back automatically.

  • Casting carries via PUT /data/projects/<project>/entities/<shot>/casting with [{asset_id, nb_occurences}] — use set_casting; breakdown pages stay empty without it.

Credits

MIT licensed.


Built by John Huikku · alienrobot.com

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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/huikku/kitsu-mcp'

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