Skip to main content
Glama
README.md
# Stashpad

**Memory for AI agents that you can read, edit and trust.**

Stashpad keeps what an agent learns as plain Markdown files. Every memory has a source, dates and a trust level. Agents propose, a person accepts. Old facts are ended, never overwritten.

- **Plain files.** Open them in any editor, diff them, keep them in git.
- **Safe by default.** Agent and web writes wait in a review queue. Secrets are refused.
- **Works with any agent.** Plain commands, an open MCP server and a plain `AGENTS.md` block. No model or company is required.
- **Optional encryption.** `stashpad encrypt` seals every file with AES-256-GCM, snapshots included. Off by default.
- **No dependencies.** Node 20 or newer is all it needs.

```bash
npm install -g stashpad        # or run without installing: npx stashpad --help
stashpad save db-choice --kind decision --source-type user --source-ref "chat" --text "We keep data in SQLite."
stashpad search sqlite
stashpad setup                 # print the MCP settings for your agent
```

Agents: read [AGENT-GUIDE.md](AGENT-GUIDE.md).

Start of a session, for any agent:

```bash
node bin/stashpad.mjs doctor                     # check the setup; says what to fix
node bin/stashpad.mjs brief                      # short summary, newest handover first
node bin/stashpad.mjs handover --text "Half done: auth. Next: tests."   # note for the next session
node bin/stashpad.mjs sync-agents AGENTS.md      # put the brief in a file agents already read
```

## Install and run

Requires Node 20 or newer. No other dependencies.

```bash
npm test                 # run the tests
npm run build            # build dist/
node bin/stashpad.mjs --help
```

Memories live in `./.stashpad/memories` by default. Set `STASHPAD_DIR` or pass `--dir`.

## Use it

```bash
stashpad save db-choice --kind decision --source-type user --source-ref "statement in chat" --text "We keep data in SQLite."
stashpad search "sqlite" --json
stashpad save db-choice-v2 --kind decision --source-type user --source-ref "later statement" --text "We keep data in Postgres." --supersedes db-choice
stashpad history db-choice-v2
stashpad search database --kind decision --as-of 2026-03-01 --explain   # what was decided on that day, and why it matched
stashpad entities                  # names, tools and files the memories talk about
stashpad about Postgres            # every memory about it, and what is mentioned with it
stashpad confirm db-choice-v2      # still true; doctor flags agent memories nobody confirmed for 180 days
stashpad handoff leave --text "Half done: auth. Next: tests."   # a note the next session reads once
stashpad handoff claim             # take it (a person's notes first); listing never takes one
stashpad feedback db-choice --signal stale   # helpful, stale or wrong; wrong also asks for it to end
stashpad lint                      # what deserves a look; changes nothing
```

The command line, the MCP server and the review page can run at the same time: every write takes a short lock on the store.

Writes from agents, tools and the web wait in review:

```bash
stashpad review
stashpad accept <id>
stashpad reject <id> --reason "not verified"
stashpad audit
```

## Use it from an MCP client

```json
{
  "mcpServers": {
    "stashpad": {
      "command": "node",
      "args": ["/path/to/stashpad/bin/stashpad.mjs", "mcp", "--dir", "/path/to/your/memories"]
    }
  }
}
```

Eight tools: `stashpad_search`, `stashpad_get`, `stashpad_recent`, `stashpad_about`, `stashpad_save`, `stashpad_forget`, `stashpad_handoff`, `stashpad_feedback`.

## Check it, import into it

```bash
stashpad eval                          # 40 notes, 33 queries (English and Dutch), safety checks; no language model is called. Paraphrased questions are measured too (about 2 of 3 found): word search misses some rewordings, and that is reported openly.
stashpad import notes.jsonl            # queue memories from an export; they wait for review
stashpad export --out memories.jsonl   # back up current memories as JSON Lines (--all adds ended ones)
stashpad save <id> --kind fact --source-type user --source-file notes.txt --text "..."   # keeps a copy of the raw source
```

`stashpad review` also shows when a waiting memory may conflict with a current one, and whether accepting it would end that one.

## Review in a page

```bash
stashpad ui            # opens http://127.0.0.1:4317/ to review, search and read the audit log
stashpad ui --open     # the same, and opens the page in your browser
```

Only this computer can reach the page. It is a small local page with no outside resources. See [the decision](docs/decisions/ui.md).

Imports come in as JSON Lines (`id`, `kind`, `text`, optional `valid_from`, `source_ref`) or as plain text, one fact per paragraph.

## Principles

- Plain files first. The files are the source of truth.
- Nothing from an agent, tool or web page is stored until a person accepts it.
- Secrets are refused at write time (keys, tokens, JWTs, Bearer tokens, passwords in connection strings).
- Invisible characters are refused, and look-alike or split-up words cannot hide an instruction or a secret.
- Instruction-like text (English and Dutch) is flagged for the reviewer.
- A gatekeeper refuses agent notes that are too short or near-copies of an existing or waiting memory, and logs the refusal in the audit log. Notes a person writes are never blocked.
- Limits: 4000 characters per memory, 200 writes waiting for review.
- Recalled text is labelled as data, not instructions.

## Docs

- [Search words and synonyms](docs/FORMAT.md#search-words-and-synonyms)
- [Handoffs, feedback, lint, expiry and ReversePort](docs/HANDOFFS.md)
- [Optional encryption](docs/ENCRYPTION.md)
- [Architecture](docs/ARCHITECTURE.md)
- [Changelog](CHANGELOG.md)
- [Use with any agent](docs/ANY-AGENT.md)
- [Updating safely: snapshots, restore, migrate](docs/UPDATING.md)
- [Memory file format](docs/FORMAT.md)
- [Search backend decision](docs/decisions/search-backend.md)
- [No vector search for now](docs/decisions/vectors.md)
- [Third-party notices](THIRD_PARTY_NOTICES.md). Code is ported with `npm run port`, which refuses any license except MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause and ISC.

## License

MIT. See [LICENSE](LICENSE).

Maintenance

ActivityMaintained
ResponsivenessNo issues