{"name":"io.github.carloshpdoc/memorydetective","slug":"carloshpdoc-memorydetective","title":null,"description":"iOS leak/perf debugging via MCP: memgraph cycles, .trace analysis, SourceKit-LSP bridging.","url":"https://mcp.market/server/carloshpdoc-memorydetective","rating":null,"grade":"B","score":82,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":28,"stars":13,"forks":0,"downloads_week":134,"last_push_at":"2026-05-25T18:53:35.000Z","license":"Apache-2.0"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/carloshpdoc/memorydetective","website":null,"version":"1.18.1","remotes":[],"packages":[{"registryType":"npm","identifier":"memorydetective","version":"1.18.1","transport":{"type":"stdio"}}],"tools":[{"name":"analyzeAbandonedMemory","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeAllocations","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeAnimationHitches","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeAppLaunch","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeEnergyImpact","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeHangs","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeLeakTimeline","description":"[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+.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeMemgraph","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeMemoryFootprint","description":"[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+.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeMetricKitPayload","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeNetworkActivity","description":"[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+.","write_action":false,"price_micros":0,"input_schema":null},{"name":"analyzeTimeProfile","description":"[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).","write_action":false,"price_micros":0,"input_schema":null},{"name":"bootAndLaunchForLeakInvestigation","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"captureMemgraph","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"captureScenarioState","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"classifyCycle","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"cleanupTraces","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"compareTracesByPattern","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"countAlive","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"detectLeaksInXCTest","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"detectLeaksInXCUITest","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"diffMemgraphs","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"findCycles","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"findRetainers","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"getInvestigationPlaybook","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"inspectTrace","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"listTraceDevices","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"listTraceTemplates","description":"[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\").","write_action":false,"price_micros":0,"input_schema":null},{"name":"logShow","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"logStream","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"reachableFromCycle","description":"[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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"recordTimeProfile","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"recordViaInstrumentsApp","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"renderCycleGraph","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"replayScenario","description":"[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 ","write_action":false,"price_micros":0,"input_schema":null},{"name":"summarizeTrace","description":"","write_action":false,"price_micros":0,"input_schema":null},{"name":"swiftFindSymbolReferences","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"swiftGetHoverInfo","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"swiftGetSymbolDefinition","description":"[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","write_action":false,"price_micros":0,"input_schema":null},{"name":"swiftGetSymbolsOverview","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"swiftSearchPattern","description":"[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.","write_action":false,"price_micros":0,"input_schema":null},{"name":"verifyFix","description":"[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","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":82,"grade":"B","scanned_at":"2026-09-27T21:28:07.013Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-27T21:28:07.011Z","components":{"code":{"score":25,"max":25,"notes":["147 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":12,"max":15,"notes":["local package, no credentials required"]},"maintenance":{"score":8,"max":15,"notes":["last push 125 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"memorydetective","version":"1.18.1","found":true,"license":"Apache-2.0","hasInstallScripts":false,"dependencyCount":5,"publishedAt":"2026-05-18T01:59:03.468Z","repositoryUrl":"git+https://github.com/carloshpdoc/memorydetective.git","weeklyDownloads":134}],"repo":{"found":true,"owner":"carloshpdoc","repo":"memorydetective","archived":false,"pushedAt":"2026-05-25T18:53:35Z","stars":13,"forks":0,"openIssues":1,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/1216101?v=4","ownerCreatedAt":"2011-11-23T16:49:00Z","license":"Apache-2.0"},"icon":{"url":"https://avatars.githubusercontent.com/u/1216101?v=4&s=128","source":"github"},"presence":{"stars":13,"forks":0,"downloadsWeek":134,"license":"Apache-2.0","lastPushAt":"2026-05-25T18:53:35.000Z","score":28}}}},"grade_history":[],"reviews":[]}