Skip to main content
Glama
Luisarg03

memory-vault-server

by Luisarg03
README.md
# dsh-memory-vault

![DeepSeek Harness](https://img.shields.io/badge/DeepSeek%20Harness-dsh-4D6BFE?logo=deepseek)
![Cordis 4.0.1](https://img.shields.io/badge/Cordis-4.0.1-6C5CE7)
![pnpm 10.15.0](https://img.shields.io/badge/pnpm-10.15.0-F69220?logo=pnpm)
![Node.js ≥22.18](https://img.shields.io/badge/Node.js-%E2%89%A522.18-339933?logo=nodedotjs)
![TypeScript 5.9](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript)
![Python ≥3.11](https://img.shields.io/badge/Python-%E2%89%A53.11-3776AB?logo=python)
![uv 0.11](https://img.shields.io/badge/uv-0.11-0B0B0F?logo=uv)
![MCP ≥1.2](https://img.shields.io/badge/MCP-%E2%89%A51.2-7C3AED)
![SQLite FTS5](https://img.shields.io/badge/SQLite-FTS5-003B57?logo=sqlite)
![Vitest 3.2](https://img.shields.io/badge/Vitest-3.2-6E9F18?logo=vitest)
![tsdown 0.15](https://img.shields.io/badge/tsdown-0.15-38BDF8)
![oxlint 1.13](https://img.shields.io/badge/oxlint-1.13-FF6B6B)

Persistent OKF memory for [DeepSeek Harness](https://deepseek-harness.github.io/deepseek-harness/) (DSH):
a Python MCP server (SQLite FTS5 + Markdown), two Cordis plugins (`memory-mcp`, `memory-auto`)
and a vault starter with templates and a type registry.

![Stack architecture](docs/diagrams/stack.png?v=2)

![Session digest pipeline](docs/diagrams/session-digest.png?v=2)

## Components

| Component | What it does | Bundle |
|---|---|---|
| `memory-mcp` | MCP stdio wrapper: connects DSH to the memory vault server | `@luisarg/memory-mcp` |
| `memory-auto` | Auto memory capture: session digest with commit/compaction checkpoints | `@luisarg/memory-auto` |
| `memory-vault-server/` | Python MCP server: SQLite FTS5 + Markdown OKF | — |
| `memory-vault/` | Vault starter: templates + type registry + tag vocabulary | — |
| `scripts/digest_session.py` | Optional standalone post-session digest (CLI, not used by the plugins) | — |

## Quickstart

```sh
pnpm install
pnpm -r build

# local dev with an overlay (paths relative to the repo cwd)
dsh web --patch ./examples/dev-memory.cordis.yml
```

## Install

```sh
# 1. install both plugins (npm, prebuilt — no build approvals, no repo clone)
dsh plugin --profile web add @luisarg/memory-mcp@0.1.4 @luisarg/memory-auto@0.1.4

# 2. launch — first boot installs the vault server + starter under $DSH_HOME
#    (~/.dsh/memory-vault-server and ~/.dsh/memory-vault) automatically
dsh web

# verify
dsh --profile web --dump-config | grep -A8 memory
```

> `uv` on PATH is recommended but no longer required: the bundled
> `launcher.mjs` runs the server with `uv run` when uv is present and falls
> back to a pip-managed venv (`python3 -m venv` + `pip install -r
> requirements.txt`, first boot needs network) when it is not. The packages
> are self-contained: they ship the Python vault server and the OKF vault
> starter, and copy them into place on first boot (existing files are never
> overwritten; upgrades copy only the missing `launcher.mjs` and
> `requirements.txt`). The version is pinned because
> pnpm's default `minimumReleaseAge` (3 days) would otherwise resolve an
> older release. Paths resolve as: env
> (`DSH_MEMORY_PATH`, `DSH_MEMORY_SERVER_DIR`) → `$DSH_HOME/memory-vault(-server)`
> → profile patch (see [Path resolution](#path-resolution-cwd-independent)).
> Launch from any directory.

**Developers** (local checkout instead of npm):

```sh
dsh plugin --profile demo add ./packages/memory-mcp ./packages/memory-auto
```

**Offline**: `pnpm --filter @luisarg/memory-mcp pack` and add the `.tgz` files.

Installing the repo root from GitHub is **not** supported (root has no
`dsh.bundle`; pnpm lacks git subdirectory specs) — use npm or the tarball.

Releases are published by CI: pushing a `v<version>` tag builds, tests,
validates the tarballs and publishes both packages to npm with a
[provenance attestation](https://docs.npmjs.com/generated-provenance-statements),
authenticated by GitHub OIDC — no publish token exists in this repository or on
the maintainer's machine. What runs before an artifact ships, and the guardrails
around it, are in [`docs/releasing.md`](docs/releasing.md#security-layers-around-the-release).

## Usage & interaction commands

Once installed, the agent can read and write the vault through the
`mcp__memory__*` tools — just ask it in the chat:

| You say | Tool the agent uses |
|---|---|
| "search your memory for `<topic>`" | `mcp__memory__search_memory` |
| "remember this: `<fact/decision>`" | `mcp__memory__store_decision` / `store_fact` / … |
| "export everything you know about `<project>`" | `mcp__memory__export_memories` |
| "summarize my profile" | `mcp__memory__get_profile` |

**Automatic capture** (`memory-auto`): git commits, compactions and session
ends trigger digests; idle checkpoints capture when there is activity. Digests
log as `[memory-auto] …` lines in the harness console, and writes land under
`<vault>/projects/<project>/<type>/` (Markdown) + the SQLite FTS5 index.

**Verify the installation and the stored memory:**

```sh
# composed config shows both bundles with the resolved paths
dsh --profile web --dump-config | grep -A8 memory

# what the vault holds (default vault: ~/.dsh/memory-vault)
ls ~/.dsh/memory-vault/projects/               # per-project OKF entries
grep -i "digest" ~/.dsh/memory-vault/log.md    # digest markers

# talk to the vault MCP server directly (standalone smoke test)
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"cli","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"ping","arguments":{}}}' \
  | MEMORY_PATH=$HOME/.dsh/memory-vault uv run --directory memory-vault-server python server.py
```

**Run a second harness instance on another port** (for testing without touching
your main session):

```sh
pnpm dsh web --port 3090
```

### Second MCP client: opencode (zona central `~/.memories`)

Since 2026-09-09 the vault lives in a dedicated git repo at `~/.memories`
(union of the former DSH vault and the legacy `opencode-memory-vault`
bundle; see [`docs/central-zone.md`](docs/central-zone.md)). opencode is a
second stdio MCP client over the same server and vault — `~/.config/opencode/opencode.json`:

```json
"mcp": {
  "memory-server": {
    "type": "local",
    "command": ["uv", "run", "--directory", "<repo>/memory-vault-server", "python", "server.py"],
    "enabled": true,
    "environment": { "MEMORY_PATH": "/home/hiro03/.memories" }
  }
}
```

> opencode requires the key **`environment`** (not `env` — that one is
> silently ignored and the server falls back to the repo default vault).

## Memory stack

The plugins work on an OKF vault (`memory-vault/` in this repo, or your own).
Runtime: `uv` on PATH, or Python ≥3.11 with a network on first boot — both
launch paths go through the bundled `launcher.mjs`, which uses `uv run` and
falls back to a pip-managed `.venv` (`requirements.txt`) when uv is missing.

The post-session digest runs **in-process** through the harness's own LLM
service (`ctx.llm`, provider `deepseek-official` by default — configurable with
`provider`/`model`), so the plugins need no external CLI and store no
credentials: they use the same key DSH is configured with.

### Path resolution (cwd-independent)

DSH does **not** chdir — the launch directory is irrelevant. Paths resolve in
this order:

1. Env vars (override everything): `DSH_MEMORY_PATH`, `DSH_MEMORY_SERVER_DIR`.
2. Defaults under the **harness home**: `$DSH_HOME/memory-vault` and
   `$DSH_HOME/memory-vault-server` (`~/.dsh` when `$DSH_HOME` is unset).
3. Profile patch (`cordis.patch.yml`) or `--patch` overlay with explicit values.

| Env var | Used for | Default |
|---|---|---|
| `DSH_MEMORY_PATH` | vault directory | `$DSH_HOME/memory-vault` |
| `DSH_MEMORY_SERVER_DIR` | directory with `server.py` (MCP server) | `$DSH_HOME/memory-vault-server` |

```sh
# run the MCP server standalone:
MEMORY_PATH=./memory-vault uv run --directory ./memory-vault-server python server.py
```

### Vault

`memory-vault/` is an OKF bundle: `templates/` (per-type templates),
`type-registry.yaml` (source of truth for types), `tag-vocabulary.json`
(tag normalization). Runtime data (`projects/`, `raw/`, `logs/`, `memory.db`)
is created by the server on first use and excluded from git (`.gitignore`).

## Architecture & diagrams

Interactive versions of the diagrams (standalone HTML, open in any browser):

- [stack.html](docs/diagrams/stack.html) — architecture
- [session-digest.html](docs/diagrams/session-digest.html) — dataflow
- [mcp-tool-call.html](docs/diagrams/mcp-tool-call.html) — sequence
- [capture-lifecycle.html](docs/diagrams/capture-lifecycle.html) — lifecycle

Editable specs live in `docs/diagrams/*.json` (generated with
[archify](https://github.com/tt-a1i/archify)). Full write-up:
[`docs/architecture.md`](docs/architecture.md); index: [`docs/README.md`](docs/README.md).

## Repository layout

```
packages/memory-mcp/          # cordis bundle: MCP stdio client to the vault
packages/memory-auto/         # cordis bundle: automatic session digest
memory-vault-server/          # Python MCP server (SQLite + Markdown OKF)
memory-vault/                 # vault starter (templates + type registry)
scripts/digest_session.py     # optional standalone digest CLI (not used by the plugins)
examples/dev-memory.cordis.yml      # memory-mcp
examples/dev-memory-auto.cordis.yml # memory-mcp + memory-auto
```

## Layer order

1. `dsh.profile.bundles` (base + every installed bundle)
2. `$DSH_HOME/profiles/<name>/cordis.patch.yml`
3. `$DSH_HOME/cordis.patch.yml`
4. `--patch` overlays

Patch replaces `config` wholesale — it does not merge.

## Troubleshooting pnpm

- `unable to open database file` → the pnpm store is not writable in a sandboxed
  environment. Use `--store-dir ./.pnpm-store` on every `pnpm install` and on
  `dsh plugin --profile X --store-dir ./.pnpm-store add ...`.
- `dsh: pnpm failed` when installing from GitHub → only applies to packages with
  a `prepare` script; copy the printed key into the profile's
  `pnpm-workspace.yaml` (allowBuilds). Note: the subpackages of this monorepo
  cannot be installed with `github:...` (pnpm has no git-subdirectory support) —
  use npm or a tarball.

## Docs

- [`docs/`](docs/README.md) — public documentation (architecture + diagrams)
- [Releasing & version tags](docs/releasing.md) — which commit each `v*` tag maps to
- [Your first plugin](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/)
- [Build a tool](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/tool)
- [Plugin configuration](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/config)
- [Package and install](https://deepseek-harness.github.io/deepseek-harness/en/develop/basic/publish)