A personal latticework knowledge graph backed by Cloudflare D1 + Vectorize, with semantic search and graph visualization. Exposes MCP tools for saving, retrieving, linking, and analyzing interconnected notes across domains.
Mind Vault demonstrates strong definition quality with excellent naming conventions, comprehensive parameter descriptions, and well-articulated tool purposes. All 9 tools follow consistent verb_noun naming patterns (save_, update_, delete_, recall, expand, get_, link, stats, reembed). Descriptions are substantive and context-aware, typically 150-400 characters with clear guidance on when to use each tool. Parameters are well-described with type constraints (enums for kind and relation_type), though some tools lack explicit output schema documentation. Error handling is documented through parameter descriptions (e.g., delete_note's confirm parameter acknowledges irreversibility, recall's topK parameter shows optional constraints). Security considerations are explicitly stated in descriptions (e.g., delete_note warns irreversibility, save_note validates domain slugs). The main limitation is that output schemas are not formally documented in the source code, they are described narratively in tool descriptions but lack JSON Schema definitions for return types.
Permanently deletes a note from the vault. IRREVERSIBLE. Removes: the note row in D1, all edges pointing to or from it (schema cascade), all tags, and the vector in Vectorize. FLOW: 1. Call recall() or get_note() first to confirm the id is correct. Do NOT delete on an invented id. 2. Ask the USER for explicit confirmation before calling — quote the title and tldr back so they know what is being removed. 3. Only then pass confirm: true. Use delete_note when: The user explicitly says 'delete this note' / 'remove it' / 'forget this'. A note was saved accidentally (duplicate, wrong concept, test data). Do NOT use delete_note to 'clean up' notes you judge low-quality on your own — that is a policy decision that belongs to the user. When in doubt, suggest update_note instead (refine, don't destroy). ORDER: deletes vector FIRST, then D1 row. If the vector delete fails, the D1 row is preserved so the note is still accessible via get_note. If the D1 delete fails after the vector was removed, the note exists in D1 without a searchable vector — use reembed to restore recall.
Graph expansion from a single note. Given a note id, returns: the note itself, all edges FROM it (outgoing), all edges TO it (incoming), and the neighboring notes (1-hop). Useful for exploring cross-domain connections and understanding how a concept fits into the larger latticework.
Fetch a single note by id, along with its tags and edges (incoming and outgoing). Returns the full note row (title, body, tldr, domains, kind, created_at, updated_at) plus related metadata. Useful when you already know the id (from recall, expand, or the user's prior conversation).
Creates a directed edge between two notes, labeling the relationship with one of 9 edge types and a substantive 'why' explanation. Each edge captures a MECHANISM: why the source note informs, influences, or relates to the target. Edges are schema-validated (both notes must exist, relation_type must be in the canonical set). The 'why' must be min 20 chars and substantive (vague whys are rejected). Prefer same_mechanism_as over analogous_to when you can justify the underlying mechanism.
Output schemas not formally documented as JSON Schema. Descriptions state what is returned (e.g., 'Returns: array of {id, title, tldr, domains, kind, score}') but lack typed schema definitions in code. This forces LLMs to infer response structure from prose descriptions, increasing hallucination risk for downstream tool chaining.
The stats tool lacks explicit pagination guidance and returns potentially unbounded lists (all domains, all edge types, all notes' metadata). For large vaults, this could bloat response size and degrade reasoning. Description does not specify result limits or truncation behavior.
No documented error classifications (retryable vs. user-fixable vs. fatal). While the code likely implements error handling (e.g., embed retry logic in src/vector/index.ts with EMBED_RETRY_DELAYS_MS), tool descriptions do not guide LLMs on recovery strategies for common failures (e.g., what happens when a domain slug is invalid, when a note ID is not found, when embedding fails).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 57 | 2026-07-28+ | v2 |
Semantic search across the vault. Takes a natural-language query, embeds it via Workers AI, and returns the topK most similar notes from Vectorize by cosine similarity. Ranks by score (higher = more similar). Returns: array of {id, title, tldr, domains, kind, score}. Use this BEFORE answering topical questions and BEFORE save_note (to sweep for cross-domain analogies). Read ALL returned domains — the valuable match often comes from the unexpected domain.
Re-embeds a single note (or all notes if none specified) via Workers AI and updates Vectorize. Use this if: (1) A prior delete_note or update_note failed partway, leaving the note in D1 but not in Vectorize. (2) The embedding model was upgraded and you want to refresh all vectors for better recall. (3) Manual recovery after a transient Vectorize outage. Returns the count of notes re-embedded and any errors encountered.
Creates and embeds a new note in the vault. Atomizes knowledge: one note = one concept. Assigns it to English canonical domain slugs, a kind (concept|decision|insight|fact|pattern|principle|question), and optional tags. Generates a semantic vector via Workers AI (@cf/baai/bge-m3) and stores it in Vectorize for recall. Validates domain slugs syntactically and rejects malformed JSON domains. Returns the new note's id.
Returns a panorama of the vault: total note count, edge count, list of all domains (with note counts per domain), list of all edge types (with counts), and the most recently edited note. Useful when the user asks about composition, growth, or overview. Use this to give the user insight into their vault structure.
Edits an existing note in-place. Accepts id and any subset of {title, body, tldr, domains, kind}. Re-embeds the note if body/title/tldr change (expensive). Validates domain slugs and rejects malformed JSON. Does NOT delete edges or tags unless explicitly called. Returns the updated note row.
The link tool requires both from_id and to_id to exist and validates the 'why' explanation (min 20 chars), but descriptions do not explicitly state what happens if a note ID does not exist or if validation fails. Error messages would help LLMs self-correct.
update_note description states 'Re-embeds the note if body/title/tldr change' but does NOT explicitly warn that re-embedding is expensive or what happens if the embedding service fails. LLMs may not understand the cost and latency implications of triggering a re-embed.