v8-cpu-profile-decoder-mcp
Decodifica perfis de CPU V8 em resumos de gráfico de chamas e hotspots para agentes de IA
Documentação
v8-cpu-profile-decoder-mcp 🐸⚡
Um servidor MCP que decodifica perfis de CPU do V8 em resumos de gargalos eficientes em tokens para agentes de IA.
Seu aplicativo Node.js está lento. Você executou --cpu-prof. Agora você tem um arquivo .cpuprofile de 20MB — e seu agente de IA está completamente cego para ele.
🤔 O Problema
Perfis de CPU do V8 são enormes. Um .cpuprofile típico de um aplicativo Node.js em produção tem 5–50MB de JSON bruto — milhões de linhas mapeando endereços de memória, contagens de ticks e sequências de execução em microssegundos. Parece assim:
{
"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, ...]
}
Um agente de IA tentando ler este arquivo colapsa instantaneamente sua janela de contexto e falha. Mesmo que pudesse lê-lo, não consegue executar os algoritmos de agregação necessários para calcular tempos de CPU inclusivos/exclusivos na árvore de chamadas.
Então, quando você pergunta ao seu agente:
- 🙈 "Qual função está consumindo mais CPU?"
- 🙈 "O que está chamando minha consulta lenta ao banco de dados?"
- 🙈 "De qual arquivo TypeScript o gargalo realmente vem?"
...ele está adivinhando. Ele não tem acesso aos dados de perfil.
v8-cpu-profile-decoder-mcp resolve isso. Ele decodifica o perfil localmente e entrega ao agente um resumo semântico de 10 linhas em vez de um arquivo de 50MB.
🛠️ Ferramentas
extract_hottest_functions
Analisa o .cpuprofile e retorna as N principais funções classificadas por tempo de CPU exclusivo (tempo próprio).
Filtra internals do V8 e built-ins do Node.js — apenas código do usuário.
{
"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
Encontra todos os chamadores de uma função específica e mostra com que frequência cada um a invocou. Aceita correspondência parcial de nome de função, sem diferenciar maiúsculas de minúsculas.
{
"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
Mapeia gargalos de JS compilado de volta para suas localizações originais no código-fonte TypeScript usando arquivos .js.map.
Faz fallback graciosamente para localizações de JS compilado se nenhum source map for encontrado.
{
"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
Relata a sobrecarga da coleta de lixo (garbage collection) como uma porcentagem da duração do perfil, dividida por tipo de GC. Sinaliza quando o GC excede um limite configurável e fornece uma recomendação direcionada.
{
"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
Compara dois arquivos .cpuprofile (antes/depois de uma otimização) e retorna deltas de tempo de CPU por função,
normalizados contra a duração total de cada perfil. Os frames são correspondidos por coordenadas de call-frame, não
por IDs de nó transitórios, então o alinhamento é estável entre sessões de perfil.
{
"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
Detecta sobrecarga do event-loop identificando frames internos do V8 que representam maquinário assíncrono —
processamento da fila de microtasks, saturação de nextTick e callbacks de timers/immediates.
{
"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."
}
🚀 Instalação
npx v8-cpu-profile-decoder-mcp
Ou instale globalmente:
npm install -g v8-cpu-profile-decoder-mcp
Gere um perfil de CPU no Node.js
# Single run
node --cpu-prof your-script.js
# With custom output dir
node --cpu-prof --cpu-prof-dir ./profiles your-script.js
Ou programaticamente via Chrome DevTools → aba Performance → Record.
Configuração do Claude Desktop
{
"mcpServers": {
"v8-cpu-profile-decoder-mcp": {
"command": "npx",
"args": ["-y", "v8-cpu-profile-decoder-mcp"]
}
}
}
💡 Exemplos de Prompts para Agentes
"Aqui está meu perfil de CPU em
/app/profiles/CPU.cpuprofile— qual função está consumindo mais CPU?"
"Encontre o que está chamando
processRequestneste perfil e com que frequência"
"Mapeie as 10 funções mais quentes de volta para seus arquivos TypeScript originais"
"Meu API Node.js está lento sob carga — o perfil está em
/tmp/CPU.cpuprofile, encontre o gargalo"
"O GC é o gargalo? Verifique o perfil em
/tmp/CPU.cpuprofilee me diga que tipo de alocação está causando isso"
"Compare esses dois perfis antes e depois da minha otimização — quais funções melhoraram e quais regrediram?"
"Este aplicativo está gastando CPU demais com sobrecarga assíncrona e maquinário do event-loop?"
🔗 Projetos Relacionados
- playwright-trace-decoder-mcp — decodifica traces do Playwright para análise de causa raiz de falhas de CI
- playwright-network-chaos-mcp — simula falhas de rede e latência em sessões de navegador
- flakiness-knowledge-graph-mcp — grafo de conhecimento de padrões de testes instáveis
- ast-impact-mapper-mcp — encontra testes afetados por mudanças de código via AST do TypeScript
- playwright-spatial-layout-mcp — consciência espacial geométrica de layouts web
📄 Licença
MIT © vola-trebla