npm: neurarch-mcp · MIT · runs offline, no API key

Give your coding agent structural awareness of your PyTorch model

Your coding agent reads your model as text and guesses at shapes, parameter counts and what an edit breaks. neurarch-mcp hands it the structured graph instead: an MCP server for Claude Code, Cursor, Claude Desktop, VS Code and Windsurf that reads a .py file straight from source.

$claude mcp add neurarch -- npx -y neurarch-mcp /abs/path/to/model.py
npm GitHub Add to Cursor Install in VS Code

Node.js 20 or newer. No install step: every client launches the server through npx. The Cursor and VS Code buttons register it against ./model.py in your project; rename the path afterwards.

What it looks like

Numbers from the tools, not from the model

A real exchange against the bundled examples/tiny-gpt.neurarch.json. Every figure below came out of a tool call.

You

Where does the parameter budget live, and is it safe to drop block_1?

Claude
calls describe_architecture
tiny-gpt: 8 layers, depth 7, 57.8M params, 8.27 GMACs. Heaviest by params: token_embedding (25.7M, 44%), lm_head (25.7M), block_0/1 (3.1M each). Heaviest by compute: lm_head, then the two decoder blocks. Validation: clean.
calls layer_impact { names: ["block_1"] }
Downstream of block_1: final_norm and lm_head (shape-sensitive, weight-carrying), then output.

The budget is dominated by the embedding + LM head (~89%), not the decoder blocks, so dropping block_1 frees only ~3.1M params (~5%) while removing one of just two decoder layers. It is structurally safe (final_norm just re-reads block_0's output), but it is the wrong lever if your goal is shrinking the model: quantizing the embedding and head would do far more.

Inputs

Three ways in, and a fourth from the Hub

Point it at what you already have. What the agent can answer depends on what the file carries.

static parse

model.py

The same PyTorch parser the app uses reads your nn.Module source. Layers, types, hyperparameters and wiring come out exact, and so do parameter counts.

Tensor shapes stay unknown, because source never says what goes in: FLOPs and shape contracts report as unknown rather than as zero. --write is refused on a .py.

everything

model.neurarch.json

Saved from the Neurarch app with File → Save. Carries shapes, groups, hyperparameters and design notes, so every tool has everything.

Add --watch so the agent sees app-side saves without a restart, and --write if you want it to edit the model (off by default).

runtime trace

neurarch-trace

A pip package that runs one forward pass through your model and records the real shapes at every layer, then writes a graph the server reads directly.

pip install neurarch-trace
neurarch-trace my_pkg.model:build --input 1,3,224,224
opt-in network

--hf Qwen/Qwen2.5-7B

Build the graph from a HuggingFace config.json, at launch with --hf or from the conversation with load_hf_model. Config only, never weights.

This is the one input that opens a socket, and only when you name a Hub id.

Tools

Four tools grade the model. Climb them in order.

Each rung answers something the rung below cannot, and each one costs more. An agent that starts at the top still pays for an answer two thirds of which a cheaper tool had. All four are offline and instant: the verifier is vendored, not called.

validate_modelIs it a well-formed graph at all: cycles, dangling connection refs, duplicate ids and names, orphan layers.
lint_modelThe 41 structural checks with no API key: attention head-dim and GQA divisibility, norm and activation ordering, dropout and feature ranges, missing residuals in deep stacks, the statically decidable shape rules. Same rule set the CI Action reports, so a clean result here is a clean CI run. Returns provenance for every rule that has a published measurement behind it.
check_designThe full verdict: readiness to train, parameter and cost estimates, the best deployment target and its latency, and any decision still left to the human. Five pipeline stages against one graph walk, about 13ms.
rank_designsOrder k candidate designs. Blocked ones go last, ties stay ties (a shared first place reads 1, 1, 3), and the response ships its own calibration numbers so the ordering is never read alone.

Inspection (always available)

ToolWhat it does
describe_architectureOne-call orientation: topo-ordered pipeline, depth, IO shapes, total params and MACs, top-5 param and compute hotspots, validation rollup. Replaces a 4-tool chain.
get_model_summaryOne-shot overview: layer count, total params, dominant types, input and output shape.
layer_impactBlast radius of changing a layer or matched set. Flags shape-sensitive and weight-carrying downstream layers before the agent recommends a destructive edit.
get_layer · compare_layers · find_layersFull definition of one layer; structural diff of two; search by type, name regex, scope or augmentation, optionally ranked by parameter count.
param_count_by_block · flops_by_blockParameters and MACs (FLOPs ÷ 2) grouped by block, scope or type.
list_blocks · get_blockCollapsed groups (or scope-derived blocks): members, totals, and the edges crossing the block boundary.
find_path · list_connectionsShortest directed path between two layers, or null; the flat edge list with from / to filters.
diff_modelsStructural diff against another .neurarch.json: layers added, removed, modified field by field, and connection changes.
mermaid_diagramThe model as Mermaid flowchart TD; groups render as labelled subgraphs.
list_hyperparams · get_design_notesModel-level hyperparameters and the pinned design rationale, optionally filtered by layer.
list_architectures · load_architecture81 verified reference graphs bundled: DeepSeek-V3, Qwen2.5, Llama, Whisper, CLIP and more. List them, load one, and diff or rank your design against it.
load_hf_modelBuild a graph from a HuggingFace config.json. The only tool that opens a socket, and only when you ask it to.

Write (opt in with --write)

ToolWhat it does
add_layer · modify_layerInsert a layer, optionally auto-wired downstream of an existing one; shallow-merge params, rename, or change scope, with a before/after diff.
add_connection · delete_connectionWire two layers (fails on self-loops and duplicate edges); remove a single directed edge.
delete_layerRemove a layer and every connection touching it. Invalidates downstream shapes.
save_modelPersist the in-memory model to disk. Call it after any mutation.

Write tools refuse a model_path: mutations always target the file passed on the command line, so an agent cannot edit, and then save over, a path it invented. Every tool declares what it does to your files, so clients that honour annotations confirm the three that can destroy something instead of prompting on all of them.

Export

export_pytorchEmit runnable PyTorch for the current graph. The same exporter the app uses, so a design the agent edited through --write comes back out as an nn.Module.

Prompts

Three MCP prompts bundle the tool calls a review usually takes: review_design (climb the ladder and report), shrink_for_target (find the parameters that actually move the size and check what each cut breaks), and pre_train_checklist (everything that should be true before a GPU is billed). They show up in your client's prompt picker.

Setup

One command + args shape, five clients

Use an absolute path in any global config: npx does not run from your project directory, so relative paths only work in project-scoped configs.

Claude Code

claude mcp add neurarch -- npx -y neurarch-mcp /abs/path/to/model.py

Or commit a project-scoped .mcp.json at the repo root so every collaborator gets the server automatically:

{
  "mcpServers": {
    "neurarch": {
      "command": "npx",
      "args": ["-y", "neurarch-mcp", "./model.py"]
    }
  }
}
Claude Desktop

Settings → Developer → Edit Config, or edit the file directly: macOS ~/Library/Application Support/Claude/claude_desktop_config.json, Windows %APPDATA%\Claude\claude_desktop_config.json. Fully quit and reopen the app afterwards; the config is read at startup.

{
  "mcpServers": {
    "neurarch": {
      "command": "npx",
      "args": ["-y", "neurarch-mcp", "/abs/path/to/model.py"]
    }
  }
}
Cursor

Create .cursor/mcp.json in your project (or ~/.cursor/mcp.json for all projects), then enable the server under Settings → MCP. Or use the Add to Cursor button above.

{
  "mcpServers": {
    "neurarch": {
      "command": "npx",
      "args": ["-y", "neurarch-mcp", "./model.py"]
    }
  }
}
VS Code (Copilot agent mode)

Create .vscode/mcp.json (note the servers key, not mcpServers), or from a shell: code --add-mcp '{"name":"neurarch","command":"npx","args":["-y","neurarch-mcp","/abs/path/to/model.py"]}'

{
  "servers": {
    "neurarch": {
      "command": "npx",
      "args": ["-y", "neurarch-mcp", "${workspaceFolder}/model.py"]
    }
  }
}
Windsurf, Codex and other clients

Same command + args shape; only the config file location differs. For clients that speak Streamable HTTP instead of stdio, run the server with --http and point the client at it:

{
  "mcpServers": {
    "neurarch": { "type": "http", "url": "http://127.0.0.1:8787/mcp" }
  }
}

It binds to loopback by default. Set NEURARCH_MCP_TOKEN to require a bearer token, which is mandatory before --write may bind to a non-loopback host.

Verify it works: ask the agent "List the Neurarch tools you can see." From a shell, npx -y neurarch-mcp --help prints usage and the full tool list.

Privacy

Network: one switch, off by default

This server opens a socket for exactly one reason, and it does not happen unless you turn it on.

SwitchWhat it sendsWhen
NEURARCH_REPORT=1 An anonymous structure+verdict row: fingerprint, layer-type histogram, edge count, rule-id and severity pairs. Structurally incapable of carrying the graph. Never parameter values, layer names, file paths, or any identity. After each validate_model, lint_model or check_design call, fire and forget, 5-second cap.

With it unset, the server makes no network calls at all, and no tool is an exception to that. Your model graph never leaves the machine. (load_hf_model and --hf fetch a public config.json from the Hub only when you name a model id; nothing of yours goes out.)

Until 0.11.0 there was a second switch: check_design POSTed the graph to /api/v1/check with an API key. It no longer exists, and no key is read anywhere in this package. The verdict is a pure function of the graph, so it is vendored and computed locally. The hosted endpoint still exists for callers who are not running this server. Data policy: neurarch.com/docs/DATA_POLICY.md.