npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xctrace-analyzer/mcp-server

v0.1.7

Published

MCP server for Xcode Instruments trace analysis

Readme

Xcode Instruments Trace Analyzer MCP Server

Model Context Protocol server for intelligent Xcode Instruments trace analysis

This MCP server provides AI assistants like Claude with the ability to automate xcrun xctrace workflows: record traces, symbolicate traces, export TOC/XML/HAR data, detect Time Profiler bottlenecks, summarize exportable Memory/Network/Energy/Allocations/Leaks data, identify Time Profiler regressions, clean up generated traces, and provide actionable recommendations.

It is an honest Instruments companion, not a complete GUI replacement. Recording tools open the saved .trace in Instruments.app by default, and any template or view that is absent from the trace or not exportable through xctrace is reported explicitly.

Features

  • 🔍 Intelligent Analysis - Automatically identifies performance bottlenecks
  • 🎥 Automated Recording - Attach to a running app, save a trace, and analyze it in one tool call
  • 🧭 Multi-Instrument Analysis - Auto-detects Memory, Network, Energy, Allocations, and Leaks data when exportable
  • 📊 Regression Detection - Compare traces to find performance regressions
  • 💡 Actionable Recommendations - Get specific optimization suggestions with code examples
  • 🧾 Structured Diagnostics - Support matrix, export attempts, and JSON output for CI or agents
  • 🧹 Trace Cleanup - Preview or delete generated .trace bundles after inspection
  • 🤖 Natural Language Interface - Use Claude to interact with your performance data
  • ⚙️ Local-first - Runs through your installed Xcode Command Line Tools

Installation

Claude Code

claude mcp add --transport stdio --scope user xctrace-analyzer -- npx -y @xctrace-analyzer/mcp-server@latest

Verify the local machine has a usable xcrun xctrace:

npx -y @xctrace-analyzer/mcp-server@latest --check

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "xctrace-analyzer": {
      "command": "npx",
      "args": ["-y", "@xctrace-analyzer/mcp-server@latest"]
    }
  }
}

Codex CLI

codex mcp add xctrace-analyzer -- npx -y @xctrace-analyzer/mcp-server@latest

Check that Codex registered the server:

codex mcp list

Building from Source

# From the monorepo root
pnpm install --frozen-lockfile
pnpm verify

Available Tools

Recommended User Experience

For human-facing use, register the bundled skill in clients that support skills. Source checkouts provide it at ../../skills/xctrace-profiler; npm installs include it at node_modules/@xctrace-analyzer/mcp-server/skills/xctrace-profiler. Then users can stay at the prompt level:

Profile this app.
Find why this app is slow.
Profile this app for hangs.
Profile this app for hangs and tell me which of my code is responsible.
Check this build for leaks and allocation churn.
Analyze network activity.
Launch this app and profile startup hangs.
I will launch MyApp; record it for 60 seconds when it appears.
Analyze this trace.
Compare these two traces.
Clean up profiling traces when we are done.

The skill is the planner for this MCP server. It chooses between recording, existing trace analysis, single-template tracking, device/template checks, scoped hang follow-ups, trace comparisons, and safe cleanup once the user no longer needs the saved trace. When the user says they will launch the app manually, the skill starts watching for the app process immediately and attaches to the first valid PID without waiting for a second prompt. The MCP server itself exposes execution tools only.

Tool Selection Guide

  • Use profile_running_app for "start profiling", "full report", or "record all issues" requests against an already-running app.
  • Use track_running_app for a single explicit Instruments template such as Leaks or Allocations.
  • Use analyze_trace when the user already has a .trace file, especially for scoped follow-up analysis with timeRangeMs and app attribution via Top User-Code Frames.
  • Use compare_traces when the user asks whether a current build regressed against a baseline.
  • Use cleanup_traces after the user confirms recorded traces are no longer needed, or as a dry-run preview for stale trace directories.
  • Use list_templates, list_devices, and check_xctrace for setup and troubleshooting.

Security Defaults

Attach profiling and trace analysis work by default. The secure defaults do not reduce the Instruments recorded by the full, memory, network, or full-ios presets; they restrict higher-risk MCP operations.

| Option | Default | Why it is useful and important | | --- | --- | --- | | XCTRACE_ANALYZER_ALLOW_LAUNCH=1 | Disabled | Enables true startup/cold-launch profiling. It is disabled by default because launchCommand asks the MCP server to execute a local program through xcrun xctrace --launch. | | XCTRACE_ANALYZER_ALLOW_ALL_PROCESSES=1 | Disabled | Enables system-wide traces when one process is not enough. It is disabled by default because the trace can include unrelated apps, services, paths, URLs, and symbols. | | XCTRACE_ANALYZER_TRACE_ROOT=/path/to/traces | ~/Library/Application Support/xctrace-analyzer/traces | Sets the allowed trace output root. Keeping traces in one user-level folder reduces accidental project churn and makes cleanup safer. | | XCTRACE_ANALYZER_ALLOW_EXTERNAL_OUTPUT=1 | Disabled | Allows outputPath, outputDirectory, targetStdin, and targetStdout outside the trace root. It is useful for CI or shared scratch volumes, but broadens where the MCP server can write. | | XCTRACE_ANALYZER_ALLOW_EXTERNAL_CLEANUP=1 | Disabled | Allows destructive cleanup outside the trace root. It is useful for maintenance of a trusted trace archive, but should be paired with a dry run or exact trace paths. | | XCTRACE_ANALYZER_MAX_DURATION_SECONDS=300 | 300 | Caps recording duration to avoid accidental long-running captures and very large .trace bundles. Raise it only for expected long repros. | | XCTRACE_ANALYZER_REDACTION=balanced | balanced | Controls report redaction. balanced hides common secrets and user paths, strict also hides hostnames, and off preserves full details for trusted local debugging. |

For startup profiling with the default security posture, manually launch the app and attach by exact PID as soon as it appears. For trusted local launch profiling, start the server with:

XCTRACE_ANALYZER_ALLOW_LAUNCH=1 npx -y @xctrace-analyzer/mcp-server@latest

Claude Desktop-style MCP configs can pass the same settings through env:

{
  "mcpServers": {
    "xctrace-analyzer": {
      "command": "npx",
      "args": ["-y", "@xctrace-analyzer/mcp-server@latest"],
      "env": {
        "XCTRACE_ANALYZER_ALLOW_LAUNCH": "1",
        "XCTRACE_ANALYZER_TRACE_ROOT": "/Users/you/Library/Application Support/xctrace-analyzer/traces"
      }
    }
  }
}

Codex can pass the same settings with --env:

codex mcp add xctrace-analyzer \
  --env XCTRACE_ANALYZER_ALLOW_LAUNCH=1 \
  --env XCTRACE_ANALYZER_TRACE_ROOT="/Users/you/Library/Application Support/xctrace-analyzer/traces" \
  -- npx -y @xctrace-analyzer/mcp-server@latest

profile_running_app

Record a running app once with a profiling preset and return one combined report. durationSeconds: 60 means one 60-second recording. The preset uses a base template plus additional Instruments where Xcode supports it.

Parameters:

  • processName (optional): Running process name or pid to attach to; required for attach mode
  • target (optional): attach, launch, or all-processes
  • launchCommand, launchArguments, environment (optional): launch target details
  • preset (optional): full, full-ios, cpu, memory, network, or energy (default: full)
  • durationSeconds (optional): Total recording duration in seconds (default: 60)
  • device (optional): Device or simulator name/UDID
  • outputDirectory (optional): Directory where generated .trace files should be saved (default: configured trace root)
  • analyze (optional): Analyze after recording (default: true)
  • openInInstruments (optional): Open the saved .trace in Instruments.app after recording (default: true). Set false for CI or headless runs.
  • outputFormat (optional): markdown, json, or both (default: markdown)

Preset recordings:

  • full: Time Profiler base with Leaks, Allocations, and HTTP Traffic instruments
  • full-ios: Time Profiler base with Leaks, Allocations, HTTP Traffic, and Power Profiler instruments
  • cpu: Time Profiler
  • memory: Allocations base with Leaks instrument
  • network: Time Profiler base with HTTP Traffic instrument
  • energy: Power Profiler. This is for iOS/iPadOS targets; Xcode commonly does not expose Power Profiler data for macOS recordings.

Report contents:

  • Recording metadata: process, preset, duration, trace path, base template, instruments, and Instruments.app open status
  • Support matrix and export diagnostics
  • CPU / Time Profiler: bottlenecks, top functions, threads, slow function count, and CPU recommendations
  • Hangs: main-thread hang events; severe hangs affect Overall status and Prioritized Recommendations even when Time Profiler CPU thresholds are otherwise clean
  • Top User-Code Frames: app-attributed CPU frames from Time Profiler samples
  • Time Profiler parse-failure callouts when CPU samples could not be parsed
  • Leaks: leak count, leaked bytes, top leak sites, and leak findings when Xcode exports usable data
  • Allocations: allocation counts, allocated bytes, top allocation sites, and churn findings when exportable
  • Network: request count, failed requests, transferred bytes, top hosts, and network failure findings when HAR/CFNetwork data is available
  • Prioritized Recommendations: deduplicated CPU and instrument recommendations sorted for review

Reports retain trace paths and include a cleanup reminder. Use cleanup_traces after the user is finished inspecting the trace in Instruments.app.

Example with Claude:

Start profiling MyApp for 60 seconds and report all issues

track_running_app

Attach to a running process with xcrun xctrace record, save the generated .trace, and optionally analyze it immediately.

Parameters:

  • processName (optional): Running process name or pid to attach to; required for attach mode
  • target (optional): attach, launch, or all-processes
  • launchCommand, launchArguments, environment (optional): launch target details
  • template (optional): Instruments template, for example Leaks, Allocations, Network, Power Profiler, or Time Profiler (default: Leaks)
  • durationSeconds (optional): Recording duration in seconds (default: 60)
  • device (optional): Device or simulator name/UDID
  • outputDirectory (optional): Directory where the .trace file should be saved (default: configured trace root)
  • outputPath (optional): Exact output .trace path. Overrides outputDirectory
  • analyze (optional): Analyze after recording (default: true)
  • openInInstruments (optional): Open the saved .trace in Instruments.app after recording (default: true). Set false for CI or headless runs.
  • outputFormat (optional): markdown, json, or both (default: markdown)

Example with Claude:

Track MyApp for leaks for 60 seconds on the iPhone 16 Pro Simulator

Use this tool when the user names a template. For broad profiling, prefer profile_running_app.

If Leaks, Allocations, or another analysis family is not_exportable, the trace may still show a GUI track in Instruments.app while xcrun export --toc exposes no exportable table schema. Use the opened Instruments trace to verify that GUI-only data.

The trace remains on disk after recording. Use cleanup_traces after the user is done inspecting it.

analyze_trace

Analyze a single trace file for performance issues. The server auto-detects supported Time Profiler, Memory, Network, Energy, Allocations, and Leaks data from the trace TOC.

Parameters:

  • tracePath (required): Path to .trace file
  • slowThreshold (optional): Threshold in ms for slow functions (default: 100)
  • topN (optional): Number of top functions to show (default: 10)
  • dsymPath (optional): dSYM file or directory. The server writes a temporary symbolicated trace before analysis.
  • timeRangeMs (optional): { startMs, endMs } trace-relative window in milliseconds. Use this for follow-up questions like "what ran during this 5 second hang?"
  • userBinaryHints (optional): app or module names used when trace metadata cannot identify user binaries
  • outputFormat (optional): markdown, json, or both

The report distinguishes data that is not present in the trace from data that is present but not exportable. A Time Profiler parse failure is reported as a failed CPU analysis with Export Diagnostics; do not read it as zero CPU work.

Scoped analysis filters Time Profiler samples before function aggregation and filters hang events that overlap the requested window. Top User-Code Frames walks each sample backtrace from leaf to root and aggregates the deepest frame whose module matches the trace's user process names or userBinaryHints.

Example with Claude:

Analyze /Users/me/app.trace and show me the performance bottlenecks

This tool does not record anything. It only reads trace files that already exist.

compare_traces

Compare two Time Profiler traces to detect regressions or improvements.

Parameters:

  • baselinePath (required): Path to baseline .trace file
  • currentPath (required): Path to current .trace file
  • regressionThreshold (optional): % increase to flag (default: 10)
  • failOnRegression (optional): Mark the MCP tool result as an error if a regression is detected (default: false)
  • baselineDsymPath, currentDsymPath (optional): dSYM paths used to symbolicate temporary traces before comparison
  • outputFormat (optional): markdown, json, or both

Example with Claude:

Compare baseline.trace with current.trace and tell me if performance regressed

This comparison currently focuses on Time Profiler data. Additional instrument comparison is future work.

cleanup_traces

Preview or delete .trace bundles created by profiling runs.

Parameters:

  • tracePaths (optional): Exact .trace paths to preview or delete. This is the preferred post-report cleanup path.
  • directory (optional): Directory to scan when tracePaths is omitted (default: configured trace root)
  • recursive (optional): Recursively scan subdirectories in directory mode (default: false)
  • olderThanMinutes (optional): Only match traces older than this many minutes. Required for destructive directory cleanup.
  • dryRun (optional): Preview only by default. Set false after the user confirms deletion.
  • outputFormat (optional): markdown, json, or both

Safety rules:

  • Only paths ending in .trace are deleted.
  • dryRun defaults to true.
  • dryRun: false with directory scanning requires olderThanMinutes, unless exact tracePaths are provided.

Example with Claude:

Clean up the traces from the last profiling run.

list_templates

List all available Instruments templates on the system.

Example with Claude:

What Instruments templates are available?

list_devices

List available devices for profiling.

Example with Claude:

Show me available devices for profiling

check_xctrace

Check if xctrace is available and report command capabilities, templates, devices, instruments, export modes, and warnings.

Example with Claude:

Is xctrace available on this system?

Usage Examples

Full Profiling Report

You: Start profiling MyApp for 60 seconds and report all issues.

Claude: I'll record the full profiling preset and combine the results.

# Profiling Report

- Process: MyApp
- Preset: full
- Recording strategy: combined
- Duration: 60s
- Base template: Time Profiler
- Instruments: Leaks, Allocations, HTTP Traffic

## Summary
- Overall status: critical issues found
- Traces recorded: 1/1
- Traces analyzed: 1/1

## Trace Files
- Time Profiler: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-full-...trace
## Prioritized Recommendations
- critical Leaks Analysis: Leaks detected - The trace contains leaked memory.

Automated Leak Tracking

You: Track MyApp for memory leaks for 60 seconds.

Claude: I'll record the running app with the Leaks template and analyze the trace.

# Running App Trace Report

- Process: MyApp
- Template: Leaks
- Duration: 60s
- Trace: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-Leaks-2026-05-02T16-30-00-000Z.trace

## Additional Instrument Analysis

### Leaks Analysis
3 leaks were detected.

Manual Launch Recording

You: I will launch MyApp; record it for 60 seconds when it appears.

Claude: I'm watching for MyApp now; launch it when ready.

# Profiling Report

- Target: MyApp PID 12345, attached immediately after launch
- Duration: 60s
- Preset: full
- Trace: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-full-...trace
- Instruments.app: opened

Basic Analysis

You: Claude, analyze my latest performance trace at ~/traces/myapp.trace

Claude: I've analyzed your trace. Here's what I found:

# Performance Analysis Report

**Duration:** 5.2s
**Template:** Time Profiler

## Summary
⚠️ Found 1 critical performance issue.
Total execution time: 5.2s across 3 threads.
Primary bottleneck: ImageProcessor.resize() (450ms, 8.7% of time).

## Performance Bottlenecks

### 🔴 1. ImageProcessor.resize()
- **Impact:** critical
- **Duration:** 450ms (8.7% of total)
- **Call count:** 24
- **Suggestion:** Consider caching rendered images or using lower resolution

## Optimization Recommendations

### ⚠️ Implement Image Caching
**Priority:** high | **Type:** caching

Frequent image operations detected. Consider implementing NSCache
or disk-based caching to avoid repeated processing.

**Potential improvement:** 50-70% reduction in image processing time

**Example:**
```swift
let imageCache = NSCache<NSString, UIImage>()

func cachedImage(for key: String) -> UIImage? {
    if let cached = imageCache.object(forKey: key as NSString) {
        return cached
    }
    let image = processImage(key)
    imageCache.setObject(image, forKey: key as NSString)
    return image
}

### Comparing Traces

You: Compare my baseline trace with the current build. Baseline: ~/traces/v1.0.trace Current: ~/traces/v2.0.trace

Claude: I've compared the two traces. Here's the analysis:

Trace Comparison Report

Baseline: v1.0.trace Current: v2.0.trace

Summary

⚠️ Performance regressed by 15.3% (+0.65s slower). 🔴 Found 2 critical regressions.

Performance Delta

⚠️ Total time change: +0.65s (+15.3%)

  • Regressions: 3
  • Improvements: 2
  • Unchanged: 15

Regressions

🔴 NetworkClient.parseJSON() (critical) 50ms → 85ms (+70%)

🟠 DatabaseManager.fetchAll() (major) 120ms → 180ms (+50%)

Improvements

ImageProcessor.cache()* 200ms → 80ms (-60%)

The NetworkClient regression is concerning and should be investigated.


### Development Workflow

You: I just profiled my app. Analyze the latest trace and help me optimize.

Claude: Let me analyze the latest trace...

[Analyzes trace]

I found 3 optimization opportunities:

  1. 🎯 High Impact - ImageCache missing (save ~400ms)
  2. 🎯 Medium Impact - JSON parsing on main thread (save ~150ms)
  3. 🎯 Low Impact - Multiple small allocations (save ~50ms)

Would you like me to help implement any of these optimizations?

You: Yes, help with #1

Claude: Great! Let's implement image caching... [Provides implementation guidance]


## Requirements

- **macOS** with Xcode Command Line Tools installed
- **Node.js** 18+ (for running the MCP server)
- **Claude Desktop** or another MCP-compatible client
- Time Profiler, Memory, Network, Energy, Allocations, or Leaks `.trace` files. Exported table availability depends on Xcode and the trace template.

## How It Works

1. **MCP Request**: The client calls a JSON-RPC tool such as `profile_running_app`.
2. **Capability Check**: The server can inspect local `xctrace` version, templates, devices, instruments, export modes, and symbolication support.
3. **xctrace Record**: Recording tools call `xcrun xctrace record` with attach, launch, or all-processes targets.
4. **xctrace Export**: Analysis calls `xcrun xctrace export --toc`, TOC-discovered XPath table exports, and HAR export when available.
5. **XML / HAR Parsing**: The core parser normalizes Time Profiler rows and supported instrument tables into typed data with export diagnostics.
6. **Analysis Engine**: The analyzer finds bottlenecks, instrument findings, support status, and recommendations.
7. **MCP Response**: The server returns Markdown, JSON, or both.

## Troubleshooting

### xctrace not found

Make sure Xcode Command Line Tools are installed:
```bash
xcode-select --install

Permission errors

The .trace files must be readable. Check file permissions:

ls -la /path/to/trace.trace

No supported data

The server reads supported tables from xcrun xctrace export --toc and uses HAR export for Network traces when available. If Xcode does not expose usable tables for a template, analysis may return a clear no-data section instead of findings.

pnpm/Corepack warnings

The root package.json pins pnpm through packageManager. Use Corepack or install pnpm 10.6.3:

corepack enable
pnpm install --frozen-lockfile

Server not connecting

  1. Check Claude Desktop config file syntax (must be valid JSON)
  2. Verify the path to index.js is correct
  3. Restart Claude Desktop after config changes

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Typecheck, test, and build
pnpm verify

# Start the built server, initialize MCP, and verify tools/list
pnpm test:mcp-smoke

# Inspect schemas exposed by local traces
pnpm inspect:trace test-traces/memory.trace

# Development with watch mode
pnpm dev:mcp

Architecture

MCP Client (Claude)
    ↓ JSON-RPC 2.0
MCP Server (this package)
    ↓
@xctrace-analyzer/core
    ↓
xcrun xctrace (macOS)

License

MIT

Contributing

Contributions welcome! Please see the main repository README for guidelines.