Skip to main content
Glama
fo0

ClawStash

by fo0

ClawStash

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.

Why ClawStash?

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.mmd files and inline ```mermaid blocks 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

Get Started

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

2. Manual setup

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 -d

Open http://localhost:3000 — done. Database persists in ./data/.

Change port mapping (e.g. "8080:3000") for a different port. Uncomment ADMIN_PASSWORD to protect the instance. If login fails and the logs show SQLITE_READONLY (data directory created by an older version), run sudo chown -R 1000:1000 ./data once 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.

MCP Connection

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. The mcp scope 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 — read to read stashes, write for create_stash, update_stash, archive_stash and delete_stash. Until now the MCP endpoint checked only mcp, 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 mcp but without write (or without read). Its calls now come back as MCP tool errors naming the missing scope. Fix: issue a new token with read, write and mcp and 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 endpoint GET /api/mcp-onboarding and docs/mcp.md named only mcp until this release — a token created by following those two must be reissued. Unaffected: tokens that already carry read/write/mcp (or admin), and the local stdio transport, which carries no token at all.

MCP Tools

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

Documentation

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

Development

Prerequisites: Node.js 20.9+ — the floor declared in package.json (engines: { "node": ">=20.9.0" }), so npm install prints an EBADENGINE warning on 20.0–20.8. 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:checktsc --noEmitlinttestbuild, 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.

License

MIT