mcpField
V
v8-cpu-profile-decoder-mcp

v8-cpu-profile-decoder-mcp

ローカル
github.com/vola-trebla開発ツール023 週間前に更新

v8-cpu-profile-decoder-mcp について

v8-cpu-profile-decoder-mcpは、V8 CPUプロファイルを簡潔な分析結果に変換するMCPサーバーです。Node.jsの性能を調べるAIエージェント向けに、ホット関数や呼び出し経路、ソース位置、GC・非同期処理の負荷、プロファイル間の差分を分析します。

主な機能

  1. 01自己CPU時間で関数を順位付け
  2. 02関数の呼び出し元を分析
  3. 03コンパイル済みコードをTypeScriptソースに対応付け
  4. 04ガベージコレクション負荷を測定
  5. 05変更前後のプロファイルを比較
  6. 06非同期処理とイベントループの負荷を検出

活用シーン

  1. 01Node.jsアプリのCPUボトルネックを発見
  2. 02遅い関数の呼び出し元を追跡
  3. 03ホットコードのTypeScriptソースを特定
  4. 04GCまたは非同期処理の負荷を評価
  5. 05最適化前後の性能プロファイルを比較

MCP 対応

関数の順位付け、呼び出しツリー分析、ソースマッピング、GC・非同期処理の分析、プロファイル比較を行うツールをMCPクライアントに提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"vola-trebla-v8-cpu-profile-decoder": {
"command": "npx",
"args": [
"-y",
"v8-cpu-profile-decoder-mcp"
]
}
}
}
起動コマンドnpx -y v8-cpu-profile-decoder-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmv8-cpu-profile-decoder-mcp0.3.0

ツール

6

掲載時のツール一覧 · 3 週間前に更新

パラメーター型必須説明
top_nintegerいいえ返すホット関数の数(デフォルト:10)
profile_pathstringはい.cpuprofile ファイルの絶対パス
min_self_percentnumberいいえ関数を含めるための自己時間の最小割合(デフォルト:0.5%)
collapse_recursionbooleanいいえソース位置(functionName + url + line + column)が同じ複数のノードを 1 つのエントリに統合します。instanceCount は統合された再帰インスタンスの数を示します(デフォルト:true)
collapse_frameworksbooleanいいえ既知のフレームワーク(express、next.js、koa、fastify、nestjs、react、vue、nuxt、hapi)のすべてのフレームを、フレームワークごとに単一の "<framework> internals>" エントリにまとめます。細かなフレームワークエントリが多数並び、上位 N 件の一覧が埋もれるのを防ぎます(デフォルト:true)
include_node_internalsbooleanいいえ結果に V8 内部関数と Node.js 組み込み関数を含めます(デフォルト:false)

詳細

v8-cpu-profile-decoder-mcp 🐸⚡

npm version npm downloads CI License: MIT

V8 CPU プロファイルを、AI エージェント向けのトークン効率の高いボトルネック要約に変換する MCP サーバーです。

Node.js アプリの動作が遅くなっています。--cpu-profを実行すると、20MB の.cpuprofileファイルが生成されます。しかし、AI エージェントはその内容をまったく読み取れません。


🤔 問題点

V8 CPU プロファイルは非常に大きくなります。一般的な本番環境の Node.js アプリの.cpuprofileは、生の JSON で5~50MBにもなります。メモリアドレス、ティック数、マイクロ秒単位の実行シーケンスを示す数百万行のデータです。たとえば、次のような内容です。

{
  "nodes": [
    { "id": 1482, "callFrame": { "functionName": "processRequest", "url": "file:///app/dist/server.js", "lineNumber": 847 }, "hitCount": 3241, "children": [1483, 1490] },
    ...
  ],
  "samples": [1482, 1483, 1482, 1490, 1482, ...],
  "timeDeltas": [120, 98, 115, 102, ...]
}

AI エージェントがこのファイルを読み込もうとすると、コンテキストウィンドウが瞬時にいっぱいになり、処理に失敗します。仮に読み込めたとしても、コールツリー全体で包括的 CPU 時間と排他的 CPU 時間を計算するために必要な集計アルゴリズムを実行できません。

そのため、エージェントに次のように尋ねても、

  • 🙈 「最も CPU を消費している関数はどれですか?」
  • 🙈 「遅いデータベースクエリを呼び出しているのは何ですか?」
  • 🙈 「実際のボトルネックは、どの TypeScript ファイルにありますか?」

……推測するしかありません。プロファイリングデータにアクセスできないのです。

v8-cpu-profile-decoder-mcpは、この問題を解決します。プロファイルをローカルでデコードし、50MB のファイルの代わりに、10行の意味的な要約をエージェントに渡します。


🛠️ ツール

extract_hottest_functions

.cpuprofileを解析し、排他的 CPU 時間(セルフ時間)で順位付けした上位 N 個の関数を返します。 V8 の内部関数と Node.js の組み込み関数を除外し、ユーザーコードのみを対象にします。

{
  "profile_path": "/app/profiles/CPU.20260516.cpuprofile",
  "top_n": 5,
  "min_self_percent": 1.0
}
[
  {
    "rank": 1,
    "functionName": "hashPassword",
    "url": "file:///app/dist/auth/crypto.js",
    "lineNumber": 42,
    "selfTimeMs": 1842.5,
    "totalTimeMs": 1842.5,
    "selfPercent": 61.32,
    "totalPercent": 61.32,
    "hitCount": 3241
  },
  {
    "rank": 2,
    "functionName": "parseJsonBody",
    "url": "file:///app/dist/middleware/body.js",
    "lineNumber": 18,
    "selfTimeMs": 412.1,
    "totalTimeMs": 412.1,
    "selfPercent": 13.71,
    "totalPercent": 13.71,
    "hitCount": 724
  }
]

analyze_call_tree_path

特定の関数の呼び出し元をすべて特定し、それぞれがその関数を呼び出した回数を表示します。 大文字と小文字を区別せず、関数名の一部で照合できます。

{
  "profile_path": "/app/profiles/CPU.20260516.cpuprofile",
  "function_name": "hashPassword",
  "top_callers": 3
}
{
  "targetFunction": "hashPassword",
  "matchedNodes": 2,
  "totalSelfTimeMs": 1842.5,
  "totalPercent": 61.32,
  "callers": [
    {
      "functionName": "loginHandler",
      "url": "file:///app/dist/routes/auth.js",
      "lineNumber": 94,
      "callCount": 2180,
      "selfTimeMs": 240.1
    },
    {
      "functionName": "validateSession",
      "url": "file:///app/dist/middleware/auth.js",
      "lineNumber": 31,
      "callCount": 1061,
      "selfTimeMs": 116.8
    }
  ]
}

correlate_source_code

.js.mapファイルを使用して、コンパイル済み JS のボトルネックを元の TypeScript ソースの位置に対応付けます。 ソースマップが見つからない場合は、コンパイル済み JS の位置を代わりに使用します。

{
  "profile_path": "/app/profiles/CPU.20260516.cpuprofile",
  "top_n": 5
}
{
  "resolved": [
    {
      "rank": 1,
      "generatedUrl": "file:///app/dist/auth/crypto.js",
      "generatedLine": 42,
      "source": {
        "originalFile": "src/auth/crypto.ts",
        "originalLine": 38,
        "originalColumn": 2,
        "originalFunction": "hashPassword"
      },
      "selfTimeMs": 1842.5,
      "selfPercent": 61.32
    }
  ],
  "sourcemapErrors": []
}
analyze_gc_pressure

ガベージコレクションのオーバーヘッドをプロファイリング時間に対する割合で報告し、GC の種類ごとに内訳を表示します。 GC が設定可能なしきい値を超えた場合に警告し、的を絞った推奨事項を提示します。

{
  "profile_path": "/app/profiles/CPU.cpuprofile",
  "threshold_percent": 10
}
{
  "gc_ticks": 184,
  "total_ticks": 1240,
  "gc_percentage": 14.84,
  "gc_type_breakdown": {
    "scavenger": 122,
    "mark_sweep": 0,
    "mark_compact": 0,
    "incremental": 62,
    "generic": 0
  },
  "exceeds_threshold": true,
  "threshold_percent": 10,
  "verdict": "GC consumed 14.84% of CPU — exceeds the 10% threshold. Dominated by Scavenger (short-lived object pressure). Consider object pooling, reusing buffers, or reducing closure captures."
}

diff_profiles

2つの.cpuprofileファイル(最適化の前後など)を比較し、プロファイルごとの合計時間を基準に正規化した、関数ごとの CPU 時間の差分を返します。 フレームは一時的なノード ID ではなく、コールフレームの座標で照合されるため、プロファイリングセッションをまたいでも安定して対応付けられます。

{
  "before_profile_path": "/app/profiles/before.cpuprofile",
  "after_profile_path": "/app/profiles/after.cpuprofile",
  "top_n": 5
}
{
  "before_duration_ms": 5000,
  "after_duration_ms": 4800,
  "total_execution_delta_ms": -200,
  "total_execution_delta_percent": -4,
  "top_improvements": [
    {
      "function_name": "hashPassword",
      "url": "file:///app/dist/auth/crypto.js",
      "line_number": 42,
      "before_ms": 1842.5,
      "after_ms": 620.1,
      "absolute_diff_ms": -1222.4,
      "relative_diff_percent": -66.34
    }
  ],
  "top_regressions": [],
  "only_in_before": [],
  "only_in_after": []
}

analyze_async_bottlenecks

非同期処理の仕組みを表す V8 内部フレーム(マイクロタスクキューの処理、nextTickの飽和、タイマーや即時コールバック)を特定し、イベントループのオーバーヘッドを検出します。

{
  "profile_path": "/app/profiles/CPU.cpuprofile",
  "threshold_percent": 10
}
{
  "total_ticks": 1240,
  "async_ticks": 186,
  "event_loop_overhead_ms": 372,
  "event_loop_overhead_percent": 15.0,
  "dominant_async_patterns": [
    { "pattern": "promise_chains", "ticks": 142, "percent": 11.45 },
    { "pattern": "nexttick_saturation", "ticks": 44, "percent": 3.55 }
  ],
  "verdict": "Event-loop overhead is 15.0% of CPU — exceeds the 10% threshold. Promise chain overhead is visible in the profile. Consider batching microtasks, using Promise.all() to parallelise I/O, or offloading CPU-bound continuations to worker threads."
}

🚀 インストール

npx v8-cpu-profile-decoder-mcp

または、グローバルにインストールします。

npm install -g v8-cpu-profile-decoder-mcp
Node.js で CPU プロファイルを生成する
# Single run
node --cpu-prof your-script.js

# With custom output dir
node --cpu-prof --cpu-prof-dir ./profiles your-script.js

または、プログラムから Chrome DevTools の「Performance」タブを開き、「Record」を選択して記録します。

Claude Desktop の設定
{
  "mcpServers": {
    "v8-cpu-profile-decoder-mcp": {
      "command": "npx",
      "args": ["-y", "v8-cpu-profile-decoder-mcp"]
    }
  }
}

💡 エージェントのプロンプト例

"/app/profiles/CPU.cpuprofile に CPU プロファイルがあります。最も CPU を消費している関数はどれですか?"

"このプロファイルで processRequest を呼び出している箇所と、その頻度を調べてください"

"CPU 使用率が特に高い上位 10 個の関数を、元の TypeScript ファイルに対応付けてください"

"Node.js API が負荷時に遅くなります。プロファイルは /tmp/CPU.cpuprofile にあります。ボトルネックを見つけてください"

"GC がボトルネックですか?/tmp/CPU.cpuprofile のプロファイルを確認して、どのような割り当てが原因か教えてください"

"最適化の前後で 2 つのプロファイルを比較して、改善した関数と悪化した関数を教えてください"

"このアプリは、非同期処理のオーバーヘッドやイベントループの処理に CPU を使いすぎていますか?"


🔗 関連プロジェクト


📄 ライセンス

MIT © vola-trebla

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。