PerfLens MCP Server

PerfLens MCP Server

Provides typed, paginated tools for evidence-driven Linux performance analysis including profile analysis, comparison, and report generation with server-side authorization.

Category
Visit Server

README

PerfLens

Evidence-driven Linux performance analysis with a CLI, MCP Server, and Codex Skill. 基于证据的 Linux 性能分析工具,集成 CLI、MCP Server 与 Codex Skill。

CI Python 3.12+ License: Apache-2.0

简体中文 | English

PerfLens is an evidence-driven performance-analysis toolkit for Linux applications and coding agents.

The current release formally supports Milestones 0 through 9:

  • streaming FlameGraph-compatible folded stack input;
  • deterministic self and inclusive hotspot aggregation;
  • root-to-leaf call-path aggregation;
  • symbol plus DSO grouping (DSO is explicitly unknown for standard folded input);
  • bounded parse diagnostics and versioned JSON artifacts;
  • a production CLI with path checks, stable error output, resource limits, and atomic writes;
  • streaming parsing of explicitly-fielded perf script text;
  • perf.data conversion through an allowlisted system perf process;
  • bounded subprocess output, stderr diagnostics, timeouts, and process-group cleanup.
  • ELF Build ID/debug capability inspection and verified module-offset symbolization;
  • bounded workspace source context and container/build path mapping;
  • generic candidate-only classification, evidence bundles, and Markdown reports.
  • an official-SDK MCP server with typed, paginated tools and server-side authorization;
  • a repository Performance Analysis Skill for evidence-constrained Agent workflows.
  • profile and repeated-benchmark comparison with environment comparability checks;
  • pyperf, Google Benchmark, and hyperfine JSON normalization;
  • default-off, explicitly authorized perf record/stat/sched/lock/off-CPU collection.

It does not include an AI/LLM API, Web UI, source-code patch tool, benchmark runner, or custom agent framework.

Install

PerfLens requires Python 3.12 or newer.

For a GitHub release, download the wheel and install it as an isolated tool:

pipx install ./perflens-0.1.0-py3-none-any.whl
# or
uv tool install ./perflens-0.1.0-py3-none-any.whl

Both commands install perflens and perflens-mcp. Confirm the release:

perflens --version
perflens-mcp --version

Installing directly from a source checkout is also supported:

python -m pip install .

For development with uv:

uv sync --all-groups

Analyze folded stacks

perflens analyze-folded \
  --input tests/fixtures/folded/normal.folded \
  --output build/analysis.json

Input follows standard folded syntax:

main;worker;parse;malloc 182
main;worker;compute 271

Frames are normalized to root → leaf. The final frame receives self weight. Every unique (symbol, DSO) in a sample receives inclusive weight once, so recursive frames cannot make a function-level inclusive percentage exceed 100%. Frame occurrences are counted separately.

Standard folded text has no DSO, PID/TID, CPU, timestamp, event, or source metadata. PerfLens records these fields as unknown; it never infers them from symbol names. Each folded line is one weighted stack record, not weight individual samples.

Analyze perf profiles

For existing text, generate the supported stable field set and analyze it:

perf script --ns \
  -F comm,pid,tid,cpu,time,event,period,ip,sym,dso,srcline \
  -i perf.data > profile.perf-script

perflens analyze-perf-script \
  --input profile.perf-script \
  --output build/analysis.json

Or let PerfLens run the same read-only conversion:

perflens analyze-perf-data \
  --input perf.data \
  --output build/analysis.json

analyze-perf-data never records, attaches to a process, or requests root. It invokes an absolute, allowlisted perf executable without a shell. Use --perf-path when several versions are installed and --timeout-seconds to lower the conversion deadline.

Inspect symbols and build evidence

perflens inspect-elf --input build/app --output build/elf.json
perflens resolve-source \
  --binary build/app \
  --module-offset 0x1234 \
  --output build/source.json

perflens classify \
  --analysis build/analysis.json \
  --output build/diagnosis.json
perflens report \
  --analysis build/analysis.json \
  --problem "Throughput regression" \
  --metric "requests/second" \
  --output build/report.md

Source resolution requires a verified module-relative offset. A runtime IP by itself is never rebased heuristically. PerfLens prefers a long-lived llvm-symbolizer JSON provider, then falls back to a long-lived addr2line provider. Cache identity includes Build ID, module offset, and resolver version.

Classification rules label investigation candidates only. Generated reports keep direct observations, missing evidence, forbidden conclusions, and A/B validation requirements separate.

Compare profiles and benchmarks

perflens compare-profiles \
  --baseline build/baseline-analysis.json \
  --candidate build/candidate-analysis.json \
  --output build/profile-comparison.json \
  --markdown-output build/profile-comparison.md

perflens normalize-benchmark \
  --input benchmark-hyperfine.json \
  --output build/benchmark.json
perflens compare-benchmarks \
  --baseline build/baseline-benchmark.json \
  --candidate build/candidate-benchmark.json \
  --output build/benchmark-comparison.json

Profile percentage changes describe the selected event distribution, not absolute elapsed time. Benchmark comparisons require repeated samples, check environment differences, apply a practical-impact threshold, and emit only candidate improvement/regression states.

Explicitly authorized active collection

Active collection is disabled by default. A CLI invocation requires both a confirmation switch and the exact per-call authorization phrase:

perflens collect-profile \
  --mode record \
  --executable /absolute/path/to/app \
  --target-arg=--workload \
  --data-output build/profile.data \
  --metadata-output build/collection.json \
  --authorize-target \
  --authorization I_EXPLICITLY_AUTHORIZE_TARGET_PROFILING

Modes are record, stat, sched, lock, and off_cpu. stat uses an independent typed metric adapter and derives IPC when cycles and instructions are available. PID attachment requires --pid, a bounded duration, --authorize-pid-attach, and the separate phrase I_EXPLICITLY_AUTHORIZE_PID_ATTACH. PerfLens never invokes sudo or changes kernel policy. See MCP server and Skill setup for the additional MCP startup gates.

Use MCP with the Skill

An installed release contains a copy of the Skill. Install it into the project that will use PerfLens:

perflens install-skill --project /absolute/path/to/workspace

The command creates .agents/skills/perflens-performance-analysis and refuses to overwrite an existing Skill. To print a project-scoped MCP configuration:

perflens codex-config --workspace /absolute/path/to/workspace

Add --allow-process-execution only when perf.data conversion or source symbolization is required. Review the printed TOML before adding it to the project's .codex/config.toml.

From a source checkout, the equivalent direct registration is:

mkdir -p perflens-results
codex mcp add perflens -- \
  "$PWD/.venv/bin/perflens-mcp" \
  --allowed-root "$PWD" \
  --artifact-root "$PWD/perflens-results" \
  --allow-writes

Restart Codex, then ask:

$perflens-performance-analysis analyze ./profile.folded and report direct evidence, candidates, and missing evidence.

See MCP server and Skill setup for permissions, project-scoped configuration, process-execution opt-in, and the full tool flow.

Resource limits

Defaults are intentionally explicit:

  • input file: 1 GiB;
  • logical records: 10 million;
  • line length: 1 MiB;
  • stack depth: 4,096;
  • unique frames: 2 million;
  • unique call paths: 1 million;
  • retained warnings: 100;
  • emitted hotspots: 10,000;
  • emitted call paths: 1,000.

Limits can be lowered from the CLI. Exceeding structural limits fails with a structured error rather than silently dropping exact data. Malformed individual records are skipped and reported with bounded line previews.

Exit codes

Code Meaning
0 success
2 invalid CLI usage or input
3 unsupported or malformed profile
4 resource limit exceeded
5 output/path safety failure
6 external tool failure or timeout
70 unexpected internal failure

Development checks

uv run ruff check .
uv run pyright
uv run pytest --cov=perflens
uv build
uv run pip-audit

The reproducible performance harness is:

uv run python tests/performance/benchmark_folded.py \
  --records 1000 100000 1000000 \
  --repetitions 3

See docs/performance-budget.md for the recorded environment and baseline.

See release readiness, release process, real-world profile acceptance, and troubleshooting for final verification evidence and operational failure guidance.

Known limitations

  • Folded input cannot distinguish identically named functions from different DSOs because the format omits DSO metadata.
  • Percentages describe selected event weight, not wall-clock duration.
  • Call paths are exact up to the configured unique-path limit.
  • Symbol names are preserved with only conservative compiler-suffix cleanup.
  • A hotspot is an observation, not a confirmed root cause.
  • perf.data portability remains dependent on the installed perf version and access to matching DSOs/symbols; preserved unknown frames make gaps explicit.
  • Active collection depends on kernel perf permissions. On the development host, perf_event_paranoid=3 rejects unprivileged sampling; PerfLens returns a bounded structured error and leaves no collection output.
  • off_cpu mode records sched:sched_switch stack evidence; workload-aware post-processing is still required before making blocked-time claims.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured