nakkas
nakkaşはトルコ語(古語)で画家/アーティストを意味します。
"make a neon terminal logo with animated binary digits"
→ AI constructs JSON config
→ nakkas renders to animated SVG
→ clean animated SVG outputなぜ使うのか
1つのツールで無限のデザイン。
render_svgはJSON設定を受け取ります。AIがすべてを埋めます。AIネイティブなスキーマ。 すべてのフィールドに
.describe()アノテーションがあるため、モデルは何をすべきかを理解しています。純粋な宣言型SVG。 CSS @keyframes + SMILアニメーション、JavaScriptは不要です。
外部依存関係ゼロ。 クラウドAPIもAPIキーも不要。ローカルで実行されます。
インストール
Claude Desktop
設定ファイルに追加してください:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"nakkas": {
"command": "npx",
"args": ["-y", "nakkas@latest"]
}
}
}Claude Code (CLI)
claude mcp add nakkas npx nakkas@latestCursor / Zed / その他のMCPクライアント
{
"mcpServers": {
"nakkas": {
"command": "npx",
"args": ["-y", "nakkas@latest"]
}
}
}ローカル開発
git clone https://github.com/arikusi/nakkas
cd nakkas
npm install && npm run build
# Use dist/index.js as the commandクイックスタート
AIに(Nakkasを接続した状態で)尋ねてみてください:
"アニメーションSVGを作成して:ダークなターミナルフレーム(800×200)、光るシアンのテキスト「NAKKAS」、ネオン発光フィルター、読み込み時にフェードイン。"
"ローディングスピナーを作成して:1.5秒ごとにループする描画ストロークアニメーション付きの円。"
"データ可視化:アニメーション付き棒グラフ、5本のバー、それぞれがずらした遅延でフェードインし、グラデーション塗りつぶし。"
"プロフィールバッジ(400×120):青から紫へのグラデーション、白いユーザー名テキスト、ドロップシャドウ、微かなパルスアニメーション。"
ツール
Nakkasは3つのツールを提供します:
ツール | 目的 |
| SVGConfig JSONを受け取り、SVG文字列とデザイン分析の警告を返します |
| レンダリングされたコンテンツを受け取り、視覚確認用のPNG画像を返します |
| レンダリングされたコンテンツを受け取り、SVG(テキスト)またはPNG(ラスター)としてディスクに保存します |
推奨されるワークフロー:レンダリング → プレビュー → 反復 → 保存。saveツールはrender_svgとは別に用意されており、保存前にプレビューと調整を促すようになっています。
save ツール
{ "content": "<svg ...>...</svg>", "outputPath": "./design.svg", "format": "auto" }フォーマット:auto(拡張子から推論)、svg(テキストファイル)、png(先にラスターにレンダリング)。ファイルが存在する場合は、上書きを防ぐために数値カウンターが付加されます。実際に保存されたパスが返されます。
render_svg ツール
入力: SVGConfig JSONオブジェクト
出力: 完全なSVG XML文字列とオプションのデザイン分析メモ
レンダリング後、レスポンスには、同時アニメーションが多すぎる、transformBoxが欠落している、グループレベルのスケール変換があるといった一般的な問題に関するデザイン警告が含まれる場合があります。
SVGConfig 構造
{
canvas: {
width: number | string, // e.g. 800 or "100%"
height: number | string,
viewBox?: string, // "0 0 800 400"
background?: string // hex "#111111" or "transparent"
},
defs?: {
gradients?: Gradient[], // linearGradient | radialGradient
filters?: Filter[], // preset or raw primitives
clipPaths?: ClipPath[],
masks?: Mask[],
symbols?: Symbol[],
paths?: { id, d }[] // for textPath elements
},
elements: Element[], // shapes, text, groups, use instances
animations?: CSSAnimation[] // CSS @keyframes definitions
}要素タイプ
タイプ | 必須フィールド | メモ |
|
|
|
|
|
|
|
| 水平/垂直半径を個別に指定 |
|
| |
|
| 開いたパス: |
|
| 自動的に閉じられる形状 |
|
| 完全なSVGパスコマンド |
|
| 埋め込み画像用のURLまたは |
|
| 文字列または |
|
| 曲線に沿ったテキスト; パスは |
|
| すべての子要素に適用される共有属性(ネストされたグループは不可) |
|
| シンボルのインスタンス化、または |
|
| 円全体にN個のコピーを配置 |
|
| 円弧に沿ってN個のコピーを配置 |
|
| M×Nグリッドにコピーを配置 |
|
| シード値に基づいたランダムな位置にN個のコピーを散布 |
|
| ポリラインに沿ってN個のコピーを均等に配置 |
|
| 数学的曲線: |
すべての視覚要素(共有フィールド)
{
id?: string, // required for filter/gradient/clip references
cssClass?: string, // matches CSS animation names
fill?: string, // "#rrggbb" | "none" | "url(#gradId)"
stroke?: string,
strokeWidth?: number,
strokeDasharray?: string, // "10 5", use for draw-on animation
strokeDashoffset?: number,
opacity?: number, // 0–1
filter?: string, // "url(#filterId)"
clipPath?: string, // "url(#clipId)"
transform?: string, // "rotate(45)" "translate(100, 50)"
transformBox?: "fill-box" | "view-box" | "stroke-box", // set "fill-box" for CSS rotation
transformOrigin?: string, // "center", works with fill-box
smilAnimations?: SMILAnimation[]
}フィルタープリセット
defs.filtersで定義した後、任意の要素でfilter: "url(#myId)"として参照します:
{ "type": "preset", "id": "myGlow", "preset": "glow", "stdDeviation": 8, "color": "#ff00ff" }プリセット | 主要パラメータ | 効果 |
|
| 柔らかなハロー |
|
| 強烈な輝き |
|
| ガウスぼかし |
|
| ドロップシャドウ |
|
| 乱流変位(アニメーション) |
|
| 彩度を落とす |
| — | 温かみのあるセピア調 |
| — | 色を反転 |
|
| 彩度を強調/低減 |
|
| 色相をシフト |
|
| レンズ歪みのようなRGBチャンネルのズレ |
|
| フィルムグレインとテクスチャのオーバーレイ |
|
| 要素の周囲に色付きのアウトライン |
|
| 要素の内側に影 |
|
| 3Dレリーフの陰影効果 |
CSS アニメーション
{
"animations": [{
"name": "pulse",
"duration": "2s",
"iterationCount": "infinite",
"direction": "alternate",
"keyframes": [
{ "offset": "from", "properties": { "opacity": "0.3", "transform": "scale(0.9)" } },
{ "offset": "to", "properties": { "opacity": "1", "transform": "scale(1.1)" } }
]
}],
"elements": [{
"type": "circle",
"cx": 100, "cy": 100, "r": 40,
"cssClass": "pulse",
"transformBox": "fill-box",
"transformOrigin": "center"
}]
}CSSプロパティキー: camelCase (strokeDashoffset) または kebab-case (stroke-dashoffset)。どちらも機能します。
アニメーション可能なCSSプロパティ: opacity, fill, stroke, transform, filter, clip-path, stroke-dasharray, stroke-dashoffset, font-size, letter-spacingなど。
SMIL アニメーション
3つのSMILタイプ。各要素でsmilAnimations: []を介してインライン定義されます:
{ "kind": "animate", "attributeName": "d", "from": "...", "to": "...", "dur": "2s" }
{ "kind": "animateTransform", "type": "rotate", "from": "0 100 100", "to": "360 100 100", "dur": "3s" }
{ "kind": "animateMotion", "path": "M 0 0 C ...", "dur": "4s", "rotate": "auto" }パスモーフィング (attributeName: "d"): from/toのパスは、コマンドの種類と数が同一である必要があります。座標のみが異なる必要があります。
フォント
システムフォントは読み込みなしでどこでも機能します: Arial, Helvetica, Courier New, Georgia, Verdana, monospace, sans-serif, serif。
カスタムフォントファミリーも受け入れられます。これらは、レンダリング環境(フォントが読み込まれたWebページ、デザインツールなど)でフォントが利用可能な場合に機能します。
ユースケースと互換性
コンテキスト | CSS @keyframes | SMIL | 外部フォント | インタラクティブ (onclick) |
GitHub README | ✅ | ✅ | ❌ | ❌ |
Webページ | ✅ | ✅ | ❌ | ❌ |
Webページ インラインSVG | ✅ | ✅ | ✅ | ✅ |
デザインツール書き出し | ✅ | ✅ | ✅ | — |
静的ファイルビューア | ✅ | ✅ | 環境依存 | 環境依存 |
トラブルシューティング
"MCP error -32602: Input validation error"
これは、ハンドラーに到達する前にMCP SDKが入力を拒否したことを意味します。通常、最初の試行で発生し、再試行で成功します。最も一般的な原因:
グラデーションタイプのタイプミス。
"linear"や"radial"ではなく、"linearGradient"または"radialGradient"を使用してください。これが最も頻繁なミスです。キーフレームオフセットが文字列。
0または100(数値)か、"from"/"to"と記述してください。"0%"や"100%"と書くと失敗します。名前付きカラー。 16進数値のみが機能します:
"#ff0000"。"red"は不可。rgb()も不可です。要素の
typeの欠落。 すべての要素オブジェクトにはtypeフィールドが必要です。
MCPクライアント統合を構築していてこれが一貫して表示される場合、クライアントが引数をシリアライズする方法に問題がある可能性があります。既知のシリアライズの癖についてはanthropics/claude-code#29104を参照してください。
プレビューが空白または予期しない画像になる
プレビューツールはt=0での静的スナップショットをレンダリングします。アニメーションはキャプチャされません。表示されるのは、CSSやSMILアニメーションが開始される前のSVGの初期状態です。
画像が完全に空白の場合:
要素に
fillまたはstrokeが設定されているか確認してください。塗りつぶしのない形状は透明なキャンバス上では見えません。座標を確認してください。
800px幅のキャンバス上のx: 2000にある要素は、単に画面外にあります。filter: "url(#myFilter)"を使用している場合、myFilterがdefs.filtersで実際に定義されていることを確認してください。
GitHubでアニメーションが機能しない
GitHubのREADMEは<img>タグを介してSVGをレンダリングしますが、これはJavaScriptを除去し、CSSとSMILを保持します。アニメーションがローカルで機能するのにGitHubで機能しない場合:
<script>やイベントハンドラー(onclick,onmouseover)は避けてください。これらは削除されます。外部フォントは読み込まれません。システムフォント(
Arial,Courier New,Georgia,monospace,sans-serif)を使用してください。フォント用のCSS
@importはブロックされます。特定のフォントが必要な場合は、システムフォントをフォールバックとして指定したインラインの<text>を使用してください。
大きなSVG出力
render_svgがファイルサイズ(50kb以上)に関する警告を返す場合、パラメトリック曲線やパターン・グループが多すぎる要素を生成している可能性があります。パラメトリック曲線のstepsやパターン・グループのcountを減らしてください。cols: 50, rows: 50のgrid-groupは2500個の要素を生成し、すぐにサイズが大きくなります。
技術スタック
TypeScript + Node.js 18+
@modelcontextprotocol/sdk(MCPサーバー)zod(スキーマ検証とAIタイプガイダンス)外部SVGライブラリなし、純粋なXML構築
Vitest (280
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/arikusi/nakkas'
If you have feedback or need assistance with the MCP directory API, please join our Discord server