MCP server for iOS memory leak detection via heap snapshots and Apple's leaks tool
Four well-defined tools with complete input schemas, clear descriptions (avg 180 chars), and proper tool annotations. Naming follows verb_noun pattern (deinitive_snapshot, deinitive_diff, deinitive_current, deinitive_leaks). All parameters have type definitions and descriptions. Tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) are present and accurate. Output schemas are not explicitly documented in the source, which is the primary gap. Error handling is basic (toolError helper exists but recovery guidance is minimal). No parameter validation rules or constraints documented (e.g., 'top' accepts 0 for unlimited but this is buried in description, not formalized as a constraint).
Capture the current heap and return the top allocators without persisting. Framework warmup classes are filtered by default; pass all=true to see everything. Default cap is 20 rows; pass top to override.
Compute the per-class delta between two saved snapshots. Positive deltas after a navigation round-trip are leak suspects. Framework warmup classes (Auto Layout solver, glyph caches, runtime metadata, etc.) are filtered out by default; pass all=true to see everything. Returns up to top rows; pass top=0 for unlimited.
Run Apple's `leaks` tool against the running simulator app and return its raw output. Reports definitively-orphaned allocations (a strict subset of deinitive_diff's signal).
Capture the iOS simulator app's heap and persist it under a tag. Pair with deinitive_diff to find round-trip leaks.
Output schemas not documented. LLMs cannot plan downstream calls or extract fields without knowing what each tool returns. deinitive_diff returns per-class deltas but structure is not specified; deinitive_current returns 'top allocators' but field names and types are absent.
Parameter constraints not formalized. 'top' parameter accepts 0 for unlimited, but this is only mentioned in description text, not as a JSON Schema constraint (minimum: 0, or enum). LLMs may pass negative or absurdly large values.
Error recovery guidance is minimal. toolError() returns a dict with 'error' key, but does not guide the LLM on next steps. E.g., if bundle is not found, should the LLM retry with a different bundle, or ask the user? No actionable error messages.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | <=2025-11-25 | v2 |
No batch or pagination support. If an agent needs to compare many snapshots or retrieve large heap dumps, tools do not offer pagination or batch operations. deinitive_diff returns 'top rows' but no cursor or offset for iterating beyond the limit.
deinitive_snapshot description mentions 'round-trip leaks' but does not explain what a round-trip is or when to pair it with deinitive_diff. Dependency hints are missing.