Skip to main content
Glama

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.js

Run 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

renderImage

PNG (default), JPEG, WebP, SVG

source, width, height, outputPath; optional css, fonts, format, quality, timeMs, dithering

renderAnimation

Animated WebP (default), APNG, GIF; detected MP4/WebM

scenes, width, height, fps, outputPath; optional css, fonts, format

renderPdf

Paginated PDF

source, outputPath; optional css, fonts, pageSize (A4/Letter), landscape, margin, title

renderChart

SVG

type (bar/line/dot), categories, series, outputPath; optional width, height, accessibility labels

renderCode

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

libx264

mp4 (H.264)

libvpx-vp9

webm (VP9)

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.tryPromise interruption 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.112 incorrectly 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 through fonts.

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-run

Tests 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

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