Skip to main content
Glama
v8-cpu-profile-decoder-mcp

v8-cpu-profile-decoder-mcp

by vola-trebla

v8-cpu-profile-decoder-mcp 🐸⚑

npm version npm downloads CI License: MIT

An MCP server that decodes V8 CPU profiles into token-efficient bottleneck summaries for AI agents.

Your Node.js app is slow. You ran --cpu-prof. Now you have a 20MB .cpuprofile file β€” and your AI agent is completely blind to it.


πŸ€” The Problem

V8 CPU profiles are massive. A typical .cpuprofile from a production Node.js app is 5–50MB of raw JSON β€” millions of lines mapping memory addresses, tick counts, and microsecond execution sequences. It looks like this:

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

An AI agent attempting to read this file instantly collapses its context window and fails. Even if it could read it, it can't run the aggregation algorithms needed to compute inclusive/exclusive CPU times across the call tree.

So when you ask your agent:

  • πŸ™ˆ "Which function is consuming the most CPU?"

  • πŸ™ˆ "What's calling my slow database query?"

  • πŸ™ˆ "Which TypeScript file is the bottleneck actually coming from?"

...it's guessing. It has no access to the profiling data.

v8-cpu-profile-decoder-mcp fixes that. It decodes the profile locally and hands the agent a 10-line semantic summary instead of a 50MB file.


Related MCP server: javaperf

πŸ› οΈ Tools

extract_hottest_functions

Parses the .cpuprofile and returns the top N functions ranked by exclusive CPU time (self time). Filters out V8 internals and Node.js built-ins β€” only user code.

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

Finds all callers of a specific function and shows how often each one invoked it. Accepts partial, case-insensitive function name matching.

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

Maps compiled JS bottlenecks back to their original TypeScript source locations using .js.map files. Falls back gracefully to compiled JS locations if no source map is found.

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

Reports garbage collection overhead as a percentage of profiling duration, broken down by GC type. Flags when GC exceeds a configurable threshold and provides a targeted recommendation.

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

Compares two .cpuprofile files (before/after an optimization) and returns per-function CPU time deltas, normalized against each profile's total duration. Frames are matched by call-frame coordinates, not transient node IDs, so alignment is stable across profiling sessions.

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

Detects event-loop overhead by identifying V8 internal frames representing async machinery β€” microtask queue processing, nextTick saturation, and timer/immediate callbacks.

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

πŸš€ Installation

npx v8-cpu-profile-decoder-mcp

Or install globally:

npm install -g v8-cpu-profile-decoder-mcp

Generate a CPU profile in Node.js

# Single run
node --cpu-prof your-script.js

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

Or programmatically via Chrome DevTools β†’ Performance tab β†’ Record.

Claude Desktop config

{
  "mcpServers": {
    "v8-cpu-profile-decoder-mcp": {
      "command": "npx",
      "args": ["-y", "v8-cpu-profile-decoder-mcp"]
    }
  }
}

πŸ’‘ Example Agent Prompts

"Here's my CPU profile at /app/profiles/CPU.cpuprofile β€” which function is consuming the most CPU?"

"Find what's calling processRequest in this profile and how often"

"Map the top 10 hottest functions back to their original TypeScript files"

"My Node.js API is slow under load β€” profile is at /tmp/CPU.cpuprofile, find the bottleneck"

"Is GC the bottleneck? Check the profile at /tmp/CPU.cpuprofile and tell me what kind of allocation is causing it"

"Compare these two profiles before and after my optimization β€” which functions improved and which regressed?"

"Is this app spending too much CPU on async overhead and event-loop machinery?"



πŸ“„ License

MIT Β© vola-trebla

Available Tools

6 tools
analyze_async_bottlenecksA

Detects event-loop overhead in a V8 CPU profile by identifying V8 internal frames that represent async machinery β€” microtask queue processing, nextTick saturation, and timer/immediate callbacks. These frames are invisible to most profilers but consume real CPU when promise chains are deep or nextTick is overused. Use to answer: is the bottleneck async orchestration overhead rather than synchronous computation?

Inputs: profile_path (required), threshold_percent.

analyze_call_tree_pathA

Finds all callers of a specific function in a V8 CPU profile and returns how often each caller invoked it. Accepts partial, case-insensitive function name matching. Use to answer: what is calling my slow function and how many times?

Inputs: profile_path (required), function_name (required), top_callers.

analyze_gc_pressureA

Analyses a V8 .cpuprofile for garbage collection overhead. Reports total GC time as a percentage of profiling duration, broken down by GC type (Scavenger = short-lived object pressure, Mark-Sweep/Mark-Compact = old-space pressure, Incremental = high allocation rate). Flags when GC exceeds a configurable threshold and provides a targeted recommendation. Use to answer: is GC the bottleneck, and what kind of allocation pattern is causing it?

Inputs: profile_path (required), threshold_percent.

correlate_source_codeA

Maps the hottest functions in a V8 CPU profile back to their original TypeScript source locations using source map files (.js.map). Falls back to compiled JS locations if no source map is found. Use to answer: which TypeScript file and line is the bottleneck actually coming from?

Inputs: profile_path (required), top_n, sourcemap_dir.

diff_profilesA

Compares two V8 .cpuprofile files (before and after an optimization) and returns per-function CPU time deltas, normalized against each profile's total duration. Frames are matched by call-frame coordinates (functionName + url + line + column), not by transient node IDs, so alignment is stable across profiling sessions. Use to answer: which functions improved or regressed after my change, and by how much?

Inputs: after_profile_path (required), before_profile_path (required), top_n.

extract_hottest_functionsA

Parses a V8 .cpuprofile file and returns the top N functions ranked by exclusive CPU time (self time). Filters out V8 internals and Node.js built-ins by default, returning only user code. Framework frames (express, next.js, koa, etc.) can be collapsed into a single entry. Recursive calls to the same source location are merged with an instanceCount field. Use this first to identify which functions are consuming the most CPU in a Node.js performance profile.

Inputs: profile_path (required), top_n, min_self_percent, collapse_recursion, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.3/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool targets a distinct analytical question: extraction of hot functions, caller analysis, source mapping, GC pressure, profile diffing, and async bottleneck detection. There is no overlap in purpose; each description clearly identifies a unique use case.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern with lowercase and underscores (extract_hottest_functions, analyze_call_tree_path, etc.). The verbs are varied but the structure is uniform, making the set easy to scan and predict.

    Tool Count5/5

    Six tools is well within the ideal range for a specialized server. Each tool covers a meaningful aspect of CPU profile analysis without redundancy or bloat, and the number feels appropriate for the server's scope.

    Completeness4/5

    The tool set covers the primary workflows for CPU profile analysis: identifying hot spots, tracing callers, mapping to source, GC overhead, before/after comparison, and async overhead. Minor gaps exist, such as a tool for basic profile metadata (total samples, duration), but the core diagnostic needs are met.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      MCP server that exposes a V8 JavaScript runtime as a tool for AI agents like Claude and Cursor. Supports persistent heap snapshots via S3 or local filesystem, and is ready for integration with modern AI development environments.
      64
      Rust
      AGPL 3.0
    • A
      license
      A
      quality
      C
      maintenance
      MCP server for profiling Java applications via JDK utilities (jcmd, jfr, jps). Enables AI assistants to diagnose performance, analyze threads, and inspect JFR recordings without manual CLI usage.
      26
      64 npm
      10
      MIT