Show HN: Mwe-MCP – self-hosted memory for AI agents that knows who may know what
Mwe-MCP is a self-hosted, wiki-based memory engine for AI agents, offering per-fact access control, attribution, validity windows, and nightly self-organization. It enables multiple agents to share a governed memory while preserving privacy and accuracy.
Notifications You must be signed in to change notification settings
Fork 0
Star 2
BranchesTags
Open more actions menu
Folders and files
NameName
Last commit message
Last commit date
Latest commit
History
78 Commits
78 Commits
.cargo
.cargo
.github/workflows
.github/workflows
agents-bridges
agents-bridges
crates
crates
docs
docs
examples
examples
migrations
migrations
schemas
schemas
static
static
tailwind
tailwind
tests
tests
.gitattributes
.gitattributes
.gitignore
.gitignore
AGENT_INSTRUCTIONS.md
AGENT_INSTRUCTIONS.md
CHANGELOG.md
CHANGELOG.md
CONTRIBUTING.md
CONTRIBUTING.md
Cargo.lock
Cargo.lock
Cargo.toml
Cargo.toml
INSTALL.md
INSTALL.md
INTEGRATING.md
INTEGRATING.md
LICENSE
LICENSE
LICENSING.md
LICENSING.md
README.md
README.md
clippy.toml
clippy.toml
deny.toml
deny.toml
install.sh
install.sh
rust-toolchain.toml
rust-toolchain.toml
rustfmt.toml
rustfmt.toml
server.json
server.json
Repository files navigation
Why mwe-mcp
Ask most agent frameworks where their memory lives and the honest answer is "in a vector index somewhere." It works, until you need to do anything human with it: open it, correct a wrong fact, understand why the agent thinks what it thinks, or — the hard one — let more than one person share a memory without everyone seeing everything. An opaque blob of embeddings has no answer to "who is this fact about, who told us, who's allowed to read it — and is it still true?"
mwe-mcp starts from the opposite end. The memory reads like a wiki — Markdown pages you browse from the built-in dashboard, owned on disk as plain files — while every fact in it is governed individually by the engine: who it's about, who said it, who may read it, and the time window in which it holds. On top of that it adds the machinery a genuinely shared, long-lived memory needs and that almost nothing else has: access control inside a single page, facts that close gracefully when life moves on, and a background process that keeps the whole thing tidy and well-written over time.
The result is a memory that a household, a team, or a single developer can all use through whatever agent they already have — Claude Code in a repo, an LLM assistant reaching them on Telegram or voice, your own — while the memory itself stays one governed source of truth.
📄 A wiki you can read, not a vector dump. Facts get compiled into flowing Markdown pages — each fact homed on exactly one page, woven into prose that spells out how facts relate. The prose isn't decoration: making relationships explicit is what makes recall accurate. Read it from the built-in dashboard; it reads like someone kept notes carefully.
🔒 Access control per fragment, inside a single page. One page can mix public, private, and group-restricted spans, redacted per reader before any text reaches a consumer agent. On disk each protected span carries only a stable key; the governing metadata — owner, sender, audience, validity — lives in the engine's per-fact index and is enforced by code, never by asking a model nicely. Sharing a page never means sharing all of it.
🪪 Owner vs. sender attribution. Who a fact is about and who reported it are separate, always. "Alice says Bob changed jobs" lands in Bob's profile — owner Bob, sender Alice — with authorship preserved for audit.
⏳ Facts that know when they stop being true. Every fact carries a validity window. A dated commitment expires on its own; "I bought the milk" closes the open shopping item as completed; "forget what I said about the greenhouse — I dropped the project" retracts the right facts and nothing else. Closing is never deleting: the window shuts, history stays, and the prose narrates it ("bought on May 12", "project abandoned").
🧭 Recall that navigates. Flat similarity search finds the look-alikes; a navigator then walks the wiki — pages, links, hubs — the way a person would, which is how the deviating facts surface: the trip that was cancelled, the allergy behind a dinner plan, the item that's already been bought. Stale windows are down-ranked as a signal, never hidden.
🧵 No compaction, no session to reset. When the context window fills, most stacks run a summarization pass that rewrites the conversation into a lossy digest — the exact point where agent state silently corrupts. mwe-mcp runs none: the durable memory stays a complete, structured wiki, and the live context is a small bounded window that topic-aware recall refills every turn. Recall replaces the summary — the thread stays continuous because the memory carries it, not a transcript that has to be compressed to survive, and there's no session boundary where it all resets to cold.
🧩 Shape emerges per fact — no schema, ever. A passing detail is a line; a topic that accumulates becomes a page, then its own sub-wiki; a shopping list renders as records while a person's story reads as prose, with consumption history riding to a registry page so the list itself stays current. Form follows mass and content, not a template you declare up front.
🌙 Nightly self-organization (REM). While no one is waiting, a background cycle deduplicates facts, merges near-synonym pages, closes completions and contradictions the conversations missed, re-anchors rotting relative dates ("today" → the date it was actually said), lets grown topics emerge into their own wikis, and recompiles it all into prose. Every structural change applies act-first with a receipt: you get a notice, and a one-tap revert window — no approval queue to babysit.
🤝 Smart wikis for coding agents. A smart consumer (e.g. Claude Code inside a repo) authoritatively maintains a project-scoped wiki — architecture decisions, bug trackers, runbooks — with a one-page _briefing.md handoff for the next session, cooperative leases, and a revertible op-log.
⚡ A lean hot path. Per turn: deterministic I/O, local embeddings, one routing call to the internal LLM (plus an optional navigation call when configured). The heavy lifting is batched into the nightly cycle. Latency stays bounded; the bill stays predictable.
🔌 Truly consumer-agnostic. Any LLM-driven agent — Claude Code, Cursor, an assistant your users reach on Telegram/Slack/voice, your own — talks to the same governed memory over MCP, at the same time. The agent's model composes each reply from the recall block; mwe-mcp governs what that block contains. Swap a harness, add another; the memory stays one.
Born as the memory-wiki-engine plugin for OpenClaw, extracted into a standalone, agent-agnostic product.
See it in action
Four short scenes. The agent calls one tool per turn (wiki_ingest_message); everything below the surface — recall, attribution, ACL, validity, the atomic writes — is composed by mwe-mcp and never leaks to the agent.
A household that shares some things, not all
A family runs one shared memory; every assistant they talk to — the voice assistant in the kitchen, an LLM bot on Telegram, Claude Code on a laptop — remembers into it and recalls from it. Alice and Bob are on the team; Zoe is family but not on the team.
Alice: "Bob changed jobs, he's at AcmeCorp now." Assistant: "Noted in Bob's profile."
mwe-mcp resolves "Bob", decides the fact is about Bob (so it lands on his page), keeps Alice as the sender, and — because a job is a team concern — scopes it to group:team. Later, two different people ask:
Bob: "What do you know about my current job?" Assistant: "You're at AcmeCorp (noted by Alice on May 17)."
Zoe: "Do you know where Bob works?" Assistant: "I don't have anything I can share about that."
Same page, same fact, two answers. Zoe isn't on the team, so the span is redacted before it ever reaches her agent — no error, no "access denied", just invisible. That per-reader redaction inside a single page is the thing most agent memories simply can't express.
Memory that lets go — on command, or on its own
Galadriel: "I bought the milk and the grated cheese, take them off the list." Assistant: "Done — marked as bought."
The two open shopping items close as completed, dated. The list page stays current; the purchase event rides to the list's registry page, so history stays navigable without cluttering the list. A recurring item simply reopens the next time someone says "we're out of milk" — a list is a cycle, not a TTL.
A shared list the morning after: open items keep their asker (Frodo asked for coffee, the kid flagged the biscuits), bought items close with a date — narrated, never deleted.
Frodo: "Forget what I told you about the greenhouse: I dropped the project." Assistant: "Done — the greenhouse plans are closed, and I noted you abandoned the project."
The greenhouse facts close as retracted — precisely those, nothing vaguely similar; when the right targets don't surface on the first lookup, the engine runs a focused second pass rather than guessing, and closing nothing always beats closing the wrong thing. History isn't destroyed: the windows shut, an outcome fact records the abandonment, and the page recompiles to narrate it. Every closure is act-first with a receipt and a 7-day revert from the dashboard.
A coding agent with a project brain
Bob opens his repo in VSCode with Claude Code, which has mwe-mcp wired in as a smart consumer:
Bob: "I've decided to use Postgres instead of SQLite for myapp — we expect >100k users and SQLite struggles on concurrent writes. Note it." Claude: "Noted as an architecture decision in myapp, linked to the backend module."
Three days later, on a fresh session:
Bob: "Remind me why we chose Postgres for myapp." Claude: "You decided 3 days ago: Postgres over SQLite, to scale past 100k users and handle concurrent writes."
Because Claude is a smart consumer, it writes the decision into its own smart wiki with its own model budget — no second LLM bill on mwe-mcp's side — and the next session starts from a _briefing.md instead of cold. The project's memory outlives any single chat.
Memory that tidies itself overnight
Months of notes pile up as loose paragraphs on Alice's work page. One night, with nobody waiting, the REM cycle notices the shape:
REM, 08:00: "Last night I reorganized your work notes: the AcmeCorp material (7 converging facts) now lives in its own section, two near-duplicate pages were merged, and three finished errands were closed. Everything's already in place — tap to review or revert any of it within 7 days."
Nothing is invented or silently lost: facts keep their identity, they're relocated, re-linked and recompiled into prose — and every structural change leaves a born-applied receipt with a revert window. You close the laptop on a pile of notes and open it on a wiki.
Quickstart
1 — get the binary (Linux x86_64 · macOS Apple Silicon)
curl -fsSL https://raw.githubusercontent.com/Fr4nZ82/mwe-mcp/main/install.sh | sh
2 — start the server (MCP endpoint + dashboard on one port)
mwe-mcp serve
On Windows — open the latest release, download mwe-mcp--x86_64-pc-windows-msvc.zip from its Assets section, unzip it, then run mwe-mcp.exe serve from a terminal.
3 — finish setup in the browser. Open http://127.0.0.1:8742/dashboard/setup: the first-run wizard creates the admin account, your users and groups, and picks how the internal LLM runs — all-local via Ollama, hybrid, or API.
4 — connect an agent. For Claude Code it's one command and an OAuth sign-in — no token to paste:
claude mcp add --transport http mwe-mcp http://127.0.0.1:8742/mcp --scope user
For every other consumer, your running server serves its own bridge catalog at /bridges with tailored copy-paste setup. The full path — deployment topologies, LLM profiles, security posture — is in INSTALL.md; the per-turn contract your agent implements is in INTEGRATING.md.
What a memory page look
[truncated for AI cost control]