MemLab MCP Server

Explore JavaScript heap snapshots to find memory leaks with Meta's MemLab analysis engine

Official · Meta TypeScript Local · stdio Developer tools

71 popularity score ★ 5.1k ↓ 3.3k/wk

Connect your client

Local (npm)

Add in one click

Opens the app, which asks before it adds the server.

Or add it by command or config

Claude CodeTerminal
claude mcp add memlab -- npx -y -p @memlab/mcp-server memlab-mcp
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "memlab": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "@memlab/mcp-server",
        "memlab-mcp"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "memlab": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "@memlab/mcp-server",
        "memlab-mcp"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "memlab": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "@memlab/mcp-server",
        "memlab-mcp"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.memlab]
command = "npx"
args = ["-y", "-p", "@memlab/mcp-server", "memlab-mcp"]
Gemini CLITerminal
gemini mcp add --scope user memlab npx -- -y -p @memlab/mcp-server memlab-mcp
Local (from source)

Add in one click

Opens the app, which asks before it adds the server. Then replace each <NAME> in its settings with your value.

Or add it by command or config

FirstTerminal
git clone https://github.com/meta/memlab.git
cd memlab
npm install
npm run build
Claude CodeTerminal
claude mcp add memlab -- node --max-old-space-size=8192 '<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js'
Claude Desktopclaude_desktop_config.json
{
  "mcpServers": {
    "memlab": {
      "command": "node",
      "args": [
        "--max-old-space-size=8192",
        "<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js"
      ]
    }
  }
}
Cursor~/.cursor/mcp.json
{
  "mcpServers": {
    "memlab": {
      "command": "node",
      "args": [
        "--max-old-space-size=8192",
        "<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js"
      ]
    }
  }
}
VS Code.vscode/mcp.json
{
  "servers": {
    "memlab": {
      "type": "stdio",
      "command": "node",
      "args": [
        "--max-old-space-size=8192",
        "<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js"
      ]
    }
  }
}
Codex~/.codex/config.toml
[mcp_servers.memlab]
command = "node"
args = ["--max-old-space-size=8192", "<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js"]
Gemini CLITerminal
gemini mcp add --scope user memlab node -- --max-old-space-size=8192 '<ABSOLUTE_PATH_TO_CLONE>/packages/mcp-server/dist/index.js'

Settings 5

NODE_OPTIONS Optional: Set --max-old-space-size=8192 or higher here so large snapshots load when it runs as memlab-mcp.
MEMLAB_DISABLE_CODE_TOOLS Optional: 1 removes every tool that runs caller-supplied JavaScript for the whole session.
MEMLAB_TOOLSETS Optional: Comma-separated tool groups to expose, such as core or growth. Unset exposes all. Default all.
MEMLAB_ANALYSIS_TIMEOUT_MS Optional: Wall-clock budget per tool call in ms. 0 or less turns it off. Default 90000.
MEMLAB_REPEAT_NOTES Optional: 1 prints the standing notes on every call instead of once.

What it does

This is the MCP side of MemLab, the JavaScript memory toolkit from Meta. Point it at a .heapsnapshot file saved from Chrome DevTools or from Node.js and it parses the file, works out the dominator tree and retained sizes, then keeps the whole graph in memory. After that an assistant can keep asking questions about the same capture without paying for the parse again, which matters because a big load can take minutes.

The everyday tools do what you would otherwise click through in DevTools: class histograms, the largest retainers, retainer paths back to a GC root, detached DOM, duplicated strings, closures and globals. Most of the package goes further than that. A whole group of tools works on a ladder, meaning a series of snapshots taken while one interaction repeats. They fit the growth per cycle and try to tell a real leak from a working set that levels off. Others check that a fix worked, or separate memory held by dev tooling from what production would keep.

The package in version 2.313.0 registers 160 tools. That count comes from the index that the memlab_tools call prints, and the README only says about 150. Because that many tools crowd a client, MEMLAB_TOOLSETS can limit the server to named groups such as core or growth, and more groups can be switched on mid-session. memlab_capture can now take fresh snapshots of a live page and its workers from a Chrome you started with remote debugging on.

Thirteen tools run JavaScript supplied by the caller or read from a run directory, memlab_eval and memlab_for_each among them, and the makers warn that this code has the full rights of the server process.

What it needs

RuntimeNode.js 18+
Runs onmacOS, Windows, Linux
Also
  • Several GB of free RAM for large snapshots
  • gzip on PATH to open .gz snapshots
  • Chrome started with --remote-debugging-port for memlab_capture

Node.js 18 or later. Give the server a large heap: NODE_OPTIONS=--max-old-space-size=8192 or more when it runs as memlab-mcp or from dist/index.js. When started by the memlab plugin or memlab-cli, set MEMLAB_MAX_OLD_SPACE_MB instead, since those pass their own flag. Claude Code users can install it as a plugin with claude plugin marketplace add meta/memlab and then claude plugin install memlab@memlab. Codex users run codex plugin marketplace add meta/memlab and then codex plugin add memlab@memlab. Gzipped snapshots are unpacked with the gzip program.

Limits

  • Size cap Loads are refused above max_file_size_mb, which defaults to about 0.25 times the heap limit in MB, never under 900 MB for a local file
  • Size cap Loads are also refused when node or edge counts pass a ceiling scaled from the heap limit, unless force is set
  • Limit Every snapshot kept with keep_previous holds its full graph in memory, and the oldest is evicted when a new load does not fit
  • Limit A light load skips retained sizes, so tools that need dominators or retainer paths cannot answer on it
  • Not covered manifold:// paths and bare snapshot names fetch from Meta's internal storage with a manifold command that outside users will not have
  • Limit Each tool call stops after 90 seconds by default, set with timeout_ms or MEMLAB_ANALYSIS_TIMEOUT_MS, but the dominator pass inside a load cannot be stopped
  • Not covered memlab_capture only attaches to a Chrome you started with a remote debugging port, it does not launch a browser

Snapshot loads are refused above max_file_size_mb (900 MB by default); around 850 MB is the largest size the docs report as reliable at an 8 GB heap limit, and larger captures need both limits raised. Every resident snapshot adds its full graph to memory. A light load skips retained sizes, so tools that need dominators or retainer paths return an error on it. The manifold:// paths and bare snapshot names fetch from Meta's internal Manifold storage through a manifold command, which outside users will not have. It analyses saved snapshots only; it does not drive a browser or capture snapshots itself.

Who it suits

Suits JavaScript and Node.js developers chasing a leak or heap bloat who can take heap snapshots and want an assistant to walk retainer paths, histograms and growth across a series of captures. It runs locally, needs no account and comes from the MemLab team at Meta. Expect to give it several GB of RAM for big captures. If you want only read-only tools, start it with MEMLAB_DISABLE_CODE_TOOLS=1 and keep the file-writing tools on manual approval, or pick a server without code execution.

Tools 60 of 160

42 only read, 6 change things, 12 can delete or overwrite. A ? marks an optional parameter.

memlab_tools
Index of every tool grouped by the question it answers, and turns more toolsets on
memlab_load_snapshot
Parse a snapshot and keep its graph resident, refusing loads that would run out of memoryfile_path: stringalias?: stringkeep_previous?: booleanrepeat_notes?: booleanquiet?: booleansuppress_suggestions?: booleanmax_file_size_mb?: numbermax_nodes?: numbermax_edges?: numberforce?: booleanforce_reload?: booleanlight?: booleanasync?: boolean
memlab_snapshot_header
Node and edge counts of a file without loading it
memlab_snapshots
List, switch between or unload resident snapshots
memlab_batch deletes
Run several tools in order against one load (can call the code runners too)
memlab_start_job deletes
Run any tool in the background and return a job id
memlab_job_status
Poll a background job and collect its result
memlab_server_status
Process memory, recent loads, evictions and slow tools
memlab_snapshot_summary
Totals and a per-type breakdown of the heap
memlab_quick_diagnosis
Summary, top objects, histogram and duplicated strings in one call
memlab_app_heap
Split the heap into app data, bundle source and V8 internals
memlab_memory_partition
One exclusive table of what uses the memory, by framework family and module
memlab_largest_objects
Objects holding the most retained memory
memlab_get_node
Full details of one heap node by ID
memlab_find_nodes_by_class
Objects with a given constructor name, by retained size
memlab_get_references
What a node points to
memlab_get_referrers
What points to a node
memlab_retainer_trace
Shortest path from a GC root to a node
memlab_dominator_chain
Walk up from a node to the app object that accounts for it
memlab_dominator_subtree
What would be freed if one node were collected
memlab_detached_dom
Detached DOM elements still held in memory
memlab_duplicated_strings
Repeated string values ranked by memory used
memlab_stale_collections
Maps, Sets and Arrays holding detached DOM or unmounted fibers
memlab_global_variables
Non-built-in globals by retained size
memlab_search_nodes
Search nodes by name pattern, type, size and detachment
memlab_query_objects
Combine class, type, property and size filters in one paged query
memlab_retained_by
Bytes kept alive only through closures, detached DOM, the console or handlers
memlab_class_histogram
Count and retained size per constructor
memlab_object_shape
Named properties of an object with their sizes
memlab_closure_inspection
A closure's captured variables and source location
memlab_aggregate
Group nodes by type, name or prefix with retained totals
memlab_cache_inventory
Module-level Maps, Sets and Arrays ranked by what their entries hold
memlab_react_owners
React components that own a set of retained objects
memlab_event_registry
What listeners are registered on which emitters
memlab_field_release_impact
Bytes freed if one property were cleared
memlab_diff_snapshots
Compare class counts between a before and an after snapshot
memlab_sequence_analysis
Classes that grow across three or more ordered snapshots
memlab_ladder changes
Name a series of snapshots once for later trend tools (saves a state file)
memlab_leak_report
Leak triage table across an ordered set of snapshots
memlab_rate_model
Fit a line and a levelling curve to one series to tell a leak from a working set
memlab_verify_fix
Compare growth before and after a change
memlab_dev_artifacts
Memory held only by dev tooling, apart from production memory
memlab_analysis_battery deletes
Run a round's whole analysis and write per-tool reports to disk
memlab_battery_status
Wait on a background battery run and collect its report
memlab_prune_run deletes
Gzip or delete a round's snapshot files (dry run by default)
memlab_capture changes
Snapshot a live Chrome page and its workers into a folder
memlab_realm_summary
Page and worker snapshots side by side per realm
memlab_anonymize_snapshot changes
Write a copy of a snapshot with identifying text replaced
memlab_finding_index changes
Record findings in a file as an investigation goes
memlab_metric changes
Save a named measurement to a file that outlasts the session
memlab_probes changes
Save named sets of probe code for later ladder runs
memlab_reports
Render recorded findings
memlab_eval deletes
Run supplied JavaScript against the loaded heap with full process rights
memlab_eval_across deletes
Run supplied JavaScript across several snapshots
memlab_for_each deletes
Map, filter and reduce over all nodes with supplied code
memlab_hypothesis deletes
Test a supplied predicate against the heap
memlab_ladder_probe deletes
Run one numeric probe across a ladder with a per-cycle rate
memlab_replicate deletes
Check that a result reproduces by rerunning probe code
memlab_judges deletes
Judge a round against its stated invariants
memlab_ab_compare deletes
Compare probe metrics between two phases of a round

Similar servers