Manent
Allows AI agents to search, read, and explore neighbors within an Obsidian-compatible Markdown vault, with retrieval ranking and git-based versioning.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Manentsearch my vault for notes about the Q3 roadmap"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Manent
Verba volant, scripta manent. — Spoken words fly away, written words remain.
File-first, git-versioned memory for AI agents. A specification plus a toolchain that turns a plain Markdown vault (Obsidian-compatible) into a queryable, lintable, MCP-served brain that any agent can mount.
Context windows evaporate — verba volant. Manent is the written memory that remains: plain files you can read, diff, and own.
Why
Agent memory today is either a proprietary vector-DB dump (lock-in, no audit trail, no human curation) or an unstructured pile of notes (no schema, no retrieval quality, no guarantees). Manent takes a third path:
Markdown files are the source of truth. Everything else — search indexes, graphs, embeddings — is derived and rebuildable from scratch.
Git is the sync and audit backbone. Every memory write is a commit: who, when, why.
A closed, versioned schema (JSON Schema 2020-12) for note types and typed edges. Linted in CI — a malformed note never lands.
MCP is the access layer. Any MCP client (Claude, ChatGPT, VS Code, Cursor, your own agent) mounts the brain with a URL — no custom SDK.
Related MCP server: Kioku
Packages
Package | What |
| The vault specification: note types, frontmatter schemas, typed edges, layout |
| Parser (frontmatter + wikilinks), vault loader, graph builder |
| Ranking: BM25 lexical, local dense embeddings, graph expansion, RRF fusion |
| Eval harness: golden sets, recall@k / MRR / nDCG, regression gate |
| Rule engine: schema-lint, link-lint, duplicate/orphan detection |
| MCP server over a vault: |
| `manent init |
Quickstart
npm install
npm run build
# scaffold a new vault
node packages/cli/dist/index.js init my-vault
# lint it
node packages/cli/dist/index.js lint my-vault
# serve it over MCP (stdio)
node packages/cli/dist/index.js serve my-vault
# or over Streamable HTTP with bearer auth (for remote clients / claude.ai)
node packages/cli/dist/index.js serve my-vault --http 3939 --token <long-random-token>Register with Claude Code:
claude mcp add mybrain -- node <repo>/packages/cli/dist/index.js serve <vault>Use from claude.ai (web)
Verified working. claude.ai will not connect to a remote MCP server that has no discoverable OAuth metadata, so the HTTP server ships its own single-owner authorization server: your vault token is the login password.
Serve over HTTP and expose it — a tunnel (
cloudflared tunnel --url http://127.0.0.1:3939) or a reverse proxy. HTTPS is required by OAuth for non-localhost redirects.claude.ai → Settings → Connectors → Add custom connector → URL
https://<your-host>/mcp. Leave the OAuth Client ID empty; discovery and registration are automatic.claude.ai opens the consent page. Paste your vault token, approve, done.
Access tokens are HMAC-derived from the vault token rather than stored, so a connected client survives server restarts. Rotating the vault token invalidates every issued token.
Three details worth knowing:
The endpoint binds
127.0.0.1by default and refuses to start without a token — a vault never reaches the network unauthenticated by accident.Redirect URIs are restricted to an allowlist (
claude.ai,claude.com, localhost) and must be HTTPS. PKCE S256 is mandatory; authorization codes are single-use and expire in five minutes./t/<token>/mcpalso works for clients that can neither set headers nor do OAuth. That URL is a credential — treat it like a password.
Run npm run test:oauth to exercise the whole flow, including wrong token, failed PKCE, code
replay, forged token and disallowed redirect.
Retrieval, measured
Ranking changes are decided by an eval harness, not by intuition. manent eval scores a
retriever against three kinds of query, and each kind answers a different question:
Source | How it's built | What it measures |
| hand written, wording close to the note | lexical recall |
| asks for the concept without the note's words | semantic recall — the hard case |
| derived from each note's own description | broad regression signal, no labelling |
manent eval <vault> --golden eval/golden-aios.json # bm25 vs hybrid side by side
manent eval <vault> --golden ... --save baseline.json # record a baseline
manent eval <vault> --golden ... --baseline baseline.json # exits 1 if a metric droppedResults on a real 305-note vault (298 queries), in the order they were measured:
Ranker | curated hit@1 | curated MRR | oblique MRR | auto hit@1 |
BM25, naive tokenizer | 45.0% | 0.621 | — | 97.8% |
BM25 + stopwords, length-gated prefix/fuzzy | 75.0% | 0.863 | 0.099 | 97.8% |
Hybrid (graph expansion + recency + centrality) | 75.0% | 0.863 | 0.104 | 93.0% |
Dense only (multilingual-e5-small, local) | 95.0% | 0.975 | 0.131 | 94.4% |
Fused, lexical 1 : dense 2 (RRF) | 100.0% | 1.000 | 0.208 | 95.9% |
Four findings worth keeping:
Tokenization was the first big win. Dropping stopwords and allowing prefix/fuzzy matching only on longer terms moved curated hit@1 by 30 points. With prefix matching on,
dimatches diritto, disposizione, documento — long notes then win on accumulated noise.Graph expansion did not pay. Once retrieval is lexically sound, Personalized PageRank over wikilinks adds nothing measurable and the recency/centrality multipliers cost ~5 points on the auto set.
hybridstays available for vaults with a much denser link structure. PPR amplifies a good seed — it cannot create one.Lexical and dense fail in opposite directions, so fusing them beats both. Dense alone found the notes BM25 missed but blurred exact slugs and identifiers; at equal RRF weights the lexical list pulled correct answers off the top spot. Weighting dense twice reached 100% hit@1 on hand-written queries, trading ~2 points on the synthetic set.
Vocabulary mismatch is improved, not solved:
obliqueMRR went 0.099 → 0.208 and recall@5 25% → 37.5%. A question whose wording shares nothing with its note is still often unreachable.Chunking made it worse here, and that is informative. Splitting notes into passages was the obvious next step; measured, it cost 10–15 points of curated hit@1. With ~2400 passages instead of 307 notes, max-scoring gives a long note one chance per passage to match by luck, so retros and legal texts float up — the same length bias BM25 normalizes away. Damping by passage count (
max-norm) recovers oblique recall (MRR 0.221) but still trades away curated and auto accuracy.
Passages | curated hit@1 | oblique MRR | auto hit@1 | Configuration |
307 | 95.0% | 0.133 | 95.9% | one passage per note, full body |
2419 | 90.0% | 0.096 | 96.3% | 1000-char passages, best-passage scoring |
2419 | 85.0% | 0.221 | 91.9% | 1000-char passages, length-damped |
1181 | 75.0% | 0.013 | 95.9% | 2000-char passages, best-passage |
1181 | 55–75% | ≤0.19 | 73–79% | any size, without the contextual prefix |
Two things to keep from that: the contextual prefix is not optional — a passage stripped of
its note's name and description loses the subject and everything collapses; and truncation
beats completeness on this corpus (1400-char single passage scored 100%, full body 95%).
Notes here are atomic and front-loaded — one fact each, stated at the top — so the tail is
elaboration that only blurs the vector. Raise maxPassages for vaults of long, multi-topic
documents, where the answer can sit in the middle of a note.
Reproduce any sweep: scripts/tune-retrieval.mjs (graph/scoring params), scripts/tune-fusion.mjs
(lexical/dense balance), scripts/tune-chunking.mjs (passage size, prefix, aggregation).
Dense retrieval setup
Embeddings run locally — no API key, nothing leaves the machine, and query time needs no
network. The model is an optional dependency, so bm25 keeps working without it:
npm install @huggingface/transformers # ~120 MB model, downloaded on first use
manent serve <vault> --retriever fused # or --retriever dense
manent eval <vault> --golden ... --retriever allVectors are cached in <vault>/.manent/embeddings.json, keyed by content hash: editing one note
re-embeds one note. Changing the model invalidates the cache. manent init gitignores that
directory — it is derived data, rebuildable from the notes.
Protocol eras
MCP revision 2026-07-28 removed the initialize handshake and sessions; every shipping client
still speaks the older, handshake-based revisions. Manent serves both, as two separate
implementations rather than one blended path:
Era | Revisions | How | File |
legacy |
| official SDK, |
|
modern |
| native: no handshake, |
|
Both adapters expose the same tools because the tool definitions live in one place
(src/tools.ts); the eras cannot drift in capability. src/http.ts only routes.
manent serve <vault> --http 3939 # auto: routes each request to its era
manent serve <vault> --http 3939 --era legacy # pin: modern requests get the fallback signal
manent serve <vault> --http 3939 --era modern # pin: 2026-07-28 onlyAuto-detection keys on the RPC itself (server/discover, subscriptions/listen) or a declared
2026+ protocol version — never on the Mcp-Method transport header alone, since dual-era clients
send it with a legacy initialize too. npm run test:era exercises all three modes.
Vault layout (see packages/spec/SPEC.md)
vault/
├─ MEMORY.md # global index, loaded every session (type: index)
├─ HOME.md # human navigation hub (type: moc)
├─ memory/ # global lessons: feedback_*.md, reference_*.md
├─ projects/<p>/ # per-project knowledge, handoffs, retros
├─ moc/ # one map-of-content per branch
├─ people/ # person notes (type: persona)
├─ library/ # raw dated sources: YYYY-MM-DD-<slug>.md
├─ wiki/ # compounding wiki: entities/ concepts/ queries/
├─ knowledge/ # read-only mirrors from external repos
└─ secrets/ # NEVER synced, NEVER indexed (enforced)Roadmap
Spec v0.1 + lint + graph + BM25 search + MCP stdio server
Eval harness: three query kinds, recall@k / MRR / nDCG, regression gate
Lexical retrieval done properly (stopwords, length-gated prefix/fuzzy): +30 pts hit@1
Graph expansion (Personalized PageRank) + RRF fusion — built, measured, not default
Local dense embeddings + RRF fusion: curated hit@1 75% → 100%, oblique MRR 0.10 → 0.21
Chunk-level embeddings — implemented, measured, not default: worse on atomic notes
Curation: embedding-cluster dedup, contradiction detection, Leiden community → MOC suggestions
Streamable HTTP transport, stateless, bearer-token auth
OAuth 2.1 (RFC 9728 metadata, dynamic registration, PKCE) — connects from claude.ai
Two protocol eras as separate implementations: legacy handshake (SDK) and native 2026-07-28
Vault hot-reload — the server currently indexes at startup
Tasks extension (
io.modelcontextprotocol/tasks) on the modern path — long-running skillsMCP Apps (
ui://): skill launcher, review queue, graph explorerMCP spec 2026-07-28 wire upgrade (no-handshake core,
server/discover, cacheable results, Tasks extension) — when the official SDK ships itWrite path:
brain_writebehind MRTR approval (input_required)MCP Apps: skill launcher, review queue, graph explorer (
ui://templates)
License
Apache-2.0 — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityBmaintenanceAn MCP server that provides controlled read/write tools for managing local-first research memory in an Obsidian vault, enabling AI agents to maintain project context across sessions.71MIT
- Alicense-qualityAmaintenanceAn MCP server that enables AI agents to read, search, and write to your Obsidian vault.4MIT
- AlicenseAqualityBmaintenanceA self-hosted MCP server that gives AI agents shared, long-term memory over a git-backed folder of markdown, enabling persistent knowledge search, read, and write without a database.16269MIT
- Alicense-qualityBmaintenanceMCP server that provides agentic memory management for markdown vaults, enabling hybrid search, governed writing, and maintenance of episodic, semantic, procedural, and working memories for LLM agents.MIT
Related MCP Connectors
An MCP server that gives your AI access to the source code and docs of all public github repos
Person-owned, portable AI memory as a remote MCP server, readable and writable by any MCP client.
Token-efficient MCP memory for Markdown vaults. Tiered search, GraphRAG, AI memories.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/colopisalvatore/manent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server