Skip to main content
Glama

License: MIT Python 3.11+

Mesh Memory

Mesh Demo

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.

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 .env

Open .env and set a password for PostgreSQL:

POSTGRES_PASSWORD=pick_any_password_here

That'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 similarity

You 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:

  1. Stores the document in PostgreSQL

  2. Generates an embedding vector in the background

  3. Auto-adds date:2026-02-23 and source:api tags

  4. After 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 overlap

No 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" 5

MCP 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:8001

Features

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

date:2026-02-23, source:api

Neighbor inference

After embedding

7 nearest neighbors share type:worklog -> auto-added

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 rendering

  • Galaxy 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

mesh_search

Semantic search (single or multi-workspace with weights)

mesh_add

Save document (auto-tags applied)

mesh_update

Update content, tags, or pinned status

mesh_delete

Delete by GUID

mesh_get

Get by GUID

mesh_bytag

Filter by tags

mesh_focus

Switch active workspace (with optional prefetch)

mesh_versions

Document version chain

mesh_projects

List projects with stats

mesh_stats

Memory statistics

mesh_recent

Recent documents

mesh_tags

List tags with counts

mesh_schema

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

POST

/admin/keys

Create scoped API key

GET

/admin/keys

List API keys

DELETE

/admin/keys/{hash}

Revoke key

GET

/admin/workspaces

List workspaces with doc counts

DELETE

/admin/workspaces/{name}

Delete workspace and all docs

GET

/admin/config

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

date:2026-02-23, source:api added automatically

Nothing

3. Neighbor inference

After embedding, tags are inferred from 7 nearest neighbors

5+ existing documents

4. AI categorization

LLM assigns category:* and subcategory:* tags

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/taxonomy

The 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

PUT

/

Create document

GET

/

Help (no params) or list documents (with params)

POST

/search

Semantic search

GET

/{guid}

Get document

PUT

/doc/{guid}

Update document

PATCH

/{guid}

Update document (alias)

DELETE

/{guid}

Delete document

PUT

/bulk

Bulk create (up to 100)

GET

/versions/{guid}

Version chain

GET

/short/{guid}

Short document summary

GET

/browse

All documents (for client-side search)

GET

/keyword

Fast keyword search (no embedding)

GET

/by-hash/{hash}

Find document by content hash

PATCH

/by-hash

Update document by content hash

Search & Discovery:

Method

Path

Description

GET

/tags

All tags with counts

GET

/stats

Statistics

GET

/activity

Document activity feed

GET

/schema

Tag schema

GET

/visualize

Visualization data for galaxy map

Metadata:

Method

Path

Description

PUT

/meta/{guid}

Set document metadata (JSONB)

GET

/meta/{guid}

Get document metadata

DELETE

/meta/{guid}

Delete document metadata

GET

/meta?type=

List metadata by document type

Embeddings:

Method

Path

Description

POST

/embed

Generate embedding for text

POST

/embed/batch

Batch embed multiple texts

AI Categorizer (requires CATEGORIZER_ENABLED=true):

Method

Path

Description

GET

/categorizer/taxonomy

Current taxonomy with stats

POST

/categorizer/bootstrap

Generate taxonomy from documents

POST

/categorizer/batch

Batch classify untagged documents

POST

/categorizer/classify/{guid}

Classify single document

GET

/categorizer/categories

List categories (workspace-scoped)

POST

/categorizer/categories

Create category (admin)

PUT

/categorizer/categories/{id}

Rename category (admin)

DELETE

/categorizer/categories/{id}

Delete category (admin)

AI & Utilities:

Method

Path

Description

POST

/summarize/{guid}

AI-powered document summary

GET

/health

Health check

GET

/help

Full API documentation

Admin (requires admin API key):

Method

Path

Description

POST

/admin/keys

Create scoped API key

GET

/admin/keys

List API keys

DELETE

/admin/keys/{hash}

Revoke API key

GET

/admin/workspaces

List workspaces

DELETE

/admin/workspaces/{name}

Delete workspace

GET

/admin/config

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 up -d

Without 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.main

With Traefik

echo "TRAEFIK_HOST=mesh.example.com" >> .env
docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d

Environment 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

type:worklog

Completed work

type:note

Notes and ideas

type:decision

Architecture decisions

type:task

Action items

type:research

Analysis and findings

type:rfc

Proposals

status:active

In progress

status:completed

Done

date:YYYY-MM-DD

When created (auto-added)

guid:project-id

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

docker compose up

Sign up

Helm chart

pip install

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/                     # Documentation

Contributing

Contributions welcome! See CONTRIBUTING.md for setup and guidelines.

For security issues, see SECURITY.md.

License

MIT


Created by Dmytro Klymentiev

A
license - permissive license
-
quality - not tested
C
maintenance

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