これは何か
vite dev の実行中、プラグインは /__svelte-devtools/mcp に MCP エンドポイント(Streamable HTTP)を提供します。エージェントはそこでツールを呼び、パネルに表示される内容を読みます:
活発なコンポーネント、1 つのインスタンスのリアクティブグラフ、サンプリングされた state の変化、レンダープロファイル、load
関数、フレームレート。変更の前後を比べる計測セッションも実行できます。
アプリのコードや state を変更するツールはありません。起きることは 2 つです:
呼び出しのたびにページ内のランタイムが約 1
分間サンプリングを続けること、そしてセッション系のツールが計測セッションを保持すること(メモリ内。ディスクには指定したときだけ書き込み、delete_session で削除できます)。実行時のデータはブラウザで開いているアプリのページから来るので、エージェントの作業中はアプリを開いたままにしてください。
Claude Code に接続する
開発サーバーを起動すると、待ち受けを始めた時点で、Claude Code にサーバーを登録するコマンドがポートとトークンつきで表示されます:
svelte-devtools MCP ready — register with Claude Code:
claude mcp add --transport http svelte http://localhost:5173/__svelte-devtools/mcp --header x-svelte-devtools-token:<token>表示された行をそのまま実行します。すべてのリクエストは x-svelte-devtools-token ヘッダーにトークンが必要で、ない場合は 403 が返ります。
トークンは起動のたびに変わる
トークンは開発サーバーの起動ごとにランダムに生成されます(設定変更で Vite が再起動した場合も同じです)。再起動したら、新しく表示された行で登録し直します:
claude mcp remove svelte
claude mcp add --transport http svelte http://localhost:5173/__svelte-devtools/mcp --header x-svelte-devtools-token:<新しいトークン>コマンドの代わりにプロジェクトのファイルを使う
claude mcp add は自分だけにサーバーを登録します(local
スコープ)。プロジェクトの .mcp.json はプロジェクトを開く全員と共有されるので(project スコープ)、トークンを書き込まないでください。Claude
Code はこのファイル内の環境変数を展開するので、トークンは環境変数から読み込みます:
{
"mcpServers": {
"svelte": {
"type": "http",
"url": "http://localhost:5173/__svelte-devtools/mcp",
"headers": { "x-svelte-devtools-token": "${SVELTE_DEVTOOLS_TOKEN}" }
}
}
}開発サーバーが表示した行からトークンを設定し、Claude Code を起動します:
export SVELTE_DEVTOOLS_TOKEN=<表示された行のトークン>
claudeURL のポートは開発サーバーのポートと一致させてください。
他の MCP クライアント
カスタムヘッダー付きの Streamable HTTP
に対応したクライアントなら接続できます。必要なのは URL(http://localhost:<port>/__svelte-devtools/mcp)とヘッダー(x-svelte-devtools-token: <token>)の 2
つです。開発サーバーが表示するのは Claude Code
のコマンドだけなので、他のクライアントではそれぞれの設定形式でこの 2
つを指定します。サーバーはステートレスで JSON で応答します。手動で確認するには:
curl -s http://localhost:5173/__svelte-devtools/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-H 'x-svelte-devtools-token: <token>' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'聞いてみる
たとえばアプリのカートページを開いた状態で:
/cart で税率を変えるとカートの合計がおかしい。
svelte MCP サーバーを使って、活発なコンポーネントを探し、
ReactivePriceChart のインスタンスを見て、grandTotal に影響しうる state と、
税率を編集したときに何が変わったかを教えて。エージェントは通常 get_reactive_summary か list_performance_issues から始め、回答に含まれるヒントをたどります。
基本の流れ
大きなアプリでも回答を小さく保つ順序です。各ステップの実際の回答は英語版の Walkthroughにあります(合成データのサンプルアプリ examples/sample-app で CI が記録したもの)。
get_reactive_summary— まず全体の活発さを見ます。グラフは取得しないので、大きなアプリでも回答は小さく収まります。回答には対象期間とサンプリングされた時間(sampledActiveMs)が含まれます。get_live_components— includeMeta: true で、インスタンスの id とその epoch(ページ読み込み)を一緒に取得します。id はページを読み込むたびに振り直されます。get_reactive_scope— componentId と epoch を渡して、1 つのインスタンスのノードと直接の隣接ノードを見ます。エッジは「影響しうる」(現在の依存関係)という意味で、変化の原因ではありません。get_state_timeline— 最初はカーソルなしで呼び(reset: true)、返された cursor を保存します。アプリで値を変えたあと、cursor を since に渡すと新しい変化だけが返ります。get_capture_info— 上限で切られたデータから結論を出す前に、DevTools が保持している量とアプリが報告した量を確認します。total が null の場合は不明という意味です。
ページをリロードすると、古い epoch のままの componentId
は別のインスタンスとして推測されず、staleReason: "epoch-changed" の空の回答になります。get_live_components で新しい id を取得し直してください。
20 のツール
入力は ? が付いていないもの以外すべて省略できます。
リアクティビティ(範囲を限定して取得)
0.4.0 で追加。どの回答も、対象期間・サンプリング・上限・ページ読み込み(epoch)・古いデータかどうかを明示します。大きなアプリではここから始めてください。
get_reactive_summarytopK?: 1–200, windowMs?: 1000–60000
全インスタンスの実行時カウンタから、最も活発なコンポーネントインスタンスを返します(グラフは取得しません)。期間内にサンプリングされた state の変化とレンダーの回数で、`rows` と `other` の合計が総数になります。
回数はサンプリング値(1 つの state につき 200 ms ごとに最大 1 回)で、発生率ではありません。追跡するのはコンポーネント初期化中に作られた state だけです。最大 1 秒間はキャッシュから回答します。
get_reactive_scopecomponentId?: number, epoch?: string, maxNodes?: 1–5000, maxEdges?: 1–20000
1 つのコンポーネントインスタンスの $state / $derived / $effect ノードと、その直接の隣接ノード。componentId を省略するとアプリ全体のグラフ(上限あり)。
componentId には取得元の epoch が必要です(includeMeta 付きの get_live_components)。リロード後は staleReason "epoch-changed" の空の回答になります。エッジは「影響しうる」関係で、記録された原因ではありません。
get_state_timelinesince?: cursor, limit?: 1–500 (default 100), maxValueChars?: 16–32768 (default 2048)
カーソル以降にサンプリングされた $state の変化を、変更前後の値つきで返します。返された `cursor` を次の呼び出しの `since` に渡します。
`reset: true` はカーソルが古く、バッファ全体(最新 500 件)を返したという意味です。大きな値はサイズの要約に置き換わります。時刻は検出した時刻です。
get_capture_info—
データセットごとに、DevTools が保持している件数とアプリが報告した件数、選択の方針、理由別の破棄件数を返します。
上限で切られたデータから結論を出す前に確認してください。
パフォーマンスの問題
レンダー、リアクティビティ、load 関数、フレームレートをまたいだ問題を順位付きで返します。
list_performance_issuesavgRenderTimeMs?, renderCount?, loadDurationMs?, fpsDropThreshold?, effectMaxDeps? (thresholds)
すべての指標を横断して問題を順位付きで返します。各問題は次に呼ぶツールを `suggestedTool` で示します。
アプリ全体のリアクティブグラフを読みます(上限 5000 ノード / 20000 エッジ)。
get_component_hotspotstopN?: 1–200 (default 20)
合計レンダー時間の多いコンポーネントを、レンダー回数と 1 回あたりの平均とともに返します。
get_render_profilefile: string (substring)
ファイル名に `file` を含むコンポーネントのレンダープロファイル。
get_reactive_graph_problemseffectMaxDeps?: number
依存の多すぎる effect、使われていない derived、孤立したノードを、グラフ全体ではなく分類として返します。
アプリ全体のリアクティブグラフを読みます(上限 5000 ノード / 20000 エッジ)。
get_load_waterfallroute?: string
SvelteKit の load プロファイルをルートごとに、時間とデータサイズつきで返します。
get_fps_dropsthreshold?: 1–120 (default 40), sinceMs?: number
しきい値を下回ったフレームレートのサンプル。
プロジェクトの情報
静的解析と実行中のページから、アプリの構成を返します。
get_project_info—
パッケージ名とバージョン、Svelte / SvelteKit / Vite のバージョン、依存関係の一覧。
get_routes—
静的解析による SvelteKit のルートツリー。
get_live_componentsincludeMeta?: boolean, limit?: 1–50000
ブラウザにマウントされているコンポーネントインスタンス(親が先)。includeMeta 付きでは `{ epoch, total, captured, truncated, components }` を返し、既定で 1000 件までです。
コンポーネント id はその epoch(1 回のページ読み込み)の中でだけ有効です。
get_component_relations—
.svelte コンポーネント間の静的な import 関係。
計測セッション
変更の前後を計測して比較します。
start_sessionlabel: string, persist?: boolean
ラベルを付けて指標の記録を始めます。同時に有効なセッションは 1 つです。
end_sessionkeep?: "memory" | "disk" | "discard" (default "memory")
有効なセッションを終了し、その差分を返します。
"disk" はプロジェクトの node_modules/.vite-devtools-svelte/sessions/ に書き込みます。
compare_sessionsa: session id, b: session id
終了した 2 つのセッションのレンダー・load・フレームレートの指標を比較します。各項目に判定(improved / regressed / unchanged)が付きます。
list_sessions—
メモリとディスクにあるセッションを新しい順に返します。
load_sessionid: session id
セッションの記録全体(終了後は差分を含む)。
delete_sessionid: session id
セッションをメモリとディスクから削除します。
変更を計測する
start_session でセッションを始めてアプリを操作し、end_session で終了します。変更後にも同じことをして、compare_sessions で比較します。比較の各項目には判定(improved / regressed / unchanged)が付きます。
セッションは開発サーバーが動いている間メモリに保持されます。end_session に keep: "disk" を指定すると、プロジェクトの node_modules/.vite-devtools-svelte/sessions/ に書き込まれます。
回答がカバーする範囲
- サンプリング。 state は 200 ms ごとに確認され、1 回のサンプル内の複数回の書き込みは 1 回と数えます。回数は総数や発生率ではありません。
- コンポーネントの state のみ。 コンポーネントの初期化中に作られた
state を追跡します。
.svelte.tsファイルのモジュールレベルの state は対象外です。 - 「影響しうる」であって「原因」ではない。 エッジは現在の依存関係です。どの書き込みが値を変えたかは記録しません。
- 一部の依存関係は欠けます。
$effectは state を読んでいても入ってくるエッジが表示されないことがあります。 - グラフ内の値は要約。 オブジェクトや配列は
(object)、[n]、{n}と表示されます。タイムラインにはmaxValueCharsまでの値が含まれます。 - signal ごとの履歴はありません。 タイムラインはすべての signal をまとめて、サンプリングされた最新 500 件の変化を保持します。
- 上限。 グラフは 5000 ノード・20000
エッジで打ち切られ、そのことを明示します(
truncated、total、edgesOmitted)。get_capture_infoが何をなぜ落としたかを報告します。 - 1 回のページ読み込み。 コンポーネント id は 1 つの epoch
の中でだけ有効です。回答は最大 1 秒間キャッシュから返ることがあり、
computedAtとwindow.untilが計算時刻を示します。
非常に大きなアプリでの性能は計測していません。対応できる規模は約束していません。
トラブルシューティング
403 Forbidden- トークンがないか、以前の起動のものです。開発サーバーが最後に表示した行で登録し直してください。
staleReason: "no-runtime"の空の回答- アプリのページが接続されていません。ブラウザでアプリを開いてから呼び直してください。
staleReason: "timeout"- アプリのページが 1 秒以内に応答しませんでした。回答は前回のもの(その
computedAtつき)か空です。呼び直してください。 staleReason: "epoch-changed"- ページがリロードされました。
includeMeta: trueでget_live_componentsを呼び、新しい id と epoch を取得してください。 componentId requires epoch- 同じ
get_live_componentsの回答に含まれる epoch を渡してください。 - コンポーネントやリアクティブノードが出てこない
componentTrackingがfalseになっていないこと、vite.config.tsでプラグインがsveltekit()より前にあることを確認してください。- アプリのタブが複数ある
- 回答は最後に報告したページに従います。他のタブは閉じてください。
セキュリティ
- エンドポイントは開発サーバーにだけ存在します。本番ビルドには含まれません。
- すべてのリクエストにトークンが必要です。トークンは起動ごとにランダムで、ターミナルにだけ表示されます。パスワードと同じように扱い、コミットしないでください。
- トークンはパネルのブラウザでのサインイン(ワンタイムコード)とは別物です。MCP クライアントはローカルのプロセスなのでブラウザの origin は確認されず、トークンだけが関門です。
get_state_timelineは実行中のアプリの実際の state の値を返すので、エージェントにも見えます。開発中の state に秘密情報を入れないか、このツールを使わないでください。- 開発サーバーがネットワークで待ち受けている場合(
--host)、エンドポイントも同様です。localhost を推奨します。 - セッションがディスクに書かれるのは
persistかkeep: "disk"を指定したときだけで、プロジェクトのnode_modules/以下です。
バージョンと資料
- vite-devtools-svelte
- ≥ 0.4.0(このガイドと 4 つのリアクティビティツール)
- Vite
- ≥ 8.3.2
- Svelte
- 5(runes モード)。plain Svelte、SvelteKit 2、Kit 3 を CI でテストしています
- MCP
- Streamable HTTP、ステートレス、JSON 応答。CI はプレーンな HTTP(
initialize、tools/list、tools/call)でエンドポイントを呼んでいます。 - 資料
- 動画による解説はまだありません。実際の回答例とスクリーンショット(CI で記録)は英語の MCP ガイドにあります。