Public alpha / Docs

Sannr docs.

Everything on one page, in order: install Sannr with one prompt, finish setup, check it and see your API map. Then how it works, how to remove it and how to install by hand.

On this page

Paste this into your coding agent

Open Claude Code or Codex in the repository where you want Sannr, then paste:

Install Sannr in this repository. From the repo root, run `npx --yes @sannr/sannr@alpha connect` and follow what it prints. It adds the Sannr skills, registers its MCP server and adds a short pointer block to AGENTS.md / CLAUDE.md. Then run `npx --yes @sannr/sannr@alpha doctor` and show me the result. doctor announces one GET to https://api.github.com/zen before sending it, so I can see the API client work (use `--offline` to skip it). Everything is stored on this machine and in this repo: no account, no Sannr server, no telemetry. If it asks for a restart, tell me; when I reopen the agent here I'll say "Finish sannr setup." What it does: https://sannr.dev/install

Monorepo? One install at the root; per-folder scoping is coming.

What this will do to your repo

The prompt has your agent run this from the repository root:

npx --yes @sannr/sannr@alpha connect

npm downloads the package. Then connect writes these files inside the repository:

PathWhat it is
.sannr/A README, settings, the skill sources and the API knowledge your team records. Meant to be committed. Request evidence lands in .sannr/evidence/, which its own .gitignore keeps out of Git.
.claude/skills/, .agents/skills/Three skills: sannr-request, sannr-write and sannr-feedback.
.mcp.json, .codex/The registration for Sannr's local MCP server. It holds paths for this machine, so each teammate runs connect once. Other servers and settings in those files are left alone.
.cursor/mcp.json, .vscode/mcp.jsonThe same registration for Cursor and VS Code, written only when your repository already has that folder.
AGENTS.md, CLAUDE.mdA short marked block in AGENTS.md that tells agents where the API knowledge is. An existing CLAUDE.md gets the same block; if there is none, connect creates a one-line CLAUDE.md that imports AGENTS.md. The rest of each file is not touched.

Where things live: API knowledge in your repository, everything else on your machine. Outside the repository, connect adds this repository's name, path and dates to ~/.sannr/registry.json, the list of repositories connected on this machine; it holds no credentials and no API knowledge. There is no account, no Sannr server and no telemetry. The network traffic in this install is npm downloading the package and the one check doctor announces below.

connect lists every file it touches. Global agent settings are not changed. Run connect twice and the second run changes nothing in the repository. To see the plan for your repository before anything is written, run npx --yes @sannr/sannr@alpha connect --dry-run --json. Review the diff before you commit, like any other change.

Restart and finish setup

Coding agents load new MCP servers when they start. Claude Code needs a restart: close it and reopen it in the same repository. In Codex, refresh or restart if the agent asks you to. Accept the project trust prompt if one appears, then open a fresh task in the same repository and say:

Finish sannr setup.

The agent checks that this repository’s installation is active. You do not need to install again or copy any setup details. Before the restart, the skills already work through the command line, so your agent can read what doctor recorded without waiting.

Check it

npx --yes @sannr/sannr@alpha doctor

It lists each part of the setup as passing, warning or failing and prints the fix for anything that fails. A repository without an OpenAPI contract gets a warning, not a failure. It also proves the API client works on your machine with one request: in a fresh install it prints GET https://api.github.com/zen before sending it, then shows the status, how long it took and the rate-limit headers GitHub returned. In a repository that already has a base URL configured, it announces a check of that address instead. No credentials go with it, and it does not follow redirects or retry. The observation is saved in .sannr/evidence/, which stays out of Git.

  • doctor --offline skips that check; the local setup checks still run.
  • doctor --probe <url> checks a different address instead.
  • context query --onboarding reads back the saved observation without making a request.

To repeat the same check yourself: npx --yes @sannr/sannr@alpha request GET https://api.github.com/zen --expect-status 200

See your API map

To see the APIs Sannr finds in this repository, ask your agent:

Show me my API map with Sannr. Generate a local HTML page without calling any APIs, and open it for me.

The map shows services, recognized routes, connections, and external API dependencies found in your files. It is a local, offline snapshot; it does not prove that those APIs are running. Regenerate it after changes. If no API surface is found, installation is still complete.

Generate the HTML map from your terminal

To generate it yourself, run this from the repository root, then open api-footprint.html in your browser:

npx --yes @sannr/sannr@alpha map . --no-execute --out api-footprint.html

Put it to work

Give the agent a real task, for example:

Use Sannr to help me integrate this API.

Name the API if it isn't obvious from the repository. The agent can ask for the base URL or authentication when needed. Sannr starts remembering an API once it has an OpenAPI file for it: the vendor's published spec, or one your agent drafts from your code or docs. From then on, the agent can record what it learns for future work.

How it works

What the parts do, which command does what, and what ends up committed. Command names match the documentation shipped with the alpha; when the product repository is public, this page will link to it.

Two tools, one folder

The map and the client are the tools; the .sannr folder is what they remember. It holds your API knowledge, its settings and the skills, committed with your code. Setup also puts what your agent needs where it looks, outside the folder; step 02 lists every file.

A map

Point it at a repository and it inventories the APIs it finds: the services, the routes it recognizes, who calls whom, and routes your code implements that the contract leaves out. The map is generated from your files, offline, without calling anything.

sannr map . walks the tree and writes the map as one self-contained HTML file that works offline. sannr start, an alternative to connect, produces the same static inventory during setup. Neither makes an API request; the --no-execute form in step 05 is the explicit way to say so.

The folder

The knowledge file, .sannr/stacks/sannr.json, records what agents observe about each operation: response shapes, the enum values a contract declares, the gotchas the documentation omits, and the decisions no traffic ever reveals, such as why an integration was rejected. It is committed with the code, so it travels with the repository.

sannr learn fills it from read-only requests. sannr note adds an authored lesson to one operation. sannr view writes an offline HTML snapshot of everything the file holds, with verification dates, confidence and each note's provenance, so a person can read it without a server.

A client

A request client your agent calls through MCP or the command line. It sends the request, applies your credentials from environment references, returns a bounded result with the assertions you asked for, and records what it observed. The client makes the calls; the folder is what it remembers.

In Claude Code or Codex the client is the api_request tool that sannr connect registers for the project. From a terminal, sannr request GET /health uses the same client and returns the same envelope: status, whether the call was ok, the assertions and their results, the bounded data, and a pointer to the local evidence.

Import. Verify. Deliver.

Import what you already have

Sannr reads Postman and Bruno collections, and seeds operations from an OpenAPI contract. Every import comes with a loss report. Scripts are never executed during an import; review the report and the generated suite before you run anything.

sannr import accepts Postman v2.1 and v3, and Bruno files and directories. It writes a request suite for the steps whose assertions it could translate or infer, and an adjacent to-do file naming every gap. An OpenAPI contract is not imported; sannr start seeds the knowledge file from it as unverified operations when the environment names one.

Verify against the running service

Read-only checks record what is actually true about each operation: the status codes seen, the field names and types, the drift between the contract and the server. Field values are never recorded unless the contract itself declares them; request and response bodies, headers and credentials never are.

sannr learn sends only GET and HEAD requests. sannr learn --dry-run previews exactly what would be written and writes nothing. Whatever it learns about a production environment is reported, not promoted into the committed file.

Deliver it where the agent already reads

The lessons agents record are listed, each with its operation, in a block in the instruction files your agent loads at the start of a session, so a new session has them in view without being told to go and look. The client also returns an operation's lessons with each result for it.

sannr connect writes that block into AGENTS.md and CLAUDE.md (step 02) and sannr learn refreshes it. It names the knowledge file and lists the recorded gotchas, pointing to the file for any it has no room for. Rerunning connect preserves unrelated configuration and reports conflicts instead of overwriting them.

Optional: a drift report in CI

sannr connect --ci adds a GitHub Actions workflow that runs on pushes, pull requests and a weekly schedule. It reports where the checked-in contract and the code disagree, in report-only mode and without API traffic, and it does not rewrite the contract or the knowledge file. sannr verify --read-only --ci runs the saved suites as read-only probes and exits non-zero on drift.

A recorded lesson

Automatic capture keeps bounded status and structure. It cannot know why a behavior matters. When an agent or a developer learns one reusable fact the contract does not state, the write convention asks for one present-tense sentence on the operation, recorded at once:

npx --yes @sannr/sannr@alpha note "POST /orders/{id}/confirm" "returns 200 while status remains draft unless payment_status is settled"

The note lands in the knowledge file under that operation, with who recorded it and when. Every note passes a secret guard: a note that looks like it holds a token, a key or an email address is refused, because the committed file ends up in every clone and fork.

"POST /orders/{id}/confirm": {
  "notes": [
    "returns 200 while status remains draft unless payment_status is settled"
  ],
  "notes_provenance": [{ "by": "agent", "at": "2026-09-15" }]
}

In any clone where the file is committed, the next session can see it: the client returns it with the result of each call to that operation, and the block in AGENTS.md and CLAUDE.md lists it once connect or learn next rewrites that block. A decision not to use an API is recorded the same way with sannr verdict, with its reason and scope, so the rejection leaves an artifact instead of a memory.

What stays on your machine

Sannr has no account to create and sends nothing to us. Credentials are referenced by environment variable name; the configuration stores the name, never the value. Recorded knowledge holds field names and types, and only the values a contract declares. Request evidence stays in a local folder that Sannr's own .gitignore keeps out of the repository. The API knowledge, its settings and the skills in the .sannr folder are what's meant to be shared, and they are designed to be safe to commit.

The environment configuration names a base URL, a contract path and an authentication reference such as bearer:LOCAL_API_TOKEN. The token itself lives in an environment variable or a local file outside the repository. The alpha's feedback report is written to a local file for a person to read and send; the product never sends it.

The .sannr folder

Setup writes a README.md into the folder that explains each path. This is its layout at the alpha:

The .sannr folder layout
PathPurpose
.sannr/stacks/sannr.jsonCommitted API knowledge: operations, observations and authored lessons.
.sannr/stacks/.sannr-graph.jsonCommitted graph configuration and provider bindings.
.sannr/stacks/graph.snapshot.jsonCommitted cross-repository graph snapshot, when exported.
.sannr/config/api-environments.jsonCommitted named environments and credential-variable references.
.sannr/config/defaults.jsonOptional committed client defaults.
.sannr/stacks/suites/Committed request suites and import provenance.
.sannr/stacks/api-audit-baseline.jsonCommitted accepted audit findings.
.sannr/vendor/sannr-ci.tgzVendored engine package, when CI is explicitly installed.
.sannr/skills/Canonical skills, copied into each agent host.
.sannr/evidence/Private local request evidence; ignored by Git.

Commit the knowledge, the configuration, the generated guide and the skill sources.

The words we use

API context
Everything an agent needs to use an API correctly that the specification does not say: prerequisites, quirks, rate limits, the reason a decision was made, and how recently each fact was checked.
Tribal knowledge
The working knowledge of a system that lives in the heads of the people who have been around longest and is not written anywhere a newcomer, or an agent, would find it.
The rediscovery tax
The cost of an agent re-deriving, in a fresh session, something a previous session already learned about the same API.
Authored lesson
A short note recorded on an operation by a developer or an agent, with its evidence, describing behavior the contract does not say. Sannr delivers lessons to later sessions.
Loss report
The part of an import that names what could not be carried over faithfully.
Drift
A difference between what the contract or the saved knowledge says and what the running service does now.
Repository-level context
Knowledge committed with the code, so it travels with the repository: anyone who clones it gets the same notes. Your agent's host may keep memory for you on your machine; the repository is what everyone else pulls.

Remove it

npx --yes @sannr/sannr@alpha unwire

This removes Sannr's MCP registration, the skills and the marked block in AGENTS.md and CLAUDE.md. It keeps any skill you edited and every server that is not Sannr's, and prints what it left for you to review. A one-line CLAUDE.md that only imports AGENTS.md stays, because Sannr can't tell whether it was yours. Emptied files such as .mcp.json can remain; with nothing in them there is no server to start. The .sannr/ folder holds what your team recorded, so it stays until you delete it yourself. This repository's entry in ~/.sannr/registry.json stays too. Restart your agent afterwards so it stops looking for the server.

Install by hand

Prefer to run it yourself? From the repository root:

npx --yes @sannr/sannr@alpha connect
npx --yes @sannr/sannr@alpha doctor

Then restart your agent and finish setup as in step 03.

Stuck, or want to tell us what broke? Ask in the Sannr Discord.