docspack
v1.2.0
Published
Local, version-locked documentation packages for AI agents, indexed in SQLite and served over MCP.
Downloads
800
Maintainers
Readme
docspack
Local, version-locked documentation packages for AI agents, indexed in SQLite and served over MCP.
Website · Documentation · GitHub · Releases
Publishing documentation for your own library? You want
docspack init, which scaffolds a documentation package. This README is mostly about consuming them.
Just want your agent to read the docs? Three lines: install a docs package, run
docspack sync, and paste one sentence intoAGENTS.md. Jump to Quick start.
Overview
An AI coding agent answers from one of three places: its training data, which is frozen at some past version; a docs site it fetches, which is whatever the vendor publishes today; or nothing at all. None of those is the version in your lockfile.
docspack closes that gap by making documentation an ordinary npm dependency. A documentation
package (@stripe/docspack, @docspack-community/jira) holds Markdown split into chunks plus
a manifest describing them, and its version tracks the library's. docspack sync indexes the
ones this project depends on into one SQLite database per machine, and docspack ask answers
from that index — offline, bounded, and matched to what you actually installed.
The mental model: publish → sync → ask.
Features
- Version-locked — answers come from the docs package resolved in your lockfile, never a newer or older one. The index may hold five versions of a library; a project sees only its own.
- Offline by construction —
sync,ask,searchandlistmake no network requests. They readnode_modulesand a local SQLite file. - Bounded responses — 3 chunks and 3,000 tokens by default, counted from the manifest before content is returned, so a query cannot overrun its budget.
- No server, no resident context — every agent already has a shell. One line in
AGENTS.mdis the whole setup, and nothing runs when nobody is asking. - MCP when you want it —
docspack mcpserves the same index over the Model Context Protocol, returning identical text, for clients that prefer a declared tool. - No native modules — the index uses
node:sqlitefrom the standard library.
Installation
npm install -D docspack
pnpm add -D docspack
yarn add -D docspackRequires Node 22.5 or newer.
Quick start
# 1. Add a documentation package, the same way you add any dependency
pnpm add -D @acme/docspack
# 2. Index every docs package this project depends on
npx docspack sync
# 3. Ask it something
npx docspack ask "how do I verify a webhook signature"Then give the agent access by pasting these two lines into AGENTS.md or CLAUDE.md:
Run `docspack ask "<question>"` for documentation on this project's
dependencies. It answers from the installed versions.That is the entire integration. No server to start, no per-client configuration.
claude mcp add docspack -- npx -y docspack mcpThe server exposes query_local_docs (query, optional packageFilter), returns the
best-ranked chunks and caps a response at 3,000 tokens. It also exposes record_docs_problem,
the equivalent of docspack feedback add — it appends to a local file and cannot send
anything anywhere.
Commands
Reading:
docspack sync Index the docs packages this project depends on
docspack ask <question> Answer from the local index — the command to give an agent
docspack search <query> Same index, formatted for a human reading the terminal
docspack list Show this project's docs packages and their index state
docspack verify Check the docs still describe the code you installed
docspack feedback <sub> Record documentation problems: add, list, submit, remove
docspack mcp Serve the index over MCP instead, as a long-lived process
docspack sources List curated sources that `docspack build` can fetchAuthoring:
docspack init Scaffold a documentation package, then build and check it
docspack build [source] Generate the .llms/ payload for publishing
docspack doctor Check a package the way the indexer and a reviewer would
docspack preview <query> Answer a query from the local package, as an agent would
docspack eval <queries.json> Measure retrieval against a set of questionsRun docspack <command> --help for that command's own flags.
Authoring a documentation package
npx docspack init # scaffold, build and check in one step
npx docspack build --from ./docs # Markdown, split at headings
npx docspack build --openapi ./openapi.json # one chunk per operation
npx docspack build --from ./docs --openapi ./api.json # prose and an API in one package
npx docspack build stripe # from a project's public llms.txtbuild writes .llms/manifest.json, .llms/chunks/*.md and an llms.txt table of contents,
ready for npm publish. docspack doctor --strict checks the result the way the indexer and
a reviewer would, and docspack eval ./queries.json --min-hit-rate 90 checks the thing it
cannot: whether the package answers the questions it is for.
Reference generated by a tool needs --min-chunk-tokens, which packs adjacent sections up to
the budget instead of splitting at every heading — a heading there is a field name, and one
chunk per field is hundreds of chunks too small to answer anything.
An HTTP API
--openapi reads an OpenAPI 3 document and writes one chunk per operation, each carrying
everything needed to make the call and nothing else: the base URL, the credential, the inputs
with their types, the body shape, the response, the failures, the types they reference, and a
runnable curl line. It is LAPIS notation — an open format for
describing an API to a model — which is about 72% smaller than the equivalent OpenAPI JSON, and a
rounding error against the whole document an agent would otherwise be handed.
create_invoice POST /invoices
Creates an invoice for a customer.
> body: InvoiceCreate
< Invoice # 201 The created invoice.
@auth bearerAuthEach chunk answers to both spellings of its endpoint — POST /v1/charges and the
operationId — so docspack ask "POST /v1/charges" returns that operation rather than the three
pages that mention charges most often. A concrete URL reaches its template, so
ask "GET /v1/charges/ch_3Ox7" finds GET /v1/charges/{charge}.
JSON or YAML, decided by what the file holds rather than by its extension. Only OpenAPI 3, though:
convert Swagger 2 with npx swagger2openapi, and a document split across files with npx
@redocly/cli bundle. An external $ref is refused rather than dropped — a schema silently replaced
by "unknown" is a chunk claiming an endpoint takes no body.
The reader and the LAPIS renderer are @docspack/lapis,
which is a standalone command too: npx @docspack/lapis ./openapi.yaml --stats.
Manifests validate against https://docspack.dev/schema/v1.json; the format is specified at https://docspack.dev/spec and served as Markdown at https://docspack.dev/spec.md.
Recording documentation problems
An agent holds the documentation, the installed library and a failing program at the same
moment — a signal that today evaporates. docspack feedback add captures it locally:
npx docspack feedback add --chunk @acme/[email protected]/api-auth \
--kind drift --evidence "client.setKey is not exported; setApiKey is"Claims must be falsifiable. drift must name the identifier; incorrect and missing must
carry --expected, --actual and --repro. There is deliberately no kind for "this page is
confusing".
Nothing is transmitted, and nothing can be — docspack contains no code that sends a report
anywhere. docspack feedback submit prints a prefilled GitHub issue URL for vendors who opted
in from their own package.json, and a human decides whether to open it.
Status
Pre-1.0 and versioned accordingly: minor releases may change behaviour. The package specification is the part most worth depending on, and it is documented at https://docspack.dev/spec.
Related packages
| Package | Description |
| --- | --- |
| @docspack/registry | Curated llms.txt sources for bootstrapping docs packages. |
| @docspack/docspack | docspack's own documentation, shipped as a docs package. |
License
MIT — see LICENSE.
