Skip to main content

MongoDB memory provider plugin for Hermes Agent — hybrid search, time-decay, TTL forgetting, and entity graph traversal in a single backend.

Project description

MongoDB Memory Provider for Hermes Agent

Hybrid search, time-decay relevance, TTL-driven forgetting, and entity graph traversal — served from a single MongoDB cluster (self-hosted or Atlas free tier).

CI License

Why MongoDB?

Existing Hermes memory providers each pick one storage angle: local SQLite (Holographic), cloud-only API (Mem0, Supermemory, RetainDB), knowledge graph (Hindsight), or vector-only stores. MongoDB collapses all of them into one backend.

Capability This plugin Closest alternative
Native hybrid (vector + BM25) ranking ✅ Atlas $rankFusion RetainDB ($20/mo cloud-only)
Self-hosted and cloud with one URI swap OpenViking (AGPL-3.0)
TTL-driven automatic forgetting ✅ Mongo TTL indexes None
Entity graph traversal without a graph DB $graphLookup Hindsight (separate KG)
Time-decay relevance built into search ✅ in-pipeline $exp None
Free tier with cloud durability ✅ Atlas free tier Holographic (local-only)
Cross-device sync ✅ via Atlas Cloud providers only

In other words: vector search, BM25, structured queries, TTL, and graph traversal are all the same database — no glue between SQLite and a vector store, no separate graph engine.

Requirements

  • Python ≥ 3.10
  • A MongoDB 7.0+ cluster, either:
    • Atlas free tier (M0) — recommended; enables $rankFusion hybrid search and managed vector indexes
    • Self-hosted (community / enterprise) — works with the portable BM25 + cosine fallback path
  • (Optional) an embedding provider key — OpenAI or Voyage AI. Without one, the plugin runs as a tuned BM25 + entity-graph store.

Install

pip install hermes-mongodb-memory
hermes-mongodb-memory install
# Optional vector backends:
pip install "hermes-mongodb-memory[openai]"
pip install "hermes-mongodb-memory[voyage]"
pip install "hermes-mongodb-memory[all]"   # both

The installer copies the provider into $HERMES_HOME/plugins/mongodb, which is the directory current Hermes releases scan for community memory providers. The package also publishes hermes.memory_providers and hermes_agent.plugins entry points for compatibility with future entry-point-based loaders.

Setup

Path 1 — Guided (recommended)

hermes-mongodb-memory install
hermes memory setup        # pick "mongodb" from the provider list
hermes mongodb init-indexes

The wizard prompts for connection URI, database, embedding provider, and tenant scope, then writes:

  • $HERMES_HOME/mongodb.json — non-secret values
  • $HERMES_HOME/.envHERMES_MONGODB_URI and any embedding API key

Path 2 — Manual

hermes config set memory.provider mongodb
echo 'HERMES_MONGODB_URI="mongodb+srv://USER:PASS@cluster.mongodb.net/?retryWrites=true"' >> ~/.hermes/.env
hermes-mongodb-memory install
hermes mongodb init-indexes

Path 3 — Local development

git clone https://github.com/alexbevi/mongodb_hermes_memory.git
cd mongodb_hermes_memory
pip install -e ".[dev,all]"
hermes-mongodb-memory install --force
docker compose up -d                            # local Mongo 7 replica set
export HERMES_MONGODB_URI="mongodb://localhost:27017/?replicaSet=rs0"

For editable development, replace the copied plugin with a symlink if you want Hermes to see source edits without rerunning the installer:

rm -rf "${HERMES_HOME:-$HOME/.hermes}/plugins/mongodb"
ln -s "$(pwd)/hermes_mongodb_memory" "${HERMES_HOME:-$HOME/.hermes}/plugins/mongodb"

Atlas free tier (zero-cost path)

  1. Create an Atlas account and a free M0 cluster.
  2. Network Access → Add your IP (or 0.0.0.0/0 for development).
  3. Database Access → Create a user.
  4. Connect → Drivers → copy the mongodb+srv://... string.
  5. Paste it into hermes memory setup (or set HERMES_MONGODB_URI).
  6. (Optional, enables hybrid search) Create the search indexes — see Atlas Search indexes below.

Configuration

$HERMES_HOME/mongodb.json — env vars override file values.

Key Default Description
connection_uri MongoDB URI (env: HERMES_MONGODB_URI)
database hermes_memory Database name
embedding_provider none none / openai / voyage
embedding_api_key Provider API key (env: HERMES_MONGODB_EMBEDDING_API_KEY)
embedding_model text-embedding-3-small Embedding model name
embedding_dim 1536 Must match your Atlas Vector Search index
tenant_scope per-workspace global / per-workspace / per-profile
auto_extract false Run regex extractor at session end
extraction_llm false Use Hermes' configured LLM for richer extraction
time_decay_half_life_days 30 Half-life for relevance decay (0 disables)
default_ttl_days 0 Default TTL for new memories (0 = never)
hybrid_vector_weight 0.6 Vector vs BM25 weight (0–1)
prefetch_limit 5 Memories injected into each turn
turn_ttl_days 30 TTL for raw turn capture (0 = forever)

Tools

The model can call six tools while the provider is active:

Tool Purpose
mongo_remember Store a memory with category, entities, tags, optional TTL
mongo_search Hybrid query (vector + BM25 + time-decay) — call before answering personal questions
mongo_recall Walk the entity co-occurrence graph for related memories
mongo_forget Remove or set short TTL on a memory by id
mongo_profile Summary of latest preferences, projects, decisions
mongo_reflect Cluster recent memories by entity for cross-category synthesis

Indexes

hermes mongodb init-indexes creates the following on memories:

Name Shape Why
tenant_category_recent {tenant_id, category, created_at} Fast mongo_profile and per-category list scans
tenant_entities {tenant_id, entities} Entity recall + $graphLookup start point
tenant_tags (sparse) {tenant_id, tags} Tag filtering without bloating non-tagged docs
ttl_expires_at (sparse, TTL=0) {expires_at} MongoDB TTL monitor evicts ephemeral memories
content_text {content: "text"} Portable BM25 fallback for self-hosted clusters

Plus on turns:

  • tenant_session_turn{tenant_id, session_id, turn_idx}
  • turns_ttl — TTL on expires_at

Atlas Search indexes

For the hybrid-search fast path, create these in the Atlas UI (or via the Atlas Admin API):

// Atlas Search index "hermes_memory_text"
{ "mappings": { "fields": { "content": { "type": "string" } } } }

// Atlas Vector Search index "hermes_memory_vector"
{
  "fields": [
    { "type": "vector", "path": "embedding", "numDimensions": 1536, "similarity": "cosine" },
    { "type": "filter", "path": "tenant_id" },
    { "type": "filter", "path": "category" },
    { "type": "filter", "path": "entities" }
  ]
}

Without these, the plugin transparently falls back to portable BM25 + in-process cosine.

Testing

# Unit tests (mongomock-backed, no docker required)
pytest tests/ -v --cov=hermes_mongodb_memory

# Integration tests against a real MongoDB
docker compose up -d
export MONGODB_TEST_URI="mongodb://localhost:27017"
pytest tests/test_integration.py -v -m integration

# Conformance tests against the real Hermes Agent ABC and loader
# (requires Python 3.11+ for hermes-agent)
pip install -e ".[dev,hermes]"
pytest tests/test_hermes_conformance.py -v -m hermes

# Lint
ruff check .

Architecture

flowchart TB
    subgraph Hermes["Hermes Agent (host)"]
        Register["register(ctx)"]
        Provider["MongoDBMemoryProvider"]
        Prefetch["prefetch / queue_prefetch"]
        SyncTurn["sync_turn"]
        Tools["tools (6)"]
        SessionEnd["on_session_end"]

        Searcher["HybridSearcher"]
        Embedder["EmbeddingClient<br/>(openai / voyage / none)"]
        Store["MongoStore"]
        Dispatcher["ToolDispatcher"]
        Regex["RegexExtractor"]
        LLM["LLMExtractor (optional)"]

        Register --> Provider
        Provider --> Prefetch
        Provider --> SyncTurn
        Provider --> Tools
        Provider --> SessionEnd

        Prefetch --> Searcher
        Searcher --> Embedder
        SyncTurn --> Store
        Tools --> Dispatcher
        Dispatcher --> Store
        Dispatcher --> Searcher
        SessionEnd --> Regex
        SessionEnd --> LLM
        Regex --> Store
        LLM --> Store
    end

    subgraph Mongo["MongoDB / Atlas"]
        Memories[("memories")]
        Turns[("turns")]
        Profiles[("profiles")]
        Entities[("entities")]

        RankFusion["$rankFusion<br/>$vectorSearch + $search (BM25)"]
        GraphLookup["$graphLookup<br/>(entity traversal)"]
        TTL["TTL indexes<br/>(automatic forgetting)"]
    end

    Searcher -.->|aggregation| RankFusion
    Store -.->|CRUD + indexes| Memories
    Store -.-> Turns
    Store -.-> Profiles
    Store -.-> Entities
    Dispatcher -.->|mongo_recall| GraphLookup
    Memories -.- TTL

    classDef host fill:#f5f5f5,stroke:#444,color:#222;
    classDef store fill:#e6f4ea,stroke:#2e7d32,color:#1b5e20;
    classDef op fill:#fff3e0,stroke:#ef6c00,color:#5d4037;
    class Register,Provider,Prefetch,SyncTurn,Tools,SessionEnd,Searcher,Embedder,Store,Dispatcher,Regex,LLM host;
    class Memories,Turns,Profiles,Entities store;
    class RankFusion,GraphLookup,TTL op;

Background daemon threads handle prefetch and sync_turn so a flaky cluster never blocks the conversation. A 5-failure / 120-second circuit breaker pauses Mongo writes when something is wrong upstream. When Hermes passes full message history, sync_turn also stores compact tool trace metadata on the assistant turn: tool name, parsed arguments, and result.

Telemetry

The plugin attaches DriverInfo(name="Hermes-MongoDB-Memory", version=<pkg-version>) to every MongoDB connection it opens. This appears in the server handshake and lets cluster operators distinguish traffic from this plugin in MongoDB's server-side metrics — no PII or query content is included. There is no opt-out short of patching provider._DRIVER_INFO; if that's a problem for your deployment, open an issue.

Releasing

Publishing is scripted in scripts/publish.sh:

scripts/publish.sh build     # build sdist + wheel only (dry run)
scripts/publish.sh test      # build, lint, test, upload to TestPyPI
scripts/publish.sh prod      # same, upload to PyPI, tag v<version>
scripts/publish.sh gh        # push tag and create GitHub release with notes

The PyPI targets enforce a clean working tree, assert that pyproject.toml and hermes_mongodb_memory/__init__.py agree on the version, run ruff + pytest, call python -m build, and use twine to upload. Configure credentials in ~/.pypirc or via TWINE_USERNAME=__token__ / TWINE_PASSWORD=pypi-....

The gh target reads the version, ensures the v<version> tag exists locally and on origin, then calls gh release create with auto-generated notes (install snippet, highlights derived from feat: / fix: commit subjects since the previous tag, and a compare link). Idempotent — re-runs detect existing tags and releases and skip safely. Requires gh to be authenticated (gh auth login).

Contributing

PRs welcome. Conventional Commits required (feat(scope): ..., fix(scope): ...); tests required for new behavior; coverage gate is 80%.

License

MIT — same as Hermes Agent.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermes_mongodb_memory-0.2.0.tar.gz (56.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermes_mongodb_memory-0.2.0-py3-none-any.whl (39.1 kB view details)

Uploaded Python 3

File details

Details for the file hermes_mongodb_memory-0.2.0.tar.gz.

File metadata

  • Download URL: hermes_mongodb_memory-0.2.0.tar.gz
  • Upload date:
  • Size: 56.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.3

File hashes

Hashes for hermes_mongodb_memory-0.2.0.tar.gz
Algorithm Hash digest
SHA256 85b3cea1db19a5704117928286da84cf4a3798382105f1f735241151735090cf
MD5 5f1e459a9052ece40e4fae7bbde3c204
BLAKE2b-256 465349db89b989e6c6b01d931bddf5d1cea472cfd4d5cb1e7c277d1c8ed2f909

See more details on using hashes here.

File details

Details for the file hermes_mongodb_memory-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for hermes_mongodb_memory-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 688175dd77a940e0dbe65e4dcce83cc4cfe6261c5cb92c74c1013bd7f8b4d827
MD5 e63599dfafc81321d0d51a6138e8fe85
BLAKE2b-256 cda1a535722452c4df8991135e03224c3b1bb576aeceaf29f383ae805dbabd97

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page