Cleya
Provides an alternative rendering runtime using GSAP (GreenSock) for HTML-based scenes, enabling advanced timeline and animation control with all plugins registered and window.cleya helpers.
Enables platform-specific review for TikTok by adding UI-occlusion zones to check that rendered content is not obscured by TikTok interface elements.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@CleyaDraft a promo video and check brand conformance"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Status: v0.6.0, actively maintained. 834 tests across 75 files, a documented scene grammar with a JSON Schema beside it, and a contract-tested starter library — a change that breaks a starter breaks the build. Issues and pull requests welcome.
What it is
67 tools on three surfaces — a CLI, an MCP server, and a TypeScript library — covering the whole path from "I have a brief" to "here is a measured, on-brand MP4":
Author. Describe an animation as declarative JSON (the scene DSL) instead of hand-writing HTML and timing code. Layers, entrances, idle motion, keyframe tracks, camera moves, tickers, data binding, multi-format output.
Render. Headless Chrome samples
window.CLEYA.seekTo(t)once per frame, so every frame is a pure function of time — deterministic, seekable, resolution-independent — then FFmpeg encodes.Measure. Perception instruments read the rendered pixels back: WCAG contrast per text box, optical alignment, dominant-colour palette, brand conformance by ΔE. The agent that made the creative can see whether the creative is actually any good.
That last step is the point. Generation is commodity; the loop is made → measured → corrected, and it runs without a human in it.
Related MCP server: flash-cast-mcp
The loop, end to end
# 1. start from a guaranteed-valid skeleton
cleya starters --name promo-hero --copy-to ./promo
# 2. render it with your brand tokens
cleya render --scene promo/promo-hero.scene.json --brand brand.json --output promo.mp4
# 3. measure what came out
cleya contrast --input promo.mp4 --time 3.2 # WCAG per OCR'd text box
cleya align --input promo.mp4 --time 3.2 # near-miss edges, broken rhythm
cleya brand_check --input promo.mp4 --time 3.2 --brand brand.json # 0-100 ΔE conformance
# 4. correct deterministically — refinement as code, not deliberation
cleya edit --scene promo/promo-hero.scene.json --op '{"op":"center","layer":"headline"}' --verify
# 5. promote a good result into a reusable starter
cleya harvest --scene promo/promo-hero.scene.json --brand brand.json \
--name book-flip-promo --when "Book-brand promo with flipping titles"Or collapse steps 1–3 into one call:
cleya draft --starter promo-hero --brand brand.json \
--copy '{"headline":"Ship it {accent:Friday}","tagline":"in one command","stat":42}' \
--output draft.mp4
# → rendered + contrast-checked + brand-scored, ~15s
# (layer ids and knobs per starter: cleya starters --name promo-hero)Quick start
Cleya is not published to npm. Install from source:
git clone https://github.com/severment/cleya.git
cd cleya && npm install && npm run build && npm link
cleya doctor # check FFmpeg, ffprobe, Chrome, Whisper
cleya recipes # goal → tool-sequence discoveryAs an MCP server
{
"mcpServers": {
"cleya": { "command": "cleya-mcp" }
}
}Every tool is registered as cleya_<tool> with a typed schema. Point an agent at
cleya_capabilities first — one call returns the whole machine-readable manifest (options,
examples, categories, cost hints), which is how an agent learns the toolkit without guessing.
As a library
import { render, contrast, brandCheck, resolveConfig } from "cleya";
const config = resolveConfig();
const out = await render({ scene: "promo.json", brand: "brand.json", output: "promo.mp4" }, config);
const wcag = await contrast({ input: "promo.mp4", time: 3.2 }, config);Every tool takes (params, config) and returns Promise<ToolResult<T>>.
Authoring — the scene DSL
A scene is data, not code. The compiler turns it into the deterministic seekTo runtime that the
capture backends drive:
{
"size": [1920, 1080], "duration": 10, "bg": "$palette.bg",
"layers": [
{ "id": "h1", "type": "text", "text": "MAKE IT MOVE", "at": { "x": 118, "y": 208 },
"style": { "size": 104, "weight": 900, "color": "$palette.ink", "uppercase": true },
"in": { "at": 0.45, "dur": 0.75, "from": "rise", "ease": "outCubic" } },
{ "id": "cta", "type": "text", "text": "Get started", "anchor": "bottom-left", "safe": true,
"style": { "bg": "$palette.accent", "pad": [18, 34], "radius": 999 },
"in": { "at": 2.1, "dur": 0.5, "from": "pop" },
"idle": { "kind": "breathe", "amp": 0.02 } }
]
}--checkvalidates without rendering (~0.05s) and warns on dead air.--at <t>renders one frame;--previewwrites a labelled contact sheet — this is how an agent "watches" a video without watching it.--format og,square,storyemits every size from one spec, with per-layer overrides.--brand brand.jsonresolves$brand.*/$palette.*tokens and merges fonts.--data/--data-eachbind typed values and batch-render one spec into N named outputs.cleya scrubopens a film in a self-contained scrub page — timeline with hover-scrub, frame-stepping, loop — with zero rendering, because it plays through the sameseekTocontract. With--brand, it also carries a live palette bar: re-tint any brand role and the film updates instantly, then download the editedbrand.jsonto render with. Works for raw--htmlfilms too, as long as their colours are authored asvar(--cleya-<role>, <hex>).
type: "video" layers put real footage on the same timeline — the runtime seeks
currentTime per frame rather than playing, so a cut is still a pure function of scene time.
Full grammar: docs/scene-spec.md · schema: docs/scene.schema.json ·
craft guidance for ambitious work: docs/craft.md
When the DSL genuinely isn't enough, render --html --runtime gsap is the escape hatch: it
injects GSAP with every plugin registered plus window.cleya helpers, and you author a paused
timeline that the same seekTo bridge drives.
Skills
skills/ ships agent-readable craft guidance, one directory per lens — read before authoring,
not after:
Skill | For |
edit-craft | The grammar of cuts: which cut, when to cut, ad pacing, and how each maps onto layer windows |
marketing-producer | Campaign work — offer, proof, CTA |
social-editor | Vertical, sound-off, first-three-seconds |
documentary-editor | Long-form, interview-led |
podcast-producer | Multi-speaker audio-first |
Perception instruments
The part nothing else in this category ships. All of these read rendered pixels, not source specs.
They work on any video, not just one Cleya rendered. contrast, align, palette,
brand_check, review and pacing take --input <file> and measure whatever is in it. Point
them at output from another renderer, at footage from an editor, at a file someone sent you. The
measuring half of this toolkit is not coupled to the authoring half, so you can adopt it without
moving anything you already have. (scrub is the exception — it needs a seekTo film to drive.)
Tool | What it measures |
contrast | WCAG ratio per OCR'd text box — strokes split from ground by Otsu, so it measures the text, not the box |
align | Infers the frame's alignment systems, then flags only a lone element that almost joins one — two deliberate systems a few px apart are not a defect. Plus broken vertical rhythm |
palette | Coverage-weighted dominant colours (ΔE-merged) + luminance stats |
brand_check | 0–100 brand conformance against a |
review | Render QA — black/empty/frozen frames, text collisions, unsafe margins, tiny text, audio dead air; |
claims | Lints copy against a claims policy — banned phrases, required disclaimer, line length, reading grade |
pacing | The film's rhythm: holds, beats, segment lengths, end-card dwell, plus an activity strip. The only instrument that reads the film as a film rather than a frame, and the only way to check "the end card holds for three seconds" without watching it |
diff | Where two frames differ (bounding box), by how much (per-channel max), PSNR, and a difference image amplified to the change it actually contains |
harvest and edit --verify are instrument-gated: alignment defects block, contrast findings warn.
A defective scene cannot silently enter your starter library.
The rest of the toolkit
Run cleya --help for all 67, or cleya capabilities for the machine-readable manifest.
Author —
render,screenshot,card,title,caption,still,tts,capture(scripted real-app screen recording with synthetic cursor, auth state seeding, dev-overlay hiding)Pipeline —
draft,compose(multi-scene assembly with transitions, music bed, ducking, beat-snap, per-scene VO and content-hashed render cache),social_clip,autosubEdit —
trim,concat,speed,reformat,audio,overlay,pip,color,lut,effects,shake,upscale,gif,kenburns,layout,multiclip,sync,bg_removeScout —
info,scenes,motion,loudness,beat_detect,cut_silence,thumbnails(saliency-ranked),transcribe,detect_text,image_similarityAssets —
cutout(Vision foreground segmentation to transparency),smart_crop,brand_extract,segment,lut_extractExport —
export_nle(FCPXML),translate_srt
Requirements
Requirement | Needed for | Notes |
Node ≥ 18 | everything | |
FFmpeg + ffprobe | everything |
|
Chrome / Chromium |
| Auto-detected; override with |
FFmpeg with libfreetype |
| Default Homebrew formula lacks it: |
whisper.cpp |
| Returns |
macOS + Xcode CLT |
| Vision-backed, so these nine need a Mac. Native helpers compile on first use and cache |
|
| Opt-in cloud; nothing else calls out |
Cleya runs on macOS, Linux and Windows. 53 of the 67 tools are platform-independent,
including the whole core loop: render, draft, starters, edit, harvest, scrub,
compose, brand_check, palette, claims and diff. Nine are macOS-only (the Vision-backed
row above), and five degrade rather than fail: review keeps its FFmpeg checks, smart_crop
falls back to a centre crop, thumbnails loses saliency ranking, reformat loses crop:auto,
autosub loses the animated style.
cleya doctor checks all of it at once.
Result contract
{ success: true, output: "/abs/path", tool, cleya_version, duration_ms, ...toolSpecificData }
{ success: false, error: "Human-readable message", code: "ERROR_CODE", suggestion?: "What to do" }Codes are stable and actionable — VALIDATION_ERROR, FFMPEG_ERROR, WHISPER_NOT_FOUND,
DRAWTEXT_NOT_FOUND, OUTPUT_EXISTS, NO_CANDIDATES, and more. Agents branch on the code;
humans read the message.
Configuration
const config = resolveConfig({
ffmpeg_path: "/opt/homebrew/bin/ffmpeg",
temp_dir: "/tmp/cleya",
ffmpeg_timeout: 600_000,
});Key | Default | Purpose |
|
| Binary locations |
|
| whisper.cpp binary |
|
| Working files |
|
| Temp cleanup |
|
| Default output directory |
|
| Execution timeouts (ms) |
| see | Per-platform size/codec/duration |
Render tuning lives in the environment: CLEYA_RENDER_WORKERS (parallel frame capture),
CLEYA_NO_GPU=1 (software raster), CLEYA_RENDER_ENGINE=chrome|webkit, CLEYA_STARTERS_DIR.
Development
npm run build # tsc
npm test # vitest — 834 tests across 75 files
npm run smoke # end-to-end render smoke testStarter scenes are contract-tested: every shipped starter must compile with zero errors and zero warnings against the neutral default brand, so a change that breaks a starter breaks the build.
License
Apache 2.0. See NOTICE for third-party attribution — in particular GSAP, which is used by the raw-HTML runtime, is licensed under GreenSock's standard "no charge" license (not Apache-2.0) and is installed from npm rather than redistributed here.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseAqualityDmaintenanceAn MCP server that transforms LLM-enabled IDEs into professional video editors by pre-processing footage into text proxies, generating motion graphics via HTML/CSS, and orchestrating complex FFmpeg renders.Last updated4
- AlicenseAqualityDmaintenanceA deterministic video rendering engine that enables AI agents to create programmable, reproducible videos via MCP protocol.Last updated14232MIT
- Alicense-qualityDmaintenanceAn MCP server that interfaces with the Creatomate API, turning LLMs into autonomous motion designers that can generate social media videos, ads, and shorts programmatically.Last updated1MIT
- AlicenseAqualityBmaintenanceAn MCP server that lets AI agents visually perceive and edit video inside DaVinci Resolve Studio by rendering frames and manipulating the timeline.Last updated2MIT
Related MCP Connectors
MCP server for Wan AI video generation
MCP server for OpenAI Sora AI video generation
MCP server for Hailuo (MiniMax) AI video generation
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/severment/cleya'
If you have feedback or need assistance with the MCP directory API, please join our Discord server