motion-mcp-server

motion-mcp-server

MCP server for reading and editing Apple Motion template files (.motn/.moti), enabling inspection and modification of layers, parameters, keyframes, and publish settings, plus saving and validation.

Category
访问服务器

README

motion-mcp-server

An MCP server for reading and editing Apple Motion (.motn / .moti) template files.

Scope — read this first

This server edits static template XML on disk. It does not, and cannot, drive a live Motion.app session.

Final Cut Pro exposes a rich AppleScript/Apple Events dictionary, which is what makes a "live control" MCP server (see fcp-mcp-server, the project that inspired this one's architecture) possible for FCP. Apple Motion's own scriptability is limited to three verbs: activate, open, quit. There is no dictionary for pushing parameter values, scrubbing the playhead, or reading back rendered frames from a running Motion document.

So this server's actual capability is: parse a .motn/.moti file (both are the same ozml XML format Motion.app itself writes), let you inspect and mutate its layer/parameter/keyframe/publish-settings tree, and save the result to a new file. Getting the result on screen means opening the written file in Motion.app yourself — motion_open_in_motion does that handoff — or handing a published/rendered template to Final Cut Pro, which does have the rich Apple Events surface (see the sibling fcpxml/commandpost MCP servers for that half of a pipeline).

What it can do

Five tool groups, 17 tools:

  • inspectmotion_open, motion_list_layers, motion_list_text_layers, motion_get_parameter, motion_list_keyframes, motion_list_rig
  • animatemotion_set_text, motion_set_parameter_value, motion_set_color, motion_create_keyframe_curve, motion_add_keyframe
  • structuralmotion_clone_layer (duplicate an existing <layer> subtree in place — see "Adding new layers" below)
  • rigmotion_publish_parameter, motion_unpublish_parameter (Final Cut Pro's Inspector reads these published/rig parameters when the template is used as an FCP title/generator/effect)
  • delivermotion_save_as, motion_open_in_motion, motion_validate

Authoring motion from scratch

motion_create_keyframe_curve seeds a brand-new <curve> on a leaf parameter that has never been keyframed in Motion — actual dynamic/ procedural animation authoring, not just editing curves Motion already created. This was initially considered too risky to guess at (a curve's type attribute is data-type-specific, and guessing wrong produces a file Motion can't open), so it's grounded in a structural scan of ~4,700 real Motion documents on the machine this was built on: every keyframed leaf parameter observed — Position X/Y/Z, Scale, Angle/Rotation, Opacity, RGB(A) color channels, behavior Amount parameters — used the same universal scalar curve (type="1"), because Motion animates a compound property (Position, Color, ...) by keyframing each numeric child parameter independently rather than through one multi-component curve. A second curve type ("0") does exist on some non-numeric/enum-like parameters (Random Seed, Blend Mode, Interpolation) but never carried an actual keypoint in that scan, so this tool deliberately doesn't attempt to synthesize it — there's no real-file evidence for what a keyed type="0" curve should look like. Verified against both the synthetic fixture and an ephemeral, never-committed round-trip against a real local .motn file.

Once a parameter has a curve — whether Motion created it or motion_create_keyframe_curve did — motion_add_keyframe appends further keypoints to it, in time order.

Adding new layers

motion_clone_layer duplicates an existing <layer> subtree (including any nested child layers, e.g. a Group's children) and inserts the copy as the next sibling of the original. This is the supported way to add new structure to a template — it's a clone, not a from-scratch synthesizer, and that's a deliberate, evidence-based choice, not a missing feature.

A structural scan of real Motion documents (same discipline as the curve work above) found two reasons hand-authoring a brand-new layer from scratch is materially riskier than editing an existing one: a Text-layer scenenode tree is far deeper than any parameter this server otherwise touches (paragraph/scroll/crawl margins, per-run styles, cross-referencing <host> links), and the numeric factoryID for the same semantic kind (e.g. "Text") is not stable across documents — it varied across every personal .motn/.moti file scanned. Hardcoding a factory id would silently produce a file that opens fine in the document it was copied from and fails to open, or resolves to the wrong factory, in another.

Cloning sidesteps both problems: the subtree being duplicated is already valid, real, Motion-authored XML from the same document, so nothing about its factory graph needs to be guessed. The only thing motion_clone_layer actually computes is id remapping — every layer/scenenode id inside the cloned subtree is reassigned to a freshly allocated, document-unique value (scanned across the entire document, not just the subtree, so it can never collide with anything already present), and any <host hostID="..."> link that points inside the cloned subtree is rewritten to match. A <host> link pointing outside the clone — an intentional cross-reference to an unrelated part of the document — is left untouched, since remapping it would silently break that reference. Verified against the synthetic fixture (including a nested-group case exercising both the internal- and external-<host> fixup paths) and two ephemeral, never-committed round-trips against real local .motn files — one a flat layer, one a layer with a nested child.

The ozml schema

Ground truth for the tag shapes this server relies on was read directly from real Motion.app output on the machine this was built on (Motion Projects/Autosave Vault/*.motn, Motion Templates.localized/*.moti), not assumed. See the module docstring in motion/parser.py for the annotated shape, including two nesting traps that are easy to get wrong by guessing:

  • Top-level layers are direct children of <scene>, not <timeline> (<timeline> in this schema is only a UI display-state block).
  • Text face/outline/glow color and font live under a <style> element that's a sibling of a scenenode's <parameter> tree, not nested inside it.

No personal .motn/.moti file is committed to this repository. The test suite runs against fixtures/sample.motn, a small hand-written synthetic document that reproduces the same tag shapes.

Install

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

Run the tests

.venv/bin/python3 -m pytest tests/ -v

Use it from Claude

Add to your MCP client config (Claude Code's .mcp.json, or the Claude desktop app's claude_desktop_config.json):

{
  "mcpServers": {
    "motion": {
      "command": "/absolute/path/to/motion-mcp-server/.venv/bin/python3",
      "args": ["/absolute/path/to/motion-mcp-server/server.py"]
    }
  }
}

Typical workflow: motion_open a template → inspect with the inspect tools → mutate with animate/structural/rig tools → motion_save_as a new file (never overwrites the source implicitly) → motion_validate to confirm the write round-trips → motion_open_in_motion for visual QC.

License

MIT — see LICENSE. Architecture informed by DareDev256's MIT-licensed fcp-mcp-server; this is an independent implementation for a different file format, not a fork.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选