mesh-memory
Mesh Memory

A memory that understands what you mean, not just what you type.
You save a note: "changed the login page to fix the auth problem". A month later you search for "security issues on the website" -- and Mesh finds your note. Even though you never used the words "security", "issues", or "website". Because Mesh understands that these ideas are related.
Why this matters
You forget the exact words you used last time. Mesh doesn't care -- it searches by meaning.
Your notes, decisions, and research are scattered. Mesh keeps them in one place and finds connections.
AI agents need memory between sessions. Mesh gives them one -- searchable, organized, persistent.
Who is Mesh for
Solo developers -- save decisions, worklogs, research. Find them months later with a vague question.
Teams -- each team gets its own workspace. Search across multiple workspaces with weighted priority.
AI agents -- Claude, GPT, or custom agents use Mesh as long-term memory via API or MCP tools.
Anyone who takes notes -- if you've ever lost a note because you couldn't remember the right keyword, Mesh solves that.
How it's different from regular search
Regular Search | Mesh Memory |
"auth bug" only finds "auth bug" | "auth bug" finds "login problem" |
Exact keyword match | Understands meaning and context |
One language at a time | Works across 100+ languages |
Forgets context | Remembers everything you saved |
Agent roles via workspaces
Create a workspace for any role -- and your AI agent instantly becomes a specialist with full history. Workspaces are free-form, create as many as you need:
sysadmin -- server configs, incident fixes, monitoring notes
marketer -- campaigns, ad performance, content plans
developer -- architecture decisions, bug investigations, code reviews
psychologist -- session notes, client progress, therapy approaches
support -- customer issues, FAQ, product knowledge base
researcher -- papers, experiments, literature reviews
...any role you can think of
Switch workspace -- and the agent sees only what's relevant to that role. No noise from other domains. Pin a role prompt to the top of each workspace, and the agent knows exactly who it is and what it should do.
Need cross-domain context? Use weighted multi-workspace search: "find nginx configs" with 70% weight on sysadmin, 20% on security, 10% on developer -- and get results from all three, ranked by relevance and priority.
Privacy first
Runs on your own server. Single Docker container. No cloud APIs, no subscriptions, no data leaving your machine. The AI model runs locally.
Quick Start
# Clone and configure
git clone https://github.com/dklymentiev/mesh-memory.git
cd mesh-memory
cp .env.example .envOpen .env and set a password for PostgreSQL:
POSTGRES_PASSWORD=pick_any_password_hereThat's the only required change. Everything else has sensible defaults.
# Start
docker compose up -d
# Check it works (takes 2-3 min on first launch)
curl http://localhost:8000/health
# {"status": "healthy", "embeddings": "ready"}First launch downloads PostgreSQL, builds the API image, and bakes in the AI model (~560 MB). Subsequent starts are instant.
# Save your first document
curl -X PUT http://localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"content": "Decided to use PostgreSQL for the project", "tags": ["type:decision"]}'
# Search by meaning
curl -X POST http://localhost:8000/search \
-H "Content-Type: application/json" \
-d '{"query": "which database did we choose?"}'It finds your document -- even though the words are completely different.
For a step-by-step walkthrough including Web UI, tagging, and MCP integration, see the Getting Started Guide.
How It Works
Mesh has three layers:
Layer 1: DOCUMENTS What you save -- notes, decisions, worklogs, research
Layer 2: EMBEDDINGS AI model turns text into 768-dim vectors (automatic)
Layer 3: SEARCH Find by meaning using vector similarityYou save a document -- plain text with optional tags:
curl -X PUT localhost:8000/ \
-H "Content-Type: application/json" \
-d '{"content": "Chose Redis for caching because...", "tags": ["type:decision"]}'Mesh automatically:
Stores the document in PostgreSQL
Generates an embedding vector in the background
Auto-adds
date:2026-02-23andsource:apitagsAfter indexing, infers tags from similar documents (e.g.
type:decision,topic:redis)
You search by meaning:
curl -X POST localhost:8000/search \
-d '{"query": "what caching solution did we pick?"}'
# -> finds the Redis decision, even with zero word overlapNo configuration. No prompt engineering. No API keys for external services. The AI model runs locally inside the container.
What Can You Do With It
Personal knowledge base
Save everything you learn, decide, or think about. Find it later by describing what you're looking for in plain language.
Team memory
Multiple people save worklogs and decisions. Anyone can search across everything by meaning. "How did we handle rate limiting?" finds the relevant design doc even if it never mentions those words.
AI agent memory
Give your AI agents persistent memory. They save context, decisions, and progress. Later they (or other agents) can search for relevant information.
# Agent saves its work
mesh add "Implemented retry logic with exponential backoff for API calls" \
"type:worklog,date:2026-02-23"
# Another agent finds it
mesh search "error handling patterns" 5MCP integration
Mesh includes an MCP server (12 tools) that works with Claude Desktop, Claude Code, and Cursor. Your AI assistant can search, save, and organize documents directly.
Demo Mode
The repo ships with 1000 pre-generated documents across 15 categories -- software development, AI/ML, infrastructure, design, DevOps, career, and more. Great for trying out the UI and search.
# Start the demo instance (auto-seeds 1000 documents)
docker compose up -d api-demo
# Open the galaxy map
open http://localhost:8001/ui/map.html
# Or the search UI
open http://localhost:8001/ui/The demo auto-seeds on first startup when the database is empty. You can also seed manually:
python scripts/seed_demo.py --api http://localhost:8001Features
Semantic search
Search by meaning, not keywords. Ask "login problems" and find "authentication bug". Works across 100+ languages thanks to the multilingual-e5-base model.
Smart auto-tagging
Three levels of automatic tagging (no AI API calls needed):
Level | When | Example |
Defaults | On save |
|
Neighbor inference | After embedding | 7 nearest neighbors share |
Manual | On save | Your tags always take priority |
Configured in mesh.yaml. Custom tags beyond the schema are always accepted.
Version chains
Track how a document evolved over time. Mesh uses embedding similarity to find related versions automatically -- no manual linking needed.
curl "localhost:8000/versions/doc_4fa2cae8?threshold=0.85"Pinned documents
Pin important documents to always appear first in workspace listings. Perfect for role prompts, onboarding docs, or project briefs.
curl -X PATCH localhost:8000/doc_abc123 \
-H "Content-Type: application/json" \
-d '{"pinned": true}'Pinned documents sort before all others in GET / listings.
Built-in Web UI
Served at /ui/:
Search page (
/ui/) -- semantic search with card grid and markdown renderingGalaxy map (
/ui/map.html) -- Three.js visualization with clustering by category, timeline view, and real-time search highlighting
No build step. Native ES modules, baked into the Docker image.
MCP Server (12 tools)
For Claude Desktop, Claude Code, and Cursor:
Tool | What it does |
| Semantic search (single or multi-workspace with weights) |
| Save document (auto-tags applied) |
| Update content, tags, or pinned status |
| Delete by GUID |
| Get by GUID |
| Filter by tags |
| Switch active workspace (with optional prefetch) |
| Document version chain |
| List projects with stats |
| Memory statistics |
| Recent documents |
| List tags with counts |
| Show tag schema |
Setup:
{
"mcpServers": {
"mesh": {
"command": "python3",
"args": ["/path/to/mcp_server.py"],
"env": {
"MESH_API_URL": "https://your-mesh-instance.com"
}
}
}
}Workspaces (multi-tenancy)
Isolate documents by workspace. Each workspace has its own documents, categories, and search index. Perfect for teams or multi-project setups.
# Save to a specific workspace
curl -X PUT localhost:8000/ \
-H "Content-Type: application/json" \
-H "X-Workspace: marketing" \
-d '{"content": "Q1 campaign results...", "tags": ["type:note"]}'
# Search only within that workspace
curl -X POST localhost:8000/search \
-H "X-Workspace: marketing" \
-d '{"query": "campaign performance"}'Without X-Workspace, everything goes to the default workspace. Fully backward-compatible.
Multi-workspace search -- search across workspaces with weighted relevance:
curl -X POST localhost:8000/search \
-H "Content-Type: application/json" \
-d '{"query": "nginx config", "limit": 10, "workspaces": {"sysadmin": 0.7, "security": 0.2, "hq-architect": 0.1}}'Each workspace gets proportional slots (min 1). Scores are adjusted by weight: a 0.85 match in a workspace with weight 0.3 becomes 0.255. Results are merged, deduped, and sorted by final score.
Scoped API keys restrict access to specific workspaces:
# Create a key that only sees "marketing" and "sales" workspaces
curl -X POST localhost:8000/admin/keys \
-H "Content-Type: application/json" \
-d '{"label": "marketing-team", "workspaces": ["marketing", "sales"]}'Admin endpoints:
Method | Path | Description |
|
| Create scoped API key |
|
| List API keys |
|
| Revoke key |
|
| List workspaces with doc counts |
|
| Delete workspace and all docs |
|
| Server configuration |
AI Categorizer (opt-in)
Automatic document classification using an LLM. Disabled by default -- works without any external API keys.
How documents get organized:
Step | What happens | Requires |
1. Save document | Tags you provide are stored as-is | Nothing |
2. Auto-tags |
| Nothing |
3. Neighbor inference | After embedding, tags are inferred from 7 nearest neighbors | 5+ existing documents |
4. AI categorization | LLM assigns | LLM API key (opt-in) |
Steps 1-3 work out of the box. Step 4 requires an OpenAI-compatible API.
Enable the AI categorizer:
# .env
CATEGORIZER_ENABLED=true
LLM_API_URL=https://openrouter.ai/api/v1 # or any OpenAI-compatible endpoint
LLM_API_KEY=sk-...
LLM_MODEL=google/gemini-2.0-flash-001 # or gpt-4o-mini, claude-haiku, etc.Generate a taxonomy from your documents:
# LLM analyzes 50 diverse documents and designs 10-15 categories
curl -X POST localhost:8000/categorizer/bootstrap \
-H "Content-Type: application/json" \
-d '{"mode": "designed"}'
# View the generated taxonomy
curl localhost:8000/categorizer/taxonomyThe bootstrap samples your documents, asks the LLM to propose meaningful categories (like "Infrastructure", "Product Decisions", "Research Notes"), then classifies every document. New documents are classified automatically as they arrive.
Manage categories manually:
Categories are workspace-scoped. Each workspace gets its own taxonomy.
# List categories for a workspace
curl localhost:8000/categorizer/categories -H "X-Workspace: marketing"
# Create a custom category
curl -X POST localhost:8000/categorizer/categories \
-H "Content-Type: application/json" \
-H "X-Workspace: marketing" \
-d '{"id": "campaigns", "name": "Campaigns", "description": "Marketing campaigns"}'
# Rename a category
curl -X PUT localhost:8000/categorizer/categories/campaigns \
-H "Content-Type: application/json" \
-H "X-Workspace: marketing" \
-d '{"name": "Ad Campaigns"}'
# Delete a category (also removes its tags from documents)
curl -X DELETE localhost:8000/categorizer/categories/campaigns \
-H "X-Workspace: marketing"Classify existing documents in bulk:
# Classify up to 500 untagged documents
curl -X POST localhost:8000/categorizer/batch \
-H "Content-Type: application/json" \
-d '{"limit": 500}'Bulk import
Import up to 100 documents per request:
# Import from JSONL
python scripts/seed_demo.py --api http://localhost:8000
# Or use the API directly
curl -X PUT localhost:8000/bulk \
-H "Content-Type: application/json" \
-d '[{"content": "doc 1", "tags": ["type:note"]}, {"content": "doc 2", "tags": ["type:note"]}]'API Reference
All endpoints accept X-Workspace header to select workspace (default: default).
Documents:
Method | Path | Description |
|
| Create document |
|
| Help (no params) or list documents (with params) |
|
| Semantic search |
|
| Get document |
|
| Update document |
|
| Update document (alias) |
|
| Delete document |
|
| Bulk create (up to 100) |
|
| Version chain |
|
| Short document summary |
|
| All documents (for client-side search) |
|
| Fast keyword search (no embedding) |
|
| Find document by content hash |
|
| Update document by content hash |
Search & Discovery:
Method | Path | Description |
|
| All tags with counts |
|
| Statistics |
|
| Document activity feed |
|
| Tag schema |
|
| Visualization data for galaxy map |
Metadata:
Method | Path | Description |
|
| Set document metadata (JSONB) |
|
| Get document metadata |
|
| Delete document metadata |
|
| List metadata by document type |
Embeddings:
Method | Path | Description |
|
| Generate embedding for text |
|
| Batch embed multiple texts |
AI Categorizer (requires CATEGORIZER_ENABLED=true):
Method | Path | Description |
|
| Current taxonomy with stats |
|
| Generate taxonomy from documents |
|
| Batch classify untagged documents |
|
| Classify single document |
|
| List categories (workspace-scoped) |
|
| Create category (admin) |
|
| Rename category (admin) |
|
| Delete category (admin) |
AI & Utilities:
Method | Path | Description |
|
| AI-powered document summary |
|
| Health check |
|
| Full API documentation |
Admin (requires admin API key):
Method | Path | Description |
|
| Create scoped API key |
|
| List API keys |
|
| Revoke API key |
|
| List workspaces |
|
| Delete workspace |
|
| Server configuration |
Full endpoint details: docs/api-reference.md
Architecture
+--------------+ +--------------+ +--------------+
| CLI / curl | | MCP Server | | Web UI /ui/ |
+------+-------+ +------+-------+ +------+-------+
| | |
+------- X-Workspace header -------+
|
+----------v----------+
| Mesh API (FastAPI) |
| localhost:8000 |
| |
| +--- Auth + RLS --+| API keys, workspace isolation
| +-- Tag Schema ---+| mesh.yaml, auto-tagging
| +-- Categorizer --+| per-workspace taxonomy
+----------+----------+
|
+----------v--------------+
| PostgreSQL + pgvector |
| +- documents | workspace_id + RLS
| +- doc_embeddings | 768-dim vectors
| +- doc_chunks | chunked embeddings
| +- category_centroids | per-workspace categories
| +- document_metadata | JSONB
| +- api_keys | scoped access
+-----------+------------+Deployment
Docker Compose (recommended)
docker compose up -dWithout Docker
# You need: Python 3.11+, PostgreSQL 16 with pgvector
pip install -r requirements.txt
cp .env.example .env
# Edit .env: set DATABASE_URL
python -m mesh.mainWith Traefik
echo "TRAEFIK_HOST=mesh.example.com" >> .env
docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -dEnvironment Variables
# Core
DATABASE_URL=postgresql://postgres:password@postgres:5432/meshdb
DATABASE_URL_APP=postgresql://mesh_app:apppass@postgres:5432/meshdb # RLS-enforced pool
MESH_APP_PASSWORD=apppass # Password for mesh_app role (RLS)
EMBEDDING_MODEL=intfloat/multilingual-e5-base
# Security
AUTH_REQUIRED=false # Require X-API-Key header
API_KEYS=key1,key2 # Valid admin API keys
IP_WHITELIST= # CIDR ranges (empty = allow all)
CORS_ORIGINS= # Allowed origins
# Rate limiting (requests/min, 0 = unlimited)
RATE_LIMIT_SEARCH=60
RATE_LIMIT_EMBED=30
# AI Categorizer (opt-in)
CATEGORIZER_ENABLED=false
LLM_API_URL= # OpenAI-compatible endpoint
LLM_API_KEY=
LLM_MODEL=Full configuration: docs/configuration.md
Tag System
Mesh supports any tags. Recommended types:
Tag | Description |
| Completed work |
| Notes and ideas |
| Architecture decisions |
| Action items |
| Analysis and findings |
| Proposals |
| In progress |
| Done |
| When created (auto-added) |
| Project marker |
How Mesh Compares
Mesh | Pinecone | Weaviate | ChromaDB | |
Self-hosted | Yes | No (SaaS) | Yes | Yes |
Database | PostgreSQL + pgvector | Proprietary | Custom | SQLite |
Auto-tagging | Yes (neighbor inference) | No | No | No |
MCP integration | Built-in | No | No | No |
Web UI | Built-in | Dashboard | Console | No |
Setup |
| Sign up | Helm chart |
|
Best for | Knowledge management | Large-scale search | Knowledge graphs | Prototyping |
Mesh is designed for personal and team knowledge management -- not for billion-scale vector search. If you need a "memory" for your projects with smart search, tagging, and simple deployment, Mesh is for you.
Project Structure
mesh/ # Python package (FastAPI app)
main.py # Application, auth, auto-tagging, version chains
crud.py # Document CRUD + search
database.py # Schema migrations + RLS setup
embeddings.py # Embedding generation
chunker.py # Document chunking for full-content search
config.py # Environment configuration
tag_schema.py # Tag schema + auto-inference
mesh.yaml # Tag configuration
categorizer/ # AI classification (opt-in, workspace-scoped)
__init__.py # Core: classify, bootstrap, batch_scan
taxonomy.py # TaxonomyStore (per-workspace)
router.py # API endpoints + CRUD
models.py # Pydantic models
classifier_embedding.py
classifier_llm.py
config.py
ui/ # Built-in web UI
index.html # Search page
map.html # Galaxy/timeline visualization
settings.html # Admin: workspaces, API keys, categorizer
js/map/ # Three.js modules (15 files)
scripts/ # Dev utilities
generate_demo.py # Generate demo data
seed_demo.py # Load JSONL into Mesh via API
reindex_chunks.py # Reindex document chunks
init-db.sh # Database initialization
examples/ # Usage examples + demo seed data
demo-seed.jsonl # 1000 pre-generated documents
mcp_server.py # MCP server (12 tools)
tests/ # Test suite
docs/ # DocumentationContributing
Contributions welcome! See CONTRIBUTING.md for setup and guidelines.
For security issues, see SECURITY.md.
License
MIT
Created by Dmytro Klymentiev
Latest Blog Posts
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/dklymentiev/mesh-memory'
If you have feedback or need assistance with the MCP directory API, please join our Discord server