Claude Media
Claude CodeのCarboneプラグインでテンプレートのタグとループを書く

Claude CodeのCarboneプラグインでテンプレートのタグとループを書く

Carboneプラグインは、Carbone記法のスキルとホスト型MCPサーバーを一括で入れます。導入、タグ・ループ・条件・フォーマッタの書き方、形式ごとの落とし穴を扱います。

Carboneプラグインは、請求書や帳票のテンプレートにJSONを流し込む文書生成エンジン「Carbone」の記法を、Claude Codeに教えるプラグインです。同梱のスキルが {d.path} のタグ、ループ、条件、フォーマッタの書き方を担い、同じく同梱のMCPサーバーがテンプレートからのレンダリングとテンプレートライブラリの管理を担います。

Carboneの記法はMustacheやHandlebarsに似て見えますが、別の言語です。モデルが記憶で書くと、存在しない {{ }} や {#if} が混ざります。スキルはその混同を防ぐための仕組みです。この記事では導入、書き方の型、形式ごとの落とし穴、MCPで描画するときの前提を順に扱います。

プラグインに入っているのはスキルとMCPサーバーの2つ

提供元のリポジトリは、Carboneのスキルと、CarboneがホストするリモートMCPサーバー(https://mcp.carbone.io)をひとまとめにしたものです。役割は次のように分かれます。

部品役割単独で使えるか
Carboneスキル役割記法を知識として持ち、テンプレートを書く・検査する・直す単独で使えるか使える(サーバー不要)
Carbone MCPサーバー役割文書の生成、形式変換、テンプレートライブラリの管理単独で使えるか使える(Carboneアカウントが必要)

スキルはAgent Skillsの標準に沿ったテキストの指示集で、それ自体は何も送信しません。MCPサーバーはCarboneが運営しているため、手元で何かを起動する必要はありません。テンプレートを書くだけならスキルだけで足り、実際にPDFやDOCXを出したくなったらサーバーにログインする、という二段階で使えます。

スキルが前提にする入出力の形式は広く、テンプレート側はDOCX、XLSX、PPTX、ODT、ODS、HTML、Markdown、PDFフォームなど、出力側はPDF、DOCX、XLSX、PPTX、CSV、画像などです。リポジトリの説明では、変換の組み合わせは160通り以上とされています。

導入はマーケットプレイス追加とOAuth認証の2段

Claude Codeでは、提供元のマーケットプレイスを追加してからプラグインを入れます。

/plugin marketplace add carboneio/carbone-agent-plugin
/plugin install carbone@carbone

入れ終えたら /mcp を開き、carbone を選んでAuthenticateを実行します。ブラウザが開くので、Carboneアカウントでサインインして承認します。アカウントがなければ先に作成します。

サーバーだけを入れたい場合は、手動でも追加できます。

claude mcp add --transport http --scope user carbone https://mcp.carbone.io

--scope user を付けると全プロジェクトで使えます。特定のプロジェクトだけに絞るなら、ルートの .mcp.json に次のように書きます。

{ "mcpServers": { "carbone": { "type": "http", "url": "https://mcp.carbone.io" } } }

スキルだけを使う場合は、リリースに添付される carbone.skill を ~/.claude/skills/ に展開します。

unzip carbone.skill -d ~/.claude/skills/

claude.aiやDesktopで使うときは別経路で、カスタムコネクタにサーバーのURLを入れ、スキルは carbone.skill をアップロードします。TeamやEnterpriseでは、先にOwnerが組織設定のコネクタで追加し、各メンバーがConnectを押してサインインします。

認証、無料枠、送信されるデータ

サインインはCarboneがアカウントを求めるときに走ります。プランがない状態で生成した文書は、透かし付きのPDFになります。公式のMCPページによれば、Freeプランは透かしなしで月100文書までです。

送信範囲は明確に区切られています。テンプレートとデータがCarbone APIに渡るのは、ツールを呼んだときだけです。生成された文書はアシスタントに返ります。個人情報や取引データを含むJSONを流すなら、この経路に載ることを前提に、ダミーデータで書式を固めてから本番データを使う運用が安全です。

もう一点、ホスト型サーバーはローカルファイルを読めません。テンプレートとデータは、公開URL、テキストそのもの、またはCarboneのテンプレートライブラリの名前で渡します。手元のファイルを直接読ませたい場合は、公式がnpmパッケージ carbone-mcp(標準入出力で動く自己ホスト版)を案内しています。

スキルが効く場面1: タグとループを正しい形で書かせる

スキルの中身(SKILL.md)には、タグの種類、ループ、フォーマッタ、条件、集計の書き方と、検証チェックリストが入っています。ここでは、Claude Codeに「請求書テンプレートを設計して」と頼んだときに出てくるべき形を、スキルの記述に沿って確認します。

タグの基本

データはメインのJSONを指す d.、補助情報を指す c. で参照します。ネストは {d.user.address.city} のようにドットでたどり、配列の末尾は {d.items[i=-1].name} で取れます。

{d.customer.name}
{d.customer.address.city}
{c.now:formatD(LL)}

c.now は描画時刻を返す組み込みタグで、formatD で整形して表示します。

ループは「2行宣言」

Carboneのループには for も end もありません。同じ構造の行を2行並べ、1行目に [i]、2行目に [i+1] を書きます。2行目は繰り返しの終端の印として使われ、出力からは消えます。

{d.items[i].name}   {d.items[i].qty}   {d.items[i].price:formatC}
{d.items[i+1].name}

2行目に書く属性は無視されるため、{d.items[i+1].name} の .name に意味はありません。スキルのチェックリストにも「[i+1] の後ろの属性は読まれない」とあります。

絞り込みは括弧の中に条件を書きます。

{d.items[i, qty > 1].name}
{d.items[i+1, qty > 1].name}

ソートは属性名をイテレータにする書き方で、sortAsc() のような関数はありません。グルーピングも同様に、[brand] と [brand+1] のように属性名を使います。ここは言語モデルが他の言語の癖で書きがちな場所で、スキルが「関数は存在しない」と明示しています。

フォーマッタは : でつなぐ

値の整形はコロンで連結します。出力が次の入力になるため、入れ子にはできません。

{d.name:lowerCase:ucFirst}
{d.birthday:formatD(LL)}
{d.total:formatC}
{d.qtyB:add(.qtyC)}

add(.qtyC) のように . で始まる引数は、同じ階層の別の属性を指します。{d.value:add(20:sub(10))} のような入れ子は動きません。{d.value:add(20):sub(10)} と連結します。

スキルが効く場面2: 条件と集計

条件は、フォーマッタの連鎖で書きます。if 文は存在しません。

{d.score:ifGT(50):show('合格'):elseShow('不合格')}

ブロックごと出し入れするなら、showBegin と showEnd(または hideBegin と hideEnd)で挟みます。Beginだけ書いてEndを忘れると文書が壊れるため、必ず対にします。

{d.isPremium:ifEQ(true):showBegin}
 プレミアム向けの案内文
{d.isPremium:showEnd}

スキルは、ブロックを消したいときの第一候補として :drop を勧めています。{d.discount:ifEM():drop(row)} のように書くと、条件に当たった行や段落そのものを取り除き、空白が残りません。

合計は集計フォーマッタで出します。ループの外に書くと全体の合計、ループの中でグループを指定すると小計になります。

合計: {d.items[].qty:aggSum}
{d.items[i].qty:aggSum(.brand)}

ここで注意が要るのは提供範囲です。スキルの記述では、:drop などのスマート条件、集計、:set、動的画像、バーコード、色、:html はEnterprise扱いとされています。基本のタグ、ループ、ifEQ 系の条件、formatD や formatN といった整形は別枠です。自分の契約でどこまで使えるかは、テンプレートに書く前にCarbone側のプラン表で確かめます。

形式ごとの落とし穴をスキルに言わせる

同じ記法でも、入れ物の形式で壊れ方が変わります。スキルの設計指針から、実務で踏みやすいものを拾います。

  • 引用符: Wordなどは ' を自動で曲線の引用符に置き換えます。Carboneが受けるのは直線の一重引用符だけなので、オートコレクトをオフにします。二重引用符はタグ内で使えません
  • PPTX: 絶対配置の形式で、ループしてもスライドは自動で増えません。フィルタでページを分けて組みます。ODPなら動的にスライドを増やせます
  • XLSX/ODS: タグと数式は別のセルに置きます。合計はループ後の行数が変わるため、数式より集計フォーマッタの利用を優先します。:formatN を通すと、セルが文字列でなく数値として入ります
  • PDFを出す: スタイルを細かく制御するならHTMLテンプレート、ページ区切りや溢れの扱いを優先するならDOCXまたはODTを選びます
  • ループ内の図形: 浮動する画像や図形は、アンカーを「行内」にしないと不正な出力になります

また、2つのループを交互に書くと文書が壊れます。fruits の [i] と vegetables の [i] を同じ行にまたがらせず、ループごとに開始と終端を対で完結させます。1行の中で別の配列を参照したいときは、ルックアップを使います。

Claude Codeに頼む型: 書かせる前に検査させる

スキルは自然文で起動します。「Carboneテンプレートを作って」「このタグを直して」と書けば、スキルが読み込まれます。依頼文には、データの形と出力形式を先に渡すと、記法のずれが減ります。

次のJSONを流し込むCarboneのDOCXテンプレートを設計して。
出力はPDF。明細は配列itemsのループ、割引があるときだけ行を消す。
タグは書いたあと、チェックリストに照らして自分で検査して。
 
{ "customer": { "name": "ACME" },
  "items": [ { "name": "A", "qty": 2, "price": 1200, "discount": 0 } ] }

スキルの検証チェックリストは、波括弧が {{ になっていないか、接頭辞が d. c. # $ t( o. のどれかか、フォーマッタの区切りが : か、showBegin と showEnd が対になっているか、といった26項目です。タグを書いたあとの検査を依頼文に入れると、これらが実際の確認に使われます。

ただし、タグが書式として正しいことと、描画結果が望みどおりであることは別です。レイアウト崩れやフォントは、実際に1度生成して目で確かめるまで分かりません。

MCPで描画して、結果を見て直す

サーバーを認証すると、同じ会話内で描画まで回せます。公式のMCPページには、次のような依頼例があります。

Use Carbone to fill the invoice template
https://carbone.io/examples/invoice-expert/template.docx
with the data at https://carbone.io/examples/invoice-expert/data.json
and give me the PDF.

自分のテンプレートなら、ライブラリに1度アップロードして名前で呼びます。公式の例では「Invoiceテンプレートが期待するフィールドを列挙して、サンプルのJSONを作って」「テンプレートをフランス語・ドイツ語・スペイン語で生成して、日付と金額を各言語の書式にして」といった依頼が挙げられています。

Salesforce、HubSpot、Stripeなどのコネクタを別に追加している場合は、そこから取った商談や請求データをテンプレートに流す依頼も例に挙がっています。ただし、その依頼にはそれぞれのコネクタが追加されている必要があります。

生成されたPDFやOffice文書は会話内に返ります。アシスタントが表示できなければ、ダウンロードリンクを頼みます。

つまずきやすい点

描画したら空欄が出る。 {d.items[0]products.value} のようにキーの前のドットを抜かすと、空になります。ドットを補います。

ループの小計だけ合わない。集計は、ループの中でグループ指定(aggSum(.brand))を付けたときだけ小計になります。外に書くと全体の合計です。

サインインが終わらない。 /mcp で carbone のAuthenticateが済んでいるか確認します。Teamプランでは、先にOwnerが追加していないと各メンバーは接続できません。

PDFに透かしが入る。有料プランの契約がなく、無料枠の外で生成すると、透かし付きPDFになります。

条件フォーマッタが効かない。 ifEQ の後ろには show、elseShow、showBegin、hideBegin、drop、keep のいずれかが必要です。条件だけを置いても何も起きません。

同じ「プラグインで外部サービスをつなぐ」型の記事に、1Passwordプラグインや42Crunchプラグインがあります。MCPサーバー側を自作したいなら、mcp-server-devプラグインが入口になります。

まとめ

Carboneプラグインの価値は、2か所に分かれます。記法の側では、独自のタグ・2行ループ・フォーマッタ連鎖をモデルの記憶に頼らず書かせられること。実行の側では、ホスト型サーバーで同じ会話内に描画できることです。テンプレートを書く作業が中心なら、スキルだけで始められます。描画まで任せるなら、データがCarboneのAPIに渡る点と、Enterprise限定の機能に当たる点を先に確認しておくと、後から書き直す手間を抑えられます。

この記事を共有:XはてブLinkedIn