Graph-Memory
Graph-Memory is an MCP server for a Neo4j-backed personal knowledge graph that lets Claude query, write, maintain, and audit weighted, bi-temporal, semantically searchable memory.
Query entities by canonical name, browse/search the entity catalog, and traverse relationships with filters for type, weight, current facts, and project context.
Run semantic natural-language searches using local embeddings, expand into graph neighborhoods, and build session context bundles.
Create or strengthen entities and relationships in single or atomic batch mode, with aliases, provenance, weights, evidence, and validity dates.
Confirm or correct recalled facts by boosting/weakening edges, or delete erroneous entities.
Detect contradictions and knowledge communities, surface duplicate merge suggestions, and merge or unmerge entities.
Maintain graph health with decay previews/application, pruning, validation, embedding regeneration, and stats dashboards.
Export JSONL backups, ingest documents for asynchronous extraction, and read/parse Claude Code transcripts.
Record structured dream/audit events and run admin-only read-only Cypher queries for custom analysis.
Support OAuth-secured multi-device use across Claude Code, Claude Desktop, and claude.ai web in the documented deployment.
Uses Neo4j as the graph database to store and query entities, relationships, embeddings, and metadata for the knowledge graph.
Graph Memory
A personal knowledge graph for Claude that survives across sessions, devices, and tools. Built on Neo4j with semantic embeddings, OAuth-secured for use from Claude Code, Claude Desktop, and claude.ai web — all hitting the same graph.
https://github.com/user-attachments/assets/826e5f5a-5759-4b31-83dd-6bd7e0e044b8
Asked from my phone. Pulls a decision made days ago on my laptop, citing the commit hash.
No external API keys or per-token costs by default. Entity extraction runs inside your Claude sessions on your Claude plan. Embedding runs locally via bge-small-en. Everything stays on your hardware unless you choose to expose it. If you'd rather pay per token, an optional runner moves the nightly dream and weekly maintenance to an Anthropic API key (see API-key runner).
Why a graph
Built-in memory in Claude Code is "append facts to markdown, grep later." That gets you 80% there but breaks at scale: no relationships, no confidence, no decay, no contradiction detection, no temporal awareness. Two memories that reinforce each other look identical to two memories that contradict each other.
This project replaces flat keyword matching with weighted, relationship-aware retrieval:
Weighted edges with configurable decay — frequently-confirmed knowledge stays strong; stale information fades naturally on per-type half-lives (preferences ~693 days, events ~99 days)
Bi-temporal validity — separate
valid_at(when fact was true),invalid_at(when superseded),ingested_at(when learned). Old facts get marked invalid rather than deletedSemantic + structural search — vector embeddings find conceptually similar entities; graph traversal then expands through real relationships
Project-context affinity — when you're working in a specific project, related entities surface first
Contradiction detection — conflicting facts are flagged, not silently coexisting
Full provenance — every edge traces back to the conversation, transcript, or document that sourced it
Dream process — a scheduled Claude session reviews recent transcripts and ingest documents overnight, extracts new knowledge, applies decay, and writes a changelog
Related MCP server: mem0-mcp-selfhosted
Architecture
Claude Code Claude Desktop claude.ai web
│ │ │
└────────── OAuth 2.1 Bearer ─────────┘
│
https://your-host.example/mcp
│
Cloudflare Tunnel
│
docker-compose
┌────────────┴────────────┐
▼ ▼
graph-memory-mcp graph-memory-neo4j
(Node 22 + jose) (Neo4j 5.20 + APOC)
port 3847 bolt://neo4j:7687
│ │
└─── bolt-internal ───────┘Two Docker services, talking over the compose network (plus an optional third, graph-dream, covered below). The MCP server is the only thing that touches Neo4j directly — it implements OAuth 2.1 itself (RS256 JWTs, public clients with PKCE-S256, RFC 7591 dynamic client registration, RFC 7009 revocation), validates bearer tokens for /mcp calls, and exposes Cloudflare Access only on /oauth/authorize for the actual user login. The Neo4j instance has no external listeners.
The dream process is just another Claude session that runs on a schedule, reads transcripts, and calls the same MCP tools any client would call — there's no separate extraction pipeline.
By default that session is a Claude Code scheduled task on your Claude plan. If you'd rather bill it to an Anthropic API key, the optional dream runner (src/dream-runner/, the graph-dream compose service under the dream profile) runs the same nightly and weekly prompts through the Messages API, with a per-run cost cap and an email summary of each run's cost. The same runner can run your other scheduled prompts on the host with only the commands, URLs and MCP tools you allow (dist/dream-runner/task.js). See API-key runner.
Two more opt-in pieces use TypeSafe's Jev, a model that returns typed judgments for a fraction of a cent each. With JEV_VERB_SELECT=on, an edge that would be stored as RELATED_TO gets a documented verb when Jev is confident, and stays RELATED_TO otherwise. With JEV_DUPLICATE_CHECK=on, the nightly runner judges graph_merge_suggestions candidates and writes them to a log for you to review; it never merges. Both are off by default and capped on cost. See Jev judgments.
Schema
Node types (19): Person, Organization, Project, Feature, Concept, Technology, Decision, Reasoning, Preference, Event, Fact, Artifact, Object, Resource, Infrastructure, Alias, Location, Issue, Task.
Edge verbs (50): grouped into people and roles (WORKS_ON, REPORTS_TO, KNOWS, …), knowledge and decisions (PREFERS, DECIDED_FOR, LED_TO, …), tech and dependencies (USES_TECH, DEPENDS_ON, IMPLEMENTS, …), composition (PART_OF, CONTAINS, INSTANCE_OF, …), reference (ABOUT, DESCRIBES, DOCUMENTS), authorship, lifecycle (SUPERSEDES, REPLACES, BLOCKS, …), place, events, and identity (ALIAS_OF, CONTRADICTS). RELATED_TO is the fallback when no specific verb fits, with a relationship_type subtype property. Writes are checked against this vocabulary; SCHEMA_ENFORCEMENT controls whether unknown verbs are coerced (default) or rejected.
Every node and edge carries:
weight(0.0–1.0) — decays over time on per-type half-livesconfidence— separate from weight, tracks the source's certaintytenant_id— multi-tenant isolation (single-user by default; multi-user-ready via OAuth email claim)embedding(nodes) — 384-dim vector for semantic searchvalid_at/invalid_at/ingested_at(edges) — bi-temporal tracking
Concise vocabulary in GRAPH_SCHEMA.md. Full reference (weights, decay, validity windows, init Cypher) in docs/GRAPH_SCHEMA_REFERENCE.md.
Tools
The MCP server exposes 24 tools across these categories:
Category | Tools |
Query |
|
Write |
|
Maintenance |
|
Operational |
|
Slash-command wrappers (/graph, /graph-ask, /graph-find, /graph-stats, /graph-boost, /graph-briefing, /graph-dream, /graph-backup, /graph-bootstrap, /graph-capture, /ingest, /ingest-audio) install into ~/.claude/skills/. Full reference: docs/SKILLS.md.
/graph-capture is the manual companion to the nightly dream: the dream extracts knowledge from Claude Code transcripts in ~/.claude/projects/, but cannot see claude.ai web conversations or Claude Desktop chats (those live server-side or in Electron app data). Run /graph-capture at the end of a substantive claude.ai or Desktop conversation to commit any new entities, decisions, or facts to the graph. Claude Code cloud sessions are different: a collector prompt (prompts/collect-cloud-sessions.md) queues their text into the ingest backlog through graph_ingest, and the nightly dream extracts it (see Cloud sessions).
Prerequisites
Required:
Node.js 22+ and npm
Docker (Desktop on Windows/macOS, or Docker Engine on Linux) with Docker Compose v2
Claude Code and/or Claude Desktop with a Claude plan that covers Claude Code access — Pro, Max, Team, Enterprise, or Console all work (the free Claude.ai plan does not include Claude Code). Pro is fine for light/exploratory use; Max is recommended for daily-use deployments because the nightly dream process can be transcript-heavy on a busy day, and an unattended run that exhausts Pro's 5-hour window will abort mid-extraction and skip that night. Running the dream on an Anthropic API key instead avoids the plan limits.
A few hundred MB of disk for Neo4j + embeddings model
Optional:
MarkItDown (
pip install "markitdown[pdf,docx,xlsx,pptx]") — enables ingesting binary documents (.pdf,.docx,.xlsx,.pptx,.epub,.msg,.csv,.xml,.png,.jpg). Without it, ingest is limited to.md,.txt,.json,.html,.srt,.vtt.yt-dlp — convenient way to grab YouTube/web video subtitle files for ingestion.
yt-dlp --write-auto-sub --sub-lang en --skip-download <url>writes a.vttyou can drop intoingest/pending/. Not a runtime dependency; just a tool that produces files graph-memory can already eat.cloudflared + a Cloudflare account — only needed for the multi-device / claude.ai web setup described in
docs/REMOTE.md. Local-only deployments don't need it.Anthropic API key — only for the optional API-key runner.
TypeSafe API key — only for the optional Jev judgments (verb selection and the duplicate check).
Python 3.10+ — required only by MarkItDown and by
scripts/sync-dream-skill.py.
Install
graph-memory has exactly one "primary device" — the machine that runs the two Docker containers (Neo4j + the MCP server) and runs the nightly dream + weekly maintenance scheduled tasks. Every other device is a "secondary device" that talks to the primary over HTTPS + OAuth — secondaries don't run their own containers and don't run their own dream process. Pick the install path that matches the role of the device you're sitting at right now.
Install — Primary Device (this device runs the containers)
Use this on the machine that will host Neo4j + the MCP server. This is also where the nightly dream and weekly maintenance scheduled tasks run, so the Claude Code transcripts you want extracted should live on this device.
Linux / macOS / Windows with Git Bash or WSL:
curl -fsSL https://raw.githubusercontent.com/stevepridemore/graph-memory/v0.6.0/scripts/install-primary.sh \
| bash -s v0.6.0
# edit ~/graph-memory/.env (NEO4J_PASSWORD, GRAPH_MEMORY_HOME, CLAUDE_PROJECTS_DIR)
cd ~/graph-memory && docker compose up -dWindows PowerShell (no bash needed):
$v = 'v0.6.0'
iwr "https://raw.githubusercontent.com/stevepridemore/graph-memory/$v/scripts/install-primary.ps1" -UseBasicParsing -OutFile $env:TEMP\gm-install.ps1
& $env:TEMP\gm-install.ps1 -Version $v
# edit $HOME\graph-memory\.env
cd $HOME\graph-memory; docker compose up -dVerify with /graph-stats in any Claude Code session.
Optional: see docs/REMOTE.md for the Cloudflare Tunnel + Access setup that lets secondary devices and claude.ai web reach this graph remotely.
Install — Secondary Device (this device just talks to the primary)
Use this on every additional laptop, work computer, or phone. No Docker, no Neo4j — just the slash commands and an MCP client config pointed at the primary device's Cloudflare Tunnel URL. The primary device must already have the tunnel set up per docs/REMOTE.md.
Linux / macOS / Windows with Git Bash or WSL:
curl -fsSL https://raw.githubusercontent.com/stevepridemore/graph-memory/v0.6.0/scripts/install-secondary.sh \
| bash -s v0.6.0 your-tunnel-host.example.comWindows PowerShell (no bash needed):
$v = 'v0.6.0'
iwr "https://raw.githubusercontent.com/stevepridemore/graph-memory/$v/scripts/install-secondary.ps1" -UseBasicParsing -OutFile $env:TEMP\gm-install.ps1
& $env:TEMP\gm-install.ps1 -Version $v -TunnelHost your-tunnel-host.example.comFirst /graph-stats call triggers the OAuth browser flow once; subsequent calls use the cached bearer token.
Install — Developer (build from source)
Use this if you want to modify graph-memory itself. Requires Node 22+ and Docker.
git clone https://github.com/stevepridemore/graph-memory
cd graph-memory
cp .env.example .env # edit as above
npm install && npm run build
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -dThe docker-compose.dev.yml override switches the MCP service from the published GHCR image to a local build: . so your edits get picked up on rebuild.
Multi-device / claude.ai web access
To use the same graph from claude.ai web, your office laptop, your phone, etc., expose the MCP server through Cloudflare Tunnel + Access. The auth flow is OAuth 2.1 with Cloudflare's IdP doing the actual user login.
Step-by-step in docs/REMOTE.md. The setup is one-time:
Cloudflare Tunnel with
cloudflaredpointing athttps://localhost:3847A single Cloudflare Access application scoped to
/oauth/authorize(everything else is public + bearer-token-protected)Server generates an RSA keypair on first run, persists it, exposes via
/oauth/jwksClaude clients hit
https://your-host.example/mcp, get a 401 with properWWW-Authenticate: Bearer ... resource_metadata="...", walk the OAuth flow, store the bearer token, and call subsequent requests with it
This makes the graph reachable from any device or AI tool that speaks MCP + OAuth 2.1.
For Claude Code on remote machines, .mcp.json.remote.example is the matching client template — copy it to ~/.claude/.mcp.json (or a project-local .mcp.json) and replace your-host.example with your tunnel hostname:
{
"mcpServers": {
"graph-memory": {
"type": "http",
"url": "https://your-host.example/mcp"
}
}
}Claude Code walks the OAuth flow on first call and caches the bearer token. claude.ai web uses its own custom-connector UI — the URL is the same.
If you use Claude Code on more than one PC and want a single dream process to ingest transcripts from all of them, see Multi-PC transcript sharing — that's a separate concern from the OAuth multi-device story above, with a one-time sync setup.
Document ingestion
Drop files into ~/graph-memory/ingest/pending/, or call graph_ingest with a file path or, from a remote caller that can't reach the server's disk, with inline text (content + file_name, up to 2 MB). The next dream run extracts entities and relationships into the graph. Native support for .md, .txt, .json, .html, .srt, .vtt. With MarkItDown installed (pip install "markitdown[pdf,docx,xlsx,pptx]"), also handles .pdf, .docx, .xlsx, .pptx, .epub, .msg, .csv, .xml, .png, .jpg, etc. — converted to Markdown first, then extracted. Original files archive to ingest/originals/<date>/.
Privacy
The graph stores personal information — names of colleagues, decisions, preferences, project details. Treat the database with the same care as a private journal:
Default deployment is local-only (Docker on
localhost); nothing leaves your machineThe optional Cloudflare Tunnel exposure adds OAuth + Cloudflare Access in front
All data lives under a directory you control (default
~/graph-memory/)A
graph_exporttool produces portable JSONL backups;~/graph-memory/backups/is auto-rotatedEmbedding model runs locally — no text leaves the machine for vector search
Entity extraction runs in your Claude sessions; same trust boundary as Claude itself. With the optional API-key runner, transcripts go to the Anthropic API under your API account instead
API keys, passwords, and secrets are explicitly excluded from extraction (see
prompts/dream-nightly.md)
Tech stack
Component | Technology |
Language | TypeScript / Node.js 22 |
Graph DB | Neo4j Community 5.20 (Docker) with APOC |
Embedding model |
|
Driver |
|
MCP framework |
|
Auth |
|
API-key runner (optional) |
|
Typed judgments (optional) | TypeSafe Jev over HTTPS |
Tunnel (optional) | Cloudflare Tunnel ( |
Testing | Vitest |
Status
All planned phases shipped:
✅ Phase 0–3: MCP server, dream process, SessionStart hook, slash commands
✅ Phase 4: Bootstrap complete (graph populated from transcripts and memory files)
✅ Phase 5: bi-temporal modeling, Reasoning entity type, semantic/vector search, community detection, build_context meta-tool
✅ Multi-tenant infrastructure (single-user by design, multi-user-ready)
✅ OAuth 2.1 + Cloudflare Tunnel for multi-device access
✅ Aura → local Neo4j migration with full data preservation
✅ OAuth 2.1 hardening: PKCE-S256 mandatory, public clients only, RFC 7009 revocation, jti tracking, refresh-token TTL 30d, redirect-URI allowlist, optional email allowlist, body-size caps (64 KB OAuth / 4 MB MCP), structured event logging
✅ Internal threat model fully resolved (16 of 16 findings closed)
✅ npm audit clean (0 vulnerabilities)
✅ Pre-built GHCR images + curl-pipeable installers (no clone or local build required for end users)
Current release: v0.6.0.
Currently steady-state. Active development is opportunistic; the system runs unattended via the nightly dream process.
Releases
Newest first. Each tag publishes ghcr.io/stevepridemore/graph-memory-mcp:<tag> and moves :latest.
Version | Date | Summary |
2026-10-27 |
| |
2026-10-27 | Optional API-key runner: the nightly dream and weekly maintenance can run on an Anthropic API key ( | |
2026-10-11 | Security and data-integrity release. Fixes Cypher injection through relation and type names, and a | |
2026-05-17 | Rule subtype for permanent preferences, exempt from decay and pruning. | |
2026-05-10 | Curl-pipeable primary/secondary device installers + pre-built GHCR image. Multi-stage Dockerfile, auto-cert generation on first run, vendored slash commands. End users no longer need to clone or build from source. | |
2026-05-09 | STRIDE threat model fully closed (16 of 16 findings). Hardens OAuth 2.1: PKCE-S256, RFC 7009 revocation, jti tracking, refresh-token TTL, redirect-URI allowlist, email allowlist, body-size caps. | |
2026-05-09 | OAuth 2.1 security hardening pass. Public clients only, mandatory PKCE, body-size caps, structured event logging. | |
2026-05-08 | Decay correctness + test coverage. Vitest in CI, decay function bug fixes. | |
2026-05-07 | Initial public release. MCP server, dream process, slash commands, bi-temporal modeling, semantic search, OAuth multi-device. |
Documentation
docs/ARCHITECTURE.md— system design, data flows, component responsibilitiesGRAPH_SCHEMA.md— concise vocabulary (node types + edge verbs) for both agent and humansdocs/GRAPH_SCHEMA_REFERENCE.md— full reference (decay functions, weight semantics, validity windows, example queries)docs/MCP_SERVER.md— every MCP tool with input/output schemasdocs/DREAM_PROCESS.md— extraction pipeline, manifest format, changelog structure, API-key runnerdocs/BACKUP.md— backups and restoredocs/SKILLS.md— slash command definitionsdocs/REMOTE.md— exposing graph-memory via Cloudflare Tunnel + Accessdocs/MULTI_TENANT.md— tenant isolation modeldocs/TESTING.md— running the test suite locally and in CICLAUDE.md— retrieval and chat-write guidelines for Claude
License
MIT — see LICENSE.
Available Tools
24 toolsgraph_aliasGraph AliasAIdempotent
Add or remove alternate names for an entity, so future writes and lookups using those names resolve to it instead of creating a duplicate node. Use when the user says two names refer to the same person or thing: a nickname, a maiden or married name, a first name used alone. Case-insensitive. An exact entity name always takes precedence over an alias. With neither add nor remove, lists the current aliases.
Inputs: entity (required), add, remove.
graph_auditDream Audit LogA
Append a structured event to the dream process audit log (logs/dream-audit.jsonl). Call this during the dream process to record run_start, run_end, transcript_start, transcript_end, entity_created, entity_resolved, edge_created, edge_modified, merge_flagged, contradiction_found, ingest_start, ingest_end, decay_applied, format_warning, or error events. entity_resolved is the audit trail for entity-resolution decisions during dream — every time the dream picks between matching an existing entity, creating a new one, or flagging an ambiguous candidate, log it here so a later graph_unmerge can reconstruct why a merge happened.
Inputs: data (required), event (required).
graph_boostGraph BoostAIdempotent
Increase an edge's weight when the user confirms recalled information. Call this when the user says 'yes', 'exactly', or confirms something you retrieved from the graph. Persists immediately; weight clamps at 1.0 so repeated boosts saturate rather than overflow. Returns the previous and new weight.
Inputs: to_name (required), relation (required), from_name (required), amount, +1 more.
graph_build_contextBuild Session ContextARead-only
Single tool call that bundles a session's worth of context: graph health, pending work, last dream run summary, recent additions, top knowledge hubs, unresolved contradictions, and (optionally) a topic neighbourhood. Use this at session start instead of running graph_stats / graph_query / graph_contradictions separately. Cuts 4-5 round trips to one.
Inputs: topic, hub_count, max_recent, project_cwd, +2 more.
graph_communitiesDetect Knowledge CommunitiesARead-only
Find clusters of densely-interconnected entities in the graph. Uses greedy seed-based BFS through edges above the weight threshold — works without GDS or APOC. Each entity is assigned to at most one community (the first that reaches it from a high-degree seed). Useful for understanding knowledge neighbourhoods (e.g. "everything related to infrastructure"). Returns {communities, coverage}. communities holds at most max_communities clusters in seed order (highest-degree seed first), each shaped {id, seed_name, seed_id, member_count, dominant_type, members: [{id, name, type}]} with at most 30 members listed; communities below min_size are left out. coverage is {total_entities, assigned, unassigned}. Use graph_query or graph_search instead when you have a specific entity to start from.
Inputs: max_hops, min_size, max_communities, weight_threshold.
graph_contradictionsGraph ContradictionsARead-only
Find facts that contradict each other in the memory graph — pairs connected by a CONTRADICTS edge. Use during reviews, before a graph_decay run, or when the user asks about conflicting information. Returns {contradictions: [{node_a, node_b, description, detected_date, resolved}], count} ordered by most-recently detected. By default only unresolved pairs are surfaced; set include_resolved=true to audit historical resolutions. Resolve a contradiction by graph_weaken on the wrong edge or by graph_relate with relation=SUPERSEDES on the new fact.
Inputs: include_resolved.
graph_cypherGraph CypherARead-only
Execute a read-only Cypher query against the memory graph. You generate the Cypher — this tool just runs it. Enforced read-only via Neo4j executeRead(). Use for custom queries not covered by other tools. Admin-only (must be the bootstrap tenant) — non-admin tenants would otherwise be able to bypass tenant filtering by writing raw Cypher.
Inputs: cypher (required), params.
graph_decayGraph DecayADestructive
Apply time-based decay to every node confidence and edge weight using per-type half-lives (preferences ~693d, events ~99d, etc.). Called by the dream process during maintenance. Always preview with dry_run=true first — decay is irreversible without restoring from a graph_export backup. Rule-subtype nodes and edges touching them are exempt. Returns totals, not per-type counts: {nodes_decayed, edges_decayed, nodes_flagged_for_pruning} (with dry_run, edges_decayed is always 0).
Inputs: dry_run.
graph_deleteGraph DeleteADestructive
Permanently delete an entity node and all its edges by ID. Use for removing duplicate or erroneous nodes. Cannot be undone.
Inputs: id (required).
graph_entitiesGraph EntitiesARead-only
Browse or search the entity catalog. Use to check if an entity exists before creating one with graph_relate, or to list entities of a given type. For relationship-aware lookups (entity + its neighbors) use graph_query instead. Returns up to limit entities ordered by sort_by; pagination is single-page (raise limit if you need more).
Inputs: type, limit, search, sort_by, +1 more.
graph_exportExport GraphA
Export all graph nodes and edges to a timestamped JSONL backup file in the backups/ directory. Run this before any risky operation, or on a weekly schedule. Old backups are pruned automatically.
Inputs: keep, label.
graph_ingestGraph IngestAIdempotent
Queue a document for asynchronous extraction into the memory graph (mode='queue'), or check the ingest backlog (mode='status'). Use this when you have a file the user wants summarized into the graph but doesn't need it reflected in the same conversation — the nightly dream process picks queued documents up. For inline assertions during a conversation, call graph_relate directly instead. Idempotent: queueing the same file twice overwrites the prior copy in the pending dir. Remote callers (e.g. a cloud session collecting its own transcripts) can't name a file on this machine, so they pass content + file_name instead of file_path (admin tenant only). status also returns session_cursors: for each cloud session queued with meta.source='claude-code-cloud', the newest meta.through already queued or dreamed.
Inputs: action (required), meta, content, file_name, +1 more.
graph_mergeGraph MergeADestructive
Consolidate two entities into one — moves source's edges onto target, adopts source properties for keys target doesn't have, then deletes source. Inverse of graph_unmerge. Use after graph_merge_suggestions surfaces a duplicate pair, or whenever you've confirmed two nodes refer to the same thing. Same-tenant only; refuses to merge an entity with itself. Edges directly between source and target are dropped (would become self-loops). When source and target both have the same edge to a third node, the edge is consolidated and the higher weight wins. Target's embedding is cleared so the next graph_reembed will re-derive it from the merged state. Logged to logs/merge-audit.jsonl with reason. DESTRUCTIVE — always preview with dry_run=true first; recovery requires a graph_export backup or graph_unmerge with the original edge layout.
Inputs: reason (required), source_id (required), target_id (required), dry_run.
graph_merge_suggestionsGraph Merge SuggestionsARead-onlyIdempotent
Surface candidate pairs of entities likely to be duplicates. Read-only — never auto-merges. Combines embedding similarity, shared-neighbor overlap, and name-token Jaccard. Same-type only. Use to triage entity-explosion before running graph_merge (destructive consolidation) or graph_relate with ALIAS_OF (soft alias).
Inputs: limit, weights, entity_id, min_score, +3 more.
graph_pruneGraph PruneADestructive
Remove entities and edges that have decayed below threshold. DESTRUCTIVE — always preview first. Requires user confirmation before execute mode.
Inputs: mode, max_age_days, edge_threshold, node_threshold, +1 more.
graph_queryGraph QueryARead-only
Query the memory graph by canonical entity name. Use when you know the entity name or close-to-canonical form (e.g. "Steve", "graph-memory"); for natural-language phrasing or synonyms (e.g. "the knowledge graph project") prefer graph_search. Returns up to limit matching nodes plus the edges that connect them within max_hops, with per-edge weight and source provenance.
Inputs: entities (required), limit, max_hops, min_weight, +4 more.
graph_read_transcriptRead TranscriptARead-only
Read and parse a Claude Code JSONL transcript file through the canonical transcript parser. Returns normalized messages with text content extracted. Use this instead of reading raw JSONL directly — if the transcript format changes, only this tool needs updating.
Inputs: file_path, text_only, session_id.
graph_reembedRe-embed EntitiesAIdempotent
Regenerate semantic-search embeddings for entities. By default only fills missing embeddings (idempotent, fast). With force=true, re-embeds every entity — use after changing the embed-text recipe (e.g. when richer fields are added). At ~10ms per entity, full re-embed of a few hundred nodes finishes in seconds.
Inputs: force.
graph_relateGraph RelateAIdempotent
Create or strengthen a relationship between entities. Creates the endpoint entities if they don't exist, matching existing ones by name, case-insensitive name, or alias first. Use single mode (from_name/to_name/relation) for one fact at a time. Use batch mode when extracting from a transcript or document: it runs in one transaction, so a database failure keeps nothing, while an invalid item is skipped and reported without blocking the rest. Types and relations must use the documented vocabulary (see GRAPH_SCHEMA.md); an unknown relation is stored as RELATED_TO with the original kept in proposed_relations, and an unknown type as Object with proposed_type. Idempotent: re-asserting an existing edge strengthens it (capped at 1.0) and reports action "strengthened".
Inputs: batch, weight, to_name, to_type, +9 more.
graph_searchSemantic Graph SearchARead-only
Find entities semantically similar to a natural-language query, then optionally expand via graph traversal. Uses local sentence embeddings (bge-small-en, 384-dim) — no external API. Best when the user's wording doesn't match canonical entity names (e.g. "containers" → Docker, "AI tools" → Claude Code/Anthropic SDK). If the embedder is unavailable it returns an error; use graph_query instead. Expansion follows the top 5 seeds only, capped at 30 edges.
Inputs: query (required), top_k, expand, entity_types, +2 more.
graph_statsGraph StatsARead-only
Graph health dashboard — node/edge counts by type, average weight, orphan count, unresolved contradictions, stale entries, schema version, and pending ingest backlog. Returns aggregate counts only; for individual entities use graph_entities. Call at session start to size up the graph before deeper queries, after graph_decay or graph_prune to verify the result, or when debugging unexpected query output. No parameters.
Inputs: no named parameters.
graph_unmergeGraph UnmergeADestructive
Split a falsely merged entity back into two separate entities, redistributing specified edges. Use when entity resolution made a mistake (e.g. merged 'Anna' and 'Anne'). The original entity keeps every edge not listed in edges_to_move; the new entity gets the listed edges plus a fresh embedding stub (re-derive with graph_reembed). Logged to the audit trail with reason. Returns the IDs of both entities.
Inputs: reason (required), entity_id (required), edges_to_move (required), new_entity_name (required), +1 more.
graph_validateValidate Graph EntitiesARead-only
Scan recently extracted entities and edges for quality issues: generic names, reference language, isolated low-confidence entities, and near-duplicate names. Call this after a dream process extraction batch to catch bad data before it settles into the graph. Returns {total_issues, by_severity, scope, issues}, where issues holds up to max_issues records of shape {entity_id, name, type, issue, severity} and severity is high/medium/low. Read-only — pair with graph_delete or graph_unmerge to act on flagged items.
Inputs: max_issues, source_session.
graph_weakenGraph WeakenAIdempotent
Decrease an edge's weight when the user corrects a recalled fact. Call this when the user says 'no', 'that's wrong', or corrects something from the graph. Persists immediately; weight clamps at 0.0. Returns an error if the edge doesn't exist — use graph_delete to remove an entity outright. To replace a fact rather than weaken it, prefer graph_relate with the new fact and SUPERSEDES.
Inputs: to_name (required), relation (required), from_name (required), amount, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 24 tools
Most tools are cleanly distinct, and the descriptions actively steer between the few lookalikes (graph_query for canonical names vs graph_search for natural language vs graph_entities for catalog browsing vs graph_cypher for raw queries). The main residual overlaps are graph_stats versus graph_build_context (which explicitly bundles stats) and the decay/prune/delete trio, but in each case the docs spell out when to use which.
Every tool is snake_case with the same graph_ prefix, and nearly all are verb-led (graph_query, graph_merge, graph_reembed, graph_build_context). No camelCase or style mixing anywhere in the set.
24 tools is at the heavy end for this surface, but the domain genuinely spans CRUD, entity resolution, decay/pruning, ingest, and dream-process maintenance, and each tool maps to a real operation rather than a convenience duplicate. A few specialist tools (graph_audit, graph_read_transcript, graph_cypher) are narrow but justified by admin/maintenance workflows.
Lifecycle coverage is strong: create/strengthen (graph_relate), read (query/search/entities/cypher), modify (boost/weaken/alias/merge/unmerge), delete (graph_delete/graph_prune), plus maintenance (decay/validate/reembed/export/stats) and ingest. Minor gaps: no direct delete-single-edge-by-id operation (weakening to 0.0 or deleting the entity is the workaround) and no in-band schema/type listing, which is deferred to an external GRAPH_SCHEMA.md.
Maintenance
Related MCP Connectors
Memory for Claude, ChatGPT and other AI apps: notes and docs as a searchable graph, EU-hosted.
Persistent knowledge graph for AI-augmented teams. Store decisions, findings, and standing rules across agent sessions with semantic search and typed connections. Includes cross-session memory, audit trail, workspace isolation, and secret detection. Built for teams running agents that need to remember. Free until launch with team tier as default, anon trial available.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Persistent, outcome-grounded episodic memory for Claude. 14ms CPU retrieval, no GPU, no vector DB.
Related MCP Servers
- AlicenseAqualityBmaintenanceGives your AI persistent memory across conversations. Stores facts automatically, finds them by meaning using hybrid search with query expansion, and organizes everything into topics without manual tagging.291MIT
- FlicenseNot gradedqualityAmaintenanceEnables Claude Code to persist, semantically search, update, and delete memories across sessions, plus explore knowledge-graph entities and their relationships, backed by self-hosted Qdrant, Neo4j, and Ollama. Session hooks and prompts automate context injection and summarization, with fact extraction handled by either the Claude Code session or a fully local Ollama model.-
- FlicenseNot gradedqualityAmaintenanceEnables Claude Code to store and recall persistent cross-session memory backed by self-hosted Qdrant, Neo4j, and Ollama, using Anthropic or fully local Ollama as the LLM. Exposes tools for adding, searching, listing, updating, and deleting memories plus querying knowledge-graph entities and relationships, with optional session hooks for automatic context injection and saving.-
- FlicenseNot gradedqualityAmaintenanceEnables Claude Code to maintain persistent memory across sessions through semantic search, memory CRUD, entity listing, and knowledge graph queries against self-hosted Qdrant, Neo4j, and Ollama, while supporting Anthropic or fully local LLM providers.-