Skip to main content
Glama

Why Wenlan

I started Wenlan because my notes, documents, and AI chats were scattered, and keeping a note system from rotting took constant upkeep. Since then we keep hearing the same about Obsidian: too much setup, with plugins to find, install, and keep updated. Wenlan is for people who use AI tools every day and don't want to maintain a note system.

Personal: download the desktop app and use it on your own.

Teams (in the next release): a self-hosted Wenlan server everyone connects to, with view-only or edit access for each person.

  • Keeps itself up to date. Your AI tools save what you decide in chats as memories and fold them into pages. When a source changes, the pages that rely on it get updated.

  • No plugins, no setup. Connect all in Settings connects your AI tools in one click. No plugins to find or update, and no API keys.

  • Bring what you have. Obsidian vaults, notes, documents, and AI chats. Full list.

  • You decide what AI changes. See every change, undo it, and choose which pages wait for your OK.

  • Pages cite their sources. A citation opens the original; a page whose citations mostly don't match isn't saved.

  • A page can be text or HTML. Ask your AI to make an HTML view of any page, or keep the HTML it made as an HTML page of its own. An HTML view shows the page's live text, so you never redo it.

  • Share a Space. With a colleague, or across your own computers, through a Google Drive or iCloud Drive folder.

How it compares

Obsidian + plugins

Notion

LLM wiki apps

Wenlan

Who organizes

You, with plugins

You, or Notion's agents

An AI you set up

Your AI tools; updates when a source changes

Setup

Find and update plugins

Full AI on the Business plan

Model key or scheduled routine

One click, no API key

Checks the AI's work

Depends on the plugin

Cites sources; no match check

Links to sources

Refuses pages whose citations don't match

What AI may change

Depends on the plugin

Pages you give an agent

Its wiki folder

You choose per page; restore anytime

Where notes live

Your computer

Notion's cloud

Your computer

Your computer; works with your vault

Related MCP server: Hoard

Get started

1. Download and open Wenlan

Download the desktop app for macOS 11 or later on Apple Silicon, Windows x64, or Linux x64 (AppImage or .deb, from v0.22). The app is in English, 简体中文, and 繁體中文.

Prefer the terminal? On a Mac, run npx -y wenlan setup, or brew install 7xuanlu/tap/wenlan and then wenlan setup. Linux and Windows: CLI install guide.

2. Bring in your material

Create a page, or bring in an Obsidian vault, a Logseq graph, a folder, or earlier AI chats. Import guide.

3. Connect your AI tool

In the App's Settings, Add a tool finds the AI tools on your computer and Connect all sets them up in one press. There is nothing else to install or keep updated. Then start a new AI session and ask:

/wenlan what did I decide about this before? Then help me: …

/wenlan ($wenlan in Codex) is the one command to remember: say what you want after it.

Works with Claude Code, Claude Desktop, Codex, Cursor, GitHub Copilot, VS Code, Gemini CLI, Windsurf, Grok Bot, and other MCP tools. Set one up by hand.

When an import finishes, the app offers Write pages with your AI tool to turn it into your first cited pages. No command needed.

What you can bring in

  • Files and folders: Markdown, text, text-based PDFs, and DOCX. Import once, or keep a folder in sync.

  • Obsidian vaults and Logseq graphs: keep them in sync, or import once. Notes you wrote start on Ask me first.

  • Web links: paste a link into a page and it becomes a source. YouTube, X, Threads, Instagram, and RedNote links show as a card or video.

  • Gmail, Notion, Google Drive, Slack, GitHub: your AI tool reads them with its own connectors and saves what matters, with a link to the original.

  • AI chats: decisions and findings are saved as memories, not full transcripts. ChatGPT and Claude export ZIPs work too.

  • A code repository: /wenlan wiki writes pages tied to the code. Code wiki.

You can also connect an Open Knowledge Format (OKF) folder as a source. Scanned PDFs need text extraction first; chat attachments are not imported. Import guide.

How it stays organized

Your AI tool reads what you bring in and writes it into Markdown pages. It links related pages, cites where each sentence came from, and brings pages up to date when a source changes. You can open any page and write in it yourself.

  • Pages with sources: Each citation opens the original. When a page cites its sources as [n], Wenlan compares each cited sentence with its source and refuses the page when most citations don't match. Passing the check does not prove a page correct.

  • Kept current: When a source, memory, or cited code changes, the pages that rely on it are flagged for an update. Without any model, Wenlan also suggests merging near-duplicate pages and lists [[links]] that point to no page yet.

  • You decide what AI may change: Pages you wrote start on Ask me first, so AI changes wait for your OK. Set any page to Allowed or Ask me first, see what changed, and restore an earlier version.

  • Two ways to run it: In On demand, the default, your AI tool does the writing while it works, so there is no API key to set up. In Automatic, Wenlan does it in the background with a model you choose, on your computer or in the cloud. Steep guide.

  • In your AI tool: type /wenlan and say what you want: look up earlier decisions, save a lesson, or pick up where you stopped. Shortcuts: /recall, /capture, /handoff, /brief. Plugin commands.

  • In the app: Add material, write and edit pages, follow citations, and review proposed changes without connecting an AI. Pages can include Mermaid diagrams, which the app draws.

Already using Claude Code or Codex on a folder of notes? Keep doing that. Wenlan connects to the same tool and adds what a folder can't do alone: citation checks, flags when sources change, and per-page control over what AI may change.

A wiki for your code repository

Run /wenlan wiki ($wenlan wiki in Codex) in a repository. Your AI tool writes an overview and one page for each part or flow a newcomer needs. A rerun writes only the pages that are missing.

  • Tied to the code: Each page records the code lines it was read from, and shows what changed when that code changes.

  • As a pull request: The GitHub button on a Space puts the pages in the repository's wiki/ folder as a pull request, when you press it or daily. The daily run uses your own AI tool on your computer, or GitHub Actions with your AI tool's key saved as a repository secret. The same pull request fixes sentences in the repository's docs that the code no longer agrees with.

  • Your edits stay: A wiki page someone edited in the repository keeps that edit. Pages that cite your memories or chats stay out of the repository.

For technical readers

One local knowledge base. The app, CLI, and connected AI tools read and write through Wenlan’s local service. Pages are Markdown files; memories, relationships, and search indexes live in local libSQL. The service, CLI, and MCP server are written in Rust; the desktop app uses Tauri with React and TypeScript.

  • Retrieval: SQLite FTS5 finds exact terms and BGE embeddings in a libSQL DiskANN index find similar meaning, fused by weighted Reciprocal Rank Fusion (RRF). Base search needs no API key. Shared-entity links boost related memories, and optional cross-encoder reranking refines the order. Choosing a Space limits results to that project.

  • Graph: With an enrichment model, entity extraction and resolution link mentions of the same person, project, or concept across sources. Label Propagation (default) or Leiden groups related topics.

  • Memories: Findings are saved as small, separate memories, so one can be found without loading a whole conversation or page.

Retrieval, evidence, and models.

Evaluation

These LongMemEval (LME) snapshots measure retrieval of saved knowledge, not AI answer quality. Recall@5 measures how much relevant material appears in the top five results.

Benchmark

Recall@5

MRR

NDCG@10

LME_Oracle (500 Q)

93.6%

0.857

0.883

LME_S (deep, 90 Q)

87.7%

0.815

0.822

On a 10,000-page test (generated pages, M2 Pro with 16 GB, v0.20.0), App search answered in 11 to 50 ms, restart took under 0.3 s, and memory peaked at about 1.2 GB. With the search fix in 0.20.1, AI-tool search found all 30 rare test words in that library.

Importing a 10,000-note Obsidian vault in 0.20.2 (invented notes, M2 Pro Mac with 16 GB, debug build, Claude Code writing the pages): searchable in 15 s, the first page in about 2 minutes, and 8 cited pages in about 4 minutes.

Evaluation method and benchmark details.

Data and privacy

  • Pages are Markdown files on your computer, and they go only where you send them.

  • Export eligible pages as an Open Knowledge Format (OKF) wiki.

  • A cloud AI tool may send what it retrieves to its provider, and a cloud model receives the material it processes, so local storage does not keep those interactions local.

  • Usage statistics are off by default.

Web access (experimental): Turn on Web access in Settings to let web AI clients such as Claude, ChatGPT, or Muse search your library or a chosen Space while your computer is online. When you allow an app, choose search only or search and write; a write app can also add, edit and delete, and AI apps can ask you before each change. Queries and results pass through a relay. See the privacy limits.

File locations, backup, and removal · Network and privacy details.

Learn more

Contributing

Join the Discord community. Report bugs or request features in GitHub issues; issues are public, so redact secrets and personal information.

For code and docs, see Contributing, Security, and the Code of Conduct.

Code signing policy

See the platform signing and notarization details.

License

The local runtime, CLI, MCP server, shared types, and plugins use Apache-2.0. The desktop app and its frontend use AGPL-3.0-only; modified versions run as a network service must offer their source to users.

Lineage and peers

Wenlan takes its name from Wenlan Pavilion. Its direction builds on the LLM-wiki and agent-memory lineages: Karpathy’s LLM-wiki note, Rohitg00’s proposal, and nashsu/llm_wiki.

Available Tools

33 tools
accept_refinementA
DestructiveIdempotent

Accept one listed refinement proposal by id only after the user gives an unambiguous item-level accept decision. For cross_space_discovery, pass the selected destination space. Not available over remote HTTP MCP transport (local stdio only).

Inputs: id (required), space.

accept_revisionA
Destructive

Accept a pending memory revision. Replaces the target memory's content with the proposed revision content and removes the revision row from the pending list. Returns the consumed revision id. Returns an error if no pending revision exists for that target. Not available over remote HTTP MCP transport (local stdio only).

Inputs: target_source_id (required).

briefA
Read-only

Read the current Space Brief when resuming project work or when the user asks to catch up. Omit topic to return only the complete Brief. Provide topic to append separately labeled related context scoped to the same Space. Reads never create or mutate a Brief; the first handoff update can create it.

Inputs: space, topic, session.

captureA
Destructive

Capture a memory: one durable insight the user's wiki should keep.

STORE PROACTIVELY, without waiting for 'remember this' (a floor, not a trigger): when the user states a preference, makes a decision, corrects you or earlier information, or shares a durable fact about themselves or the people, projects, and tools they care about.

WHEN NOT TO STORE: conversation filler; things the user can trivially re-derive (file paths, recent git history); anything already stored (recall first if unsure); Tool output or command results (file contents, build logs, system prompts); transient task state; general world facts not personal to this user; Your own inferences the user did not express; agent operating rules ('always X' / 'never Y' belong in the agent's own config, not shared memory: store the preference as a fact, never the rule).

CONTENT QUALITY: Specific beats vague ('prefers Rust for CLI tools because of compile-time safety' > 'likes Rust'). Include the WHY, which only you know. Name people, projects, and tools; this powers the knowledge graph. Atomic: one idea per memory. Each call is one atomic idea: 'prefers TDD' and 'uses pytest' are two calls. Declarative, not narrative: 'User prefers X because Y', not 'User said today they prefer X'; memories outlive the conversation.

MEMORY TYPES: omit and trust the backend. By default do NOT set memory_type; the backend auto-classifies into identity / preference / decision / lesson / gotcha / fact with more context than you have, and agents that over-specify pick wrong. Opt in only when sure: 'profile' (about the user: identity / preference), 'knowledge' (about the world: decision / lesson / gotcha / fact), or a precise type when the distinction matters. EXCEPTION: set memory_type="decision" explicitly ONLY when the user articulated the alternatives weighed AND the reasoning; those structured fields power the Decision Log view. A bare 'I'm switching to Cursor' is a preference change, not a decision. NO MODEL: when a capture receipt says enrichment: paused or enrichment: off, nothing classifies memories, so set memory_type yourself on every capture.

Omitting structured_fields beats guessing. If supersedes is supplied for a correction, this call can replace an existing memory in retrieval; use it only when that replacement is intended.

Inputs: content (required), space, entity, session, +5 more.

confirm_memoryA
Idempotent

Confirm a pending memory by source_id. Use during review to accept a memory the agent captured. The user typically picks from a list_pending result. To reject instead, call forget with the same memory_id.

Inputs: memory_id (required).

create_entityA
Idempotent

Resolve a durable named entity idempotently. Use only as a support step when the user explicitly establishes a durable named entity, or when resolved ids are needed for a relation the user explicitly stated. Do not call create_entity for every ordinary capture: with a model source chosen, daemon enrichment extracts entities. Without one (a capture receipt says enrichment is paused or off), capture's entity links only an entity that already exists, so create the entity first.

Inputs: name (required), entity_type (required), space, confidence.

create_relationA
Destructive

Create a source-backed directed relation only when the user explicitly states a durable relation. Resolve both endpoint ids with create_entity, capture the user's relation statement, then pass those ids plus the capture result's source_memory_id. If a conflicting relation already exists for the same endpoints, the daemon may auto-supersede that existing relation. Entity names are not accepted or auto-created. Never infer an unstated relation.

Inputs: to_entity_id (required), relation_type (required), from_entity_id (required), source_memory_id (required).

delete_pageA
DestructiveIdempotent

Delete a page by id only when the user explicitly asks to remove it. Destructive — removes both the DB row and the on-disk md projection. To refresh an existing page while preserving its page_id and version history, use write_page. Pages without sources can be re-derived by running /distill again on the same scope.

Inputs: page_id (required).

dismiss_revisionA
Destructive

Dismiss a pending memory revision. Deletes the revision row; the original memory is unchanged. Returns an error if no pending revision exists for that target. Not available over remote HTTP MCP transport (local stdio only).

Inputs: target_source_id (required).

distillA
DestructiveIdempotent

Trigger Wenlan's distillation pass. With no target, runs a full pass that clusters new memories into pages and refreshes the wiki view. With a target, scopes the pass: a page id (page_* or concept_*) re-distills that single page, an entity name scopes clustering to that entity, a space value (e.g. work, personal) scopes to that space. With force=true on a page target, clears the user-edited guard and can replace the page prose during rebuild. Rebuild may send page and source material to the daemon's configured external LLM provider. Use when the user explicitly asks to synthesize, distill, or rebuild a page. With a model source chosen the daemon also distills in the background, so don't trigger redundantly; without one, nothing distills in the background.

Inputs: force, target.

forgetA
DestructiveIdempotent

Delete a memory by ID. Use when the user says 'forget this', 'delete that', 'that's wrong and should be removed'. Requires the source_id — get it from recall first.

This is destructive and cannot be undone. For corrections, prefer storing a new memory with the supersedes param pointing to the old one — this preserves history. If your agent's trust level is below full, that supersedes write may stage for human review instead of taking effect immediately.

Inputs: memory_id (required).

get_memory_revisionsA
Read-onlyIdempotent

Fetch the supersede chain for one memory, ordered by depth (0 = current). Use after recall only when the user explicitly asks for that memory's history or evolution, or to verify that a correction was recorded.

Inputs: memory_id (required).

get_page_revisionsA
Read-onlyIdempotent

Fetch the version changelog for one page, ordered newest-first. Use only when the user explicitly asks for a page's changelog, version history, or which source memories triggered a re-distill.

Inputs: page_id (required).

get_page_sourcesA
Read-onlyIdempotent

Fetch the source memories of a page — the memory ids the page was distilled from, each enriched with the memory's title, content, type, and space. The /distill skill uses this on the stale-page refresh path after obtaining the page id from the stale_pages block in distill output.

Inputs: page_id (required).

lintA
Read-only

Run Wenlan's read-only system lint on demand. General is the default bounded deterministic profile. Deep adds expensive deterministic checks plus full-store local semantic candidate generation; bounded candidate packets are adjudicated either by the daemon's configured provider or, with explicit agent_assist consent, by the calling agent through a typed prepare-and-submit protocol. General returns the text wenlan lint prints; Deep returns the canonical typed report. Incomplete takes precedence over findings. With work_digest (plus offset and limit) it instead pages the cached agent-assisted Deep work packet from this local MCP process: each page holds candidates plus only their referenced records; follow next_offset until absent, then submit exactly one verdict per candidate in the second lint call.

Inputs: limit, space, offset, profile, +3 more.

lint_repair_applyA
DestructiveIdempotent

Apply exactly one prepared lint repair through the daemon's CAS canonical writer. Requires the exact user approval string apply repair <manifest-id> <manifest-digest> and refuses stale targets. Local stdio only.

Inputs: approval (required), manifest_id (required), approved_manifest_digest (required).

lint_repair_prepareA

Plan or prepare lint repairs from the reports this local MCP process cached for the exact lint_scope (never paste reports). With only lint_scope: open a new repair plan; returns the summary with source_reports, the first page of entries (up to 100), and next_offset. With plan_id, plan_digest and offset: read the next page; pages are byte-bounded, so follow next_offset until absent. With choice: turn exactly one Review Item into one approval-gated manifest (reclassification needs complete General plus agent-assisted Deep). Planning and preparing write private immutable artifacts and never mutate canonical data. Do not retry a lost plan response: artifacts may already exist. Local stdio only.

Inputs: lint_scope (required), limit, choice, offset, +2 more.

lint_repair_verifyA
Idempotent

Record verification for an applied lint repair after rerunning complete General and applicable agent-assisted Deep lint. Rejects surviving target evidence, new actionable findings, stale reports, or any non-target state change. Local stdio only.

Inputs: manifest_id (required), general_report (required), manifest_digest (required), apply_receipt_digest (required), +2 more.

list_pagesA
Read-onlyIdempotent

List wiki pages with their ids, titles, summaries, Space, status, and last-modified time. Use it to browse what the wiki already covers before writing a page, or to find the page id read_page needs. Filter by Space or status; page with limit and offset.

Inputs: limit, space, offset, status.

list_pendingA
Read-only

List pending captures: memories waiting for review before they count. Use when the user wants to audit what got captured — typical phrases: 'review pending', 'pending captures', 'what got captured'. Pair with confirm_memory to accept and forget to reject.

Inputs: limit, space.

list_pending_importsA
Read-onlyIdempotent

List in-flight chat-history imports awaiting processing or completion. Use only when the user asks what imports are running, whether an export is done, or requests import progress. Returns id, vendor, stage, and processed/total conversation counts; the id distinguishes concurrent imports. The source_path is included only over local stdio; remote HTTP returns a progress summary without filesystem paths.

list_pending_revisionsA
Read-onlyIdempotent

List memories awaiting human accept/dismiss because a newer version was proposed (Protected tier supersede). Use when the user asks 'what revisions are pending', 'show me memories awaiting approval'. Each item carries target_source_id (the memory being revised; pass this to accept_revision only after the user explicitly approves that item) and revision_content for display. Review acceptance is local-only; accept_revision is unavailable over remote HTTP MCP. Optional limit caps results (default 50, max 500).

Inputs: limit.

list_refinementsA
Read-onlyIdempotent

List pending daemon refinement proposals only when the user explicitly asks to inspect or review the proposal/refinement queue; never poll this queue ambiently. Returns typed actions and payloads, including vocab_promote. Filter by action and bound the result with limit. Pair with accept_refinement or reject_refinement only after an unambiguous item-level user decision.

Inputs: limit, action.

list_rejectionsA
Read-onlyIdempotent

List quality-gate flags and rejections: memories the daemon discarded before storing (low quality or another filter), plus near-duplicate memories that were stored anyway but logged for review (reason "near_duplicate"). Use only to diagnose a missing capture, a flagged near duplicate, or when the user asks what Wenlan rejected. Returns reason codes, detail, and similarity info; optional limit and reason filters narrow the audit.

Inputs: limit, reason.

page_basisA
Idempotent

Track what a wiki page relies on another page for. Use when read_page, list_pages or recall shows a pending basis. mark/confirm need version (the basis note's page.version from read_page) and fail if it moved on. diff shows the text relied on next to the text now. remove drops it. Changes are local stdio only.

Inputs: action (required), page_id (required), basis_page_id (required), version.

page_code_basisA
Idempotent

Settle a code_basis row that is pending, unavailable or moved, after reading the code. confirm: the page still holds for the code as it reads now; Wenlan re-reads the file and sets the row ok. If it no longer holds, rewrite with write_page. remove: drop the reliance. Pass the row's repo_root, path, line_start, line_end. Local stdio only.

Inputs: path (required), action (required), page_id (required), line_end (required), +2 more.

read_pageA
Read-onlyIdempotent

Read one wiki page in full: its title, body, status, Space, and the source memories it cites, in one call. Use it after list_pages or recall when the user wants the page itself rather than search snippets. The page id is opaque; never guess it from a title.

Inputs: page_id (required), session.

recallA

Search memories by query. Use when the user asks 'do you remember', 'what do you know about', 'look up', or when you need a specific fact before acting.

Write queries as natural language — the search engine handles semantic matching. For precision, use filters (memory_type, space) to narrow results. If you get too many results, add filters rather than making the query longer.

For higher retrieval quality at the cost of latency, pass rerank: true to opt into the cross-encoder reranker (requires WENLAN_RERANKER_ENABLED=1 on the daemon).

This is for targeted lookups. To resume work from a Space-owned project snapshot, use brief instead. Search records the query and accessed memory IDs in local activity history for auditability; it does not rewrite stored knowledge.

Inputs: query (required), limit, space, rerank, +2 more.

reject_refinementA
DestructiveIdempotent

Reject one listed refinement proposal by id only after the user gives an unambiguous item-level reject decision. Rejecting marks the proposal dismissed and terminal, so it cannot be retried; this changes workflow state but does not delete or overwrite the underlying memory or page. Skip or cancel is a no-op. Not available over remote HTTP MCP transport (local stdio only).

Inputs: id (required).

rename_pageA
DestructiveIdempotent

Rename an existing page only when the user explicitly asks to change its title. Pass the page_id and expected_version from the latest page result; the version prevents renaming a page that changed since it was read. This changes the title only and preserves the page id and content. It is unavailable over remote HTTP MCP transport (local stdio only). Do not call this during distillation, synthesis, or content refresh; write_page keeps an existing title when refreshing.

Inputs: title (required), page_id (required), expected_version (required).

save_sourceA
DestructiveIdempotent

Save a document from another app or the web (email, Notion or Drive page, Slack thread, article) with a permanent link to the original. Use this instead of capture when the content has a link. Pass the text as read, not a summary; never bulk-copy an inbox or channel. It is a snapshot: Wenlan does not fetch or sync the original; saving the same url replaces it.

Inputs: url (required), title (required), content (required), space, +2 more.

update_briefA
Idempotent

Hand off to the next session by updating the Space Brief: replace the summary (guarded by expected_version) and add, edit, move, gate, or complete items. Read brief first and reuse its brief_version and item versions; conflicts are reported, never silently overwritten. The first update creates the Brief. Local stdio only.

Inputs: space, session, summary, mutations, +1 more.

write_pageA
Destructive

Create or refresh a wiki page. When the user asks to turn something from this conversation into a page, call write_page with a title and the content; source_memory_ids are optional. This write can replace an existing page: omit page_id to create a new page (title required); with enough cited sources it lands as a distilled page, otherwise as an authored page. The daemon writes the DB row and the on-disk /.md projection atomically (default ~/.wenlan/pages/, slug made unique on collision). Pass page_id (from the stale_pages block in distill output) to refresh that page in place — replaces content + source_memory_ids + optional summary, clears stale_reason, preserves page_id and created_at, bumps version monotonically so external [[wikilinks]] keep working. Never delete_page + recreate to refresh: that churns ids and loses version history. To change an existing page's title at the user's explicit request, use rename_page; refresh keeps the existing title. Before a refresh, read_page and pass its page.version as expected_version: if the page moved on, the write is refused with nothing changed, so re-read and retry. Without expected_version, a refresh of a page the user wrote or edited is refused the same way. A page with review_required set stages every refresh as a revision card for the user. basis [{page_id, version}] lists notes relied on (versions from read_page); a changed one lands pending (see page_basis). minor: true = small edit. code_basis [{repo_root, path, line_start, line_end}]: code lines relied on (see page_code_basis). Refresh is not available over remote HTTP MCP transport (local stdio only).

Inputs: content (required), basis, minor, space, +8 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 33 tools

    Disambiguation4/5

    Most tools target clearly distinct resources and actions (capture vs save_source vs write_page vs read_page), and descriptions supply explicit disambiguation cues like 'use this instead of capture when the content has a link'. Residual confusion lives in the review-queue family — list_pending, list_pending_revisions, list_pending_imports, list_refinements, plus confirm_memory/accept_revision/accept_refinement — and in the near-twin page_basis/page_code_basis pair, where an agent must read carefully before choosing.

    Naming Consistency4/5

    The dominant pattern is snake_case verb_noun (list_pages, get_page_sources, delete_page, dismiss_revision, create_relation), which is applied consistently across CRUD and review operations. Deviations are minor: a handful of bare verbs (capture, recall, distill, lint, forget, brief) and two noun-first names (page_basis, page_code_basis).

    Tool Count3/5

    33 tools is on the heavy side, and a tail of rarely invoked, local-stdio-only operations (lint_repair_prepare/apply/verify, page_code_basis, list_rejections, list_pending_imports) inflates the surface. The domain genuinely spans several subdomains — memory lifecycle, distillation, wiki pages, lint/repair, refinements, briefs — so each tool has a defensible role, but the set is borderline oversized for a single MCP endpoint.

    Completeness4/5

    Coverage is unusually thorough: memories have capture/recall/confirm/forget plus revisions, pages have full create/read/list/write/rename/delete with revisions and sources, and review queues, lint, briefs, entities, and relations all have entry points. Gaps are minor but real — no direct get_memory-by-id (forget depends on finding the memory via recall first), no entity/relation listing or deletion, and no page search beyond list_pages paging.

    Maintenance

    ActivityActive
    ResponsivenessUsually handled

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      Local Markdown-backed memory tools for Codex and other MCP-capable agents. Exposes durable agent knowledge via CLI and MCP server.
      5
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      MCP server for persistent, compounding markdown wikis maintained by LLMs. Enables incremental knowledge base building with interlinked pages, search, and raw source management.
      34 npm
      1
      MIT