Persistent storage for AI agents. Store text, code, configs, and files — retrieve them via MCP or REST API.
Built for agents like OpenClaw that need a reliable place to save and recall information across sessions.
AI agents lose context between sessions. ClawStash gives them a persistent memory:
- Store anything — code snippets, configs, notes, multi-file projects
- Organize with tags & metadata — structured key-value metadata and tags for easy retrieval
- Full-text search — find stashes by content, name, description, or tags
- Token-efficient — MCP tools return summaries first, full content only on demand
- Version history — every change is tracked, diffable, and restorable; the last 200 snapshots per stash are kept (
STASH_VERSION_LIMIT,0= keep everything — what gets deleted, and when) - Duplicate a stash — open any stash as a pre-filled new one and use it as a template
- Import files from disk — drop text files onto the editor (or pick them) to add them as file rows, instead of copy-pasting each one
- GitHub backup — mirror all stashes into a GitHub repo (scheduled, on change, or manual) with "Sign in with GitHub" or a PAT — see docs/backup.md
- Mermaid diagrams —
.mmdfiles and inline```mermaidblocks in Markdown render as diagrams (lazy-loaded, no bundle bloat) - One-click code copy — every fenced code block in rendered Markdown gets a copy button (keyboard reachable, always visible on touch)
- Web GUI included — dark-themed dashboard to browse, search, and manage stashes manually, with a resizable sidebar that remembers its width
Copy this into your OpenClaw agent — it installs ClawStash, creates test stashes, and sets up MCP automatically:
Install ClawStash (ghcr.io/fo0/clawstash) on my server and set it up as your default persistent storage via MCP. Server: <HOST_OR_IP>, User: <SSH_USER>, Auth: <PASSWORD_OR_KEY>. Use port <PORT> (docker compose port mapping "<PORT>:3000"). Set ADMIN_PASSWORD to a secure value. After install: create an API token (scopes: read, write, mcp), create 2 test stashes to verify, then fetch /api/mcp-onboarding to read the full MCP spec and configure yourself. Details: https://raw.githubusercontent.com/fo0/clawstash/main/docs/openclaw-onboarding-prompt.md
Replace the <...> placeholders with your server details — your agent handles the rest.
Step-by-step version: docs/openclaw-onboarding-prompt.md
Run this on your server — no clone needed:
mkdir clawstash && cd clawstash && cat > docker-compose.yml <<'EOF'
services:
clawstash:
image: ghcr.io/fo0/clawstash:latest
ports:
- "3000:3000"
volumes:
- ./data:/app/data
environment:
- NODE_ENV=production
- DATABASE_PATH=/app/data/clawstash.db
# - ADMIN_PASSWORD=your-secret-password
restart: unless-stopped
EOF
docker compose up -dOpen http://localhost:3000 — done. Database persists in ./data/.
Change port mapping (e.g.
"8080:3000") for a different port. UncommentADMIN_PASSWORDto protect the instance. If login fails and the logs showSQLITE_READONLY(data directory created by an older version), runsudo chown -R 1000:1000 ./dataonce and restart — details in Deployment → Bind mounts & file permissions.
After starting, hand your AI agent the onboarding prompt from Settings → API & Tokens → MCP API ("Copy onboarding prompt for your agent" — the token banner offers the same prompt with a freshly created token filled in). Or point the agent at the server's own guides:
GET http://<HOST_OR_IP>:<PORT>/api/agent-skill # SKILL.md — when to store, workflow, conventions, limits, errors, maintenance
GET http://<HOST_OR_IP>:<PORT>/api/mcp-onboarding # the skill plus the complete MCP specification (every tool's JSON Schema)
GET http://<HOST_OR_IP>:<PORT>/llms.txt # discovery index when the agent only knows the host
Connected via MCP, the agent gets the same guidance without fetching anything: the server hands out usage instructions on initialize, exposes the two guides as resources (clawstash://guide/skill, clawstash://guide/onboarding), and get_server_info returns the token's scopes, the callable tools, the size limits and every endpoint in one call.
Add to your MCP client config (OpenClaw, Claude Code, Cursor, etc.):
{
"mcpServers": {
"clawstash": {
"type": "streamable-http",
"url": "http://<HOST_OR_IP>:<PORT>/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN" }
}
}
}Create API tokens in the web GUI under Settings > API & Tokens (scopes: read, write, mcp).
Breaking change — MCP tokens need
read/write. Themcpscope is a transport gate: it lets a token connect to/mcp, and nothing more. Each MCP tool is authorized separately, with the same scope its REST equivalent requires —readto read stashes,writeforcreate_stash,update_stash,archive_stashanddelete_stash. Until now the MCP endpoint checked onlymcp, so a token carrying just that scope could write through MCP while every REST write route rejected it.Who is affected: anyone whose agent uses a token with
mcpbut withoutwrite(or withoutread). Its calls now come back as MCP tool errors naming the missing scope. Fix: issue a new token withread,writeandmcpand swap it into the agent's MCP config. Expect to need this: the scope combination was recommended here and in docs/openclaw-onboarding-prompt.md, but the self-onboarding endpointGET /api/mcp-onboardingand docs/mcp.md named onlymcpuntil this release — a token created by following those two must be reissued. Unaffected: tokens that already carryread/write/mcp(oradmin), and the local stdio transport, which carries no token at all.
| Tool | What it does |
|---|---|
create_stash |
Store new content with files, tags, metadata |
read_stash |
Get stash metadata + file list (content on demand) |
read_stash_file |
Read a single file — most token-efficient |
list_stashes |
Browse all stashes with summaries |
search_stashes |
Full-text search with ranked results |
update_stash |
Update existing stash content |
delete_stash |
Remove a stash |
archive_stash |
Archive/unarchive a stash without deleting |
list_tags |
List all tags with usage counts |
get_tag_graph |
Explore tag relationships |
get_stats |
Storage statistics |
get_rest_api_spec |
Fetch the OpenAPI 3.0 schema (JSON) |
get_mcp_spec |
Fetch the full MCP specification (markdown) |
refresh_tools |
Get latest tool specs (for connected agents) |
check_version |
Check for updates (with upgrade instructions) |
get_server_info |
Orient: scopes, callable tools, limits, endpoints |
| Doc | Content |
|---|---|
| OpenClaw Onboarding | Copy-paste prompt for full agent-driven setup |
| API Reference | REST endpoints, examples, query parameters |
| MCP Guide | MCP tools, token-efficient patterns, transport options |
| Authentication | Admin login, API tokens, scopes |
| GitHub Backup | Mirror stashes into a GitHub repo: setup, security |
| Deployment | Docker, CI/CD, GHCR, production setup |
Prerequisites: Node.js 22+ in practice. package.json declares engines: { "node": ">=20.9.0" }, so npm install prints an EBADENGINE warning below 20.9 — but better-sqlite3 13.x declares engines: { "node": ">=22" }, which warns on Node 20.x and 21.x as well. Docker and CI run Node 26.
git clone https://github.com/fo0/clawstash.git
cd clawstash
npm install
cp .env.example .env # adjust DATABASE_PATH / ADMIN_PASSWORD as needed
npm run dev # Next.js dev server at http://localhost:3000
npm run format # auto-format with Prettier (CI verifies formatting via format:check)
npm run lint # ESLint (correctness rules; formatting stays with Prettier)
npx tsc --noEmit # TypeScript type check (no npm script — CI runs this exact command)
npm test # vitest test suite (npm run test:watch for watch mode)
npm run build # production build
npm start # serve the production build
npm run mcp # MCP server (stdio transport, for local MCP client testing)docker-publish.yml runs that same chain (format:check → tsc --noEmit → lint → test → build, in
that order) before it builds the image — but it is workflow_dispatch-only, so it does not run
on a push or a pull request. The only checks that run automatically on a PR are docs-format.yml
(Prettier on **.md) and GitHub's CodeQL analysis. The local chain above is therefore the real gate
for correctness: run it before every push.
See CONTRIBUTING.md for code-style rules and the PR workflow.