@xctrace-analyzer/mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +558 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2219 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 James Rochabrun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
# Xcode Instruments Trace Analyzer MCP Server
|
|
2
|
+
|
|
3
|
+
> Model Context Protocol server for intelligent Xcode Instruments trace analysis
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
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.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- ๐ **Intelligent Analysis** - Automatically identifies performance bottlenecks
|
|
12
|
+
- ๐ฅ **Automated Recording** - Attach to a running app, save a trace, and analyze it in one tool call
|
|
13
|
+
- ๐งญ **Multi-Instrument Analysis** - Auto-detects Memory, Network, Energy, Allocations, and Leaks data when exportable
|
|
14
|
+
- ๐ **Regression Detection** - Compare traces to find performance regressions
|
|
15
|
+
- ๐ก **Actionable Recommendations** - Get specific optimization suggestions with code examples
|
|
16
|
+
- ๐งพ **Structured Diagnostics** - Support matrix, export attempts, and JSON output for CI or agents
|
|
17
|
+
- ๐งน **Trace Cleanup** - Preview or delete generated `.trace` bundles after inspection
|
|
18
|
+
- ๐ค **Natural Language Interface** - Use Claude to interact with your performance data
|
|
19
|
+
- โ๏ธ **Local-first** - Runs through your installed Xcode Command Line Tools
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### Claude Code
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
claude mcp add --transport stdio --scope user xctrace-analyzer -- npx -y @xctrace-analyzer/mcp-server
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Verify the local machine has a usable `xcrun xctrace`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx -y @xctrace-analyzer/mcp-server --check
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Claude Desktop
|
|
36
|
+
|
|
37
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"xctrace-analyzer": {
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["-y", "@xctrace-analyzer/mcp-server"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Building from Source
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# From the monorepo root
|
|
54
|
+
pnpm install --frozen-lockfile
|
|
55
|
+
pnpm verify
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Available Tools
|
|
59
|
+
|
|
60
|
+
### Recommended User Experience
|
|
61
|
+
|
|
62
|
+
For human-facing use, register the bundled skill at [`../../skills/xctrace-profiler`](../../skills/xctrace-profiler/SKILL.md) in clients that support skills. Then users can stay at the prompt level:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
Profile this app.
|
|
66
|
+
Find why this app is slow.
|
|
67
|
+
Profile this app for hangs.
|
|
68
|
+
Profile this app for hangs and tell me which of my code is responsible.
|
|
69
|
+
Check this build for leaks and allocation churn.
|
|
70
|
+
Analyze network activity.
|
|
71
|
+
Launch this app and profile startup hangs.
|
|
72
|
+
I will launch MyApp; record it for 60 seconds when it appears.
|
|
73
|
+
Analyze this trace.
|
|
74
|
+
Compare these two traces.
|
|
75
|
+
Clean up profiling traces when we are done.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
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.
|
|
79
|
+
|
|
80
|
+
### Tool Selection Guide
|
|
81
|
+
|
|
82
|
+
- Use `profile_running_app` for "start profiling", "full report", or "record all issues" requests against an already-running app.
|
|
83
|
+
- Use `track_running_app` for a single explicit Instruments template such as Leaks or Allocations.
|
|
84
|
+
- 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.
|
|
85
|
+
- Use `compare_traces` when the user asks whether a current build regressed against a baseline.
|
|
86
|
+
- Use `cleanup_traces` after the user confirms recorded traces are no longer needed, or as a dry-run preview for stale trace directories.
|
|
87
|
+
- Use `list_templates`, `list_devices`, and `check_xctrace` for setup and troubleshooting.
|
|
88
|
+
|
|
89
|
+
### Security Defaults
|
|
90
|
+
|
|
91
|
+
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.
|
|
92
|
+
|
|
93
|
+
| Option | Default | Why it is useful and important |
|
|
94
|
+
| --- | --- | --- |
|
|
95
|
+
| `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`. |
|
|
96
|
+
| `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. |
|
|
97
|
+
| `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. |
|
|
98
|
+
| `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. |
|
|
99
|
+
| `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. |
|
|
100
|
+
| `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. |
|
|
101
|
+
| `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. |
|
|
102
|
+
|
|
103
|
+
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:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
XCTRACE_ANALYZER_ALLOW_LAUNCH=1 npx -y @xctrace-analyzer/mcp-server
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Claude Desktop-style MCP configs can pass the same settings through `env`:
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"mcpServers": {
|
|
114
|
+
"xctrace-analyzer": {
|
|
115
|
+
"command": "npx",
|
|
116
|
+
"args": ["-y", "@xctrace-analyzer/mcp-server"],
|
|
117
|
+
"env": {
|
|
118
|
+
"XCTRACE_ANALYZER_ALLOW_LAUNCH": "1",
|
|
119
|
+
"XCTRACE_ANALYZER_TRACE_ROOT": "/Users/you/Library/Application Support/xctrace-analyzer/traces"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `profile_running_app`
|
|
127
|
+
|
|
128
|
+
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.
|
|
129
|
+
|
|
130
|
+
**Parameters:**
|
|
131
|
+
- `processName` (optional): Running process name or pid to attach to; required for attach mode
|
|
132
|
+
- `target` (optional): `attach`, `launch`, or `all-processes`
|
|
133
|
+
- `launchCommand`, `launchArguments`, `environment` (optional): launch target details
|
|
134
|
+
- `preset` (optional): `full`, `full-ios`, `cpu`, `memory`, `network`, or `energy` (default: `full`)
|
|
135
|
+
- `durationSeconds` (optional): Total recording duration in seconds (default: 60)
|
|
136
|
+
- `device` (optional): Device or simulator name/UDID
|
|
137
|
+
- `outputDirectory` (optional): Directory where generated `.trace` files should be saved (default: configured trace root)
|
|
138
|
+
- `analyze` (optional): Analyze after recording (default: true)
|
|
139
|
+
- `openInInstruments` (optional): Open the saved `.trace` in Instruments.app after recording (default: true). Set false for CI or headless runs.
|
|
140
|
+
- `outputFormat` (optional): `markdown`, `json`, or `both` (default: `markdown`)
|
|
141
|
+
|
|
142
|
+
Preset recordings:
|
|
143
|
+
- `full`: Time Profiler base with Leaks, Allocations, and HTTP Traffic instruments
|
|
144
|
+
- `full-ios`: Time Profiler base with Leaks, Allocations, HTTP Traffic, and Power Profiler instruments
|
|
145
|
+
- `cpu`: Time Profiler
|
|
146
|
+
- `memory`: Allocations base with Leaks instrument
|
|
147
|
+
- `network`: Time Profiler base with HTTP Traffic instrument
|
|
148
|
+
- `energy`: Power Profiler. This is for iOS/iPadOS targets; Xcode commonly does not expose Power Profiler data for macOS recordings.
|
|
149
|
+
|
|
150
|
+
Report contents:
|
|
151
|
+
- Recording metadata: process, preset, duration, trace path, base template, instruments, and Instruments.app open status
|
|
152
|
+
- Support matrix and export diagnostics
|
|
153
|
+
- CPU / Time Profiler: bottlenecks, top functions, threads, slow function count, and CPU recommendations
|
|
154
|
+
- Hangs: main-thread hang events; severe hangs affect Overall status and Prioritized Recommendations even when Time Profiler CPU thresholds are otherwise clean
|
|
155
|
+
- Top User-Code Frames: app-attributed CPU frames from Time Profiler samples
|
|
156
|
+
- Time Profiler parse-failure callouts when CPU samples could not be parsed
|
|
157
|
+
- Leaks: leak count, leaked bytes, top leak sites, and leak findings when Xcode exports usable data
|
|
158
|
+
- Allocations: allocation counts, allocated bytes, top allocation sites, and churn findings when exportable
|
|
159
|
+
- Network: request count, failed requests, transferred bytes, top hosts, and network failure findings when HAR/CFNetwork data is available
|
|
160
|
+
- Prioritized Recommendations: deduplicated CPU and instrument recommendations sorted for review
|
|
161
|
+
|
|
162
|
+
Reports retain trace paths and include a cleanup reminder. Use `cleanup_traces` after the user is finished inspecting the trace in Instruments.app.
|
|
163
|
+
|
|
164
|
+
**Example with Claude:**
|
|
165
|
+
```
|
|
166
|
+
Start profiling MyApp for 60 seconds and report all issues
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### `track_running_app`
|
|
170
|
+
|
|
171
|
+
Attach to a running process with `xcrun xctrace record`, save the generated `.trace`, and optionally analyze it immediately.
|
|
172
|
+
|
|
173
|
+
**Parameters:**
|
|
174
|
+
- `processName` (optional): Running process name or pid to attach to; required for attach mode
|
|
175
|
+
- `target` (optional): `attach`, `launch`, or `all-processes`
|
|
176
|
+
- `launchCommand`, `launchArguments`, `environment` (optional): launch target details
|
|
177
|
+
- `template` (optional): Instruments template, for example `Leaks`, `Allocations`, `Network`, `Power Profiler`, or `Time Profiler` (default: `Leaks`)
|
|
178
|
+
- `durationSeconds` (optional): Recording duration in seconds (default: 60)
|
|
179
|
+
- `device` (optional): Device or simulator name/UDID
|
|
180
|
+
- `outputDirectory` (optional): Directory where the `.trace` file should be saved (default: configured trace root)
|
|
181
|
+
- `outputPath` (optional): Exact output `.trace` path. Overrides `outputDirectory`
|
|
182
|
+
- `analyze` (optional): Analyze after recording (default: true)
|
|
183
|
+
- `openInInstruments` (optional): Open the saved `.trace` in Instruments.app after recording (default: true). Set false for CI or headless runs.
|
|
184
|
+
- `outputFormat` (optional): `markdown`, `json`, or `both` (default: `markdown`)
|
|
185
|
+
|
|
186
|
+
**Example with Claude:**
|
|
187
|
+
```
|
|
188
|
+
Track MyApp for leaks for 60 seconds on the iPhone 16 Pro Simulator
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Use this tool when the user names a template. For broad profiling, prefer `profile_running_app`.
|
|
192
|
+
|
|
193
|
+
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.
|
|
194
|
+
|
|
195
|
+
The trace remains on disk after recording. Use `cleanup_traces` after the user is done inspecting it.
|
|
196
|
+
|
|
197
|
+
### `analyze_trace`
|
|
198
|
+
|
|
199
|
+
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.
|
|
200
|
+
|
|
201
|
+
**Parameters:**
|
|
202
|
+
- `tracePath` (required): Path to .trace file
|
|
203
|
+
- `slowThreshold` (optional): Threshold in ms for slow functions (default: 100)
|
|
204
|
+
- `topN` (optional): Number of top functions to show (default: 10)
|
|
205
|
+
- `dsymPath` (optional): dSYM file or directory. The server writes a temporary symbolicated trace before analysis.
|
|
206
|
+
- `timeRangeMs` (optional): `{ startMs, endMs }` trace-relative window in milliseconds. Use this for follow-up questions like "what ran during this 5 second hang?"
|
|
207
|
+
- `userBinaryHints` (optional): app or module names used when trace metadata cannot identify user binaries
|
|
208
|
+
- `outputFormat` (optional): `markdown`, `json`, or `both`
|
|
209
|
+
|
|
210
|
+
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.
|
|
211
|
+
|
|
212
|
+
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`.
|
|
213
|
+
|
|
214
|
+
**Example with Claude:**
|
|
215
|
+
```
|
|
216
|
+
Analyze /Users/me/app.trace and show me the performance bottlenecks
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
This tool does not record anything. It only reads trace files that already exist.
|
|
220
|
+
|
|
221
|
+
### `compare_traces`
|
|
222
|
+
|
|
223
|
+
Compare two Time Profiler traces to detect regressions or improvements.
|
|
224
|
+
|
|
225
|
+
**Parameters:**
|
|
226
|
+
- `baselinePath` (required): Path to baseline .trace file
|
|
227
|
+
- `currentPath` (required): Path to current .trace file
|
|
228
|
+
- `regressionThreshold` (optional): % increase to flag (default: 10)
|
|
229
|
+
- `failOnRegression` (optional): Mark the MCP tool result as an error if a regression is detected (default: false)
|
|
230
|
+
- `baselineDsymPath`, `currentDsymPath` (optional): dSYM paths used to symbolicate temporary traces before comparison
|
|
231
|
+
- `outputFormat` (optional): `markdown`, `json`, or `both`
|
|
232
|
+
|
|
233
|
+
**Example with Claude:**
|
|
234
|
+
```
|
|
235
|
+
Compare baseline.trace with current.trace and tell me if performance regressed
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
This comparison currently focuses on Time Profiler data. Additional instrument comparison is future work.
|
|
239
|
+
|
|
240
|
+
### `cleanup_traces`
|
|
241
|
+
|
|
242
|
+
Preview or delete `.trace` bundles created by profiling runs.
|
|
243
|
+
|
|
244
|
+
**Parameters:**
|
|
245
|
+
- `tracePaths` (optional): Exact `.trace` paths to preview or delete. This is the preferred post-report cleanup path.
|
|
246
|
+
- `directory` (optional): Directory to scan when `tracePaths` is omitted (default: configured trace root)
|
|
247
|
+
- `recursive` (optional): Recursively scan subdirectories in directory mode (default: false)
|
|
248
|
+
- `olderThanMinutes` (optional): Only match traces older than this many minutes. Required for destructive directory cleanup.
|
|
249
|
+
- `dryRun` (optional): Preview only by default. Set false after the user confirms deletion.
|
|
250
|
+
- `outputFormat` (optional): `markdown`, `json`, or `both`
|
|
251
|
+
|
|
252
|
+
Safety rules:
|
|
253
|
+
- Only paths ending in `.trace` are deleted.
|
|
254
|
+
- `dryRun` defaults to true.
|
|
255
|
+
- `dryRun: false` with directory scanning requires `olderThanMinutes`, unless exact `tracePaths` are provided.
|
|
256
|
+
|
|
257
|
+
**Example with Claude:**
|
|
258
|
+
```
|
|
259
|
+
Clean up the traces from the last profiling run.
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### `list_templates`
|
|
263
|
+
|
|
264
|
+
List all available Instruments templates on the system.
|
|
265
|
+
|
|
266
|
+
**Example with Claude:**
|
|
267
|
+
```
|
|
268
|
+
What Instruments templates are available?
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### `list_devices`
|
|
272
|
+
|
|
273
|
+
List available devices for profiling.
|
|
274
|
+
|
|
275
|
+
**Example with Claude:**
|
|
276
|
+
```
|
|
277
|
+
Show me available devices for profiling
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### `check_xctrace`
|
|
281
|
+
|
|
282
|
+
Check if xctrace is available and report command capabilities, templates, devices, instruments, export modes, and warnings.
|
|
283
|
+
|
|
284
|
+
**Example with Claude:**
|
|
285
|
+
```
|
|
286
|
+
Is xctrace available on this system?
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Usage Examples
|
|
290
|
+
|
|
291
|
+
### Full Profiling Report
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
You: Start profiling MyApp for 60 seconds and report all issues.
|
|
295
|
+
|
|
296
|
+
Claude: I'll record the full profiling preset and combine the results.
|
|
297
|
+
|
|
298
|
+
# Profiling Report
|
|
299
|
+
|
|
300
|
+
- Process: MyApp
|
|
301
|
+
- Preset: full
|
|
302
|
+
- Recording strategy: combined
|
|
303
|
+
- Duration: 60s
|
|
304
|
+
- Base template: Time Profiler
|
|
305
|
+
- Instruments: Leaks, Allocations, HTTP Traffic
|
|
306
|
+
|
|
307
|
+
## Summary
|
|
308
|
+
- Overall status: critical issues found
|
|
309
|
+
- Traces recorded: 1/1
|
|
310
|
+
- Traces analyzed: 1/1
|
|
311
|
+
|
|
312
|
+
## Trace Files
|
|
313
|
+
- Time Profiler: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-full-...trace
|
|
314
|
+
## Prioritized Recommendations
|
|
315
|
+
- critical Leaks Analysis: Leaks detected - The trace contains leaked memory.
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Automated Leak Tracking
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
You: Track MyApp for memory leaks for 60 seconds.
|
|
322
|
+
|
|
323
|
+
Claude: I'll record the running app with the Leaks template and analyze the trace.
|
|
324
|
+
|
|
325
|
+
# Running App Trace Report
|
|
326
|
+
|
|
327
|
+
- Process: MyApp
|
|
328
|
+
- Template: Leaks
|
|
329
|
+
- Duration: 60s
|
|
330
|
+
- Trace: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-Leaks-2026-05-02T16-30-00-000Z.trace
|
|
331
|
+
|
|
332
|
+
## Additional Instrument Analysis
|
|
333
|
+
|
|
334
|
+
### Leaks Analysis
|
|
335
|
+
3 leaks were detected.
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Manual Launch Recording
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
You: I will launch MyApp; record it for 60 seconds when it appears.
|
|
342
|
+
|
|
343
|
+
Claude: I'm watching for MyApp now; launch it when ready.
|
|
344
|
+
|
|
345
|
+
# Profiling Report
|
|
346
|
+
|
|
347
|
+
- Target: MyApp PID 12345, attached immediately after launch
|
|
348
|
+
- Duration: 60s
|
|
349
|
+
- Preset: full
|
|
350
|
+
- Trace: ~/Library/Application Support/xctrace-analyzer/traces/MyApp-full-...trace
|
|
351
|
+
- Instruments.app: opened
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Basic Analysis
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
You: Claude, analyze my latest performance trace at ~/traces/myapp.trace
|
|
358
|
+
|
|
359
|
+
Claude: I've analyzed your trace. Here's what I found:
|
|
360
|
+
|
|
361
|
+
# Performance Analysis Report
|
|
362
|
+
|
|
363
|
+
**Duration:** 5.2s
|
|
364
|
+
**Template:** Time Profiler
|
|
365
|
+
|
|
366
|
+
## Summary
|
|
367
|
+
โ ๏ธ Found 1 critical performance issue.
|
|
368
|
+
Total execution time: 5.2s across 3 threads.
|
|
369
|
+
Primary bottleneck: ImageProcessor.resize() (450ms, 8.7% of time).
|
|
370
|
+
|
|
371
|
+
## Performance Bottlenecks
|
|
372
|
+
|
|
373
|
+
### ๐ด 1. ImageProcessor.resize()
|
|
374
|
+
- **Impact:** critical
|
|
375
|
+
- **Duration:** 450ms (8.7% of total)
|
|
376
|
+
- **Call count:** 24
|
|
377
|
+
- **Suggestion:** Consider caching rendered images or using lower resolution
|
|
378
|
+
|
|
379
|
+
## Optimization Recommendations
|
|
380
|
+
|
|
381
|
+
### โ ๏ธ Implement Image Caching
|
|
382
|
+
**Priority:** high | **Type:** caching
|
|
383
|
+
|
|
384
|
+
Frequent image operations detected. Consider implementing NSCache
|
|
385
|
+
or disk-based caching to avoid repeated processing.
|
|
386
|
+
|
|
387
|
+
**Potential improvement:** 50-70% reduction in image processing time
|
|
388
|
+
|
|
389
|
+
**Example:**
|
|
390
|
+
```swift
|
|
391
|
+
let imageCache = NSCache<NSString, UIImage>()
|
|
392
|
+
|
|
393
|
+
func cachedImage(for key: String) -> UIImage? {
|
|
394
|
+
if let cached = imageCache.object(forKey: key as NSString) {
|
|
395
|
+
return cached
|
|
396
|
+
}
|
|
397
|
+
let image = processImage(key)
|
|
398
|
+
imageCache.setObject(image, forKey: key as NSString)
|
|
399
|
+
return image
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Comparing Traces
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
You: Compare my baseline trace with the current build.
|
|
408
|
+
Baseline: ~/traces/v1.0.trace
|
|
409
|
+
Current: ~/traces/v2.0.trace
|
|
410
|
+
|
|
411
|
+
Claude: I've compared the two traces. Here's the analysis:
|
|
412
|
+
|
|
413
|
+
# Trace Comparison Report
|
|
414
|
+
|
|
415
|
+
**Baseline:** v1.0.trace
|
|
416
|
+
**Current:** v2.0.trace
|
|
417
|
+
|
|
418
|
+
## Summary
|
|
419
|
+
โ ๏ธ Performance regressed by 15.3% (+0.65s slower).
|
|
420
|
+
๐ด Found 2 critical regressions.
|
|
421
|
+
|
|
422
|
+
## Performance Delta
|
|
423
|
+
โ ๏ธ Total time change: +0.65s (+15.3%)
|
|
424
|
+
- Regressions: 3
|
|
425
|
+
- Improvements: 2
|
|
426
|
+
- Unchanged: 15
|
|
427
|
+
|
|
428
|
+
## Regressions
|
|
429
|
+
|
|
430
|
+
๐ด **NetworkClient.parseJSON()** (critical)
|
|
431
|
+
50ms โ 85ms (+70%)
|
|
432
|
+
|
|
433
|
+
๐ **DatabaseManager.fetchAll()** (major)
|
|
434
|
+
120ms โ 180ms (+50%)
|
|
435
|
+
|
|
436
|
+
## Improvements
|
|
437
|
+
|
|
438
|
+
โ
**ImageProcessor.cache()***
|
|
439
|
+
200ms โ 80ms (-60%)
|
|
440
|
+
|
|
441
|
+
The NetworkClient regression is concerning and should be investigated.
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Development Workflow
|
|
445
|
+
|
|
446
|
+
```
|
|
447
|
+
You: I just profiled my app. Analyze the latest trace and help me optimize.
|
|
448
|
+
|
|
449
|
+
Claude: Let me analyze the latest trace...
|
|
450
|
+
|
|
451
|
+
[Analyzes trace]
|
|
452
|
+
|
|
453
|
+
I found 3 optimization opportunities:
|
|
454
|
+
|
|
455
|
+
1. ๐ฏ **High Impact** - ImageCache missing (save ~400ms)
|
|
456
|
+
2. ๐ฏ **Medium Impact** - JSON parsing on main thread (save ~150ms)
|
|
457
|
+
3. ๐ฏ **Low Impact** - Multiple small allocations (save ~50ms)
|
|
458
|
+
|
|
459
|
+
Would you like me to help implement any of these optimizations?
|
|
460
|
+
|
|
461
|
+
You: Yes, help with #1
|
|
462
|
+
|
|
463
|
+
Claude: Great! Let's implement image caching...
|
|
464
|
+
[Provides implementation guidance]
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Requirements
|
|
468
|
+
|
|
469
|
+
- **macOS** with Xcode Command Line Tools installed
|
|
470
|
+
- **Node.js** 18+ (for running the MCP server)
|
|
471
|
+
- **Claude Desktop** or another MCP-compatible client
|
|
472
|
+
- Time Profiler, Memory, Network, Energy, Allocations, or Leaks `.trace` files. Exported table availability depends on Xcode and the trace template.
|
|
473
|
+
|
|
474
|
+
## How It Works
|
|
475
|
+
|
|
476
|
+
1. **MCP Request**: The client calls a JSON-RPC tool such as `profile_running_app`.
|
|
477
|
+
2. **Capability Check**: The server can inspect local `xctrace` version, templates, devices, instruments, export modes, and symbolication support.
|
|
478
|
+
3. **xctrace Record**: Recording tools call `xcrun xctrace record` with attach, launch, or all-processes targets.
|
|
479
|
+
4. **xctrace Export**: Analysis calls `xcrun xctrace export --toc`, TOC-discovered XPath table exports, and HAR export when available.
|
|
480
|
+
5. **XML / HAR Parsing**: The core parser normalizes Time Profiler rows and supported instrument tables into typed data with export diagnostics.
|
|
481
|
+
6. **Analysis Engine**: The analyzer finds bottlenecks, instrument findings, support status, and recommendations.
|
|
482
|
+
7. **MCP Response**: The server returns Markdown, JSON, or both.
|
|
483
|
+
|
|
484
|
+
## Troubleshooting
|
|
485
|
+
|
|
486
|
+
### xctrace not found
|
|
487
|
+
|
|
488
|
+
Make sure Xcode Command Line Tools are installed:
|
|
489
|
+
```bash
|
|
490
|
+
xcode-select --install
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Permission errors
|
|
494
|
+
|
|
495
|
+
The .trace files must be readable. Check file permissions:
|
|
496
|
+
```bash
|
|
497
|
+
ls -la /path/to/trace.trace
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### No supported data
|
|
501
|
+
|
|
502
|
+
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.
|
|
503
|
+
|
|
504
|
+
### pnpm/Corepack warnings
|
|
505
|
+
|
|
506
|
+
The root `package.json` pins `pnpm` through `packageManager`. Use Corepack or install pnpm 10.6.3:
|
|
507
|
+
```bash
|
|
508
|
+
corepack enable
|
|
509
|
+
pnpm install --frozen-lockfile
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Server not connecting
|
|
513
|
+
|
|
514
|
+
1. Check Claude Desktop config file syntax (must be valid JSON)
|
|
515
|
+
2. Verify the path to index.js is correct
|
|
516
|
+
3. Restart Claude Desktop after config changes
|
|
517
|
+
|
|
518
|
+
## Development
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
# Install dependencies
|
|
522
|
+
pnpm install
|
|
523
|
+
|
|
524
|
+
# Build
|
|
525
|
+
pnpm build
|
|
526
|
+
|
|
527
|
+
# Typecheck, test, and build
|
|
528
|
+
pnpm verify
|
|
529
|
+
|
|
530
|
+
# Start the built server, initialize MCP, and verify tools/list
|
|
531
|
+
pnpm test:mcp-smoke
|
|
532
|
+
|
|
533
|
+
# Inspect schemas exposed by local traces
|
|
534
|
+
pnpm inspect:trace test-traces/memory.trace
|
|
535
|
+
|
|
536
|
+
# Development with watch mode
|
|
537
|
+
pnpm dev:mcp
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
## Architecture
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
MCP Client (Claude)
|
|
544
|
+
โ JSON-RPC 2.0
|
|
545
|
+
MCP Server (this package)
|
|
546
|
+
โ
|
|
547
|
+
@xctrace-analyzer/core
|
|
548
|
+
โ
|
|
549
|
+
xcrun xctrace (macOS)
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
## License
|
|
553
|
+
|
|
554
|
+
MIT
|
|
555
|
+
|
|
556
|
+
## Contributing
|
|
557
|
+
|
|
558
|
+
Contributions welcome! Please see the main repository README for guidelines.
|