takumi-mcp
takumi-mcp
A Bun stdio MCP server for Takumi images, animations, PDFs, TanStack charts, and Shiki code assets. One package, composed from Effect services. Results contain { path, mimeType, bytes }; binary media never enters the agent context.
Run
Requires Bun 1.4.2 or newer. After the package is published:
{
"mcpServers": {
"takumi": {
"command": "bunx",
"args": ["--bun", "takumi-mcp"]
}
}
}From this checkout (no npm publishing required):
bun install --frozen-lockfile
bun run build
bun dist/cli.jsRun bun run demo to generate a card, effects image, chart, code asset, animation, and PDF in out/. The demo overwrites only its named sample files. A machine-local .mcp.local.json is available in this checkout for testing with an MCP client; it is ignored by Git.
For local MCP configuration, use bun as the command and the absolute path to dist/cli.js as its argument. stdout is reserved for MCP; Effect logs go to stderr.
Tools
Tool | Output | Inputs |
| PNG (default), JPEG, WebP, SVG | source, width, height, outputPath; optional css, fonts, format, quality, timeMs, dithering |
| Animated WebP (default), APNG, GIF; detected MP4/WebM | scenes, width, height, fps, outputPath; optional css, fonts, format |
| Paginated PDF | source, outputPath; optional css, fonts, pageSize (A4/Letter), landscape, margin, title |
| SVG | type (bar/line/dot), categories, series, outputPath; optional width, height, accessibility labels |
| SVG | code, outputPath; optional language, theme, width, height, css, fonts |
All tools accept overwrite: true; by default existing files are preserved. Writes commit atomically from a temporary file in the destination directory. Directories are created as needed. The selected format controls encoding; use a matching file extension.
source accepts { "html": "<div>...</div>" }, { "sourcePath": "/absolute/template.tsx", "props": { ... } }, or { "code": "const x = 1", "language": "typescript", "theme": "github-dark" }. HTML files are also accepted; their props are unused. React modules must default-export an element or a component/factory, which may be async and receives props plus signal.
Local JS/TS/JSX/TSX templates execute trusted code with the server's permissions. They are not sandboxed. Keep template logging on stderr. Inline HTML does not execute scripts. Root modules refresh when their modification time changes; restart the server after changing imported template dependencies.
Paths are relative to the server's working directory. Image paths inside file templates resolve relative to the template. For inline HTML, image paths resolve relative to the server's working directory. Fonts are local paths or HTTP(S) URLs, resolved from the working directory. Native Takumi's default font is available without configuration; supply fonts for brand typography, monospace, or additional scripts.
Examples
Render a reusable React/Tailwind card:
{
"source": { "sourcePath": "examples/card.tsx", "props": { "title": "A better way to render." } },
"width": 1200,
"height": 630,
"outputPath": "out/card.png"
}Generate a chart once with renderChart:
{
"type": "bar",
"categories": ["Jan", "Feb", "Mar"],
"series": [{ "name": "Revenue", "values": [12, 18, 27] }],
"width": 640,
"height": 360,
"outputPath": "out/revenue.svg"
}Then compose it into renderPdf (or renderImage) without passing SVG text through the model:
{
"source": { "html": "<main><h1>Quarterly report</h1><img src='out/revenue.svg' width='640' height='360'/></main>" },
"pageSize": "A4",
"margin": 32,
"title": "Quarterly report",
"outputPath": "out/report.pdf"
}Render CSS motion with renderAnimation:
{
"scenes": [{ "source": { "sourcePath": "examples/animation.html" }, "durationMs": 2000 }],
"width": 400,
"height": 160,
"fps": 24,
"format": "webp",
"outputPath": "out/motion.webp"
}Scene CSS shares one animation stylesheet: use unique selectors/keyframe names when scenes define different rules. Native animated formats require no FFmpeg. Video formats are advertised only when their encoder passes the startup checks below.
Render highlighted code as a reusable SVG asset with renderCode:
{
"code": "const answer = Effect.succeed(42)",
"language": "typescript",
"theme": "github-dark",
"outputPath": "out/code.svg"
}Shiki tokens become React text nodes, preserving escaping. Use the resulting SVG with <img> in another card, report, or motion scene. Omit width and height to derive the asset dimensions from the highlighted content; set them to control the viewport, with long code clipped to that viewport.
SVG assets are convenient to embed and scale. Embedding one with <img> treats it as a single image in the outer scene, so use the direct { code, language, theme } source when individual lines or tokens need CSS animation hooks.
Animated highlighted code
Use highlighted code directly as a scene source. Shiki runs once per scene; Takumi samples the CSS animation across its frames. No intermediate PNG is needed, so individual lines/tokens remain animatable.
{
"scenes": [{
"source": { "code": "const answer = 42;", "language": "typescript" },
"durationMs": 1500
}],
"css": "@keyframes reveal { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .shiki-line { animation: reveal 600ms ease-out both; }",
"width": 640,
"height": 120,
"fps": 24,
"format": "webp",
"outputPath": "out/code-motion.webp"
}CSS hooks are .shiki (the whole block), .shiki-line, .shiki-line-1 (1-based line number), .shiki-token, and .shiki-token-line-1. Add different animation-delay values to numbered lines for staggered reveals. Whitespace and empty lines are preserved. Use !important when overriding the block's inline theme/layout defaults, such as font size or padding.
Run bun run demo:code for a complete staggered reveal, using the ready-to-call MCP arguments. It writes out/code-animation.webp and a still frame at out/code-animation.png. The same code source works with renderImage (including timeMs) and renderPdf.
This follows Takumi's CSS keyframe animation model. Output is WebP/APNG/GIF, plus MP4/WebM when supported by the locally installed FFmpeg.
Styling and visual effects
className, HTML class, and tw compile through the installed Tailwind 4 compiler. Standard theme utilities and arbitrary values work without a CSS build step. No Tailwind plugins, project config, or browser preflight are loaded. Raw styles, <style> tags, and the tool's css argument pass through to Takumi.
Use the effects example for gradient text, masks, clipping, filters, and shadows. CSS also exposes Takumi's blend modes, conic gradients, inline SVG filter graphs, and motion paths. renderImage.dithering accepts none or ordered-bayer. See Takumi visual effects for the supported CSS recipes. Rendering support is determined by Takumi, not by browser CSS support; SVG/PDF output can differ from raster output for advanced effects. For exact raster appearance in PDFs, render the effect to PNG and embed it.
Optional FFmpeg video
At startup, the server checks ffmpeg on PATH, inspects its encoders, and tests a tiny encode. Each successful format is added to renderAnimation.format:
FFmpeg encoder | Additional format |
|
|
|
|
If FFmpeg is missing, unusable, or lacks a working encoder, that format is omitted from both the tool schema and description. The server never installs FFmpeg. Restart the server after installing or changing it. Set TAKUMI_FFMPEG_PATH to an executable path to use a particular installation.
Video uses the same scenes, CSS, dimensions, and frame rate as native animations. Frames stream from Takumi into FFmpeg with backpressure; output is written directly to a temporary file and committed only on success. Cancellation aborts rendering and terminates the encoder, escalating to a forced kill after two seconds if necessary.
Video dimensions must be even. MP4/WebM have no audio or alpha channel; transparent pixels are composited over black so opacity animations remain visible. The current presets prioritize readable graphics: H.264 CRF 18/veryfast, or VP9 CRF 28 with unconstrained bitrate. Scene clocks reset at scene boundaries, with each scene rounded up to a whole number of frames.
If MP4 is detected, try bun run demo:code mp4; use webm for VP9. Unsupported formats fail validation. Standard bun run demo:code always uses WebP.
Architecture and limits
Effect RC's MCP server, Toolkit, Schema, Context services, Layers, filesystem, HTTP client, semaphores, timeouts, and scoped finalizers handle orchestration. Promises are limited to library/runtime boundaries.
A shared native renderer reuses a 32 MiB cache and serializes native renders. At most two tool jobs prepare/render concurrently.
Effect.tryPromiseinterruption and scoped finalizers propagate AbortSignal to Takumi and template factories. PDF rendering runs in a disposable worker because takumi-pdf has no native signal API; cancellation terminates its WASM runtime.Effect
4.0.0-rc.112incorrectly converts numeric MCP cancellation IDs to strings. The checked-in one-line patch preserves ID types. Effect and its Bun platform are bundled into the CLI so npm users receive the fix. Remove the patch after an upstream release passes the numeric cancellation integration test.File-backed templates/assets are limited to 32 MiB each. Each prepared source allows 10,000 nodes, 64 image references, 1 MiB of text/classes/CSS, and 64 MiB of fetched assets; fonts allow 64 MiB per request. HTTP requests time out after 30 seconds. Tool jobs time out after two minutes. Dimensions are 1–8192, raster images at most 32 million pixels. Animations are at most 60 seconds, 600 sampled frames, and 250 million total pixels. Charts allow 512 categories and 64 series; code inputs allow 100,000 characters.
The source pipeline loads
<img>resources locally or over HTTP(S). Prefer image elements/data URIs for assets; external CSS resources and web font declarations are not a browser loading pipeline. Pass font files throughfonts.
The single package keeps these concerns as services rather than small published subpackages. Dependencies and the Bun lockfile pin the verified versions, including the Effect RC.
Development and publishing
bun run format
bun run check
bun test
bun run build
bun run test:dist
npm pack --dry-runTests exercise the real stdio protocol, native raster pixels, chart-to-PDF composition, all animation formats, Shiki, output commits, cancellation, and worker failures. CI checks macOS and Linux. Publishing setup covers npm OIDC and the one-time account configuration. No package has been published by this checkout.
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/Kennybll/takumi-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server