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

@nativesoil/handover-mcp

v0.2.0

Published

A local MCP stdio server exposing soil_save, soil_load and soil_list against the handover store in ~/.soil.

Readme

@nativesoil/handover-mcp

A local MCP server over stdio, so your assistant can save and load a project's state without you copying text around. JSON-RPC 2.0, newline-delimited, no dependencies beyond the SDK.

Wire it up

Claude Code:

claude mcp add soil -- node /absolute/path/to/handover/packages/mcp/bin/soil-mcp.js

Codex CLI:

codex mcp add soil -- node /absolute/path/to/handover/packages/mcp/bin/soil-mcp.js

Cursor (~/.cursor/mcp.json, or .cursor/mcp.json in a project) and anything else that reads a JSON MCP config:

{
  "mcpServers": {
    "soil": {
      "command": "node",
      "args": ["/absolute/path/to/handover/packages/mcp/bin/soil-mcp.js"]
    }
  }
}

The tools

Exactly three, on purpose.

soil_save takes projectId, title, and sections (the 17 keys, each a prose string), plus optional project, sectionStatus, sectionProvenance, soilHandover, quality, safety, source, observations and workingStyle. It stores the handover in ~/.soil and returns the load code with an honest section count, and the receipt carries the grade and finding counts from the open deterministic check of the stored document. The grade informs and never refuses a save, and it is never written onto the handover. A section the model cannot fill honestly should be left out, and the save records it as a gap.

project addresses a project: a shared container of handovers inside the same store, in exactly the layout the self-hostable server serves for a shared project. The reference follows the product's one grammar, @ says where and # says which, so "@acme" and "acme" name the same container. A save never creates a project and a stated reference never falls back to the personal store: an unknown project is refused, and the refusal names soil project add <name>, which is where containers are created. Removal is soil project remove at a terminal too; deletion is a human decision, so these tools deliberately cannot create or remove a project, only save into, load from and list one.

sectionStatus and sectionProvenance are keyed by the same 17 section keys as sections, and they are what lets a model say through the tool interface what the recipe asks it to say: that a section was withheld for safety (blocked), and where each section's claims came from. They are three flat parallel objects rather than one section object per key with a union type, because a union is a loose shape and some clients flatten a loose schema to no parameters at all. Values come from the format's fixed sets: four statuses, eleven provenance labels.

observations attaches evidence beyond the 17 sections. The caller states the kind and the payload, as named text entries; this server stamps producedBy and producedAt, because it is the thing writing the entry and an attribution it cannot check is not one it should repeat. Observations are attached before validation, so the fail-closed secret scan reaches inside them exactly as it reaches a section.

The workingStyle object holds the answers to four fixed questions about how the project actually works: how the last blocker was handled, how conflicting instructions were resolved, how new work was checked before it was trusted, and an assumption the thread made and how it was caught. Each answer is a recorded instance from the thread, a few sentences about one real moment, never an adjective. The answers are stored on the handover as a single working.style observation attributed to this server (see spec/observations.md). All of it is optional and fail-soft: a save without answers is stored exactly as before, an unusable answer is dropped rather than failing the save, and nothing anywhere turns the answers into a score.

soil_load takes an optional code and an optional project, and returns the restore prompt: the durable truth, the state as of the capture, the stated gaps, and how to read them. Defaults to the most recent handover in the addressed store. When the handover carries working.style observations, the recorded instances come last in the prompt, as a labelled block of attributed evidence whose heading carries the same per-render marker every other heading does. Evidence, not instructions: where an instance disagrees with the workflow section, the section wins.

soil_list takes an optional project and lists what is stored: with a reference, that container; without one, the personal store and every project container, each row saying where it lives.

Design notes

Strict schemas. Every input schema declares every property and sets additionalProperties: false. This is not pedantry: a client that meets a loose schema is free to flatten it to "no parameters", and then the model calls the tool with nothing and the save captures nothing.

Honest descriptions. The tool descriptions say what the tools do, including what they do not do. A save is a local file write and nothing is sent anywhere. The save runs the open deterministic rules from docs/checking.md on the stored document and reports the grade; the grade informs, never blocks a save, and is never written onto the handover, because the format has no grade field and will not get one. Whether a handover actually restores a session is answered only by a real load, and nothing here claims otherwise.

Fail closed on secrets. A save carrying credential-shaped material is refused, nothing is stored, and the message tells the model to say that the thing exists and where it is configured instead. It never repeats the value back.

Working-style answers are evidence, never a grade. The four questions exist because a stated description of how a project works can be complied with superficially, while a recorded instance gives the next session something concrete to anchor against. That is a design rationale, not a measured result: whether recorded evidence helps a cold model has not been measured here, and this server claims nothing about it. What it does guarantee is narrower: at most one working.style observation per save, the same fail-closed secret scan inside the answers as everywhere else, and a presentation at load that names the producer and never counts, scores or grades.

Same store as the CLI. ~/.soil, or SOIL_HOME. Save from your editor, load in your terminal.