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 Agent。它可分析热点函数、调用路径、源代码位置、GC 与异步开销,并比较不同配置文件。

主要功能

  1. 01按独占 CPU 时间排列函数
  2. 02分析函数的调用方
  3. 03将编译代码映射到 TypeScript 源码
  4. 04测量垃圾回收开销
  5. 05比较优化前后的配置文件
  6. 06检测异步及事件循环开销

适用场景

  1. 01查找 Node.js 应用的 CPU 瓶颈
  2. 02追踪慢函数的调用方
  3. 03定位热点代码对应的 TypeScript 源码
  4. 04评估 GC 或异步开销
  5. 05比较优化前后的性能配置文件

MCP 相关

它向 MCP 客户端提供配置文件分析工具,包括函数排序、调用树分析、源码映射、GC 与异步分析,以及配置文件比较。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 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)的多个节点合并为一个条目。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

一个 MCP 服务,可将 V8 CPU 性能分析文件解码为适合 AI Agent 使用的高效令牌瓶颈摘要。

你的 Node.js 应用运行缓慢。你运行了 --cpu-prof。现在,你有一个 20MB 的 .cpuprofile 文件,而你的 AI Agent 完全无法读取其中的内容。


🤔 问题所在

V8 CPU 性能分析文件体积庞大。一个典型的生产环境 Node.js 应用 .cpuprofile 文件包含5–50MB 的原始 JSON,数百万行数据映射内存地址、时钟计数和微秒级执行序列。它看起来是这样的:

{
  "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 Agent 会立刻耗尽上下文窗口并失败。即使它能读取,也无法运行计算调用树中包含时间和独占 CPU 时间所需的聚合算法。

因此,当你询问 Agent:

  • 🙈 “哪个函数占用的 CPU 最多?”
  • 🙈 “是什么调用了我缓慢的数据库查询?”
  • 🙈 “瓶颈实际来自哪个 TypeScript 文件?”

……它只能猜测,无法访问性能分析数据。

v8-cpu-profile-decoder-mcp 可以解决这个问题。它会在本地解码性能分析文件,并向 Agent 提供10 行语义摘要,而不是一个 50MB 的文件。


🛠️ 工具

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

比较两个 .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 饱和以及 timer/immediate 回调。

{
  "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"]
    }
  }
}

💡 Agent 提示词示例

“这是我的 CPU 性能分析文件,位于 /app/profiles/CPU.cpuprofile——哪个函数占用了最多的 CPU?”

“查找此性能分析文件中调用 processRequest 的代码,以及调用频率”

“将最热门的 10 个函数映射回其原始 TypeScript 文件”

“我的 Node.js API 在负载下运行缓慢——性能分析文件位于 /tmp/CPU.cpuprofile,找出瓶颈”

“GC 是瓶颈吗?检查 /tmp/CPU.cpuprofile 中的性能分析文件,并告诉我是什么类型的内存分配导致了这个问题”

“比较优化前后的这两个性能分析文件——哪些函数有所改善,哪些出现了退化?”

“这个应用是否在异步开销和事件循环机制上消耗了过多的 CPU?”


🔗 相关项目


📄 许可证

MIT © vola-trebla

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。