Connecting an agent
There are two ways to give an agent the documentation. The command line is the simpler one and works everywhere; MCP is there for clients that prefer a declared tool.
The command line, which is the recommended way
Any agent that can run a shell command can use docspack:
npx docspack ask "how do I verify a webhook signature"Tell the agent the command exists, with one line in AGENTS.md or CLAUDE.md. One command
writes it for you, into whichever of those files the project already has:
npx docspack agent installRun `npx docspack ask "<question>"` for documentation on this project's dependencies.
It answers from the installed versions.That is the whole setup. There is no server to configure, nothing per-agent, and nothing resident when nobody is asking. It works in Claude Code, Cursor, Codex, Aider, a shell script, or a CI job, including agents that do not speak MCP at all.
ask prints exactly what the MCP tool returns: the best-ranked chunks with their package,
version and file, bounded by the same token budget. The two interfaces are the same code
path, so neither is second class.
Writing the wiring, and keeping it current
docspack agent install writes a block delimited by <!-- docspack:start --> and
<!-- docspack:end -->. Everything outside the markers is left exactly as it was, and
re-running rewrites the block in place rather than appending a second copy — so a repository
wired a year ago gets the current text by running the command again.
It writes more than the block when the project has somewhere to put it:
| Flag | What it writes |
|---|---|
| (default) | the block in AGENTS.md or CLAUDE.md, whichever exists |
(default, with .claude/) | .claude/skills/docspack/SKILL.md, a skill whose body loads only when it is used |
--feedback | the reporting block below, as well |
--hooks | a SessionStart hook that runs docspack sync, so the index follows the lockfile |
--mcp | the MCP server in .mcp.json |
--recipe repo, --recipe factory | a way of working on top — see Recipes |
--dry-run | nothing; prints the plan |
npx docspack agent checkcheck writes nothing and exits non-zero when the wiring is missing or out of date. It needs
no flags: it reads back which of those surfaces the project chose and compares them against
what this version would write, so it belongs in CI. A pasted instruction that has drifted from
what the tool does is otherwise something nobody ever notices.
check also prints what each instruction file costs: an agent sends CLAUDE.md or AGENTS.md
again on every turn, so the size is paid once per turn. Over 1,000 tokens it names the file’s
three largest sections, which are usually reference material that would cost nothing in docs/
until an agent searched for it. See
Setting up an agent to spend fewer tokens.
Every command the block and the skills tell an agent to run starts with npx. An agent’s shell
does not have node_modules/.bin on its PATH, so a bare docspack would fail in a project that
installed it as a dev dependency, and the agent would spend a turn finding out why. The hooks use
npx --no-install, so they do nothing, silently, where docspack is not installed.
Recipes: a way of working
A recipe is everything above plus the instructions and layout for one way of working with
agents. The default, deps, is what agent install has always written. factory is for
autonomous sessions in ephemeral containers — a “dark factory”, where the repository is the only
state that survives:
npx docspack agent install --recipe factory| What | Kind | Purpose |
|---|---|---|
the block in AGENTS.md / CLAUDE.md | managed | the rules every session needs: which milestone is yours, recall before deciding, propose lessons, never edit approved knowledge |
.claude/skills/docspack-factory/SKILL.md | managed | the procedure: milestones, CI incidents, lessons, governor sessions |
.claude/settings.json | managed | SessionStart runs docspack sync, then docspack index --from .factory/knowledge |
.factory/README.md, .factory/templates/* | seeded | the layout, and templates for a milestone, an incident and a lesson |
.factory/plan/, knowledge/, inbox/ | seeded | one file per item, so parallel branches do not conflict |
Managed files are rewritten on every install and checked by agent check. Seeded files
are written once, when absent, and never again: they are the project’s to fill in, and filling
one in is not drift. The recipe is recorded in the start marker
(<!-- docspack:start recipe=factory -->), so agent check still needs no flags.
A milestone is a file in .factory/plan/ whose frontmatter carries status and branch; an
agent finds its assignment with Grep and reads only that file. Only .factory/knowledge/ is
indexed, and lessons reach it when a person moves them out of .factory/inbox/ in review — an
agent-written rule becomes something every later session trusts, so a human decides.
Finding things in an ordinary repository
repo is for everyday work in a repository with lots of docs and lots of code. It gives the
agent a search over the repository’s docs and code, and asks it to use fewer, larger tool calls:
pnpm add -D docspack # the hooks run the project's own install
mkdir -p .claude # with Claude Code: where the skills and the hooks go
npx docspack agent install --recipe repo
npx docspack index --repo # once; after that the SessionStart hook rebuilds it| What | Kind | Purpose |
|---|---|---|
the block in AGENTS.md / CLAUDE.md | managed | ask recall --name repo-code where something lives, and --name repo-docs what the docs say, then read only that range; and read, search and edit in fewer, larger tool calls |
.claude/skills/docspack-repo/SKILL.md | managed | how to read an answer, when grep is better, and what to do when the index is out of date |
.claude/settings.json | managed | SessionStart runs docspack sync, then docspack index --repo |
The fewer-calls part of the block is what saves tokens: over 780 Claude Code sessions it cut the cost of feature-sized tasks by 24%, and saved little on short ones. The index finds things but did not measurably lower a session’s cost on its own. Setting up an agent to spend fewer tokens has the numbers and the block to paste by hand.
The index is described in Indexing your own sources. Without Claude
Code nothing builds it when a session starts, so the block also tells the agent to run
docspack index --repo when recall finds nothing indexed.
Letting an agent report a problem
An agent reading documentation is unusually well placed to notice it is wrong. Add a second
block to AGENTS.md if you want it to write those observations down:
If the documentation is wrong, record it: `npx docspack feedback add --chunk <id>
--kind <drift|incorrect|missing> --evidence "<claim>"`. The chunk id is the
heading above each answer. Only claims that can be shown false; incorrect and
missing also need --expected, --actual and --repro. It writes to a local file
for a human to review, and sends nothing.The chunk id is the ## @acme/docspack@1.4.0/webhooks heading printed above every answer,
so an agent already has what --chunk needs without another query.
The last sentence is the one that matters. An agent that thinks it is filing an issue behaves
differently from one that knows it is appending to a file a human will read, and only the
second is true. See the chunk on trust and safety for what add refuses and why.
This block is deliberately separate. Reading documentation and reporting on it are two decisions, and a team that only wants the first pastes only the first.
What a query costs
A query spawns a process, which sounds expensive and is not: about 101 milliseconds, of which roughly 41 is Node itself starting. That is invisible next to the seconds a model spends thinking, and it is only paid when a question is actually asked.
Commands that need heavier machinery load it when they run, not at startup. Importing the whole
library costs about 263 milliseconds, against about 16 for the
query path alone, so ask imports only what it needs.
MCP, for clients that prefer a tool
claude mcp add docspack -- npx -y docspack mcpOr, for Cursor and other clients that read a JSON configuration:
{
"mcpServers": {
"docspack": { "command": "npx", "args": ["-y", "docspack", "mcp"] }
}
}The server exposes two tools. query_local_docs takes a free-text query and an optional
packageFilter, and returns text identical to docspack ask. record_docs_problem is the
MCP equivalent of docspack feedback add, taking chunkId, kind, evidence and — for
anything but drift — expected, actual and repro. The server speaks the protocol on
stdout and writes diagnostics to stderr.
record_docs_problem is the only tool that writes anything, and what it writes is a line in
a local file. It cannot reach a maintainer: docspack has no code that can send a report, over
MCP or otherwise. Its description says so, because a model that believes it is filing an issue
behaves differently from one that knows a human reads the file first.
Every rule is enforced in one place, so MCP is not a looser way in than the command line. A
kind outside drift, incorrect and missing is refused by the schema; an incorrect
finding without a reproduction is refused by the same check the CLI uses; a chunk that is not
installed is refused before anything is written. When a call is refused, the reason comes back
naming the field that was missing, so an agent can correct itself instead of guessing.
The trade is real in both directions. A declared tool advertises itself: the agent sees the name, the schema and the description, and knows when to reach for it without being told. In exchange, the tool definition occupies the context window for the whole session whether or not it is used, the server process stays resident, and every client configures MCP differently.
Choose MCP when you want the agent to discover the capability by itself. Choose the command line when you want zero setup and nothing running in the background — which is most of the time.
How results are scoped
Both interfaces read the package.json of the directory they run in, and restrict results
to the package versions that project installed.
This matters because the index is shared. Another project on the same machine may have indexed a different major version of the same library. That version is in the database, but it is invisible to this project’s queries. An agent cannot accidentally answer from documentation for a version you are not running.
How much context a query returns
Agents over-fetch. Left alone, a retrieval tool will happily return more than the model can use and crowd out the rest of the conversation.
docspack bounds every response, over MCP and on the command line alike. It returns the three best-ranked chunks by default and stops adding chunks once the response would exceed 3,000 tokens, using the token count recorded for each chunk rather than measuring after the fact. A single chunk larger than the budget is still returned, so a query never comes back empty because of the limit.