mcp-samply
v0.1.0
Published
MCP server for recording and analyzing samply profiles
Downloads
24
Maintainers
Readme
mcp-samply
mcp-samply is a MCP server for samply.
It is designed for AI agents that need to:
- record CPU profiles with
samply - load existing
profile.json/profile.json.gzfiles - turn Firefox Profiler data into compact, agent-friendly hotspot summaries
- drill down into specific threads and functions
The intended runtime is:
npx mcp-samplyWhy this exists
samply is excellent at recording profiles and opening them in Firefox Profiler, but AI agents need a second layer:
- a stable MCP interface
- structured summaries instead of raw table-heavy profile JSON
- a way to work offline from saved profiles
mcp-samply provides that layer.
Tools
The server exposes eight MCP tools:
samply_doctor: verify whether thesamplybinary is available and report version / environment detailssamply_record: runsamply record --save-onlyand save a profile to disksamply_summarize_profile: generate a compact summary of threads, hotspots, markers, and overall sample distributionsamply_inspect_thread: inspect one thread in detail, including representative stackssamply_search_functions: search for functions or library names across the loaded profilesamply_breakdown_subsystems: group native functions by namespace prefix so agents can see which Rust / C++ subsystems dominate a profilesamply_focus_functions: recover the most common caller / callee contexts around a target function or namespacesamply_locate_symbols: map hot native symbols back to likely local source files so an agent can inspect implementation details
Presymbolication
By default, samply_record enables --unstable-presymbolicate.
That causes samply to emit a sidecar file such as:
profile.json.gz
profile.json.syms.jsonmcp-samply reads that sidecar automatically and uses it to resolve native addresses into function names during offline analysis. This is critical for AI-driven performance work; without it, saved profiles often contain only raw addresses.
Use With Codex
Example MCP server config:
{
"mcpServers": {
"samply": {
"command": "npx",
"args": ["-y", "mcp-samply"],
"env": {
"MCP_SAMPLY_BIN": "samply"
}
}
}
}If samply is not on PATH, set MCP_SAMPLY_BIN to an absolute executable path.
You can still use the analysis tools on an existing profile file even when samply itself is not installed.
Typical Agent Workflow
- Call
samply_doctor. - Call
samply_recordwith a command, PID, orall=true. - Call
samply_summarize_profileon the produced profile. - Use
samply_inspect_threadfor the hottest thread. - Use
samply_search_functionsfor focused follow-up questions. - Use
samply_breakdown_subsystemsto quantify native hotspots by crate / module prefix. - Use
samply_focus_functionsto turn syscalls such asstat/readback into actionable upstream call paths. - Use
samply_locate_symbolsto map the hottest native frames back to local source files before reading or patching code.
Local Development
npm install
npm run build
npm testRun the MCP server locally:
npm run devBuild output is published through the mcp-samply bin entry so the package can be launched with npx.
Publishing To npm
This repository includes a GitHub Actions workflow at .github/workflows/publish-npm.yml.
Before using it, add a repository secret named NPM_TOKEN with publish access to the mcp-samply package on npm.
The workflow can be triggered in two ways:
- Publish a GitHub Release whose tag matches the package version, for example
v0.1.0. - Run the workflow manually from the Actions tab with
workflow_dispatchand provide the exact package version, for example0.1.0.
On every publish run, the workflow will:
- Install dependencies with
npm ci. - Run
npm run check. - Run
npm pack --dry-run. - Publish with
npm publish --provenance --access public.
Debugging The MCP Surface
This repository also includes a small local debug client so you can inspect the MCP surface and call tools without wiring up an external MCP host first.
List the exposed MCP surfaces:
npm run debug:mcp -- list-toolsThe output includes:
tools: the currently registered MCP tools, including input and output schemasprompts: prompt definitions, if anyresources: resource definitions, if any
Call a tool and print the full JSON result:
npm run debug:mcp -- call samply_doctorSummarize one of the sample profiles committed in this repo:
npm run debug:mcp -- call samply_summarize_profile --args '{"profilePath":".samply/presym-smoke.json.gz"}'Run symbol lookup against a local source tree:
npm run debug:mcp -- call samply_locate_symbols --args '{"roots":["/absolute/path/to/project"],"symbols":["rspack::Compiler::build"],"extensions":[".rs",".cc",".cpp"]}'For larger payloads, store the tool input in a JSON file and use --args-file:
npm run debug:mcp -- call samply_record --args-file ./tool-args.jsonRecommended manual debug loop:
- Run
npm run debug:mcp -- list-toolsto confirm the tool names and schemas. - Call
samply_doctorfirst to verify environment and binary resolution. - Use
samply_recordor a savedprofile.json(.gz)to generate real inputs. - Run
samply_summarize_profile, then drill intosamply_inspect_thread,samply_search_functions,samply_breakdown_subsystems, andsamply_focus_functions. - Use
samply_locate_symbolswith your project root to confirm hotspot symbols map back to the files you expect.
