Open-core motion layer for the web: deterministic compiler + MCP server. Validates motion specs fail-closed, reports WCAG 2.2.2 pause-path candidates, and flags missing reduced-motion guards (2.3.3, an AAA best practice).
MotionSpec MCP server demonstrates strong tool design with clear purpose, comprehensive descriptions, and well-structured schemas. All 5 tools have explicit registration with descriptions 194-421 characters, meeting the 10-1024 character baseline. Tool names follow verb_noun convention (motion_catalog, motion_validate, motion_compile, motion_audit, motion_stats). Input schemas are present for all tools with proper type definitions. The server implements toolAnnotations (readOnlyHint, openWorldHint) across all tools, showing current spec alignment. Error handling is explicit with fail-closed validation. Main gaps: (1) motion_audit's input schema lacks 'required' array, url parameter is documented as required but not enforced at schema level; (2) motion_validate and motion_compile lack documented output schemas in the source (returned fields are partially visible in descriptions but not formally specified); (3) parameter descriptions could be more prescriptive about constraints (e.g., MAX_SPEC_BYTES is mentioned in code but not in motion_validate/motion_compile parameter docs); (4) no pagination guidance for motion_stats which could grow with scale.
Static motion-a11y checker: fetches a URL's HTML + linked stylesheets and scans the CSS for (1) animation/transition without a prefers-reduced-motion guard, (2) animated non-transform/opacity properties, (3) infinite animations with no pause path, (4) <marquee>/autoplay >5s. Runtime motion (WAAPI/GSAP/JS) is disclosed as 'not audited (V2)'. Returns {ok, score, findings, summary, badge, disclosures, markdown}; a clean site earns the badge 'reduced-motion-safe'. Does network I/O (openWorldHint).
Returns the catalog of verified motion primitives (names, purpose, parameter schemas, defaults) plus the authoring rules for writing a MotionSpec. Call this FIRST, then write the spec yourself and validate it with motion_validate (motion_compile runs in the CLI or with a key on the hosted endpoint).
Validates (fail-closed) and deterministically compiles a MotionSpec into production-ready vanilla-GSAP JavaScript and CSS, with enforced prefers-reduced-motion fallbacks and a performance-budget report. Same spec always yields identical code. Returns {ok, js, css, report} or {ok:false, errors}.
Summary of routing/compile telemetry (counts per outcome). Escalation clusters indicate which new primitive the catalog needs next.
Checks a MotionSpec against the schema, the primitive allow-list, parameter bounds and injection rules. Fail-closed: returns ok=false with precise errors. Returns {ok, errors, warnings, deprecations, catalogVersion}. IMPORTANT: warnings[] carries the WCAG 2.2.2 / reduced-motion findings and can be non-empty while ok=true — a spec that compiles is not automatically accessible. Use to pre-check a spec before compiling.
motion_validate and motion_compile: documented output structure is partially visible in description text but no formal response schema is defined in the source. LLMs cannot plan downstream operations without knowing the exact field names and types of the response object.
motion_audit input schema does not declare 'required: ["url"]' at the schema level, though the description says url is required. This forces the LLM to infer requirements from prose rather than machine-parseable constraint.
motion_compile specName parameter has a regex pattern (^[A-Za-z0-9_-]{1,64}$) in the schema but the description does not mention the character constraints or length limit. LLMs cannot read JSON Schema pattern fields, they need explicit constraint descriptions.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 72 | 2025-06-18+ | v2 |
motion_validate and motion_compile: MAX_SPEC_BYTES constraint (enforced in oversizeError() function) is not documented in the tool descriptions or parameter hints. LLMs have no way to know that extremely large specs will be rejected.
motion_stats returns 'counts per outcome' and mentions 'escalation clusters' but neither the tool description nor visible response schema define what fields/structure the output contains. Output structure must be documented for LLM planning.
AUTHORING_RULES constant embedded in register-tools.js is extensive and excellent but not discoverable, it's only returned by motion_catalog. If an LLM forgets to call motion_catalog first, it won't know the critical rule 'never invent primitives' or WCAG 2.2.2 pause-path guidance. Consider including a brief reminder in motion_validate and motion_compile descriptions.