Kleo MCP server

MCP serverEverything else

Narrated 4K 60 fps films from a brief, realistic or animation, made from your assistant via MCP.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use Kleo MCP server

Install Kleo MCP server

The server’s own address, for the clients that take one directly. Or connect ahel onceand every client you use reads it from one address, with the account kept on ahel rather than in each client’s config.

  • Claude Code

    claude mcp add --transport http kleo-mcp-server 'https://mcp.kleooai.com/mcp'

    Run it once in your project, then open /mcp to approve any sign-in the server asks for.

  • Claude Desktop

    https://mcp.kleooai.com/mcp

    Add a custom connector in Settings, paste this address, and approve the sign-in.

  • Cursor

    cursor://anysphere.cursor-deeplink/mcp/install?name=kleo-mcp-server&config=eyJ1cmwiOiJodHRwczovL21jcC5rbGVvb2FpLmNvbS9tY3AifQ==

    Open the link and Cursor adds the server at that address.

  • ChatGPT

    https://mcp.kleooai.com/mcp

    In Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.

  • Codex

    codex mcp add kleo-mcp-server --url 'https://mcp.kleooai.com/mcp'

    Run it once, then sign in with codex mcp login kleo-mcp-server if the server asks for an account.

From the project's README

As published by tonnooooo/kleo-mcp in README.md.

Kleo is a remote Model Context Protocol server that renders YouTube videos and Shorts. A user connects one URL to Claude, ChatGPT, Grok, Claude Code, Cursor, VS Code, OpenCode or Gemini CLI, presses one button to get in (no email, no password, no invite code) and asks for a video in plain language. The render runs on a GPU machine rented for that job only (Vast.ai) with the Keou motion-design engine, every shot a generated clip bought from kie.ai; the result comes back as signed download links (MP4, .srt subtitles, thumbnail) that last 7 days.

The server runs entirely on Cloudflare (Workers + KV + D1 + R2 + Workers AI + Cron), free plan. Production address: https://mcp.kleooai.com/mcp (Streamable HTTP, OAuth 2.1; the Worker itself answers at https://kleo-mcp.plural-juice.workers.dev/mcp). The public site (../kleo-site) reads that address from its config.json.

Connect

WhereHow
Claude (web/desktop)Settings → Connectors → Add custom connector → https://mcp.kleooai.com/mcp
Claude Codeclaude mcp add --transport http kleo https://mcp.kleooai.com/mcp
ChatGPTSettings → Connectors → Developer mode → Create → https://mcp.kleooai.com/mcp, OAuth
Cursor / VS Code / OpenCode / Gemini CLIan http server named kleo with the same URL
MCP Registrycom.kleooai/kleo (see server.json)

One button signs you in (no email, no password); 7 credits arrive with the account. Guides with screenshots: https://kleooai.com/connect/

Tools

ToolWhat it does
kleo_adapt_promptCalled first. Reads the request against Kleo's intake (subject, length, format, look; audience, tone, what must appear), answers with the questions the request leaves open, and once everything is known hands the assistant the producer's method for writing the treatment.
kleo_list_templatesThe ten templates (format, length range, voices, credit cost) and the credits left on the account.
kleo_storyboard_guideThe storyboard format Kleo renders (styles, scene kinds, beats, icons, voices, rules) with examples, so the assistant can write an original storyboard. Optional: without one, Kleo plans the video from the prompt.
kleo_create_videoQueues a render from a template, a prompt and (optionally) a storyboard. Returns job_id, eta_min and the credits charged at once; nothing is charged on error.
kleo_wait_for_videoWaits (as long as the calling client allows: 45 s for ChatGPT/Grok, up to 5 min for OpenCode) and returns the links as soon as the video is ready, so the assistant keeps its spinner and delivers on its own.
kleo_get_jobState, current track, percent and minutes left; without job_id, the recent videos of the account.
kleo_get_resultSigned download links for a finished job.
kleo_generate_thumbnailNot enabled yet in the beta (every render already includes a thumbnail): records the request and returns a notice.
kleo_cancel_jobCancels a queued or running job and refunds the unused credits.
kleo_accountCredits left, the read-only link to the account page (/credits) and the "Kleo key" that carries the account to another browser. The link is safe to paste anywhere; the key is the account.

Credits (src/templates.ts): 1 credit = 2 seconds of film, rounded up, 10 credits minimum; the film is made for accounts that bought a credit pack (€5 = 10 credits, €15 = 35, €40 = 100, one-off, no subscription). The animatic (the same storyboard with the camera moving over drawn frames, no generated clip, 15–60 s) costs 5 credits and is open to every account: the 7 credits that come with a new account pay for one. tariffSentence() is the sentence every page quotes. Accounts are anonymous: no email and no password, just an HMAC-signed handle (src/accounts.ts) kept in a cookie, which doubles as the pasteable "Kleo key". The D1 table invites survives only as an optional gift: a code typed into the collapsed field of the sign-in page adds credits on top of the free ones, and an unknown code never blocks anyone. Output: 2160×3840 for 9:16, 1920×1080 for 16:9, 60 fps, H.264 + AAC. A Short takes about 10–20 minutes including the machine boot; a long video takes proportionally longer, and the timeout a render is given follows the length it was quoted (jobTimeoutMin), never a flat number below it.

How a job flows

client (Claude…) ──OAuth 2.1──▶ /mcp  (src/mcp.ts; login page in src/auth.ts)
                                │  D1: users, credits, gift codes, jobs, audit · KV: OAuth tokens · R2: rendered files
                                │  cron every minute (src/orchestrator.ts):
                                │    1. a storyboard for each queued job (Workers AI, src/storyboard.ts; validated by src/keou-contract.ts)
                                │    2. one Vast.ai instance per job (src/backends/vast.ts, image VAST_IMAGE)
                                │    3. watch running jobs, apply timeouts, purge expired files
                                ▼
                     Vast.ai instance → worker/kleo_worker.py (Keou engine) → uploads → POST /internal/jobs/:id/done → self-destroys
                     Free fallback: a GitHub Actions runner (.github/workflows/render-pool.yml) claims jobs that Vast could not start
                     (POST /internal/pool/claim with POOL_SECRET) and runs the same worker image.

Render backends (RENDER_BACKEND): vast (production: real GPUs, costs money), mock (simulated one-minute render with placeholder files, free; the server tells every client that renders are simulated), pool (only external runners), manual (a container you start by hand; used by test/worker-e2e.mjs).

Worker image

worker/Dockerfile.keou builds ghcr.io/tonnooooo/kleo-worker:keou (about 11 GB: Keou engine, Chromium, Node, ffmpeg, Kokoro voices, faster-whisper). GitHub Actions (.github/workflows/worker-image.yml) builds and pushes it on every push to main that touches worker/, or by hand from the Actions tab. The package must stay public on ghcr.io so Vast.ai machines can pull it. Details: worker/README-keou.md.

Local development

npm install
npm run db:migrate:local
npm run dev                # http://localhost:8787 with .dev.vars: simulated renders, no GPU, bundled storyboard (STORYBOARD_FIXTURE=example)

Connect Claude Code to the local server: claude mcp add --transport http kleo-local http://localhost:8787/mcp, then /mcp → Kleo → Authenticate and press the button; there is nothing to type.

Tests

npm run test:smoke                                                  # starts its own wrangler dev on port 8799: OAuth, tools, queue, simulated render, signed download, cancel + refund
node --test test/keou-contract.test.mjs test/storyboard.test.mjs    # unit tests: storyboard validator and generator (offline, fake AI)
node --test test/accounts.test.mjs test/credits.test.mjs            # sign-in, signed handles, free credits, daily caps, credit lifecycle (offline, sqlite)
node test/worker-e2e.mjs                                            # real Keou render inside the container (podman, no GPU) against a local server in manual mode
node test/vast-e2e.mjs                                              # one real 20 s job on Vast.ai: costs a few cents, see the file header for the setup
npm run typecheck

Deploy

Everything is provisioned: npm run deploy publishes wrangler.jsonc (every variable is explained there in a one-line comment). First-time setup, secrets and the step-by-step guide for the owner (Italian): DEPLOY.md. Secrets: INTERNAL_SECRET, VAST_API_KEY (set); POOL_SECRET (pool fallback); RESEND_API_KEY + NOTIFY_FROM (email notifications; not set, so notify_email is currently a no-op); TURNSTILE_SECRET (not set, so the bot check on the sign-in page is skipped). INTERNAL_SECRET must never be rotated: it signs the account handles as well as the download links, so a new value detaches every user from their credits.

To switch the GPUs off for a free demo, set RENDER_BACKEND to mock in wrangler.jsonc and deploy. To stop the spending right now, with no deploy: POST /internal/admin/pause with Authorization: Bearer <INTERNAL_SECRET> (/internal/admin/resume to start again). See DEPLOY.md section 5.

Safety rails

Credits are debited when a job is queued and refunded on failure or cancellation; at most MAX_JOBS_PER_USER open jobs per account and MAX_CONCURRENT_GPUS instances in total; every job has a hard JOB_TIMEOUT_MIN after which the instance is destroyed, and a machine that stays silent for START_TIMEOUT_MIN after rental is destroyed and the job requeued; the worker carries its own watchdog and destroys its instance with Vast's restricted CONTAINER_API_KEY; after a "no credit / no offer" answer Vast is left alone for VAST_RETRY_MIN; download links are HMAC-signed and expire with the files; a prompt filter blocks forbidden content before any GPU money is spent.

Above all of those sits DAILY_GPU_BUDGET_USD: before renting anything, the orchestrator adds what today's rentals cost — finished, failed and cancelled alike, since cost_usd is written every time a machine is torn down — to what the paid machines running right now have already committed (each priced at VAST_MAX_DPH for its own timeout; free pool jobs commit nothing) and, over the ceiling, pauses rentals for an hour while the jobs keep their place in the queue. The figure is still an estimate: the price cap is an upper bound and the real number is the Vast.ai balance. New accounts are capped per day (MAX_NEW_USERS_PER_DAY) and per address per day (MAX_NEW_USERS_PER_IP_DAY, on a hash of the address), jobs per account per day (MAX_JOBS_PER_DAY, counting only the ones that were not refunded), and sign-in attempts per address per minute (the SIGNUP_LIMIT rate-limit binding, keyed on a hash of the address, never the address itself). Every limit runs inside the Worker and only on /authorize: never in front of /mcp, where a 403 or 429 breaks connectors before the application sees the request.

Docs

  • DEPLOY.md — current status, going live, day-to-day operations (Italian)
  • docs/MCP-GUIDA.md — what MCP is, how each client connects, the seven tools (Italian)
  • docs/ARCHITETTURA.md — the original feasibility analysis and architecture (Italian)
Advanced
Delivery
kleo MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
Catalog kind
mcp-server
Gateway key
com-kleooai-kleo
Source
github.com/tonnooooo/kleo-mcp
Hosted endpoint
https://mcp.kleooai.com/mcp