npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@qe-mcp/server-ena

v0.1.8

Published

MCP server for Epistemic Network Analysis — WASM backend, zero Python dependency

Readme

@qe-mcp/server-ena

MCP server for Epistemic Network Analysis (ENA), powered by a WebAssembly backend. Zero Python dependency — runs entirely in Node.js.

Designed for use with Claude Desktop and Claude Code.


What it does

Gives Claude a set of ENA tools that run locally on your machine. The WASM model computation never leaves your computer. Only results (node positions, plots, summary statistics) are returned to Claude.

| Tool | Description | |---|---| | ena_profile | Privacy-safe column metadata — no raw data transmitted | | ena_inspect | Triage a dataset: is ENA appropriate? Returns suggested parameters | | ena_fit | Full ENA pipeline → model + inline PNG plot | | ena_compare_groups | Mean-rotation group comparison → model + inline PNG plot | | ena_plot | Any view from a cached model (all / group / unit / comparison / subtraction) | | ena_accumulate | Accumulation step only, no rotation or projection |


Prerequisites

  • Node.js 18 or later
  • Claude Desktop or Claude Code

Installation

Recommended — one-click desktop extension (.mcpb)

The easiest install, no terminal or config files. Download server-ena.mcpb from the releases, then in Claude Desktop go to Settings → Extensions and drag the file in (or double-click it). Click Install and restart. Node.js ships inside Claude Desktop, so nothing else is required.

The bundle is pure JS/WASM and cross-platform. It produces SVG (svg_plot) and interactive HTML (interactive_plot) plots; inline PNG rendering is omitted from the bundle (it requires a native module) — open the SVG or HTML to view the network.

To build the bundle yourself: bash scripts/build-mcpb.shdist/server-ena.mcpb.


The package is also published to the public npm registry — no registry configuration needed.

Option A — npx (no install needed)

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (Mac):

{
  "mcpServers": {
    "ena": {
      "command": "npx",
      "args": ["--yes", "@qe-mcp/server-ena"]
    }
  }
}

Restart Claude Desktop.

Option B — global install

npm install -g @qe-mcp/server-ena

Then in claude_desktop_config.json:

{
  "mcpServers": {
    "ena": {
      "command": "server-ena"
    }
  }
}

Option C — local clone (development)

git clone <repo-url> server-ena
cd server-ena
npm install
{
  "mcpServers": {
    "ena": {
      "command": "node",
      "args": ["/absolute/path/to/server-ena/server.js"]
    }
  }
}

Dev builds

Pre-release builds are published only to the QE GitLab registry with a dev tag. To use one, add the scope mapping once and pin @dev:

echo "@qe-mcp:registry=https://gitlab.com/api/v4/projects/22522458/packages/npm/" >> ~/.npmrc
echo "@qe-libs:registry=https://gitlab.com/api/v4/projects/22522458/packages/npm/" >> ~/.npmrc
npx --yes @qe-mcp/server-ena@dev

Verify

In Claude Desktop, open a new conversation and ask:

"What ENA tools do you have available?"

Claude should list ena_profile, ena_inspect, ena_fit, ena_compare_groups, ena_plot, and ena_accumulate.


Skill (claude.ai / Claude Desktop / Claude Science)

The skill/ena-analysis/ folder contains a companion skill that teaches Claude the full ENA workflow — privacy gate, triage, fitting, and plot exploration — so it drives the connector correctly without per-conversation prompting.

To install:

cd skill && zip -r ena-analysis.zip ena-analysis

Then upload ena-analysis.zip under Settings → Customize → Skills (claude.ai / Claude Desktop) or Customize → Skills (Claude Science).


Privacy model

The WASM computation always runs locally. What reaches Claude depends on how you provide data:

| Method | What Claude sees | |---|---| | data_path (file path) | Nothing from the file — only model results (node positions, unit labels, plots) | | data_csv (inline CSV) | The full raw CSV, as a tool call argument |

For research data, always use data_path. Use data_csv only for small toy or demo datasets.

Unit labels (the values in your unit column, e.g. participant IDs) are included in model results regardless of input method. If those are sensitive, be aware they will appear in the conversation.

Privacy gate hook

To technically enforce the data_path preference and block large inline CSVs, install the privacy gate hook. This intercepts tool calls before they execute and rejects any data_csv payload with more than 50 rows.

Step 1 — Copy the hook script:

mkdir -p ~/.claude/hooks
cp hooks/ena-privacy-gate.mjs ~/.claude/hooks/

Step 2 — Add to ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "mcp__(ena-wasm|ena|enajs)__(ena_inspect|ena_fit|ena_accumulate|ena_compare_groups)",
        "hooks": [
          {
            "type": "command",
            "command": "node /Users/YOUR_USERNAME/.claude/hooks/ena-privacy-gate.mjs"
          }
        ]
      }
    ]
  }
}

Replace YOUR_USERNAME with your macOS username. If you already have a hooks block in settings.json, add the new entry to the existing PreToolUse array.

The hook takes effect immediately — no restart needed.

Threshold: ≤ 50 rows of data_csv are allowed (toy/demo use). Larger payloads are blocked with a message instructing Claude to ask for a file path instead.


Usage

Basic analysis

"Analyze /path/to/data.csv"

Claude will call ena_inspect first, confirm ENA is appropriate, then call ena_fit and return a network plot.

Sensitive data

"I have sensitive data at /path/to/data.csv — what can you tell me about its structure?"

Claude will call ena_profile (column metadata only, no raw data transmitted), identify appropriate parameters, then run the model with data_path.

Group comparison

"Compare First vs Second half using data at /path/to/data.csv, unit column UserName, conversation column GameHalf"

Claude will call ena_compare_groups and return a comparison plot. Follow up with:

"Show me the subtraction network"
"Show me the First half mean network"
"Show me unit steven_z"

These use ena_plot with the cached model_id — no refitting.


Output

Each fitting or plotting call returns:

  • svg_plot — path to the rendered SVG (vector; embeddable). Always produced.
  • interactive_plot — path to a self-contained HTML file with the interactive qeviz visualization, openable in any browser. Always produced.
  • png_plot — path to the rendered PNG (static raster). Only when the optional PNG rasterizer is installed.
  • Inline PNG — an image content block rendered directly in clients that support it (Claude Desktop, Claude web). Only when the optional PNG rasterizer is installed.

The file-path outputs let clients that don't render inline image blocks (Claude Code, Claude Science) still open or embed the real ENA network plot. All files are written to the OS temp dir under ena-viz/ and persist until the next system restart.

Optional PNG rendering

PNG output (png_plot and the inline image block) is powered by @resvg/resvg-js, a native module listed under optionalDependencies. It is installed automatically by npm install on supported platforms. When it is absent — e.g. a cross-platform bundle built without optional dependencies — the server logs a notice and produces svg_plot + interactive_plot only; no error, no crash.


Testing

node test-mcp.mjs \
  /path/to/data.csv \
  UnitColumn ConversationColumn \
  Code1 Code2 Code3 Code4

This drives the server over stdin/stdout (same transport Claude uses) and saves all PNG outputs to /tmp/ena-test-N.png.

To test group comparison, edit test-mcp.mjs and set GROUP_COL, GROUP1, GROUP2 at the top of the file.