Skip to main content
Glama
README.md
# global-memory — cross-client global memory for AI instruction presets

**English** | [简体中文](README.zh-CN.md)

Tell an AI a **reusable requirement** once ("always use a formal tone in emails", "write commit messages in English"), confirm it, and it is stored for the long term. From then on, every connected AI tool (Claude Code / Claude Desktop / Codex CLI / Gemini CLI) recalls it automatically by scope — and a **trust curve** decides whether to ask you again before applying it.

Unlike "fact memory" products such as OpenMemory, this stores **behavioral constraints you place on the AI**. The core promise is **control**: nothing is saved without your confirmation, presets can be confirmed before they apply, every action leaves a visible trace, and everything can be uninstalled in one command. The full design is in [DESIGN.md](DESIGN.md) (Chinese).

- **What it is**: an MCP server (stdio) + a management CLI + a local web admin
- **Runtime**: Node ESM, no build step; all dependencies are pinned inside the project directory (`./pixi` + `node_modules`) — nothing is installed system-wide
- **Memory data**: `~/.global-memory/memories.json` (outside the repo, shared by all clients)
- **Platform**: currently verified on macOS (Apple Silicon) only — `pixi.toml` targets `osx-arm64` and consent dialogs use `osascript`; other platforms fall back to in-conversation confirmation
- **Language**: CLI output, dialogs, the web admin, and the generated SKILL.md are currently in Chinese

---

## Quick start

```bash
git clone https://github.com/chy4pro/global-memory-mcp.git
cd global-memory-mcp
./pixi install && ./pixi run setup    # project-local Node + npm deps (pixi bootstraps itself into ./.pixi-home on first run)
./bin/global-memory setup --dry-run   # preview which files would be written
./bin/global-memory setup             # connect every detected AI tool on this machine
./bin/global-memory status            # show integration status
```

`setup` only touches clients it **detects**, and does four things (all backed up, marked, idempotent, and reversible):

1. **MCP registration**: writes each tool's config (Claude Code `~/.claude.json`, Claude Desktop `claude_desktop_config.json`, Codex `~/.codex/config.toml`, Gemini `~/.gemini/settings.json`), all pointing at `bin/global-memory` (a self-contained launcher that uses the project-local Node). An existing same-named entry written by someone else is skipped, never overwritten
2. **Skill links**: the canonical workflow SKILL.md lives only in `~/.global-memory/skills/global-memory/`; each tool's skills directory gets a symlink — edit once, every tool picks it up (falls back to a version-marked copy if symlinks fail)
3. **L1 hook** (Claude Code): a SessionStart hook in `~/.claude/settings.json` deterministically injects applicable presets
4. **L2 standing instructions** (Codex/Gemini): a marked section appended to `AGENTS.md` / `GEMINI.md`

Original files are backed up with timestamps to `~/.global-memory/backups/` before any change. Afterwards, whenever a client launches the server it **self-heals**: it restores a missing canonical skill / skill link, hook, or instruction section — but **never touches MCP registration**.

> The configs store the launcher's **absolute path**. If you move the repository, run `uninstall` and then `setup` again.

## How it works

- **Recall**: at the start of a task the AI calls `recall_presets` (with the project name and task type). Presets not yet due for review apply directly; due ones go through the **consent broker**:
  - Local macOS session: due presets are merged into **one checklist dialog** (all pre-selected, at most 8 per dialog; unchecking = rejecting that preset; "hand over to chat" = handle them one by one in the conversation; after 60 s of no input each preset is resolved by its `unattended_policy`). If only one preset is due, a single confirm dialog with a 45 s countdown is used instead
  - Non-macOS, SSH sessions, or `GLOBAL_MEMORY_CONSENT=conversation`: falls back to one-by-one confirmation in the conversation; the AI reports results via `record_usage`
  - The outcome is announced in a one-line `user_notice` (composed by the server, relayed verbatim by the model); **nothing is shown when there is nothing to report**
- **Unattended**: `mode=unattended` (scheduled jobs, etc.) never shows dialogs and resolves by `unattended_policy` — `apply` / `skip` / `by_trust` (apply if `harmless` or trust ≥ L2, otherwise skip); `always_ask` presets are never auto-applied. Unattended decisions go into a **pending re-confirmation** backlog
- **Risk tiers**: each preset has a `risk` tier — `harmless` (preferences with no bad outcome, e.g. language/format: confirmed once when saved, **never prompts again**) / `normal` (default, follows the trust curve) / `sensitive` (destructive operations, security, credentials: never batched, always a single dedicated confirmation). The AI proposes the tier at save time and you approve it together with the save
- **Trust curve**: a fixed, explainable ladder — L0 asks every time → L1 review after 1 auto-apply → L2 after 3 → L3 after 7 days → L4 after 30 days → L5 after 90 days (cap). An explicit confirmation moves up one level; a rejection or override halves the level; **silence is not consent** — unattended applications never advance the curve. `confirm_policy` can pin a preset to `always_ask` / `always_auto`
- **Saving**: the AI spots a durable requirement → proposes a scope (global / project / task type + free-form category) → you confirm → it is stored (on the dialog channel the server shows its own confirmation dialog as a guarantee; rejection or timeout means it is not saved). Duplicates are detected automatically, and existing presets in the same scope are returned so the AI can check for contradictions
- **Correction**: when you override an applied preset on the spot, the AI must point it out and diagnose with one question — one-off exception / scope too broad / outdated / badly worded — and handle each case accordingly
- **Management**: say "show / tidy up my memories" to the AI — browse, search, edit, disable, delete, and deep consolidation (semantic de-duplication / disabling stale presets / clustering presets into a dedicated skill)
- **SessionStart injection** (Claude Code): the hook runs `global-memory recall-context`, uses the current directory name as the project name, and lists applicable presets plus the pending re-confirmation count — informational only, no dialogs, no usage counting

### MCP tools

| Tool | Purpose |
| --- | --- |
| `recall_presets` | Recall and resolve applicable presets (applied / skipped / pending_confirmation / backlog / suggestions) |
| `record_usage` | Report confirmation results gathered in conversation (confirmed / rejected / overridden) |
| `save_requirement` | Save a durable requirement the user has confirmed |
| `list_memories` / `update_memory` / `delete_memory` | Browse, edit, delete |
| `memory_overview` | Statistics and health checks |
| `start_consolidation` / `apply_consolidation` | Deep consolidation: produce proposals → apply atomically after user approval |

## Configuration (environment variables)

| Variable | Effect |
| --- | --- |
| `GLOBAL_MEMORY_CONSENT` | `auto` (default: dialogs on a local macOS session, conversation otherwise) / `dialog` / `conversation` (if you dislike pop-ups) |
| `GLOBAL_MEMORY_BATCH_CAP` | Max presets per checklist dialog (default 8 — an attention budget) |
| `GLOBAL_MEMORY_NO_AUTO_SYNC=1` | Disable self-healing on server start |
| `GLOBAL_MEMORY_DIR` | Data directory (default `~/.global-memory`) |
| `GLOBAL_MEMORY_AI` | Pin the AI provider: `claude` / `codex` / `gemini` (auto-detected by default) |
| `GLOBAL_MEMORY_RAW_DIR` | Output directory for `extract-raw` (default `<repo>/raw-memories`) |
| `GLOBAL_MEMORY_HOME` | Fake HOME from which all client paths are derived (for tests) |

## Memory migration and built-in AI features

The tool can **call the AI CLIs already installed on your machine** (claude / codex / gemini — auto-detected, falls back to the next on failure, no API key needed):

```bash
./bin/global-memory extract-raw [--clean]  # collect memories from every local AI tool → raw-memories/ (with provenance)
./bin/global-memory distill                # have an AI distill raw memories into presets, then review repeatedly until clean
./bin/global-memory web [port]             # web admin, default http://127.0.0.1:7777
```

`extract-raw` details:

- Memory sources: Claude Code user-level `CLAUDE.md` and per-project `memory/`, Codex `AGENTS.md`, Gemini `GEMINI.md` (this tool's own marked sections stripped), and this tool's existing preset store
- Full transcripts are copied verbatim (no provenance header, so the formats stay valid; they are **not** fed into distill or search): Claude Code session jsonl, Codex `sessions/` rollouts + `history.jsonl`, Gemini `tmp/<project>/chats/session-*` + `logs.json`
- Codex / Gemini sources are allow-listed, so credential files such as `auth.json` and `oauth_creds.json` are not copied; however `~/.hermes` and `~/.openclaw/memory` (if present) are collected as whole directories — every md/txt/json file under 1 MB — **without credential filtering**
- Claude Desktop chats live in the cloud; there is no local plaintext to extract

> ⚠️ `raw-memories/` is a **plaintext copy** of your local AI memories and full conversation transcripts. It is excluded in `.gitignore` — never commit or share it.

Presets produced by `distill` always start at **L0 trust** — you are still asked the first time each one is used; AI consolidation never bypasses consent.

**Web admin** (zero-dependency `node:http`, listens on `127.0.0.1` only): statistics and health checks, search/filter, enable/disable/delete, risk-tier tags, plus **AI management** — give an instruction in natural language ("merge and tighten the communication presets"); the AI only produces proposals, and **nothing runs until you approve them one by one or all at once**. The **Raw memories** section at the bottom browses every `extract-raw` file read-only (grouped by source), with instant plain-text search (line excerpts + highlighting, no AI) and AI semantic search (relevant files + reasons; hallucinated paths are filtered out).

> ⚠️ The web admin has no login and no Origin/CSRF checks: while it is running, a malicious web page open in your browser could in theory send modifying requests to `127.0.0.1:7777`. Stop it with Ctrl+C when you are done.

## Command line

```text
Install & maintain
  global-memory setup [--dry-run]                 connect local AI tools
  global-memory status                            show per-tool integration status
  global-memory uninstall [--dry-run] [--purge]   revert all writes (--purge also deletes memory data)

Manage the store (day to day, just tell the AI "manage memories")
  global-memory list [--all]                      list presets (--all includes disabled/archived)
  global-memory show <id>                         full JSON of one preset
  global-memory enable|disable <id>               enable / disable
  global-memory rm <id>                           delete
  global-memory stats | export | path             stats & health / export whole store as JSON / storage path

Migration & AI consolidation
  global-memory extract-raw [--clean] | distill | web [port]

Internal
  global-memory                                   start the MCP server (stdio)
  global-memory recall-context                    called by the Claude Code SessionStart hook
```

pixi tasks work too: `./pixi run serve`, `./pixi run cli <subcommand>`.

## Client support

| Client | MCP | Local skill | Recall guarantee |
| --- | --- | --- | --- |
| Claude Code (CLI / Desktop Code / IDE) | ✓ | ✓ symlink | SessionStart hook (deterministic) |
| Codex CLI | ✓ | ✓ symlink | `AGENTS.md` standing instructions |
| Gemini CLI | ✓ | ✓ symlink | `GEMINI.md` standing instructions |
| Claude Desktop (Chat mode) | ✓ | ✗ (platform limitation) | MCP server instructions as fallback |

## Data & privacy

All personal data lives **outside** the repo (except `raw-memories/`, which is git-ignored):

| Location | Contents |
| --- | --- |
| `~/.global-memory/memories.json` | The preset store (JSON + file lock + atomic writes) |
| `~/.global-memory/skills/global-memory/` | Canonical SKILL.md |
| `~/.global-memory/backups/` | Timestamped backups taken by setup / uninstall before editing configs |
| Each client's config | MCP registration, skill symlink, hook, marked sections in `AGENTS.md` / `GEMINI.md` |
| `<repo>/raw-memories/` | `extract-raw` output (git-ignored) |

Uninstall: `./bin/global-memory uninstall` (removes only content marked as written by this tool; data is kept); `--purge` also deletes `~/.global-memory`.

## Development & testing

```bash
./pixi run test    # 45 tests: trust / store / consent / setup (fake HOME) / ai-pipeline (stub) / server (real stdio end-to-end) / web API
```

All tests use temporary directories (`GLOBAL_MEMORY_DIR` / `GLOBAL_MEMORY_HOME` / `GLOBAL_MEMORY_RAW_DIR`), and dialogs and AI calls are stubbed, so **your real environment is never touched**.

Design document (Chinese): [DESIGN.md](DESIGN.md)

### Source map

| File | Responsibility |
| --- | --- |
| [src/cli.js](src/cli.js) | Entry point; no args = start the MCP server, subcommands = install / manage / migrate / web |
| [src/server.js](src/server.js) | MCP server + the 9 tool definitions; triggers self-heal on start |
| [src/store.js](src/store.js) | Storage: JSON + file lock + v1→v2 migration + scope matching + health heuristics + atomic consolidation |
| [src/trust.js](src/trust.js) | Trust curve: ladder scheduling, confirm-to-promote / reject-to-halve, unattended resolution, system suggestions |
| [src/consent.js](src/consent.js) | Consent broker: osascript single/checklist dialogs / conversation fallback / direct resolution |
| [src/notice.js](src/notice.js) | `user_notice` text (composed by the server, relayed verbatim by the model) |
| [src/clients.js](src/clients.js) | Client adapter matrix (detection / config / skills / hook paths) |
| [src/setup.js](src/setup.js) | setup / status / uninstall / self-heal; backup-and-merge, no clobbering, idempotent |
| [src/skill-template.js](src/skill-template.js) | Canonical SKILL.md content (four-duty skeleton + red lines) + version marker |
| [src/extract.js](src/extract.js) | Enumerates local memory sources and extracts them into `raw-memories/` |
| [src/ai.js](src/ai.js) | AI provider layer: detect/invoke local claude/codex/gemini CLIs, fallback, JSON parsing |
| [src/distill.js](src/distill.js) | Consolidation engine: raw → AI distillation into the store → iterative review |
| [src/web.js](src/web.js) | Zero-dependency web admin (`node:http`, 127.0.0.1 only) |
| [bin/global-memory](bin/global-memory) | Self-contained launcher: runs the CLI with the project-local pixi Node |
| [test/](test/) | Unit tests + fake-HOME install flow + AI pipeline stubs + real stdio end-to-end + web API |

## Roadmap (Phase 2+, not implemented yet)

npm release (configs switch to `npx -y`) | Linux/Windows dialogs | MCP sampling enhancements | guided graduation of presets into skills | BYOK scheduled consolidation | cloud sync / team sharing. See [DESIGN.md](DESIGN.md) §12.

## License

[MIT](LICENSE)

TDQS

A3.8/5.0

Scored across 9 tools

Disambiguation4/5

Most tools have clearly distinct roles: recall/record_usage, list/overview, and start_consolidation/apply_consolidation are well separated. The only potential confusion is between update_memory and apply_consolidation (both can modify presets) and between delete_memory and apply_consolidation's delete, but the usage context (direct user action vs. consolidation workflow) disambiguates them.

Naming Consistency4/5

Eight of nine tools follow a consistent verb_noun pattern (record_usage, list_memories, update_memory, start_consolidation, apply_consolidation, recall_presets, save_requirement, delete_memory). memory_overview breaks the pattern by being noun_noun, but it is still readable and clearly the odd one out.

Tool Count5/5

Nine tools is a well-scoped size for a memory/preset management server. Each tool covers a distinct operation or workflow stage—CRUD, recall, usage reporting, and consolidation—without redundancy or bloat.

Completeness5/5

The tool surface covers the full lifecycle: save_requirement creates presets, list_memories/memory_overview/recall_presets read them, update_memory plus apply_consolidation handle updates/disable/archive, and delete_memory covers deletion. The two-phase consolidation workflow and record_usage for outcome tracking round out the domain with no obvious gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues