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

@suss/mcp

v0.38.2

Published

An MCP server over suss, so a coding agent can ask what an endpoint does and who calls it while it works.

Readme

@suss/mcp

Part of suss, which reads both sides of every call in a repository and says where the two disagree.

An MCP server over suss. A coding agent can ask what a route serves, what reads a table, and where two sides of a boundary disagree, at the moment it needs to know.

The server keeps its summaries current while it runs, so an answer describes the working tree as it is now. It does not depend on when somebody last ran an extract.

Run it

npx @suss/mcp /path/to/project

With no path it reads the working directory. The project needs a suss.json, which suss init writes. Without one the server starts, prints a warning on stderr, and every answer comes back empty.

In a host that reads a config file:

{
  "mcpServers": {
    "suss": {
      "command": "npx",
      "args": ["-y", "@suss/mcp", "/path/to/project"]
    }
  }
}

The tools

| Tool | What to use it for | |---|---| | suss_ask | One question about one boundary. The question forms are in the tool description. | | suss_check | Compare both sides of every boundary and report where they disagree. Takes a boundary to narrow to, or a git base such as origin/main to keep the findings the change since that branch introduced. | | suss_boundaries | The boundaries, split into the ones with both sides and the ones with only one. | | suss_stub_draft | A draft stub for a package suss cannot read into, built from how this project calls it. | | suss_intent_outcomes | Every outcome the boundary intent documents declare, as the link a PRD scenario writes. | | suss_status | Which commands ran, which failed, and whether the project has a suss.json. |

Every tool only reads. None of them change a file, and each is marked read-only, so a host never has to ask a person before calling one.

Each answer is trimmed to leave the model room to act on it. On a repository of any size, suss_check produces hundreds of findings. It shows the first twenty, counts every kind in findingCounts, and tells the model to ask again about one boundary for the rest. When two summaries files both provide one boundary, it lists them under collisions, as suss check does. suss_boundaries does the same trimming with its three lists and keeps the totals in counts.

Reach for suss_ask first. Ask about a table before changing it, and ask what calls a function before changing its signature. When it cannot answer, needs lists the input that would let it, and that is usually the thing to act on.

The cache and the socket record go under .suss in the project. Pass --cache-dir <path> after the project, or set SUSS_CACHE_DIR, to put them elsewhere, for a checkout you cannot write to.

Staying current

The server connects to its host first and reads suss.json in the background, so a host with a short connect timeout never waits on a cold extract. A tool call that arrives before that first build finishes waits for the build instead of answering from nothing. suss_status does not wait, and reports that a build is in progress.

Once the first build finishes, the server keeps the summaries in its own directory and watches the tree. When a source file changes, it waits until writes have stopped for 400ms, then re-runs the extract and contract commands listed in suss.json.

The server keeps each command's adapter between builds. A TypeScript build after an edit parses only the files whose text changed and keeps the compiler's program, and a Python or Ruby build keeps every unchanged file's tree. The disk cache that suss extract keeps per file then decides which summaries to rebuild. After a build served whole from that cache, the server loads the program anyway, so the first edit does not pay for it.

A large TypeScript program takes gigabytes: the server raises its own heap the way the CLI does, and lets the programs go after 30 minutes with no build. The next build costs what a CLI run with a warm cache costs.

The plugin's socket

The supervisor plugin's hooks run extract --out-dir and check --since --json after every edit. The first server started for a repository listens on a local socket and writes its path to .suss/live/server.json, and the hooks send those commands there and get back what the CLI would have printed. A server started later for the same repository has the first one build for it and keeps no program of its own. When no server is up, or it does not serve a command, the hooks run the CLI.

Writes under node_modules, dist, .git, coverage, .next, .turbo, build, and .suss are ignored. A watcher that rebuilt on those would never stop rebuilding, since a build writes its own cache under .suss.

Mounting it yourself

createServer builds the server without connecting it, so a host can put it on its own transport:

import { createServer } from "@suss/mcp";

const { server, project } = createServer({ root: "/path/to/project" });
await server.connect(myTransport);

createServer does not wait on the first build, so you can connect right away. Await project.settled() first if a caller needs the build finished before doing anything else.

Pass watch: false to extract once and stop there. Pass summaryDir to put the summaries in a directory you choose instead of a temporary one. close() leaves that directory alone, because the server only removes a directory it created. Pass live: true to listen on the plugin's socket, which the suss-mcp executable does.