Memorydetective MCP server
io.github.carloshpdoc/memorydetective·v1.18.1·13 starsiOS leak/perf debugging via MCP: memgraph cycles, .trace analysis, SourceKit-LSP bridging.
13 stars134 downloads/wk
Reviews
Write oneNobody has reviewed Memorydetective yet.
If you have run it, two minutes of your experience saves the next person an afternoon.
Memorydetective tools (42)
write = sends, deletes, buys or postsRead from the package source without running it. The installed server may list more.
analyzeAbandonedMemoryanalyzeAllocations[mg.trace] Parse the `allocations` schema from a `.trace` recorded with the Allocations Instruments template. Returns per-category aggregates (cumulative bytes, allocation count, lifecycle = transient/persistent/mixed), top allocators by size and by count, and a one-liner diagnosis identifying the dominant allocator.
analyzeAnimationHitches[mg.trace] Parse the `animation-hitches` schema from a `.trace` recorded with the Animation Hitches Instruments template. Returns hitch totals, by-type counts, longest hitches, and how many crossed the user-perceptible 100ms threshold.
analyzeAppLaunch[mg.trace] Parse the `app-launch` schema from a `.trace` recorded with the App Launch Instruments template. Returns total launch time, launch type (cold/warm), per-phase breakdown (process-creation, dyld-init, ObjC-init, AppDelegate, first-frame), and the slowest phase.
analyzeEnergyImpact[mg.trace] Parse the `energy-impact` schema from a `.trace` recorded with an Energy Log template. Returns per-sample bucket classification (idle / passive / active / high), aggregate wakeup count, active-state ratio, top-N samples by energy cost. The 'why is my app draining battery?' investigation. Distinct from analyzeTimeProfile (CPU sampling); reads the OS power-management subsystem directly. v
analyzeHangsanalyzeLeakTimeline[mg.trace] Parse the `leaks` schema from a `.trace` recorded with a Leaks template. Distinct from leaks(1) CLI (snapshot): this is a time series of leak events captured throughout the recording. Returns per-class first-seen-at timestamp, peak instance count, peak bytes, event count. Useful for answering 'when in the timeline did the leak appear?' which the snapshot CLI cannot. v1.15+.
analyzeMemgraph[mg.memory] Run `leaks(1)` against a `.memgraph` file (exported from Xcode Memory Graph Debugger) and return a structured summary: header info, totals, top-level ROOT CYCLE blocks with chain length, plain-English diagnosis. Set `fullChains: true` to also include the full nested retain forest. Pipeline: → `classifyCycle` (named-antipattern + fix hint) → `reachableFromCycle` (scope blame to a single
analyzeMemoryFootprint[mg.trace] Parse the `memory-footprint` schema from a `.trace` recorded with Allocations or System Trace template. Returns peak resident bytes (RAM in use), peak dirty bytes (the OOM-kill discriminator on iOS), peak VM regions, per-sample timeline. Distinct from analyzeAllocations (cumulative malloc bytes by category). Use when investigating 'why is my app getting jetsam-killed?'. v1.15+.
analyzeMetricKitPayloadanalyzeNetworkActivity[mg.trace] Parse the `network-connections` schema from a `.trace` recorded with a Network template. Returns per-request URL/host, method, status code, response time, bytes in/out. Top-N rankings by duration (which calls blocked the user) and by bytes (which calls bloat the budget) plus per-host aggregates surfacing chatty SDKs. v1.14+.
analyzeTimeProfile[mg.trace] Export the `time-profile` schema from a `.trace` bundle and return top symbols by sample count. Note: heavy/unsymbolicated traces may crash xctrace export — when that happens, the tool returns a `notice` field with workarounds (open in Instruments first to symbolicate, or re-record shorter).
bootAndLaunchForLeakInvestigation[mg.build] Single-call orchestration that runs `xcodebuild build` (optional), boots the iOS Simulator, installs the .app, and launches it with `MallocStackLogging=1` propagated via `SIMCTL_CHILD_*`. Required because `leaks --outputGraph` regressed on macOS 26.x and only works when the target was launched with malloc-stack-logging in its environment. Returns the host PID + simulator UDID + bundle i
captureMemgraph[mg.memory] Wrapper around `leaks --outputGraph`. Resolves `appName` to a PID via `pgrep -x` (or accepts `pid` directly), then writes a `.memgraph` snapshot. **Limitation**: only works for processes running on the local Mac (Mac apps + iOS simulator). Does NOT work for physical iOS devices, use Xcode's Memory Graph button there.
captureScenarioState[mg.scenario] Composite snapshot: writes a `.memgraph`, a `.png` screenshot, and a `.ui.json` accessibility tree into `outputDir`, all prefixed by `label` (e.g. `before` / `after`). Designed to bracket a fix or a replayScenario call so you can chain into diffMemgraphs and validate that a cycle actually closed. Sub-captures are best-effort: if leaks fails (macOS 26.x minimal-corpse), the screenshot
classifyCycle[mg.memory] Match each ROOT CYCLE against a built-in catalog of 8 known antipatterns (TagIndexProjection cycle, ForEachState retention, Combine sink-store-self, Task-without-weak-self, NotificationCenter observer, viewmodel-wrapped-strong closure, UINavigationController host, _DictionaryStorage internal). Returns `patternId`, `confidence`, and a `fixHint` per cycle. Pipeline: this is the killer to
cleanupTracescompareTracesByPattern[mg.trace][mg.ci] Trace-side counterpart to `verifyFix`. Compares two `.trace` bundles for a specific perf category (`hangs`, `animation-hitches`, or `app-launch`) and emits a PASS/PARTIAL/FAIL verdict plus before/after stats and deltas. Apply thresholds: hangs PASS when longest is below `hangsMaxLongestMs` (default 0); hitches PASS when longest is below `hitchesMaxLongestMs` (default 100ms — Appl
countAlive[mg.memory] Count how many times each class appears in a `.memgraph`'s leaked nodes. Provide `className` (substring) for a single number, or omit it to get the top N most-leaked classes. Use this to confirm whether a fix actually reduced instance counts.
detectLeaksInXCTestdetectLeaksInXCUITest[mg.ci] Build the workspace for testing, launch the test cycle, capture a baseline `.memgraph` once the app appears, run the test to completion, capture an after `.memgraph`, and diff. Returns `passed: false` when new ROOT CYCLE blocks appear that aren't in the `allowlistPatterns` list. Designed for CI gating: non-zero exit code on failure.
diffMemgraphs[mg.memory] Compare a baseline `.memgraph` (`before`) against a comparison `.memgraph` (`after`). Returns total leak/byte deltas, classes whose counts increased or decreased, and ROOT CYCLE signatures bucketed into newInAfter / goneFromBefore / persisted. The killer feature for verifying that a fix actually worked.
findCycles[mg.memory] Extract just the ROOT CYCLE blocks from a `.memgraph` as flattened chains (depth + edge + retainKind + className + address). Optionally filter to cycles touching a specific class name (substring match). Use this when you want to inspect chains without the noise of standalone leaks.
findRetainers[mg.memory] Walk the cycle forest from a `.memgraph` and return every retain chain that ends in a node whose className contains the given substring. Useful for answering "who is keeping <class> alive?". Returns paths from a top-level node down to the matching node.
getInvestigationPlaybook[meta] Returns a versioned, declarative pipeline for a known investigation flow (`memgraph-leak`, `perf-hangs`, `ui-jank`, `app-launch-slow`, `verify-fix`). Each step has a tool name, purpose, and argsTemplate. Use this once at the start of an investigation so any LLM agent can follow the right sequence without rediscovering it from individual tool descriptions.
inspectTracelistTraceDevices[mg.discover] Run `xcrun xctrace list devices` and return parsed devices/simulators with their UDIDs. The LLM should call this before `recordTimeProfile` to discover the right UDID without asking the user. Set `includeOffline: true` to include disconnected devices.
listTraceTemplates[mg.discover] Run `xcrun xctrace list templates` and return parsed standard + custom templates. Useful when picking a template name for `recordTimeProfile` (e.g. "Time Profiler", "Animation Hitches", "Allocations").
logShow[mg.log] Wrap `log show --style compact --last <window>` with optional NSPredicate filter, process and subsystem sugar. Returns parsed entries (timestamp, type, process, pid, subsystem, category, message) bounded by `maxEntries`. Use this to look back at app logs without leaving chat.
logStream[mg.log] Wrap `log stream --style compact` for a bounded duration (≤60 s — MCP requests should not block longer). Returns parsed entries collected during the window. Useful for capturing a specific user flow without setting up a full Console.app session.
reachableFromCycle[mg.memory] Cycle-scoped reachability + class counting. Answers questions like "how many `NSURLSessionConfiguration` instances are reachable from the cycle rooted at `DetailViewModel`?" — distinguishing the actual culprit (the cycle root) from its retained dependencies. Pick a cycle by zero-based `cycleIndex` or by `rootClassName` substring. Returns per-class counts ranked by occurrence, plus the
recordTimeProfile[mg.trace] Wrapper around `xcrun xctrace record`. Capture a `.trace` bundle from a running app on a device or simulator. Required: exactly 1 of `deviceId`/`simulatorId`, exactly 1 of `attachAppName`/`attachPid`/`launchBundleId`, an `output` path ending in `.trace`. Defaults: template = "Time Profiler", durationSec = 90.
recordViaInstrumentsApp[mg.build] Open Instruments.app, prompt the user to record + save a .trace, then poll a watchDir for the new bundle and chain into inspectTrace. The macOS 26.x escape hatch: `xcrun xctrace record` wedges on this OS but Instruments.app GUI still produces valid traces. Returns instructions[] for the user-in-loop step, tracePath when found, plus a chained inspectTrace summary. Times out after `timeou
renderCycleGraph[mg.render] Read a `.memgraph`, pick a ROOT CYCLE by index, and emit the chain as a Mermaid graph definition (default — embeddable in markdown / GitHub) or a Graphviz DOT file. App-level classes are highlighted; CYCLE BACK terminators are styled distinctly. Use `cycleIndex` to render cycles other than the first.
replayScenario[mg.scenario] Drive the iOS Simulator through a sequence of UI actions (tap, swipe, wait, type) and optionally repeat the sequence N times to amplify a leak that only manifests after iteration. Tied to verify-fix: pair with captureScenarioState before/after to make leak reproductions deterministic. Soft dependency on `axe` (https://github.com/cameroncooke/AXe) — when missing, returns a structured
summarizeTraceswiftFindSymbolReferences[mg.code] Locates the symbol's declaration in `filePath`, then asks SourceKit-LSP for `textDocument/references`. Returns every callsite + capture across the project, with a snippet of each line. **Requires an IndexStoreDB** at `<projectRoot>/.build/index/store` for cross-file references — build it with `swift build -Xswiftc -index-store-path -Xswiftc <projectRoot>/.build/index/store`. The result i
swiftGetHoverInfo[mg.code] SourceKit-LSP `textDocument/hover` at a (line, character) position. Returns the markdown / plaintext hover content plus a best-effort extracted declaration fragment. Use to disambiguate `self` captures: a class self in a closure can leak; a struct self can't.
swiftGetSymbolDefinition[mg.code] Find the file:line where a Swift symbol (class, struct, enum, protocol, func, var, etc.) is declared. Pre-scans `candidatePaths` (or `hint.filePath`) with a fast regex first, then asks SourceKit-LSP for jump-to-definition. Returns the position even when LSP can't follow through. Use after `findRetainers` / `classifyCycle` surface a class name from a memgraph cycle to land in the actual s
swiftGetSymbolsOverview[mg.code] Cheap orientation: returns the top-level symbols (classes, structs, enums, protocols, free functions) declared in a Swift file via SourceKit-LSP's `documentSymbol`. Set `topLevelOnly: false` for nested children too. Useful right after `swiftGetSymbolDefinition` lands you in a new file.
swiftSearchPattern[mg.code] Pure regex search over a file's contents — no SourceKit-LSP, no IndexStoreDB. Catches what LSP misses: closure capture lists (`[weak self]`, `[unowned self]`), `Task { ... self ... }` blocks, and any other pattern the agent constructs from a leak chain. Returns matches with line/character positions and a trimmed snippet.
verifyFix[mg.memory] Cycle-semantic diff. Classifies both `before` and `after` `.memgraph` snapshots and emits a per-pattern PASS/PARTIAL/FAIL verdict plus bytes freed and instances released. Use as a CI gate: if `expectedPatternId` is provided, `expectedPatternVerdict` tells you in one field whether the fix landed. Pipeline: this is the natural followup to `classifyCycle` after you've shipped a fix. Captu
Public scan report
scanner v0.1.9 · 2026-09-27 · same rubric, same numbers if you re-run it
- Code scan147 source files scanned25/25
- –Live reliabilityno gateway calls yet and no remote to proben/a
- –Tool poisoningtools not inspected (local package is not executed); not countedn/a
- Auth qualitylocal package, no credentials required12/15
- Maintenancelast push 125 days ago8/15
- Maintainer identityregistry namespace matches repository owner; GitHub account older than a year8/10
How Memorydetective compares
Against every graded MCP server, from our own scans and uptime checks. Updated after each scan run.
- Safety score
- 82/100
- higher than 63% of 48,255 servers
- Tools
- 42
- the typical server has 7
- Tools that change things
- 0%
- typical: 0%. Fewer write tools means less an agent can break
- GitHub stars
- 13
- more than 89% of 28,688 servers
- Downloads a week
- 134
- more than 69% of 12,191 servers with a package
What its tools let an agent do: 42 read
Install Memorydetective in Claude Code, Cursor or VS Code
Runs npx -y memorydetective on your machine. Read the scan report first; the gateway never runs local packages.
claude mcp add memorydetective -- npx -y memorydetective
What the publisher says
From the Memorydetective repository's README, as published. We do not edit it. Read it on GitHub
memorydetective
English · Português brasileiro
Diagnose iOS retain cycles and performance regressions from your chat window. No Xcode required.
Highlights
- CLI-driven leak hunting. Read .memgraph files captured by Xcode (or by memorydetective itself on simulators), find ROOT CYCLEs, classify them against known SwiftUI/Combine patterns, and get a one-liner fix hint. All from a script or a chat.
- MCP-native. Plugs into Claude Code, Claude Desktop, Cursor, Cline, and any other MCP client. The agent drives the full investigate → classify → suggest-fix loop without you opening Instruments.
- Honest about its limits. No mocked outputs, no over-promises. Hangs analysis works clean from xctrace; sample-level Time Profile is parsed when xctrace symbolicates the trace and returns a structured workaround notice when it can't (the underlying xctrace SIGSEGV on heavy unsymbolicated traces is an Apple-side limitation we surface explicitly). Memory Graph capture works on Mac apps and iOS simulator; physical iOS devices still need Xcode.
Shortened. The full README is on GitHub.
Nothing above is checked by us. What we check is on the safety report.
Memorydetective: common questions
- Is Memorydetective MCP server safe?
- Mostly: it is graded B (82/100). Read the Memorydetective safety report
- How do I install Memorydetective?
- It runs on your machine. Copy the Claude Code, Cursor, VS Code or Claude Desktop config from the install section.
- Does Memorydetective need an API key?
- Not as far as the registry entry and our scan can tell: no credentials are declared or required.
- Is Memorydetective maintained?
- The last commit was 163 days ago (2026-05-25). The latest release is v1.18.1.
- How does Memorydetective compare with other MCP servers?
- safety score 82/100 (higher than 63% of 48,255 servers); tools 42 (the typical server has 7); tools that change things 0% (typical: 0%. Fewer write tools means less an agent can break). Full comparison.