Skip to main content
Glama
osaken55

mcp-memory-graph

by osaken55

mcp-memory-graph

A personal memory MCP server for Obsidian / markdown vaults — semantic + keyword + tag + time-aware co-occurrence hybrid retrieval, shared across 3 AI clients (Claude Code / Codex / agy).

Built for complex-systems thinkers who refuse to delete old memories. Every note stays forever; you just retrieve it better.

CI License: MIT


Why this exists

You started keeping a memory file alongside your AI assistant. It worked. Then your MEMORY.md index passed the 24KB read limit and your AI couldn't even load it. The obvious fix is "compress" — but that means deleting things you might need next year.

This server takes the other path: keep everything, retrieve smarter.

Related MCP server: Grove

The 4 principles

  1. Memory is permanent. Old notes are not garbage — they're future re-discoveries waiting to happen.

  2. Separate inject from retrieve. Boot-time context stays tiny; everything else is pulled on demand via MCP tools.

  3. Honor complex-systems thinking. One keyword should pull 3–5 related memories by meaning, structure, AND time.

  4. Evolve without breaking. Adding a new note never invalidates indexing. Old notes resurface naturally.

How it retrieves

Four signals merge into a single hybrid score:

Signal

Source

Weight (default)

Semantic

Voyage AI embeddings (default model: voyage-multilingual-2)

0.5

Keyword

ripgrep --json over markdown body (with Node.js fallback)

0.3

Tag

metadata.type + wikilinks + filename tokens

0.2

Co-occurrence

"Memories accessed together in the same session" (Phase 3)

0.2 (addition planned)

Weights are overridable per environment:

MEMORY_WEIGHTS="semantic=0.5,keyword=0.3,tag=0.2"

Tools

Tool

Purpose

memory.search

Hybrid retrieval with recency tie-breaker

memory.get

Read one memory + (optional) auto-prefetch top-2 related

memory.related

Related memories via wikilink, tag, semantic distance

memory.recent

Sorted by last_accessed (SQLite)

memory.by_tag

Filter by metadata.type

memory.by_session

Cluster memories born in the same conversation session (originSessionId)

memory.list_archived

Hybrid search without recency boost (surfaces older notes)

Install

git clone https://github.com/osaken55/mcp-memory-graph.git
cd mcp-memory-graph
npm install
npm run build
npm test

Default paths:

MEMORY_DIR     = ~/.claude/projects/.../memory/
MEMORY_DB_PATH = ~/.claude/memory-mcp/cache.db        # SQLite is OUTSIDE the memory dir
VOYAGE_MODEL   = voyage-multilingual-2                # override with env

Phase 0 — smoke test (no MCP client needed)

node dist/bin/probe.js

Reports how many .md files are readable, how many have/lack frontmatter, and which iCloud / Syncthing artifacts were excluded. Read-only — zero writes.

Register with the 3 AI clients

Claude Code (CLI / Plugin)

~/.claude/settings.json:

{
  "mcpServers": {
    "memory-graph": {
      "command": "mcp-infisical-env",
      "args": ["--", "node", "/Users/junshu/Documents/Projects/mcp-memory-graph/dist/index.js"],
      "env": {
        "MEMORY_AUTO_PREFETCH": "true"
      }
    }
  }
}

Codex (OpenAI Codex CLI / Desktop)

~/.codex/config.toml (or via codex mcp add):

[[mcpServers]]
name = "memory-graph"
command = "mcp-infisical-env"
args = ["--", "node", "/Users/junshu/Documents/Projects/mcp-memory-graph/dist/index.js"]

agy (Antigravity CLI)

Use agy's MCP config or wrap in agy-with-context:

# Agy doesn't natively load MCP servers in CLI mode yet;
# in the Antigravity IDE the server registers via the same MCP config above.

All three clients hit the same SQLite cache. last_accessed, embedding cache, and co-occurrence stats are shared — your 3 AI workforce really has one shared memory.

Why voyage-multilingual-2 by default

The author's memory is roughly half Japanese, half English (Obsidian Vault notes from a Japanese small business owner). On benchmarks, voyage-multilingual-2 outperforms voyage-3.x on mixed-language retrieval. Pure-English vaults should override with VOYAGE_MODEL=voyage-3-large.

Comparison

Axis

Typical mcp-memory

mcp-memory-graph

Storage

Internal DB

Existing flat markdown directory

Migration

Imports / rewrites

Zero-destructive — never edits your notes

Search

Keyword OR vector

Semantic + keyword + tag (+ co-occurrence) hybrid

Recency

Often implicit

SQLite last_accessed, outside memory dir

Multilingual

English-tuned

voyage-multilingual-2 default

Failure handling

Vector API down = broken

Falls back to keyword + tag automatically

ripgrep absent

Crashes

Node.js readline + RegExp fallback

Sync artifacts (iCloud / Syncthing)

Pollutes index

Excluded by glob

Same-session clustering

None

memory.by_session(originSessionId)

Auto prefetch

Manual related call

Opt-in MEMORY_AUTO_PREFETCH=true

Roadmap

  • Phase 0 ✅ Probe — non-destructive read of every markdown file.

  • Phase 1 ✅ Hybrid skeleton, 7 tools, SQLite last_accessed, ripgrep + Node.js fallback, iCloud-exclude.

  • Phase 2 ✅ Voyage embedding cache, content-hash dedup, multilingual default model, semantic + keyword + tag merged.

  • Phase 3 ✅ Time-aware co-occurrence table (co_access), 4th signal in memory.related, in-memory ring buffer auto-records pairs from memory.get / memory.search.

  • Phase 4npx mcp-memory-graph init zero-config bootstrap; Jaccard coefficients for wikilink / tag signals.

  • (next) Local embedding fallback via @xenova/transformers; multi-tag arrays; tag taxonomy beyond metadata.type.

Real-world numbers (from the author's vault)

Built on a real corpus of 130 personal markdown memories (mix of Japanese + English).

Operation

Result

Phase 0 probe

131 files / 123 with frontmatter / 0 errors

Phase 1 memory.search("CTO")

top-1 score 1.000, expected hit at top

Phase 2 Voyage indexing

204 s for 130 files, ~$0.015 (0.26% of free tier)

Phase 2 semantic query "責任を取って判断する役割" (no keyword overlap)

top-1 = CTO role memory (score 0.464)

Phase 2 multilingual: English query → Japanese memory

top-1 score 0.555

Phase 3 co-occurrence smoke

"memories from the same session cluster correctly"

License

MIT — see LICENSE.

Acknowledgements

This server was designed in a 3-AI parallel review pattern that the project author has been refining for months:

  • agy (Gemini 3.5 Flash High) wrote the Python design draft.

  • Codex (GPT-5.x) wrote the TypeScript scaffold and ADRs.

  • Claude Code (Opus 4.7) wrote the CTO integration review and added the 6 unique observations (Phase 0 probe, time-aware co-occurrence, originSessionId clustering, auto-prefetch, zero-config init, the name itself).

  • The owner (オサケンさん) wrote the principles.

If three AIs and a complex-systems thinker can build a better personal memory, so can yours.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    MCP server that exposes a local Obsidian vault as persistent, searchable memory for AI agents, with hybrid retrieval, reranker, and PDF support.
    34
    88 npm
    33
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    An open-source MCP server that makes your Obsidian vault accessible from any AI client with hybrid search, read/write, and graph analysis capabilities.
    3 npm
    23
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Local-first AI Memory MCP server for AI agents to search and manage knowledge stored in Obsidian vaults, optimized for CJK languages with zero AI dependency.
    2
    MIT