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

netops-mcp

v0.1.0

Published

Local-first network diagnostics & tunnel/proxy MCP server. Diagnose connectivity and inspect your WireGuard/proxy setup from your AI assistant — from your own machine, not a remote probe.

Readme

What is this?

You ask your AI assistant "why can't I reach this site?" — and normally it just runs ping/dig/curl and dumps the raw output back at you. You're left to interpret it yourself.

netops-mcp gives your assistant a verdict instead of a data dump. Not "here's what ping said" — but "it's your side: line 2 of your /etc/hosts is pinning the site to a dead address."

The catch: it runs on your machine, so it sees what no cloud service can — your home network, your VPN, your local config.

            "Why can't I reach api.example.com?"
                          │
                          ▼
        ┌─────────────────────────────────────┐
        │  netops-mcp  (runs on YOUR machine) │
        │                                     │
        │   DNS → ping → TCP → TLS → HTTP     │  ← checks every layer
        │   + asks Globalping: up elsewhere?  │  ← "is it me or them?"
        │   + reads your /etc/hosts           │  ← the thing no remote probe sees
        └─────────────────────────────────────┘
                          │
                          ▼
   "It's YOUR side. /etc/hosts:2 pins it to a stale 10.0.0.5.
    The site is live from the US, EU & Asia — remove that line."

In short: a translator between "the network is broken" and "here's the exact cause."

Why it's different

  • Local-first — it sees what cloud tools can't. Probes run from your host, so it sees your homelab, your VPN, your /etc/hosts, your resolvers. A stale /etc/hosts pin breaks a site for you while it works for everyone else — and a SaaS probing from its own data center is structurally blind to it. netops-mcp catches it.
  • Verdicts, not data. Instead of dumping raw output, net_diagnose and net_triangulate reason across DNS / TCP / TLS / HTTP and your local config and tell you which side the fault is on — yours or theirs. One answer, not a wall of text to re-read.
  • Safe by default. Read-only. No shell (every system call is execFile with an argv array, never a string). Anti-scan caps, allow/deny lists, audit log to stderr, zero telemetry. The WireGuard write ops are behind a flag and dry-run unless you explicitly confirm. See SECURITY.md.
  • Few moving parts. DNS, TCP, TLS and HTTP probing are pure Node — no dig, curl, or openssl shelled out — so it works even in slim containers or locked-down images where those aren't installed. ping / traceroute / wg are used when present and skipped gracefully when not.

What you actually get back

The verdicts below are the real strings the tools emit — not marketing paraphrase.

net_triangulate — is it me or them?

YOUR SIDE: api.example.com is down for you but reachable from 4/4 global probes.
The target is up — problem is your machine, network, DNS, or ISP routing.
THEIR SIDE: api.example.com is unreachable from you AND from all 4 global probes.
The target is down.

config_correlate — the stale-pin catch no remote probe can make:

/etc/hosts:2 pins api.example.com -> 10.0.0.5; this OVERRIDES DNS (DNS itself
returns nothing). If api.example.com seems stuck on an old address, this line is why.

net_diagnose — one-shot, short-circuits at the first failing layer:

DNS resolves (93.184.216.34) but TCP/443 is closed/filtered. Firewall, the service
is down, or wrong port. ICMP also fails.

Tools (v0.1)

Diagnose & orchestrate

| Tool | What | |---|---| | net_diagnose | One-shot "why can't I reach X" — DNS→ping→TCP→TLS→HTTP, stops at the first failure, returns a verdict | | net_triangulate | Is it me or them? Local probe vs Globalping worldwide probes | | diagnosis_bundle | Full probe battery → shareable Markdown report for bug tickets | | config_correlate | Cross-check /etc/hosts against live DNS — surfaces stale/overriding pins | | net_overview | Interfaces + resolvers + WireGuard snapshot |

Single probes

| Tool | What | |---|---| | dns_lookup | A/AAAA/MX/TXT/NS/CNAME, custom resolver | | net_ping | ICMP with TCP-ping fallback (no root needed) | | tcp_port_check | Connectivity check of named ports (capped — not a scan) | | tls_inspect | Cert chain, expiry, SANs, protocol/cipher, handshake timing | | http_probe | Status, redirects, DNS/connect/TLS/TTFB timing breakdown | | traceroute | Hop-by-hop path to a host with per-hop latency | | mtu_blackhole | Path-MTU discovery; catches MTU black holes (VPN "connects then hangs") | | cert_sweep | TLS expiry across many domains — auto-extracts them from nginx/Caddy/Traefik/compose |

Tunnel & proxy

| Tool | What | |---|---| | tunnel_diff | Direct vs interface/tunnel egress identity & reachability — split-tunnel leak detection | | dns_leak_check | Egress IP + which resolvers you actually use (leak heuristics) |

WireGuard

| Tool | What | Gated? | |---|---|---| | wg_status | Interfaces/peers, stale-handshake flags | read-only | | wg_config_generate | Fresh keypair + ready-to-paste client config | read-only | | wg_peer_add | Add/update a peer | --enable-write, dry-run unless confirm:true | | wg_peer_remove | Remove a peer | --enable-write, dry-run unless confirm:true |

Install

npx netops-mcp

Claude Desktop / Claude Code / Cursor — mcp.json

{
  "mcpServers": {
    "netops": {
      "command": "npx",
      "args": ["-y", "netops-mcp"]
    }
  }
}

Privacy-strict (no third-party calls at all — disables Globalping and the egress-IP echo):

{
  "mcpServers": {
    "netops": {
      "command": "npx",
      "args": ["-y", "netops-mcp", "--local-only"]
    }
  }
}

Reference & advanced

Flags & env

| Flag / Env | Effect | |---|---| | --local-only / NETOPS_LOCAL_ONLY=1 | Disable all outbound third-party calls (Globalping, egress echo) | | --enable-write / NETOPS_ENABLE_WRITE=1 | Allow mutating WireGuard ops (wg_peer_add/remove); still dry-run unless confirm:true | | --no-audit | Silence the stderr audit log | | NETOPS_ALLOW | Comma/space list of allowed targets (host or CIDR) — strict mode | | NETOPS_DENY | Denylist of targets | | NETOPS_MAX_PORTS | Cap for tcp_port_check (default 20) | | NETOPS_HOSTS_FILE | Override the hosts-file path (used by config_correlate) |

Requirements & platform support

  • Node ≥ 20. No other hard dependency — DNS/TCP/TLS/HTTP probes are pure Node.
  • Optional system binaries, used when on PATH, gracefully skipped otherwise:
    • pingnet_ping falls back to a TCP connect if it's missing; mtu_blackhole needs it.
    • traceroute (tracert on Windows) — for traceroute.
    • wg (wireguard-tools) — for the WireGuard tools.

| Platform | Status | |---|---| | Linux | First-class. All tools work given the optional binaries. | | macOS | Works. Caveat: macOS doesn't use /etc/resolv.conf, so resolver lists in config_correlate / dns_leak_check may come back empty. | | Windows | Partial. Pure-Node probes (DNS/TCP/TLS/HTTP) work; wg show dump and some binary-output parsers are Linux/macOS-oriented. |

Applying WireGuard changes (wg set) needs root / CAP_NET_ADMIN — the server never auto-escalates; it surfaces the error if it lacks privilege.

The shareable report

diagnosis_bundle renders a full probe battery as paste-ready Markdown — drop it straight into a bug ticket or a Slack thread:

# netops-mcp diagnosis — `api.example.com`
_2026-06-13T10:04:11Z_

**Verdict:** Reaches the host but TLS chain is invalid — their side.

## DNS
- A: 93.184.216.34 (12ms)
## Reachability
- ping: reachable via tcp 18ms
- TCP/443: open (21ms)
## TLS
- TLSv1.3 TLS_AES_256_GCM_SHA384, handshake 41ms
- cert: 3d left (2026-06-16), valid chain
## From the world (Globalping)
- Amsterdam: ✓ loss 0% avg 12ms
- New York: ✓ loss 0% avg 81ms
## Local context
- resolvers: 1.1.1.1, 8.8.8.8
- egress IP: 203.0.113.7

cert_sweep: point it at your reverse proxy

Instead of listing domains by hand, give cert_sweep a config path and it extracts the hostnames itself — from nginx server_name, Traefik Host(`…`) labels, Caddy site blocks, and compose files — then reports expiry soonest-first:

cert_sweep  config_path: /etc/nginx/sites-enabled/

⚠ shop.example.com   — expires in 6d  (2026-06-19)
✓ api.example.com    — 71d left
✓ www.example.com    — 71d left
Checked 3 domains — 1 needs attention (≤21d or expired), 0 unreachable.

Develop

npm install
npm run build
npm run smoke      # boots the server, asserts the 19-tool handshake
node dist/index.js # or: npm run dev

Demo

The animation is a real recording of the server: vhs demo/demo.tape drives demo/cli.mjs, where config_correlate is a genuine call against demo/hosts.fixture. The two probe lines above it (net_diagnose, net_triangulate) show what an agent would run; the stale-pin catch is the live call. The regenerate demo gif GitHub Action re-renders assets/cli.gif from the tape.

Roadmap (v0.2+)

dns_diagnose (deep), mtr-style continuous path stats, HTTP/SSE transport, an opt-in --enable-scan nmap mode behind an allowlist.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md. Found a security issue? Please open a private advisory rather than a public issue (details in SECURITY.md).

License

MIT