stylespeak について
stylespeakは、CSSを編集する前にカスケードを把握するための、AIコーディングエージェント向けMCPサーバーとCLIです。CSS、SCSS、CSS Modules、styled-components、Emotionを解析し、実行中のChromiumで計算済みスタイルも確認できます。
主な機能
- 01セレクターに適用されるスタイルの解決
- 02プロパティ宣言と優先ルールの追跡
- 03スタイル変更の影響範囲の予測
- 04プロジェクトのCSS構成の要約
- 05Chromiumの計算済みスタイルの取得
- 06CSS-in-JSとカスタムプロパティの解析
活用シーン
- 01スタイル編集前の適用ルール確認
- 02CSSプロパティ変更の影響評価
- 03エージェント用プロジェクトスタイル概要の読み込み
- 04実行中ブラウザーでの計算済みスタイル確認
MCP 対応
MCPサーバーとして、スタイル解決、プロパティ追跡、影響予測、プロジェクト概要、ブラウザーでのリアルタイム検査を行うツールをMCPクライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
5掲載時のツール一覧 · 3 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| files | array | いいえ | 解析する CSS/SCSS ファイルの絶対パス。 |
| selector | string | はい | 解決する CSS セレクター。例:".btn.primary"、"#header a:hover" |
| projectRoot | string | いいえ | 任意:プロジェクトルートのパス。すべての CSS/SCSS ファイルを再帰的に検出します。 |
| componentFiles | array | いいえ | 任意:JSX/TSX ファイルの絶対パス。指定すると AST コンポーネントグラフを構築し、祖先関係が確認された場合にセレクターの確信度を possible から likely に引き上げます。 |
詳細
StyleSpeak - MCP と CLI
stylesafeに付属する MCP サーバーと CLI です。CSS を AI エージェントが理解しやすい形にし、カスケードの解決、プロパティの追跡、変更の影響予測を行います。エージェントがスタイルに手を加える前に、何が適用されるのか、そしてその理由を説明します。
問題点
AI コーディングエージェントは、CSS の効果を把握できないまま CSS を記述します。ルールを変更して効果があったと思い込み、そのまま次に進みます。しかし実際には、別の場所にある詳細度の高いルールにすでに上書きされていたり、別のファイルにあるコンビネーターのルールがひそかに優先されていたり、CSS 変数が予想とはまったく異なる値に解決されていたりします。stylespeak は、変更を加える前にエージェントが参照できる、構造化された知識レイヤーを提供します。
できること
resolve_styles — 「このセレクターに実際に適用される CSS は何か?」に答えます。
セレクターとファイルのセットを指定すると、そのセレクターが受け取るすべての CSS プロパティ、各プロパティで優先されるルール、上書きされたルールを返します。実際の DOM は利用できないため、信頼度レベルも示します。CSS カスタムプロパティ(var())は、連鎖する変数、フォールバック、メディアコンテキストによる上書きを含め、実際の値に解決されます。
trace_property — 「このプロパティが設定されているすべての場所で、どのルールが優先されるか?」に答えます。
プロパティ名とファイルのセットを指定すると、そのプロパティを設定するすべてのルールを返し、重複するセレクターを対象とする競合ルールをグループ化して、各グループのカスケード全体を表示します。解決済みの変数値も含まれます。
impact_preview — 「これを変更したら、ほかに何が壊れるか?」に答えます。
セレクター、プロパティ、任意の新しい値を指定すると、変更を加える前に、その影響範囲全体を予測します。異なる値を受け取るセレクター、詳細度の高いルールに保護されるセレクター、カスケードの関係が不確かな箇所、CSS 変数の連鎖やプロパティの継承を通じて影響を受ける下流のルールを表示します。ブラウザーなしで動作します。
style_manifest — 「このプロジェクト全体の CSS は、ひと目で見るとどのような状態か?」に答えます。
プロジェクト全体の CSS に関する知識を、セレクター、プロパティ、変数、競合グループ、リスクの高い箇所を含む、圧縮された構造化サマリーにまとめます。エージェントはセッション開始時に一度読み込み、個々のファイルを繰り返し問い合わせる代わりに、その情報をコンテキスト内に保持できます。
live_resolve — 「このセレクターについて、ブラウザーが実際に計算する値は何か?」に答えます。
CDP 経由で実行中の Chromium ブラウザーに問い合わせ、正確な計算済みスタイルと一致したルールを返します。ヒューリスティックや信頼度レベルはなく、ブラウザーが解決した値を返します。--remote-debugging-port=9222 を指定して Chrome を起動する必要があります。
通常の CSS 以外にも対応しています。 上記の 4 つの静的ツールは、.css、.scss、CSS Modules に加えて、v1.3 以降は styled-components と Emotion のソースファイル(.js/.jsx/.ts/.tsx)も、すべて同じカスケードエンジンで解析します。
クイックスタート
CLI ツールとして
npm install -g @patrizzos/stylespeak
stylespeak resolve ".btn.primary" src/styles/main.css
stylespeak trace "color" --projectRoot src/styles
stylespeak impact ".btn" "background-color" src/styles/main.css --newValue "#ff0000"
stylespeak manifest --projectRoot src/styles
# styled-components / Emotion — components are addressed by variable name (const Button = styled.button`` -> .Button)
stylespeak resolve ".Button" src/components/Button.jsx
stylespeak manifest --projectRoot src
MCP サーバーとして
MCP クライアントの設定に追加してください(Cursor:.cursor/mcp.json、VS Code:.vscode/mcp.json)。
{
"mcpServers": {
"stylespeak": {
"command": "node",
"args": ["/absolute/path/to/stylespeak/src/server.js"]
}
}
}
接続すると、エージェントは次を呼び出せます。
resolve_styles({ selector, files, projectRoot, componentFiles? })trace_property({ property, files, projectRoot })impact_preview({ selector, property, newValue?, files, projectRoot })style_manifest({ files?, projectRoot?, maxSelectors? })live_resolve({ selector, port?, tabUrl? })
出力例
impact_preview
stylespeak impact ".btn" "background-color" src/styles/buttons.css --newValue "#ff0000"
{
"change": {
"selector": ".btn",
"property": "background-color",
"currentValue": "var(--color-primary)",
"newValue": "#ff0000"
},
"blastRadius": {
"total": 3,
"valueChanges": 1,
"shielded": 1,
"risks": 0,
"variableDownstream": 0,
"inheritanceDownstream": 1
},
"riskLevel": "low",
"safeToChange": true,
"impacts": [
{
"type": "value-change",
"affectedSelector": ".btn",
"currentValue": "var(--color-primary)",
"newValue": "#ff0000",
"confidence": "certain"
},
{
"type": "shielded",
"affectedSelector": ".btn.primary",
"shieldingValue": "darkblue",
"confidence": "certain",
"reason": ".btn.primary has higher specificity — elements with both classes won't be affected"
}
],
"summary": "1 selector will see a different value, 1 selector is shielded by higher specificity.",
"agentNote": "Change appears safe to make. Shielded selectors are safe — higher-specificity rules protect those elements."
}
resolve_styles
stylespeak resolve ".btn" src/styles/buttons.css
{
"properties": {
"background-color": {
"winner": {
"value": "var(--color-primary)",
"resolvedValue": "#2563eb",
"variableChain": ["--color-primary → #2563eb"],
"selector": ".btn",
"specificity": "(0,0,1,0)"
},
"confidence": "certain"
}
},
"variables": { "--color-primary": { "value": "#2563eb", "selector": ":root" } }
}
信頼度レベル
| レベル | 意味 |
|---|---|
certain | セレクターが完全に一致 — ルールが確実に適用されます |
likely | ルールのトークンが問い合わせたセレクターのサブセット — ほとんどの場合に適用されます |
possible | コンビネーターのルール — DOM の祖先要素に依存し、レンダリングしないと不明です |
exact | live_resolve のみが返す値 — ブラウザーによって解決され、ヒューリスティックはありません |
CSS カスタムプロパティの解決
v0.2 以降、stylespeak はすべての出力で CSS カスタムプロパティ(var())を完全に解決します。
value— 記述されたままの生の値(var(--color-primary))resolvedValue— 実際に解決された値(#2563eb)variableChain— 連鎖した変数を含む、解決経路全体conditionalValues— 変数の解決結果が異なるメディアコンテキストでの上書き
対応範囲:単純な参照、フォールバック、ネストされたフォールバック、連鎖、スコープ、メディアコンテキスト、循環参照の保護。
CSS-in-JS のサポート(styled-components と Emotion)
v1.3 以降、stylespeak は styled-components、@emotion/styled、@emotion/react、または @emotion/css をインポートする .js、.jsx、.ts、.tsx、.mjs、.cjs ファイルからスタイルを静的に抽出し、通常の CSS と同じカスケードエンジンで処理します。resolve_styles、trace_property、impact_preview、style_manifest はすべてこれらのファイルで動作し、CSS-in-JS と通常の CSS をまとめて分析できます。
files に JS/TS ファイルを指定するか、projectRoot にディレクトリを指定します。これらのライブラリのいずれかをインポートするファイルは自動的に検出され、それ以外の JS/TS ファイルは無視されます。
コンポーネントの指定
生成されるクラス名は実行時にハッシュ化されるため、スタイル付きコンポーネントは変数名をクラスセレクターとして指定します。
const Button = styled.button`...`; // -> .Button
export default styled.section`...`; // -> .Card (named after the file, e.g. Card.jsx)
ルールには cssInJs、library、component のタグが付けられ、ローカルスコープとして扱われます(CSS Modules と同様です)。異なるファイルにある Wrapper という名前のコンポーネントは互いに独立しており、競合として報告されることも、「N か所で宣言された」リスクとして数えられることもありません。このような名前をクエリすると、両方のファイルの結果が混在するため、曖昧であることが示されます。
抽出対象
| 構文 | 処理 |
|---|---|
| タグ付きテンプレート | styled.div`…`、styled(Comp)`…`、styled.div.attrs(…)`…`、styled.div<Props>`…`(TypeScript のジェネリクス)、css`…` |
| オブジェクト構文 | styled.div({ … })、styled(Comp)({ … })、css({ … })、styled.div(props => ({ … })) |
| グローバルスタイル | createGlobalStyle / injectGlobal — ローカルスコープではなく、実際のセレクターを使用 |
| ネスト | &、&&(詳細度を引き上げ)、&:hover、単独の :hover、ネストされたセレクター、@media / @supports / @container |
| コンポーネントセレクター | ${Icon} { … } は .Icon になります。例:.Button .Icon |
| 定数 | 同一ファイル内の const 文字列、数値、オブジェクトパス:${SPACING}、${colors.primary}、@media ${bp.md} |
css ヘルパー | 同一ファイル内の const mixin = css`…` は、補間箇所(${mixin}、...mixin)にインライン展開され、独自の名前(css-helper タグ付き)でもクエリできます。Emotion の css={mixin} プロパティでは、このヘルパーだけがスタイルを示すレコードになるため便利です。 |
| オブジェクト表記 | キャメルケースをケバブケースに変換します。ベンダープレフィックス(WebkitX → -webkit-x、msX → -ms-x)を変換し、単位のない数値には px を付けます(opacity、z-index、line-height など、単位のないプロパティを除く)。 |
推測せず、フラグを付ける対象
props やテーマに依存する値は静的には判別できません。stylespeak は元の式を保持してフラグを付け、エージェントに次のように通知します。
"color": {
"winner": {
"value": "${props => props.color}",
"selector": ".Button",
"cssInJs": true,
"library": "styled-components",
"component": "Button",
"dynamic": true
},
"confidence": "certain",
"dynamic": true
}
- 宣言、勝者、プロパティの
dynamic: trueは、値が実行時の props やテーマに依存することを示します。props によって勝者が異なる場合があります。 - 条件ブロックやミックスイン呼び出し(
${p => p.active && css…})は評価できません。これらは除外され、dynamicInterpolationsに集計されます。また、実行時に追加のスタイルが適用される可能性があることをagentNoteが警告します。 - セレクターに関連付けられないスタイルブロックは、黙って無視するのではなく、
style_manifestの出力にあるcssInJs.skippedに一覧表示されます。 styled(Base)はextendsを記録します。agentNoteは、エージェントにベースコンポーネントも解決するよう伝えます。
制限事項
これは静的解析のため、いくつかの制約があります。
styled(Base)はベースコンポーネントのスタイルを子コンポーネントにマージしません。ベースのセレクターは個別に解決してください。- 別ファイルからインポートされた定数やテーマオブジェクトは解決されません(同じファイル内のもののみ)。
ThemeProviderのテーマも解決されません。 - JSX 要素の Emotion の
cssプロパティや、名前付き変数に割り当てられていないスタイルブロックは匿名です。対象となるセレクターがないため、スキップとして報告されます。 keyframesはモデル化されず、.attrs({ className })も考慮されません。- ファイル間の注入順序は、指定されたファイルの順序で近似されます。
- 実行中のアプリで正確な結果を確認するには、実際の要素に対して
live_resolveを使用してください。
stylesafe との連携
stylesafe は、CSS の競合、不要なルール、Tailwind との衝突などの問題を、リリース前に検出します。
stylespeak は、カスケードの解決、プロパティの追跡、影響の予測、変数の解決などを行い、CSS を説明することで、エージェントが変更前に状況を理解できるようにします。
編集後のチェックには stylesafe を使用してください。編集前の相談には stylespeak を使用してください。両者を組み合わせることで、AI コーディングエージェントにスタイルに関する完全なフィードバックループを提供できます。
ライブブラウザー検査
live_resolve を使用するには、リモートデバッグを有効にした Chromium ブラウザーを起動しておく必要があります。
# Windows
chrome.exe --remote-debugging-port=9222
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
セキュリティに関する注意: 信頼できないネットワークに公開されたマシンや本番環境で、
--remote-debugging-portを実行しないでください。このフラグを指定すると、マシン上のあらゆるプロセスが接続できるローカル API が開きます。
ファイル形式のサポート
| 形式 | サポートレベル |
|---|---|
.css | 完全 |
.scss | 完全 — ネスト、& 参照、@media のパススルー |
.module.css / .module.scss | 完全 — ローカルスコープのクラスを検出してタグ付け |
| vanilla-extract / Linaria / StyleX | コンパイル済み CSS 出力を介してサポート |
| styled-components / Emotion | サポート(v1.3)— .js / .jsx / .ts / .tsx / .mjs / .cjs から静的に抽出。props やテーマに依存する値は推測せず、dynamic としてフラグ付け |
| CSS-in-JS オブジェクト構文 | サポート(v1.3)— styled.div({…})、css({…})、関数が返すオブジェクト |
Emotion の css プロパティ(インライン JSX) | 抽出不可 — 匿名のため、スキップとして報告 |
アーキテクチャ
src/
cssParser.js — CSS tokenizer with SCSS nesting support
specificity.js — standard (id, class, type) specificity calculator
cssomBuilder.js — in-memory cascade model builder (CSS, SCSS, CSS Modules, CSS-in-JS)
selectorMatcher.js — heuristic selector matching with confidence levels
variableResolver.js — CSS custom property resolution
cssModulesAnalyzer.js — CSS Modules local scope detection
scssNestingExpander.js — SCSS nesting pre-processor
cssInJsExtractor.js — styled-components / Emotion static extractor (template + object syntax)
astComponentGraph.js — AST component graph for graph-aware matching
resolveStyles.js — resolve_styles tool
traceProperty.js — trace_property tool
impactPreview.js — impact_preview tool
styleManifest.js — style_manifest project-wide knowledge builder
cdpBridge.js — Chrome DevTools Protocol WebSocket client
liveResolve.js — live_resolve tool
server.js — MCP server (stdio JSON-RPC) + CLI entry point
外部依存関係はありません。Node.js 21+ が必要です。
ロードマップ
- v0.2 ✅ — CSS カスタムプロパティの解決
- v0.3 ✅ — SCSS のネスト、CSS Modules のスコープ認識、AST コンポーネントグラフ
- v1.0 ✅ — Chrome DevTools Protocol によるライブ解決
- v1.1 ✅ — impact_preview:変更前の影響範囲予測
- v1.2 ✅ — style_manifest:エージェントのコンテキスト向けに圧縮したプロジェクト全体の CSS ナレッジ
- v1.3 ✅ — CSS-in-JS:styled-components と Emotion の静的抽出(テンプレート構文とオブジェクト構文)
次の予定(スケジュール未定)
CSS-in-JS サポートにおける既知の不足項目(順不同):styled(Base) のスタイルを子コンポーネントにマージすること、別ファイルからインポートされた定数やテーマオブジェクトを解決すること、keyframes と Emotion の css プロパティをモデル化すること。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。