Kindlepaw Rescue Adoption posts
1 template · 4 dogs · a post and an animated story
The same card, one row per dog: name, age, traits and photo come from the data.




Photos: Matthew Wiebe, André Spieker, Alexander Dimitrov, Yamon Figurs / Unsplash
Canva for your agent
A free MCP server for Claude Code, Cursor and Codex. Your agent describes a social post, ad or banner once; keyline renders it as images and video at every size, with real text in your fonts and colors, the same every run.
Free · Fair Source · Latest release
Make a listing ad for Villa Lefka in Oia: an Instagram post, a Facebook banner and a skyscraper. Give the photo a slow zoom.
Done: three sizes from one layout, all checks clean. The photo zooms toward the tower and back, and the loop runs every 8 seconds.
Everything an agent needs to ship a campaign, and nothing it has to guess.
Stacks, grids and constraints adapt one design to a post, a banner and a skyscraper ad, and any size can be tweaked on its own.
The server measures text, overflow, contrast and safe areas, and say where every layer landed and which part of each photo shows, so the agent verifies with numbers instead of screenshots.
Entrance effects, keyframes, staggered text and video clips, rendered as GIF, animated PNG, MP4 or WebM.
One native Rust binary on Skia. No headless Chrome, Puppeteer or Playwright to install, run or patch.
No model generates pixels: a scene always renders the same way, on every machine.
Six tools, batched edits and terse replies, so the agent spends its tokens on the design, not on reading the scene.
We gave Claude two briefs, a conference speaker card and a vote-by-mail flyer with a photo, each at three sizes, and three ways to make them: keyline, HTML screenshotted by headless Chrome, or a browser driven through Playwright MCP. keyline used fewer tokens on both, and was correct as often. Here's what the speaker card took.
2× fewer tokens than headless Chrome, 6× fewer than Playwright MCP.


Each card is one correct run near its arm's median tokens. The model designs each run afresh, so layout and touches like the "Keynote" label differ from run to run in every arm; the tool doesn't add them.
| Tokens | |
|---|---|
| Model requests | |
| Time | |
| Images looked at |
Every run, with its prompt and the judge's scores, is in the benchmark.
The agent works in a small JSON scene. keyline measures it and says what's wrong, so the agent fixes the design before anyone looks at pixels.
Text, images, shapes, layout and motion, in names models already know from CSS and Figma.
{"id": "headline",
"type": "text",
"text": "Cold Brew Season",
"fontSize": 168,
"fontWeight": 900,
"textWrap": "balance",
"media": {"banner":
{"fontSize": 104}}}
Every edit replies with what doesn't fit, per size: cut text, overflow, low contrast, text under a platform's buttons.
changed headline v4
story headline text
96,1110 888×290 168px 2L
banner sub text
60,372 470×62 26px
!truncated needs 470×96
PNG, JPEG, WebP, PDF, animated PNG, GIF, MP4 or WebM, with the layout as drawn: every layer's box and the part of each photo that shows.
banner …/banner-v0.png
(1200×628, 931 KB)
photo image 0,0 1200×628
cover shows 2400×1256
from 0,155 of 2400×1600
name text 48,228 525×99 99px
empty y 423–628 (33%)
Each campaign is one small JSON scene, rendered and checked by keyline. The brands are fictional; the photos are real.
1 template · 4 dogs · a post and an animated story
The same card, one row per dog: name, age, traits and photo come from the data.




Photos: Matthew Wiebe, André Spieker, Alexander Dimitrov, Yamon Figurs / Unsplash
1 scene · 5 sizes, down to 728×90 · a pan that follows the rider
The layout reflows from a post to a leaderboard banner; the checks confirm every size.




Photo: Abigail Keenan / Unsplash
4 shots · duotone photos · letters that fly in
Three unrelated photos read as one campaign; the headliner's letters land in place.

Photos: Daniel Robert, Gonzalo Poblete, Desi Mendoza / Unsplash
2 languages · 4 sizes · the longer Spanish still fits
One campaign, one row per language; the text-fitting checks prove every size holds.




Photo: Nicholas Swanson / Unsplash
A UI built from layers · a focus ring that draws itself · hours that count up
No screenshot: the app's interface is built in the scene, so it stays sharp at every size.

Photo: William Iven / Unsplash
1 scene · a print PDF, a post and a story
The same menu as vector A4 for the printer and as social posts; dot leaders run to the prices.
Photos: Todd Quackenbush, Annie Spratt / Unsplash
keyline is a free, source-available MCP server that lets AI agents (Claude Code, Cursor, Codex, VS Code) design social posts, display ads, banners, flyers and video at every size from one JSON scene. It measures text fit and overflow before rendering, and renders with Skia instead of a headless browser.
There's no browser to install, run or patch: keyline is one native binary. It measures text fit, overflow and contrast itself, so the agent fixes a layout without taking screenshots. In our benchmark, on two tasks, an agent used 2× fewer tokens than with HTML and headless Chrome, and 6× fewer than with Playwright MCP.
keyline runs on your machine or in CI, for free, with no hosted templates and no API key. The agent writes the design itself, as a JSON scene, instead of filling in a template someone made in a web editor.
No. keyline renders deterministically: the agent writes the scene, and the same scene always renders the same pixels. Photos and logos are your own files.
Install the binary (brew install keyline-dev/tap/keyline-mcp, or a release download), then add { "mcpServers": { "keyline": { "command": "keyline-mcp" } } } to ~/.cursor/mcp.json. The install guide has every other client.
Yes. keyline is free to use, change and share, commercially too, under the Functional Source License (FSL-1.1-ALv2). The one thing it doesn't allow is offering keyline itself as a competing commercial product or service. Each release also becomes Apache-2.0 two years after it ships.
macOS, Windows and Linux. Every download is checksummed and built by GitHub Actions.
The plugin installs everything, downloading keyline if it isn't on your PATH.
/plugin marketplace add keyline-dev/keyline
/plugin install keyline@keylineDownload keyline-mcp-<version>.mcpb from the latest release and double-click it, or install it from Settings, Extensions. Mac (Apple silicon) and Windows.
Designs and their renders go in ~/keyline, a folder per design, where you can also put the images and logos Claude should use. To work in folders of your own instead: open Settings → Extensions → keyline → Configure, add them, and click Save.
First install keyline (on a Mac: brew install keyline-dev/tap/keyline-mcp), then:
Codex is OpenAI's coding agent, included in ChatGPT plans. Its app, CLI and IDE extension share one setting:
codex mcp add keyline -- keyline-mcpChatGPT itself, like grok.com and the xAI API, connects only to remote servers, so it can't start keyline, which runs on your machine.
First install keyline (on a Mac: brew install keyline-dev/tap/keyline-mcp), then:
Any client that starts local (stdio) MCP servers works, Cursor, VS Code and Gemini CLI included. Add a server named keyline whose command is keyline-mcp, in the client's MCP settings or with its mcp add command. Most clients take this JSON:
{ "mcpServers": { "keyline": { "command": "keyline-mcp" } } }Claude Code without the plugin (and on Windows): claude mcp add --scope user keyline -- keyline-mcp. Claude Desktop without the .mcpb: Settings → Developer → Edit Config, with the full path (/opt/homebrew/bin/keyline-mcp), since it doesn't read your shell's PATH.
GitHub Actions: keep designs as scene files in a repo; every push renders them and fails on a broken layout.
- uses: keyline-dev/keyline@v0
with:
scenes: campaigns/*.json