mcpField
M
MotionLint

MotionLint

ローカル
github.com/bobaba99開発ツール014 週間前に更新

MotionLint について

MotionLintは、実行中のWebページのアニメーションを監査し、ビジョンLLMで複数ビューポートのデザインやユーザーフローもレビューできます。フロントエンド開発者やコーディングエージェント向けに、APIキー不要の決定論的検査とCI用レポートを提供します。

主な機能

  1. 01アニメーション時間とイージングの測定
  2. 02視覚効果を減らす設定の確認
  3. 03複数ビューポートでのデザインレビュー
  4. 04ユーザーフローのアニメーション撮影
  5. 05SARIF・HTMLレポートの生成
  6. 06stdio MCPサーバーの提供

活用シーン

  1. 01マージ前に不適切な動きを検出
  2. 02複数ビューポートでページ体験をレビュー
  3. 03登録フローのアニメーションを分析
  4. 04CIで重大なUX問題をゲート

MCP 対応

MotionLintはClaude CodeとCursor向けにstdio MCPサーバーを提供します。実行中ページのレビュー結果をコーディングワークフローに渡します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"bobaba99-motionlint": {
"command": "npx",
"args": [
"-y",
"motionlint"
],
"env": {
"ANTHROPIC_API_KEY": "<ANTHROPIC_API_KEY>",
"OPENAI_API_KEY": "<OPENAI_API_KEY>",
"GOOGLE_API_KEY": "<GOOGLE_API_KEY>",
"OPENAI_BASE_URL": "<OPENAI_BASE_URL>"
}
}
}
}
起動コマンドnpx -y motionlint
設定が必要な環境変数
ANTHROPIC_API_KEYシークレットAnthropic API key for vision-LLM review. Optional — the deterministic audit needs no key, and Ollama, OpenAI or Google can be used instead.
OPENAI_API_KEYシークレットOpenAI API key for vision-LLM review. Optional.
GOOGLE_API_KEYシークレットGoogle API key for vision-LLM review. Optional.
OPENAI_BASE_URLOverride the OpenAI base URL to target an OpenAI-compatible endpoint. Optional.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmmotionlint0.2.1

ツール

5

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
urlstringはいレビューする URL。
modelstringいいえモデルの上書き設定。
formatenumいいえ出力形式(デフォルト:md)。'html' は見栄えがよく、共有しやすいレポートです。md | json | sarif | html
recordbooleanいいえキャプチャの動画を録画します。
new_onlybooleanいいえ同じ URL の過去の実行で見つかっていない問題のみを報告します。
providerstringいいえLLM プロバイダーの上書き設定(auto|ollama|anthropic|openai|google|mock)。
wait_forstringいいえキャプチャ前に待機する CSS セレクターまたは 'networkidle'。
viewportsarrayいいえキャプチャするビューポート(デフォルト:mobile + desktop)。
max_findingsnumberいいえ重要度順に上位 N 件の指摘のみを残します(エージェントの注目点)。
max_pr_annotationsnumberいいえSARIF のみ:レポートごとに最大 N 件の結果を出力し、重大度順に並べます(レビュアーの疲労を防止)。

詳細

MotionLint

npm version license: MIT CI

どんなページでも、アニメーションの品質を1つのコマンドでスコア化できます。APIキーも設定も不要です。

npx motionlint audit http://localhost:3000 --open

ターミナルで実行中の motionlint audit:デモアプリの /loading ルートは、duration、easing、アクセシビリティに関する指摘を受け、64/100のスコアを獲得

決定論的です。稼働中のページを測定し、LLMは使用しません。最初に一度だけ、npx playwright install chromiumを実行してください。

MotionLintは、アプリが実際に提供しているモーション(継続時間、イージング曲線、スタガー間隔、終了タイミング、動きを減らす設定への対応)を測定し、公開済みのアニメーション基準に照らしてスコア化します。ドロップダウンのイーズイン、600msのモーダル、0から拡大するカード、タッチ操作で発生するホバーモーションなどをすべて検出し、測定値と具体的な修正方法を提示します。

監査は無料で、オフラインで実行できます。APIキーを追加すると、MotionLintはビジョンLLMによるデザインレビューも行います。複数のビューポートのスクリーンショットと、実際のユーザージャーニーを50ms間隔で撮影したフレームバーストをモデルが評価し、ランク付けした指摘をコーディングエージェントに返します。Claude CodeやCursor内でMCP サーバーとして実行できます。

これが必要な理由

AIコーディングエージェントはJSX、HTML、CSSを読みますが、ユーザーが実際に見て、クリックし、アニメーションを目にするものは確認できません。プロンプトのルールはエージェントに「こうあるべき」という内容を伝えますが、実際に「どうなったか」を確認するものはありません。スライドインするはずのモーダルが突然表示されたり、ローディング状態が省略されたり、フォーカスリングが消えたりします。これらは差分には現れないため、マージ前のコードレビューでは検出できません。

MotionLintは、実行中のアプリを測定し、その評価をフィードバックすることで、このループを閉じます。

他との違い

MotionLintビジュアルリグレッションツール(Percy、Chromatic、Playwright snapshots)AIデザイン生成ツール(v0、Galileo、Claude Design、Stitch)
決定論的なモーション監査13項目を稼働中のページから測定 — APIキー不要、$0✗✗
複数ビューポートのUXレビュー12の観点にわたる、ランク付けされた指摘ピクセル差分のみプロンプトから新しいレイアウトを生成
アニメーションレビューCDPスクリンキャストで50ms間隔のフレームバーストを撮影 → コンタクトシートを作成 → LLMで評価✗✗
実行中アニメーションの調整Shadow DOMのプレビュー+スライダー+Claude Codeへのエクスポート✗新しいモーションを生成しますが、既存のものは調整しません
ネイティブMCP サーバー✓ Claude Code / Cursor向けstdio MCP✗ツールによる
CIゲート✓ SARIF+コードスキャン用の終了コード✓ 画像差分のしきい値✗
品質の検証5つの最先端モデルで、24種類のフィクスチャを使ったストレステストの再現率100%該当なし該当なし

MotionLintが解決する概念的なギャップは、ビジュアルリグレッションツールが「何が変わったか」は検出しても、新しいピクセルが「良いかどうか」は判断できず、AIデザインツールはゼロから生成しても、すでに実行中のものをレビューしないことです。MotionLintはビジョンLLMで実際の動作をレビューし、その評価をコーディングのループにフィードバックします。

まずはこちら — APIキーは不要です

npx playwright install chromium          # one-time per machine (~300MB)
npx motionlint audit http://localhost:3000 --open

監査のセットアップはこれだけです。決定論的で、オフラインで実行でき、費用はかからず、読み込み可能なあらゆるURL(開発サーバー、ステージング環境、他の人のサイト)で動作します。Node 18以降が必要です。

チェック対象のルールはdocs/STANDARDS.mdで公開されています。インストールする前にお読みください。

次に:LLMデザインレビュー

1つのAPIキー(ANTHROPIC_API_KEY、OPENAI_API_KEY、GOOGLE_API_KEYのいずれか。無料で使うならOllamaをローカルで実行)を設定すると、さらに3つのコマンドで機能を利用できます。

npm install -g motionlint

# Multi-viewport UX review of a page → ranked findings across 12 dimensions.
motionlint review http://localhost:3000

# Animation review of a scripted user journey → frame contact sheet + report.
motionlint flow --spec flows/signup.json

# Interactive HTML tuner — every animation on the page, with live sliders.
motionlint tune http://localhost:3000
Claude Code / Cursor 内
claude mcp add motionlint -- npx -y motionlint mcp
すべてのフラグの概要 — CI ゲート、ルート検出、Storybook、ダークモード、ベースライン
# CI mode — non-zero exit on critical issues, SARIF output for code scanning.
motionlint review https://staging.acme.dev --ci --threshold critical --format sarif -o ux.sarif

# Polished, shareable HTML review with embedded screenshots + before/after fixes.
motionlint review http://localhost:3000 --format html -o review.html

# Review every route the site knows about (sitemap.xml + Next.js app/ directory).
motionlint review http://localhost:3000 --discover-routes

# Storybook mode — discover stories from /index.json, review each story iframe as its own route.
motionlint review http://localhost:6006 --storybook

# Color-scheme sweep — light and dark modes, plus Windows High Contrast.
motionlint review http://localhost:3000 --schemes --forced-colors --format html -o review.html

# Interaction affordances — grid each element's default/hover/focus/active states.
motionlint review http://localhost:3000 --state-grid

# Agent focus — keep only the top 5 findings, and only ones not seen in prior runs.
motionlint review http://localhost:3000 --max-findings 5 --new-only

# Before/after comparison — PR preview vs. production baseline.
motionlint review https://pr-123.preview.example.com --against https://prod.example.com

# Reviewer focus — cap the SARIF upload at 10 annotations per report.
motionlint review https://staging.acme.dev --format sarif -o ux.sarif --max-pr-annotations 10

# Pick a provider explicitly (auto-detect picks the first reachable one).
motionlint review http://localhost:3000 --provider anthropic --model claude-sonnet-5

# Track provider quality across runs + teach the reviewer from eval misses.
motionlint eval --provider anthropic --evolve

npm パッケージ:motionlint。

フローをレビューする際のターミナル出力例:

$ motionlint flow --spec flows/signup.json --provider anthropic
→ Running flow "signup-happy-path" against http://localhost:3000/signup (11 steps, 50ms intervals × 750ms window)
  provider: anthropic (claude-sonnet-5)
  capturing flow…
  ✓ step 1: 16 frames    ✓ step 2: 16 frames    ✓ step 3: 16 frames    …
  captured 176 frames in 31s
  contact sheet → .motionlint/flows/signup-happy-path-…png
  analyzing flow…
  report → .motionlint/flows/signup-happy-path.md

Score: 4/10 · 3 critical findings
  [critical] interaction — input focus rings missing across steps 2/4/6
  [critical] interaction — submit button has no pressed state
  [critical] loading_state — 1.4s wait with no spinner during submit

デモを試す

複数のルートを備えた TS アニメーションのショーケースが demo/ に含まれています。Motion One、GSAP、anime.js、@formkit/auto-animate、lottie-web を取り上げており、1 つの URL ですべての MotionLint 機能を試せる、猫をテーマにした 1 ページのデモもあります:

node demo/server.mjs                                # http://localhost:4173
motionlint review http://localhost:4173/cat --record --embed
motionlint flow --spec flows/signup.json
motionlint tune http://localhost:4173/dashboard

利用可能なルート:/、/pricing、/signup、/dashboard、/loading、/cat。レポートは .motionlint/reports/ に、スクリーンショットは .motionlint/screenshots/ に、動画は .motionlint/videos/ に保存されます。

セットアップ

API キー

MotionLint は起動時に、作業ディレクトリ内の .env ファイルを自動的に読み込みます:

# .env (gitignored)
ANTHROPIC_API_KEY=sk-ant-...
# or
OPENAI_API_KEY=sk-...
# or
GOOGLE_API_KEY=...
# or run a local Ollama (no key needed) — auto-detected on http://localhost:11434

実際の環境変数は .env より優先されます。キーが設定されておらず、Ollama も実行されていない場合、MotionLint は決定論的なモックプロバイダーにフォールバックします。これにより、スモークテスト用にパイプライン全体(キャプチャ → 分析 → レポート)がエンドツーエンドで実行されます。

プロバイダーの自動検出

MotionLint は次の順序でプロバイダーを自動検出します:Ollama(ローカル)→ Anthropic → OpenAI → Google。有効な API キーがある(またはサービスが実行中の)最初のプロバイダーが選択されます。--provider <name> と --model <id> で指定できます。プロバイダーごとの品質スコアカードと選び方については、プロバイダーの詳細をご覧ください。


以下は、MotionLint の内部の仕組みを理解したい方、ワークフローに合ったプロバイダーを選びたい方、または CI に組み込みたい方向けの内容です。

プロバイダーを横断した品質検証

flow-review パイプラインは、一般的なウェブアプリのアニメーションパターン12種類 × 2バリアント(フィクスチャ合計24件)でストレステストを実施しました。対象は、段階的な表示、ホバー/押下/フォーカス、モーダルの表示、ローディングスケルトン、フォームエラー、トースト、カウンターの増加、複数アニメーションを使うダッシュボード、コンテンツを段階的に表示するモーダル、豊富なフォームフィードバック(フォーカス+押下+スピナー+成功)、スクロール駆動アニメーション(プログレスバー+IntersectionObserver による表示+パララックス)です。

2026-07-27に、主要プロバイダー各社の現行フラッグシップモデルを使って実行しました。

プロバイダー · モデル再現率(検出した不具合)FPR(問題のないものへの誤検出)スコア差実時間
OpenAI · gpt-5.6-sol100%(12/12)0%(0/12)+3.310.9 min
OpenAI · gpt-5.5100%(12/12)0%(0/12)+3.311.5 min
Anthropic · claude-opus-5100%(12/12)8%(1/12)+4.121.0 min
Google · gemini-3.6-flash100%(12/12)17%(2/12)+5.14.9 min
Anthropic · claude-sonnet-5100%(12/12)33%(4/12)+3.110.8 min

次のように読み取ってください。再現率は、もはや差別化要因ではありません。 現行のフラッグシップモデルはどれも、仕込まれた不具合を12件すべて検出します。これが今回の検証結果です。1年前はそうではありませんでした。つまり、MotionLint が機能するかどうかは、もはやモデルの選択では決まりません。コストとレイテンシーで選んでください。

FPR の列でモデルを順位付けしないでください。 24件のフィクスチャを使った1回の実行では、差を判定できません。同一のスイートを条件を変えずにサンプリングだけ変えて2回実行したところ、FPR はモデルごとに1~2件のフィクスチャ分変動しました。gpt-5.5 は1/12 → 0/12、gpt-5.6-sol は2/12 → 0/12、gemini-3.6-flash は3/12 → 2/12でした。フィクスチャ1件で8パーセントポイントに相当するため、「0%」から「17%」までの差全体がノイズフロアの範囲内です。この列は順位ではなく、*「どのモデルも、問題のないものを誤検出することがある」*と捉えてください。

この表の過去の数値が誤っていた理由

このスイートを最初に実行した2026-07-27の結果では、claude-opus-5 の再現率は83%となり、5モデル中最下位でした。また、2026-04-29版のこの表では、複数のモデルのFPRが0%と報告されていました。どちらもモデルの挙動ではなく、MotionLint のバグによるものでした。

Anthropic の max_tokens はデフォルトで4096でした。冗長な応答は上限に達してJSONの途中で切れ、解析できない結果が 0/10, no issues found として採点されました。これは問題のないレビューと区別できませんでした。Opus 5の3件の応答切り詰めのうち2件は不具合のあるフィクスチャで発生し、83%という数値を生み出しました。

同じバグによって、すべてのモデルでFPRも低く見積もられていました。レビューが途中で切れると何も報告されないため、誤検出を増やせません。過去に「FPR 0%」とされた値は、モデルの精度だけでなく、解析の失敗も一部測定していました。この問題は2026-07-27に修正しました。あわせて、途中で切れた応答、拒否された応答、安全性フィルターでブロックされた応答を問題のない結果に見せていた関連経路も修正しました。

各プロバイダーの詳細なスコアカードは、scripts/run-all-benchmarks.mjs を実行した後に .motionlint/stress/ で確認できます。単一のモデルを再実行するには、--only <provider>:<model> を使用してください。

プロバイダーの詳細

プロバイダーモデルセットアップ品質(24 件のフィクスチャ)レビューあたりのコスト¹
googlegemini-3.6-flashGOOGLE_API_KEY=…再現率 100% · FPR 17% · 差 +5.1$0.019
anthropicclaude-sonnet-5ANTHROPIC_API_KEY=…再現率 100% · FPR 33% · 差 +3.1$0.089
openaigpt-5.5OPENAI_API_KEY=…再現率 100% · FPR 0% · 差 +3.3$0.248
openaigpt-5.6-solOPENAI_API_KEY=…再現率 100% · FPR 0% · 差 +3.3$0.265
anthropicclaude-opus-5ANTHROPIC_API_KEY=…再現率 100% · FPR 8% · 差 +4.1$0.293
ollama任意のビジョンモデルollama serve + ollama pull <model>今回の実行ではベンチマーク未実施$0
mockヒューリスティックなスタブ(自動フォールバック)該当なし — CI のスモークテスト用の決定論的なスタブ$0

¹ 推定値ではなく実測値です — 各モデルでデモアプリに対して、デフォルトの 2 つのビューポートを使い、フルページで実際の motionlint review を 1 回実行しました。各プロバイダーの使用量フィールドから実際のトークン数を読み取り、公表されている定価を乗じています。任意の実行で formatUsageLine() を使って再現できます。Sonnet 5 には導入価格が適用されています(2026-08-31 まで)。その後はおよそ 1.5 倍になります。フローレビューではフローごとに 1 枚の合成画像を送信しますが、コンタクトシートはより大きくなります。Animation Tuner と motionlint audit は LLM を一切呼び出さず、コストもかかりません。

コストの大部分は出力トークンです。 入力は 5 モデル間で 2 倍以内ですが、出力は 1,390(Gemini)から 10,219(Opus 5)まで幅があります。最も高価なモデルが最も安価なモデルの 15 倍になるのは、画像サイズではなく、この 7 倍の差によるものです。

選び方
  • デフォルト。 Google の gemini-3.6-flash — 再現率 100% で、Opus 5 より13 倍安く、5 モデル中で最速です(4.9 分)。すべてのモデルがすべての不具合を検出したため、デフォルトで追加料金を払う品質上の理由はありません。
  • Anthropic を標準採用する場合。 claude-sonnet-5 は $0.089 で、claude-opus-5 より 3 倍安く、再現率は同じです。Opus 5 はより高価で、実測した再現率に優位性がないにもかかわらず、実時間が2 倍かかりました(21.0 分対 10.8 分)。わずかに高いスコア差(+4.1 対 +3.1)を重視する場合にのみ選んでください。
  • OpenAI を標準採用する場合。 gpt-5.5 と gpt-5.6-sol は、測定したすべての軸で差がなく、価格差も 7% 以内です。すでにアカウントで利用できる方を選んでください。
  • 厳格な CI ゲート。 再現率を基準にすれば、どれでも問題ありません。FPR を基準に選ばないでください — 上記のノイズフロアに関する注意を参照してください。誤検知がゲートに影響する場合は、こちらの 24 件のフィクスチャによる単一実行をそのまま信頼せず、独自のフィクスチャを実行してください。
  • ローカル/エアギャップ環境。 Ollama のビジョンモデルならどれでも動作しますが、ビジョン機能に対応していることを確認してください。API 経由で画像を受け付けても、画像を黙って無視し、プロンプトだけをもとに回答するモデルもあります。今回の実行ではいずれもベンチマークを実施していません。
プロバイダーの切り替え

すべてのコマンドで --provider と --model を使用できます。

motionlint review http://localhost:3000 --provider openai    --model gpt-5.5
motionlint flow   --spec flows/signup.json --provider google --model gemini-3.6-flash
motionlint review http://localhost:3000 --provider ollama    --model llava:13b
独自のプロバイダーのベンチマーク

新しいプロバイダーを同じ 24 件のフィクスチャによるストレステストと比較するには、次のようにします。

node -e "
import('./dist/config/env.js').then(async ({ loadEnv }) => {
  loadEnv();
  const { runStress, renderStressMarkdown } = await import('./dist/flow/stress.js');
  const { writeFile, mkdir } = await import('node:fs/promises');
  const { resolve } = await import('node:path');
  await mkdir('.motionlint/stress', { recursive: true });
  const r = await runStress({
    stressPath: resolve('eval/animation-stress.json'),
    fixturesDir: resolve('eval/animation-fixtures'),
    artifactDir: resolve('.motionlint/stress'),
    provider: 'YOUR_PROVIDER',  // 'openai' | 'google' | 'ollama'
  });
  await writeFile('.motionlint/stress/SCORECARD.md', renderStressMarkdown(r), 'utf8');
  console.error('Recall:', (r.broken_recall*100).toFixed(0)+'%, FPR:', (r.good_false_positive_rate*100).toFixed(0)+'%, gap:', r.avg_score_gap.toFixed(1));
});
"

パターンごとの内訳は .motionlint/stress/SCORECARD.md を開いて確認してください。

motionlint flow の仕組み

静的なスクリーンショットでは、フローのアニメーションやインタラクション状態が機能しているかどうかはわかりません。最終フレームの見た目が正しいかどうかしか確認できません。motionlint flow はそのギャップを埋めます。

スクリプト化されたユーザージャーニーを指定すると、次の処理を行います。

  1. Playwright を介してヘッドレス Chromium でユーザージャーニーを実行します。ユーザーと同じように、クリック、入力、ホバー、スクロール、キー押下を行います。
  2. CDP のスクリーンキャスト(Page.captureScreenshot JPEG、1枚あたり約8ms)を介して、各インタラクション後の750ms間に16フレーム(50ms間隔)を連続撮影します。50msは人間の視覚検出閾値の半分であり、業界で一般的なアニメーション間隔の最小値である100msを下回ります。そのため、100msのボタン押下のような短いアニメーションも、中間状態のフレームを2~3枚捉えられます。各インタラクションの連続撮影では、入力からフィードバックまでの遅延もピクセル差分で検出します。バースト期間内に視覚的な応答がないインタラクションは、決定論的にフラグ付けされます。
  3. 後からスクラブ再生できるアーティファクトとして、Playwright の動画全体を記録します。
  4. 各バーストをラベル付きのコンタクトシートに合成します。ステップごとに1行で、フレームは副行に配置されます。
  5. フローを考慮した評価基準とともにシートをビジョン LLM に送信します。評価基準には、アニメーションの欠落、アニメーションの不具合やカクつき、ローディング状態の欠落、体感パフォーマンス、アフォーダンスと状態変化、演出、滑らかさ、意図しないちらつき、ナビゲーションの連続性、モーション軽減への対応が含まれます。
  6. ステップごとのトレース、優先順位付けされた検出結果、末尾の **「Claude Code 用プロンプト」**ブロックを含む Markdown レポートを生成します。これを CC に貼り付けると、検出結果に直接対応します。
複数アニメーションの処理

1つの記録で、複数のアニメーションを同時に撮影し、分析できます。次のケースで検証済みです。

  • ダッシュボードの表示(同時に3つ:タイルの段階表示+カウンターの段階的変化+チャートの棒の伸長)
  • モーダルの重ね表示(背景のフェード+モーダルのスライドとフェード+内部コンテンツの段階表示)
  • 詳細なフォームのフィードバック(フォーカスリング+ボタン押下+ローディングスピナー+成功カード)
  • スクロール連動(スクロール進捗バー+IntersectionObserver によるセクション表示+ヒーローの視差効果)

LLM は、動作しているアニメーションを誤ってフラグ付けすることなく、どのアニメーションに不具合があるかを正しく特定します。検証済み品質の表を参照してください。

スクロール連動アニメーション

スクロール連動アニメーションのあるサイトでは、scroll <px> ステップによって、バースト期間中に requestAnimationFrame 経由でスクロールをアニメーションさせます。そのため、各フレームでスクロール位置が段階的に変化し、ページのスクロール中のタイミングを LLM が把握できます。

フローの例
# Inline DSL — semicolon-separated steps
motionlint flow \
  --url http://localhost:3000 \
  --steps "navigate /signup; click input#email; type input#[email protected]; click button[type=submit]; wait 2000; capture \"post-submit\"" \
  --name signup-happy-path

# Or load a structured spec with expected_animations[] hints
motionlint flow --spec flows/signup.json --provider anthropic

# Pass team motion preferences (philosophy + inspirations + accepted defaults)
# Embedded into the prompt AND the report's CC handoff block.
motionlint flow --spec flows/signup.json --preferences flows/preferences.md

# Tighten the interval below 50ms for fine-grained timing review
motionlint flow --spec flows/signup.json --interval 30 --burst-ms 600

# Auto-detect: scan the page's animations, pick an interval that captures
# the shortest one with 4 frames inside it (clamped to [20, 100]ms).
motionlint flow --spec flows/signup.json --auto-interval
インライン DSL リファレンス
アクション形式備考
navigatenavigate /pricingパスまたは完全な URL
clickclick button#startCSS セレクター
hoverhover .featureCSS セレクター
typetype input#[email protected]セレクター=値
presspress Enterキー
scrollscroll 800ピクセル数。バースト期間中にアニメーションします
waitwait 500ms
capturecapture "post-submit"任意のラベルを付けて明示的にバーストを撮影します

デフォルトでは、すべてのインタラクション後にフレームのバーストを撮影します。明示的な capture ステップの場合のみバーストを撮影するには、--no-implicit-bursts を指定します。動画の記録を省略するには、--no-record を指定します。

すぐに実行できるサンプルフローが3つ、リポジトリに含まれています。flows/signup.json、flows/loading-state.json、flows/preferences.md。

アニメーションチューナーの仕組み

ほとんどの AI コーディングツールは、アニメーションを一から生成します。チューナーを使うと、ページ上ですでに動作しているアニメーションをリアルタイムで調整し、その変更を構造化されたプロンプトとしてコーディングエージェントに渡せます。

アニメーションチューナー:検出されたアニメーションを再生し、継続時間スライダーを300msから150msに動かしてから、ease-out(Emil)プリセットを適用

motionlint tune http://localhost:3000 --open

次の処理を行います。

  1. 主要な TS アニメーションライブラリ(Motion One、GSAP、anime.js、@formkit/auto-animate、lottie-web)に加え、ページ上で実行されているすべての CSS トランジションと @keyframes をフックする計測スクリプトを使って、ヘッドレス Chromium でアプリを開きます。
  2. 検出されたアニメーションをすべてキャプチャします。対象要素のセレクター、ソースライブラリ、タイミングパラメーター、バウンディングボックスが含まれます。
  3. 自己完結型のインタラクティブな HTML ページを .motionlint/tuner/index.html に生成します(--open を指定すると自動で開きます)。
    • アニメーションごとのライブプレビュー領域(Shadow DOM — iframe もちらつきもなく、ソースページのテーマを適用)。
    • 継続時間/遅延/スタガー/速度を調整するスライダー。
    • イージングプリセットのドロップダウン — Emil Kowalski の力強いカーブ(ease-out、ease-in-out、iOS ドロワー)が先頭に並び、その後に穏やかで装飾的なオプションが続きます。
    • インラインの標準準拠チェック — 各カードで、アニメーションがモーション標準から外れている箇所を表示します(重大度バッジ、修正方法、推奨値)。ヘッダーにはスコアも表示されます。
    • デザインの意図を記録できる、アニメーションごとのコメント欄。
  4. Markdown ファイルと、構造化された changes[] JSON ブロックを含む Claude-Code 対応プロンプトをエクスポートします。これを CC に貼り付けると、コードベースが編集され、新しいパラメーターが適用されます。
$ motionlint tune http://localhost:3000

→ Capturing animations on http://localhost:3000…
  detected 15 animation(s)
  tuner → /Users/you/proj/.motionlint/tuner/index.html
  open with: file:///Users/you/proj/.motionlint/tuner/index.html

アニメーション標準 — motionlint audit

MotionLint は、Emil Kowalski のデザインエンジニアリング標準を決定的なリンターとして実装しています。ビジョンモデルも API キーもコストも必要ありません。motionlint audit はページを計測し、各アニメーションで実際に使われているタイミング、イージング、変形の値を読み取り、評価します。

監査 HTML レポート:スコアリングを表示した後、指摘事項をスクロールして確認。それぞれに、何が起きているか、なぜ重要か、修正方法、現在と推奨するイージングカーブをグラフで表示

カテゴリ検出する問題標準
イージングUI での ease-in、意図的な登場アニメーションでの弱い組み込みカーブ登場/退出には強い ease-out cubic-bezier(0.23, 1, 0.32, 1) を使用し、ease-in は使わない
継続時間モーダル/ドロワーの 200~500ms は除き、300ms の上限を超える UI モーション180ms のトランジションは 400ms よりきびきびと感じられます。退出は約 20%速くします
物理感scale(0) から始まる登場アニメーション何もないところから出現させず、scale(0.95) と opacity: 0 から始めます
パフォーマンスtransition: all、レイアウトプロパティのアニメーション、不要な無限ループtransform と opacity のみをアニメーションさせます。これらはレイアウトとペイントをスキップします
一貫性手作業で作られたイージングカーブの乱立、30~80ms の範囲外のスタガー間隔カーブと継続時間は共有トークンとして定義し、グループ化された登場アニメーションは 30~80ms 間隔でずらします
継続時間(ペア)対応する登場アニメーションより退出アニメーションが速くないケース(fadeIn 300ms/fadeOut 300ms)退出は対応する登場アニメーションより約 20%速くします
motionlint audit http://localhost:3000 --open          # polished HTML report, scored 0–100
motionlint audit http://localhost:3000 --json audit.json --ci   # machine-readable; non-zero on critical

--layout を追加すると、ライブ DOM の計測値に基づいてレイアウト(タップ領域、文字サイズ、コントラスト、オーバーフロー)もチェックします。引き続き決定的で、API キーも不要です。

--watch [dir] を追加すると、[dir](デフォルト:cwd)以下のファイル変更時に監査を再実行し、実行ごとにスコアとその変化を表示します。反復作業中に、結果をリアルタイムで確認できます。再帰的な監視には、macOS、Windows、または Node 20 以降の Linux が必要です。

レポートでは、各指摘事項を変更前 → 変更後のパネルと並べて表示します。イージングに関する指摘では、cubic-bezier カーブをライブで比較できるため、修正内容を説明だけでなく目で確認できます。同じ標準は flow のレビュー用プロンプトにも使われるため、ビジョンによる指摘が具体的なルールに基づくものになります。また、アニメーションチューナーにもインラインで表示されます。

MCP サーバー — ツール、リソース、デプロイ

MotionLint は stdio 経由の MCP サーバーを提供しており、LLM エージェントがチャット内から直接操作できます。motionlint mcp サブコマンドで起動し、ツールが呼び出されるとエージェントのクライアントがプロセスを生成します。

Claude Code へのインストール

公開済みの npm 版(推奨):

claude mcp add motionlint -- npx -y motionlint mcp

ローカルのチェックアウト版(開発中に便利):

claude mcp add motionlint -- node /absolute/path/to/motionlint/dist/index.js mcp

登録後:

  1. 一覧に表示されることを確認します:claude mcp list — motionlint が running または available と表示されるはずです。
  2. API キーにアクセスできることを確認します。MCP サーバーは、起動元から環境変数を引き継ぎます。最も簡単な方法は、作業中のプロジェクトディレクトリに .env ファイルを配置することです。MotionLint は起動時に自動で読み込みます。
  3. 初回実行時:まだ実行していない場合は、npx playwright install chromium を実行します。

続いて、Claude Code で:

"motionlint を使って、ローカルアプリをモバイルとデスクトップでレビューし、修正すべき主な問題を上位 3 件教えてください。"

"http://localhost:3000/signup で、手順 click input#email; type input#[email protected]; click button[type=submit]; wait 2000; capture を使って motionlint review_flow を実行し、アニメーションを確認してください。"

"http://localhost:3000/pricing で motionlint tune_animations を実行してください。カードのホバーアニメーションを微調整したいです。"

公開されるツール
ツール機能
review_url(url, viewports?, provider?, model?, wait_for?, record?, format?, max_findings?, max_pr_annotations?, new_only?)複数のビューポートで URL の静的 UX レビューを行います。Markdown/JSON/SARIF 形式のレポートを返します。
review_routes(base_url, routes, viewports?, ..., max_findings?, max_pr_annotations?, new_only?)1 つのアプリの複数ルートで同じレビューを行います。
review_flow(url, steps?|spec_path?, preferences_path?, provider?, ...)スクリプト化されたユーザージャーニーのアニメーション/インタラクションレビューを行います。構造化された CC ハンドオフブロックを含むフローレポートを返します。
tune_animations(url, viewport_*?, settle_ms?, output?)ページ上のすべてのアニメーションを検出し、操作可能な HTML チューナーを書き出します。ファイルパスを返します。
get_latest_report(format?)最新のレビュー/フローレポートの内容を返します。

リソース:motionlint://reports/latest — 最新のレポートの内容です。

デプロイのチェックリスト

MCP サーバーをデプロイする前、または他のユーザーと共有する前に確認してください。

  • ビルドが最新であること。 npm run build を実行し、dist/index.js が存在することを確認します。これを行わないと、motionlint mcp は起動しません。
  • Playwright Chromium が対象マシンにインストールされていること: npx playwright install chromium。postinstall フックで通知されますが、必須ではありません(npm install 時に 300 MB のバイナリを自動ダウンロードすることはありません)。
  • API キーにアクセスできること — シェルの環境変数を使うか、MCP クライアントの起動元となる作業ディレクトリに .env ファイルを配置します。
  • MCP の機能をスモークテストすること。 npm test には、サーバーを起動してツールを一覧表示し、想定されるツール構成を検証する MCP スモークテストが含まれています。
  • シークレットがコミットされていないこと。 .env は gitignore 対象です。.env.example はプレースホルダーにしてください。プッシュ前に最後に git diff --cached | grep -i 'sk-\|api_key' を実行しておくとよいでしょう。
  • claude mcp list で確認すること: サーバーが表示され、起動時にエラーが発生していないことを確認します。

CI 連携

# .github/workflows/ux.yml
- run: npm ci
- run: npx playwright install chromium
- run: npx motionlint review $STAGING_URL --ci --threshold critical --format sarif -o ux.sarif
- uses: github/codeql-action/upload-sarif@v3
  with: { sarif_file: ux.sarif }

クリティカルな問題が設定されたしきい値(failOnCritical)を超えると、MotionLint は 1 で終了します。これをステータスチェックとして設定してください。

キャプチャ対象・分析内容

キャプチャ対象:

  • デフォルトの3つのビューポート(モバイル 375/タブレット 768/デスクトップ 1440)でのページ全体のスクリーンショット。設定で変更できます。
  • --no-full-page を指定した場合のファーストビューのスクリーンショット。
  • --record を指定した場合の、ナビゲーションとキャプチャの実行を記録した動画(Playwright の .webm)。
  • キャプチャ前に実行するインタラクションのシーケンス:click、hover、type、scroll、wait。
  • 認証状態:Cookie、localStorage、beforeNavigate スクリプト。すべて .motionlintrc.json で設定できます。

フローバーストキャプチャのコンタクトシート:サインアップフォームがアニメーションするタイムスタンプ付きフレームがグリッド状に並んでいます。これがビジョンモデルのレビュー対象です

motionlint flow のコンタクトシート。各インタラクション後のタイムスタンプ付きバースト画像で、ビジョンモデルに表示される内容をそのまま示しています。

分析内容: 各スクリーンショットを、12の観点(hierarchy、spacing、alignment、typography、color、contrast、responsiveness、interaction、content、navigation、consistency、loading_state)を網羅した、独自のUXレビュープロンプトとともにビジョンモデルに送信します。モデルは各問題について次の内容を返します。

{
  "category": "hierarchy",
  "severity": "critical | warning | suggestion",
  "location": "above-the-fold hero",
  "issue": "Primary CTA blends into the background gradient.",
  "why_it_matters": "Users miss the conversion path on first scroll.",
  "fix": "Increase background contrast or use a solid surface behind the button."
}

--rules path/to/your-design-rules.md を指定すると、プロジェクト固有のヒューリスティクスを組み込むためにプロンプトを上書きできます。

レビュー用のキャプチャでは毎回DOMスナップショットも取得します。見出し、CTA、入力欄などの注目すべき要素には、計測したピクセル単位の矩形とともに、安定した参照ID(E1、E2、…)が割り当てられ、プロンプトに一覧表示されます。モデルはこれを根拠として、指摘に "element_ref": "E3" を指定できます。参照されたIDは対応する矩形に解決され、HTMLレポートのスクリーンショット上に重要度別の色付きバウンディングボックスとして描画されます(Markdownでは Where: E3 at (x, y) w×h として報告されます)。ページに表示されていない参照IDは除外されます。モデルに提示されていない要素には注釈を付けられません。

--format html を指定すると、指摘が共有可能な単一のレポートとして表示されます。スコアリング、観点別の内訳、各指摘に対する問題と修正案のパネル、注釈付きスクリーンショットが含まれます。

HTMLレビューのレポート:スコアリングがアニメーションで表示された後、スクリーンショット付きの問題と修正案のパネルがスクロールしていきます

設定リファレンス

リポジトリのルートに .motionlintrc.json を配置してください(または motionlint.config.js、package.json 内の "motionlint" キーを使用してください)。

{
  "provider": "auto",
  "fallbackProvider": "anthropic",
  "fallbackModel": "claude-sonnet-5",
  "viewports": {
    "mobile":  { "width": 375,  "height": 812 },
    "tablet":  { "width": 768,  "height": 1024 },
    "desktop": { "width": 1440, "height": 900 }
  },
  "defaultViewports": ["mobile", "desktop"],
  "waitFor": "networkidle",
  "waitTimeout": 10000,
  "screenshotDir": ".motionlint/screenshots",
  "videoDir": ".motionlint/videos",
  "reportDir": ".motionlint/reports",
  "rules": null,
  "record": false,
  "maxFindings": null,
  "maxPrAnnotations": null,
  "memory": {
    "enabled": true,
    "path": ".motionlint/memory.json",
    "baseline": ".motionlintignore",
    "newOnly": false
  },
  "resources": { "maxConcurrentReviews": null, "providerCallsPerMinute": null, "maxTokensPerRun": null },
  "ci": { "threshold": "warning", "failOnCritical": true },
  "auth": { "cookies": null, "localStorage": null, "beforeNavigate": null }
}

レビュー量の制御

同じルートでレビューを再実行すると、毎回同じ指摘が表示されていました。出力を重要な内容に絞るため、次の 2 つの仕組みを用意しています。

  • 実行ごとの出力上限 — --max-findings N(または設定の maxFindings)を指定すると、実行ごとの指摘を重要度順に上位 N 件に絞り込めます。これにより、エージェントは最も重要なものから対応できます。レポートの Omitted 行には、上限により除外された件数が表示されます。
  • PR 表示上限 — --max-pr-annotations N(または設定の maxPrAnnotations。SARIF のみ)を指定すると、レポートごとの結果を重要度順に最大 N 件まで出力できます。これにより、コードスキャンのアップロードで PR に注釈があふれるのを防げます。除外された件数は、SARIF の実行プロパティ omitted_by_pr_cap に記録されます。
  • リソース上限 — resources.maxConcurrentReviews は、1 つのプロセス内で同時に実行するレビュー数(複数のエージェントからのレビューに対応する MCP サーバーなど)を制限します。また、resources.providerCallsPerMinute は、ビジョン LLM の呼び出しに対するプロセス全体のスライディングウィンドウ上限です(プロバイダーの割り当て量/コストを制御します。また、flow レビューにも適用され、各 --consistency サンプルがカウントされます)。どちらもデフォルトでは無制限で、設定ファイルでのみ指定できます。なお、これらは組み合わせて適用されます。つまり、同時実行枠を使用しているレビューもレート制限を待つため、両方の値を厳しくすると、遅延が相乗的に大きくなります。
  • コスト上限 — すべてのプロバイダー呼び出しのトークン使用量を取得し、実行ごとに合計します(レポートの Tokens: 行、SARIF の実行プロパティ token_usage)。--max-tokens N(または設定の resources.maxTokensPerRun)を指定すると、実行ごとのトークン予算を設定できます。累計がこの上限を超えると、残りのビューポートはスキップされ、レポートの skipped_viewports に記載されます。使用量を報告しないプロバイダーの呼び出しも件数には含まれますが、予算は消費しません。
  • 実行間の記録 — 各指摘には安定した ID(カテゴリ、要素の位置、正規化された問題文のハッシュ)が付与されます。再発の検出では、単純なハッシュ一致よりも踏み込んでいます。カテゴリの類義語の互換性と正規化トークンの重複度(実際の実行間データで調整したしきい値)をもとに、ビジョン LLM が実行ごとに言い換えても同じ問題を照合します。検出された回数は .motionlint/memory.json に URL ごとに記録され、再発した指摘には黙って除外するのではなく、過去 N 回の実行で検出 と注記されます。差分のみを表示するには --new-only を指定します。指摘を恒久的に無視するには、その ID を .motionlintignore にコピーします(1 行に 1 つのハッシュを記述し、# コメントや末尾の注記も使用できます)。すべての機能を無効にするには --no-memory を指定します。

SARIF 出力には指摘 ID が partialFingerprint として含まれるため、GitHub コードスキャンは同じ指摘を実行や PR をまたいでネイティブに重複排除します。

同じプロジェクトのレビューを同時に実行しても安全です。記録された検出回数が並行実行によって上書きされないよう、古いロックを検出できるファイルロック(memory.json.lock)を使ってメモリストアを更新します。ロックが解除されなくてもレビューが失敗することはありません。短時間待機した後、警告を表示してロックなしで続行します。

ユースケース

  • マージ前の UX ガードレール。 デザイナーがいない個人開発者や 2 人のスタートアップ向けです。CI で motionlint review https://pr-123.preview.example.com --ci --threshold critical を実行すると、少なくとも問題を確認するまで、警告以上の指摘がマージをブロックします。
  • Claude Code 内の MCP デザインパートナー。 MotionLint を MCP サーバーとして追加し、CC に 「ローカルアプリをモバイルとデスクトップでレビューして、修正すべき上位 3 件を教えてください」 と尋ねます。CC がツールを操作し、同じ会話内で注釈付きフィードバックを返します。
  • 継続的な品質モニタリング。 夜間 cron を設定し(motionlint review https://prod.example.com --format sarif -o ux.sarif)、コードスキャンのダッシュボードに SARIF を表示することで、本番環境でのリグレッションを翌朝に検出できます。
  • リリース直後の機能に対するアニメーション/フローの QA。 motionlint flow は Playwright で人間のようにスクリプト化されたユーザージャーニーを実行し、各インタラクションで連続フレームをキャプチャして動画を記録し、キャプチャしたフレームをもとに LLM に アニメーションの動作 をレビューさせます。
  • アニメーションのライブ調整と Claude Code への引き継ぎ。 ページ上のすべてのアニメーションをキャプチャし、スライダーでタイミング/イージング/遅延をライブ調整して、CC が直接実行できる構造化プロンプトをエクスポートします。

プロジェクトの構成

src/
  capture/      Playwright capture (screenshot, mosaic, DOM snapshot) + interaction sequences
  providers/    Vision LLM providers (ollama, anthropic, openai, google, mock) + self-consistency wrapper
  analysis/     Rubric-style UX prompt + JSON parser + rule injection
  report/       Markdown / JSON / SARIF report generators
  eval/         Tiered eval harness (L1/L2/L3 fixtures, scorer, runner, report)
  flow/         Flow runner — spec parser, capture orchestrator, animation-aware report
  tuner/        Animation Tuner — extractor, instrumentation script, Shadow-DOM render
  mcp/          MCP server for Claude Code
  cli/          Commander.js commands + terminal output
  config/       cosmiconfig loader + .env loader
demo/           TS animation showcase used as a review target
flows/          Sample flow specs (signup, loading-state) for `motionlint flow`
eval/fixtures/  Labelled HTML pages with seeded UX faults at three complexity levels
test/           Node test runner unit + integration tests

ロードマップ

v0.1(今回のリリース) — リリース済み:

  • 3 つの CLI コマンド:review、flow、tune と MCP サーバー(motionlint mcp)。
  • 5 つのビジョンプロバイダー:Anthropic、OpenAI、Google、Ollama、mock。
  • モザイクキャプチャ、DOM 計測のサイドチャネル、自己一貫性サンプリング、同義語グラフを用いたソフトキーワードスコアリングに対応した、複数ビューポートの静的レビュー。
  • 21 件のラベル付きフィクスチャと、後続の LLM コーディングツール向けの構造化された next_actions[] JSON を備えた、段階的な評価ハーネス(L1/L2/L3)。
  • CDP スクリーンキャストによる フレーム間隔 50ms のフローレビュー(750ms のバーストで 16 フレーム)、複数アニメーションとスクロール連動に対応。
  • Shadow DOM プレビュー、ライブスライダー、イージングプリセット、Claude Code 向けエクスポートを備えた Animation Tuner。
  • 12 パターンにわたる 24 件のフィクスチャで、再現率 100%/FPR 0% を検証したアニメーションストレステストハーネス。
  • LLM の評価基準と CC への引き継ぎブロックに埋め込まれる、チームのモーション設定 Markdown(--preferences)。
  • ページ上で検出された最短アニメーションに基づいてフレーム間隔を選ぶ、自動間隔スキャン(--auto-interval)。
  • GitHub コードスキャン向けの SARIF 出力。

v0.2(進行中) — これまでにリリース済み:

  • トークン使用量の記録と実行ごとのコスト上限(--max-tokens/resources.maxTokensPerRun。すべてのレポートに Tokens: 行を表示)。
  • ルートの自動検出(--discover-routes:sitemap.xml と Next.js の app ディレクトリ)。
  • 注釈付きバウンディングボックス:プロンプト内の DOM 要素参照、HTML レポート内のスクリーンショットへの指摘の描画。
  • インタラクション状態グリッド(--state-grid:要素ごとに default/hover/focus/active を 1 枚のラベル付き画像に表示)。
  • モデルごとのリグレッション検出に対応したプロバイダーのスコアカード履歴(.motionlint/eval-history.json)。
  • 評価の next_actions によるクローズドループのプロンプト改善(eval --evolve → レビュープロンプトに学習済みヒューリスティクスを適用)。
  • 監査ルールを 2 つ追加:スタガー間隔の範囲(30~80ms)と、退出を進入より約 20% 速くするルール。

v0.2(次期予定):

  • GitHub Action ラッパー(motionlint-action)。

謝辞

MotionLint は、他の方々の成果を基盤としています。

  • Emil Kowalski — motionlint audit のアニメーション基準、チューナーのイージングプリセット、フローレビューの評価基準は、彼のデザインエンジニアリングに関する執筆と、animations.dev のコースから要点をまとめたものです。彼のオープンソース UI ライブラリである sonner(トースト)と vaul(ドロワー)は、これらのルールが説明するモーションの、生きた参照実装です。MotionLint は独立したプロジェクトであり、Emil との提携や、Emil による推奨を受けているものではありません。
  • ctx(ctx.rs) — ローカルのコーディングエージェントの履歴検索ツールです。エージェントの実行をまたいで調査結果がどのように保持される(あるいは失われる)のかを調べるため、実行間メモリレイヤーの開発中に使用しました。これらの実験は、調査結果 ID とベースラインの設計に直接反映されています。

ライセンス

MIT © Resila Technologies Inc.

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。