Skip to content

@tabula-css/mcp

Tabula の読み取り専用 MCP サーバー: 生成された .tabula/ アーティファクト上のエージェント向けサーフェス。

インストール

bash
npm install --save-dev @tabula-css/mcp

開発時依存です — これはあなたのアプリのランタイム依存ではなく、コーディングエージェントの MCP クライアントが起動するローカルツールです。@tabula-css/cli@tabula-css/core@tabula-css/eslint-plugin@tabula-css/merge@tabula-css/registry@tabula-css/tokens をバンドルしています。@typescript-eslint/parser は通常の依存関係として同梱されます。eslint は任意のピア依存で、validate_source ツールにのみ必要です。

概要

llms.txt/llms-full.txt がエージェントに語彙の静的な地図を与えるのに対し、MCP サーバーは同じ .tabula/ アーティファクトへのライブで構造化されたアクセスを与えます: クラス文字列が実際に何をレンダリングするかを解決すること、cn() のマージを書く前にプレビューすること、名前を思い出す代わりに意図からクラスを逆引きすること、そして提案された編集が着地する前に実際のレジストリに照らして検証すること。すべてのツールは読み取り専用です — ここでのどれもファイルを書き込みません。2 つの提案ツールは、エージェント自身の編集経路が適用するパッチを返すため、人間が diff をレビューします。

実行

bash
npx tabula-mcp [--cwd <dir>]

バイナリは tabula-mcp(bin.ts から)です。stdio(StdioServerTransport)で MCP を話します — 標準出力はプロトコルだけを運び、それ以外は何も運びません。すべての診断は標準エラーへ送られます。そうしないとプロトコルフレームとしてパースされてしまいます。--cwd は、現在のディレクトリではない別のプロジェクトルートを指定します。.tabula/ が存在しないか不正な場合、決して読んでいないプロファイルを提供するのではなく、起動を拒否します(exit 2)。

MCP 対応クライアントの設定で、直接これを指定してください。例:

json
{
  "mcpServers": {
    "tabula": { "command": "npx", "args": ["tabula-mcp"] }
  }
}

すべてのレスポンスは陳腐化エンベロープを伴います

json
{ "profileVersion": "…", "sourceHash": "…", "stale": false }

陳腐化は呼び出しのたびに再計算されます — サーバーは .tabula/ とトークンのソースを再度 stat し、それらが変化していれば再読み込みするため、編集してから再ビルドするループは決して再起動を必要としません。すべてのツールは、古い読み取りを次のように拒否します:

json
{
  "error": "STALE_REGISTRY",
  "message": "The .tabula/ artifacts do not match the current inputs. …",
  "command": ["tabula", "build"],
  "reasons": ["…"],
  "profileVersion": "…", "sourceHash": "…", "stale": true
}

2 つのツールはこの拒否から除外されます(該当する場合には stale: true を報告し続けますが): doctor はその仕事全体が陳腐化を報告することであり、explain@tabula-css/core の凍結されたカタログしか読まず、どのアーティファクトにも触れません。ソースのドリフトチェックを実行できなかった場合(解決不能なパッケージバージョン、または読み取り不能なプロジェクトソース)、エンベロープにはさらに "staleCheck": "artifacts-only" が含まれます — 陳腐化と成果物のみのチェック を参照してください。

ツール

resolve_classes

「この要素は実際にはどう見えるか?」クラス文字列に対する完全なローカルスタイリングモデルです: 基本の宣言、条件付きの帯域、アンビエントプロパティ、アトミック/未知のクラス、グループ依存関係。

ParamTypeRequired
classesstring | string[]yes
axesRecord<string, string>(例: { theme: "dark" })no
jsonc
// → resolve_classes({ classes: "bg-surface p-md" })
{ "profileVersion": "…", "sourceHash": "…", "stale": false, /* declarations, bands, … */ }

preview_merge

cn(...) を書く前に、それが実際に何を生成するかを正確に予測します: マージされた文字列に加え、破棄されたすべてのクラス、それを何が shadow したか、そしてどの CSS プロパティ上でかを返します。

ParamTypeRequired
fragmentsstring[] — 順序どおり。呼び出し側の className は最後に置きますyes

find_class_for

意図による逆引きです — このセット内で最も価値の高いツールです。実際のテキスト(クラス名、ファミリー、宣言されたプロパティ/値、トークンの説明)のみをマッチさせ、ヒットごとに matchedOn を報告します。同義語テーブルもファジースコアもありません。ヒットしないことは、そのようなクラスが存在しないことを意味し、「任意の値を推測せよ」ということではありません。

ParamTypeRequired
intentstringno
propertystring、例: "padding-inline"no
valuestring、例: "#ffffff"no
familystring、例: "bg"no
limitnumber(デフォルト 25)no
jsonc
// → find_class_for({ intent: "raised card background" })
{ "matches": [{ "class": "bg-surface-raised", "family": "bg", "matchedOn": ["intent"], "rank": 30091300002,  }], "total": 1 }

get_tokens

tokens.resolved.json から直接得られる、すべてのトークン(または名前空間/部分文字列によるスライス)です — 値を選ぶ前にこれを読んでください。

ParamTypeRequired
namespacestring、例: "color"no
querystring、パス + 説明に対する部分文字列マッチno

get_vocabulary

ページングされた、クラスの完全な一覧です — 静かに切り詰められることは決してなく、レスポンスは total/pages/hasMore を報告します。

ParamTypeRequired
familystringno
prefixstringno
pagenumber、0 始まりno
pageSizenumber(デフォルト 100、最大 500)no

explain_ban

なぜあるクラスが禁止されている、あるいは未登録なのか、その置き換え案とともに — 単なる「見つかりません」で終わることは決してありません。自信のないクラス(space-x-4dark:bg-blackpl-4)を書く前に呼び出してください。

ParamTypeRequired
classstring、例: "space-x-4"yes

resolve_element

{ file, line, col } によって JSX 要素を指し示し、その解決済みクラス、同一ファイル内の祖先から継承されるテキストコンテキスト、そしてそれが参照する各 group/peer がそのファイル内にマーカーを持つかどうかを返します。同一ファイル内の解析のみ — コンポーネントの境界では、コンポーネントが何をレンダリングするかを推測するのではなく、次に開くべきファイルとともに status: "unknown" を返します。また、要素がどの軸の組み合わせの下でレンダリングされるかは実行中のドキュメントについての事実であってソースについての事実ではないため、axisValues は省略されます。

ParamTypeRequired
filestring、プロジェクトルートからの相対パスyes
linenumber、1 始まりyes
colnumber、1 始まりyes

validate_source

ソース文字列を、あなたのレジストリに対する実際の strict ESLint 設定で lint します — check_classes が構造的に捉えられないもの(ランタイムでのクラス構築、className の順序、group/peer の構造、継承の境界、例外のスコープ)を捕捉します。これは AST を見るためです。インラインの eslint-disable コメントは無視されるため、スニペットが話術でクリーンな判定を得ることはできません。eslint@typescript-eslint/parser がインストールされている必要があります。なければ LINTER_UNAVAILABLE とインストールコマンドを返します。

ParamTypeRequired
codestring — lint 対象のソーステキストyes
filenamestring、例: "src/ui/card.tsx" — ディスクから読み取られることは決してありません。ルールと例外のスコープを選択するためのものですyes

propose_exception

トークンを持たない値を導入する唯一の合法な方法です。パッチを返します — 何も書き込みません。 実際のトークンバリデーターを通じて検証し、既存のトークンが約 5% 以内にある場合はそちらへ促し、パッチが発行するであろうクラス名を返します。

ParamTypeRequired
namestring、ケバブケースyes
$typestring(DTCG の型)yes
valuestring、例: "347px"yes
familiesstring[]、例: ["w"]yes
reasonstring、40 文字以上yes
ownerstring、例: "@design-systems"yes
expiresstringYYYY-MM-DD、12 か月以内(literal の場合は 90 日以内)yes
allowedInstring[](glob)yes
descriptionstringno
ticketstringno
literalbooleanno

propose_token

新しいデザイントークンを発行します — トークンは永続的な語彙となるため、propose_exception よりもこちらを優先してください。パッチを返します — 何も書き込みません。 実際のトークンドキュメントに継ぎ足すことで検証されます。

ParamTypeRequired
namestring"<namespace>.<name>"yes
$typestring(DTCG の型)yes
valuestring — 単一のリテラル。cases とは互いに排他的no
casesobject — 軸マップ、例: { $axis: "theme", light: "#fff", dark: "#0b0b0b" }value とは互いに排他的no
descriptionstringno

find_group_marker

名前付きの group/<name> マーカーがどこで宣言されているか。これにより、要素間の依存関係がツリーウォークではなくルックアップになります。「そのようなマーカーはない」ことと「このビルドがマーカーインデックスを生成しなかった」ことを区別します。

ParamTypeRequired
namestring、例: "card"yes

check_classes

事前チェックです — class 属性を書く前に呼び出してください。未知のクラス(「もしかして」提案付き)、禁止されたメカニズム、同一文字列内のスロット競合を報告し、正規のマージ済み文字列を返します。

ParamTypeRequired
classesstring[]yes

doctor

ヘルスチェックです: 陳腐化(理由と修正コマンド付き)、手編集されたアーティファクト、期限切れ間近の例外、そしてエスケープ予算。古い状態でも 応答します — 陳腐化を報告する仕組み自体が「古いから」という理由で拒否してしまっては、何がドリフトしたのかを決して伝えられません。

パラメータなし。

jsonc
// → doctor()
{
  "stale": false, "reasons": [], "checkedSource": true,
  "drift": [], "expiringExceptions": [], "escapeBudget": { "used": 3, "max": 25 },
  "profileVersion": "…", "sourceHash": "…", "manifestInputsHash": "…"
}

explain

@tabula-css/core の凍結されたカタログからの、TAB-Exxx/TAB-Wxxx コードの原因と修正方法です。

ParamTypeRequired
codestring、例: "TAB-E113"yes

関連パッケージ

Released under the MIT License.