memory-service
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., "@memory-servicesearch my memory for the decision on Postgres search"
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.
memory-service
Self-hosted, versioned project memory for Claude Cowork (or any MCP client). One place for Claude to read and write structured notes across projects — searchable, versioned, editable by a human, and independent of any single chat session.
Why this exists
Cowork's built-in memory is scoped to a session and doesn't reliably survive the split between local-desktop sessions and cloud-run scheduled tasks — a fact learned the hard way, not a theoretical concern. If a cloud task researches something today, a local session tomorrow has no way to know. There's no version history, no way to search across everything Claude has learned, and no way for a human to look at what got stored without asking Claude to recite it.
memory-service is the fix: an explicit, external store. Every Cowork session — local, cloud, scheduled, interactive — talks to the same MCP server. Writes land in Postgres and a git repository in the same operation, so every change is both instantly queryable and permanently versioned. A human can browse, search, and edit the same data through a plain web UI, no prompt required.
Prior art
The individual ingredients here aren't new. WUPHF
pairs a git-backed markdown wiki with a SQLite/BM25 index for search — the closest existing
project to "git holds the real history, a database holds a fast index into it," just without
MCP, pgvector, or a shared write path. Mem0's
self-hosted stack is the closest on the other axis — Postgres+pgvector, an MCP server, a web
dashboard — but versions nothing via git; history is a database table.
DiffMem goes further than either: git as the
only store, no database index at all, live git log/grep shell-outs at query time. And the
"memory bank" convention used by several AI coding tools (Cline, Roo Code) — markdown files an
agent is prompted to maintain inside the project repo — solves a related but different problem
with no dedicated service, index, or MCP contract at all.
What doesn't seem to exist elsewhere is the specific combination: MCP tools and a plain human-editable web UI sharing one write path (so they can't drift apart), backed by a real git-commit-per-write history and a properly indexed hybrid (full-text + vector) Postgres search — rather than either git alone, a database alone, or a UI that's read-only.
Related MCP server: OpenChronicle
Architecture
One FastAPI process serves three things from the same codebase, sharing one database connection pool and one write path:
┌─────────────────────────────────────────────────────┐
│ FastAPI process │
│ │
│ web UI (Jinja2+htmx) MCP server (/mcp) │
│ │ │ │
│ └──────────┬───────────────┘ │
│ ▼ │
│ app/services/*.py │
│ (the ONLY code that touches DB or git) │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ Postgres git repo │
│ (query + search) (version history) │
└─────────────────────────────────────────────────────┘Single write path. Every mutation — whether it comes from an MCP tool call or a web form
submission — goes through app/services/*.py and nowhere else. Neither the MCP layer
(app/mcp/tools.py) nor the web routes (app/web/routes.py) touch the database or the git
repo directly; they're both thin wrappers around the same service functions. That means the two
surfaces can never drift apart in behavior, and there's exactly one place to look for how a
write actually happens (app/services/entries.py's upsert_entry/update_entry).
Hybrid search, not just one or the other. Every entry gets both a Postgres tsvector
(full-text, GIN-indexed) and a pgvector embedding (intfloat/multilingual-e5-small,
HNSW-indexed), computed locally on CPU — no embeddings API call, no data leaving the box. A
search merges both rankings with Reciprocal Rank Fusion, so an exact keyword match and a
semantically related note that doesn't share any words both surface. See
app/services/search.py.
Git is the real history; Postgres is the fast index into it. Every write does: DB
transaction → render+commit a markdown file (one .md per entry, YAML frontmatter) → insert an
entry_versions row recording the resulting commit hash → commit the transaction. If the git
commit fails, the DB transaction rolls back — the two are never allowed to disagree about what
the latest version is. entry_versions exists purely so "show me the last 5 changes" is an
indexed SQL query instead of a git log shell-out; the commit hash it stores is how you get
back to the actual git object if you need the full diff. See app/services/git_store.py.
Everything nests, nothing is hardcoded. Projects contain subtopics, subtopics can nest
arbitrarily deep (kunde-mueller/vorgang-2026-08/...), and subtopic paths auto-create on first
write — an agent doesn't need a separate "create subtopic" call before it can file a note under
one. Projects don't auto-create (a project carries a sensitivity_level that has real
access-control implications later, so creating one is a deliberate action — either a human in
the web UI, or the one memory_create_project MCP tool).
MCP tools
Tool | Purpose |
| Full-text + semantic search, optionally scoped to a project/subtopic and/or filtered by tags (OR across multiple tags; can browse by tag alone with an empty query). Every result includes its exact |
| Current entries for a project or subtopic (call this before answering). Every result includes its exact |
| Create or update an entry, identified by (subtopic, title) -- pass the |
| Entries flagged as needing follow-up |
| Version history for one entry |
| Permanently delete one entry (DB row + git file, one commit) |
| Batch dedup check for daily sync tasks (has this mail/message already been logged?) |
| Create a new project — the only structural MCP tool; rename/delete are web-UI-only, human-confirmed actions |
| Record a direct, typed link between two entries ( |
| Remove a specific link between two entries (idempotent) |
| Every entry directly linked to this one, in either direction |
| Scan for likely-duplicate entries via embedding similarity (optionally scoped to one project); reports candidate pairs by default, only links (never merges) with |
Relations are direct links only — no transitive graph traversal, no automatic entity
extraction. They live in Postgres only, not mirrored into git frontmatter like tags/sources
are, since a link to another entry would go stale if that entry is later renamed or deleted;
the relation row's own created_at/created_by is audit trail enough. See
app/services/relations.py.
Quickstart
docker compose up --buildPostgres: localhost:5433 (user/db
memory)
# migrate, then seed 5 example projects with nested subtopics and sample entries
docker compose exec app alembic upgrade head
docker compose exec app python -m scripts.seed_dummy_dataRun tests (spins up its own memory_test database on the same Postgres):
docker compose up -d db
DATABASE_URL=postgresql+asyncpg://memory:memory_dev_password@localhost:5433/memory_test \
python -m pytestRepo layout
Path | What's there |
| SQLAlchemy models: |
| All business logic — |
| The 8 MCP tools, each a thin wrapper over |
| Jinja2 + htmx server-rendered UI — no SPA build step, no CDN dependencies (EasyMDE and htmx are vendored) |
| Schema migrations |
| pytest suite — service-layer, MCP-layer (via |
| Real engineering gotchas hit and fixed while building this — async SQLAlchemy footguns, an MCP-client redirect bug, a Traefik routing collision. Worth a read if you're extending this. |
Status
Built and running in production for one real deployment (Postgres + git-backed history + web
UI + MCP server, behind Authelia OIDC via Traefik). Not yet hardened for multi-tenant use —
row-level security by project_id is designed but not yet implemented (currently
application-layer filtering only); see tasks/lessons.md and the design doc referenced in
tasks/todo.md for what's done versus planned.
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
- AlicenseNot gradedqualityDmaintenanceA database-backed MCP server that acts as a project memory bank, enabling AI assistants to store, retrieve, and search structured context like decisions, tasks, and architecture using SQLite and vector embeddings.Apache 2.0
- AlicenseNot gradedqualityBmaintenancePersistent memory database for LLM agents with hybrid semantic and keyword search, project namespacing, and MCP/REST interfaces.16AGPL 3.0
- AlicenseAqualityBmaintenanceProvides self-hosted memory management for coding agents via MCP, with local vector storage and tools for adding, searching, updating, and deleting memories.81MIT
- -licenseNot gradedqualityNot gradedmaintenanceMCP server for local-first project memory, enabling AI agents to log, search, and retrieve structured project history, summaries, and per-file dossiers with client-specific configuration and diagnostics.
Related MCP Connectors
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.
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/mbay-ODW/memory-service'
If you have feedback or need assistance with the MCP directory API, please join our Discord server