Skip to main content

Qdrant Memory for Hermes

CI Platform compatibility Standalone CLI and MCP CodeQL Python 3.11+ License: MIT

Runtime 0.2.1 provides the standalone CLI/MCP and fixes explicit writes of distinct, highly similar texts. MCP distribution 0.1.1 pins Runtime 0.2.1. The Hermes Plugin Catalog has its own reviewed immutable pin. A PyPI release does not upgrade it. One writer per destination remains required. See release notes and validation.

English | 简体中文

Native long-term memory plugin for Hermes Agent, implemented as a MemoryProvider. Hermes performs extraction through its trusted ctx.llm facade. Qdrant stores named dense vectors and schema-v1 payloads. No Mem0 SDK, separate LLM SDK, telemetry, or core modifications.

Available in the official Hermes Plugin Catalog as a community-maintained plugin.

How it works

For non-Hermes users, install in a private Python 3.11+ environment: pip install 'hermes-plugin-qdrant-memory[mcp]==0.2.1' (omit [mcp] for CLI only). qdrant-memory is the CLI and mcp is its server subcommand. Standalone does not require Hermes. See setup and quick start. MCP-focused agents may instead use the metadata-only distribution. Public releases: Runtime on PyPI and MCP distribution on PyPI. For native Hermes use its official plugin installation mechanism below. Before an authorized upgrade, verify the same profile, collection and embedding pipeline.

flowchart LR
    turn["Hermes turn"] --> admit["Provider callback"]
    admit --> ledger[("SQLite ledger<br/>durable admission")]
    ledger -.async.-> extract["LLM extraction +<br/>relation checks"]
    extract --> store[("Qdrant<br/>dense vectors + payloads")]
    ask["Recall / search"] --> search["Scoped dense search"]
    search --> store

Why this plugin

  • Durable, private memory for Hermes Agent: conversations become searchable memories in your own Qdrant store, with recall, update and scoped deletion.
  • A native Hermes MemoryProvider, not Mem0. The migrate mem0 command imports existing Mem0 exports.
  • Embedded Qdrant needs no separate service. The same code targets self-hosted Server and Qdrant Cloud.
  • A fully local setup works: embedded Qdrant and local Ollama keep the data on your machine.
  • Data locality follows the destination. Extraction uses the LLM configured in Hermes, and embedding uses the configured embedding service. Either can be remote. See Data flow and privacy.
  • Not supported in this preview: multi-writer Server/Cloud, hybrid search and a web UI.

Additional compatibility with other agents

The plugin primarily provides Hermes Agent's durable memory integration. As an additional capability, its shared backend can serve other agents through the Runtime's qdrant-memory --home PATH JSON CLI and optional local stdio MCP interface. Standalone use does not require Hermes. These interfaces support explicit scoped memory operations and maintenance/migration. Automatic extraction and prefetch remain Hermes lifecycle features. See standalone setup for configuration and boundaries, and the agent-neutral qdrant-memory skill for multi-agent installation and usage guidance.

The optional MCP server exposes four scoped tools: qdrant_memory_search, qdrant_memory_add, qdrant_memory_update and qdrant_memory_delete. Compatible clients launch it as a local stdio process and discover/call those tools. Maintenance and migration use the operator CLI. See the MCP capabilities and connection guide for setup, shared-memory boundaries and the verified agent matrix. Runtime 0.2.0 published these interfaces. The published v0.1.0 plugin release does not include the MCP entrypoint.

See it in action

Terminal recording: install the plugin, store a preference, and recall it in a new session

The recording shows the full flow on a clean profile. It installs from the official Hermes Plugin Catalog, teaches a preference, and waits for the background extraction. Then it recalls the preference in a new session and cleans up the demo scope. All steps run in embedded mode. scripts/demo.sh reproduces the same walkthrough with the pinned release.

Install

Requirements: Python 3.11+, a compatible Hermes installation, and a reachable embedding service. The minimum supported Hermes release is v0.21.5 (v2026.9.24). The CI services page documents the tested host versions. The default model needs Ollama and enough local resources to serve qwen3-embedding:4b.

Choose the active profile's home explicitly. Do not reuse another profile's data.

Recommended: install from the official Hermes Plugin Catalog.

export HERMES_HOME="/absolute/path/to/your/hermes-profile"
ollama pull qwen3-embedding:4b
# Start Ollama if it is not running. Keep its service available.
hermes plugins install qdrant-memory
hermes plugins enable qdrant-memory
hermes memory setup
hermes config set memory.provider qdrant-memory
hermes qdrant-memory init

The install resolves the catalog's reviewed commit and prints the entry's declared tools, requirements and known issues before it clones anything. hermes plugins enable prepares the declared dependencies through Hermes PM.

Version-locked: install the verified Runtime 0.2.1 source through the Hermes CLI.

This immutable source revision includes the explicit-write fix. It does not depend on a PyPI release or a catalog update.

export HERMES_HOME="/absolute/path/to/your/hermes-profile"
ollama pull qwen3-embedding:4b
# Start Ollama if it is not running. Keep its service available.
hermes plugins install https://github.com/cnkang/hermes-plugin-qdrant-memory \
  --ref 8929693fcccd1efa91bfa062145e35d2369ca9cc   # verified Runtime 0.2.1 source
hermes plugins enable qdrant-memory
hermes memory setup
hermes config set memory.provider qdrant-memory
hermes qdrant-memory init

For this version-locked form, hermes plugins install checks out the given ref, and hermes plugins enable prepares the declared dependencies through Hermes PM. --ref takes a full 40-character commit SHA. The releases page lists the release commits. Do not pip-install into a managed Hermes environment. Omit --ref to track main, the development line.

Historical release: clone a published tag manually.

The v0.1.0 tag below predates the standalone interfaces and the explicit-write fix. Use the pinned source above for Runtime 0.2.1.

export HERMES_HOME="/absolute/path/to/your/hermes-profile"
mkdir -p "$HERMES_HOME/plugins"
RELEASE_TAG=v0.1.0   # set a published release tag
git clone --branch "$RELEASE_TAG" --depth 1 \
  https://github.com/cnkang/hermes-plugin-qdrant-memory.git \
  "$HERMES_HOME/plugins/qdrant-memory"
ollama pull qwen3-embedding:4b
# Start Ollama if it is not running. Keep its service available.
hermes memory setup
hermes config set memory.provider qdrant-memory
hermes qdrant-memory init

Then verify the install:

hermes qdrant-memory status
hermes qdrant-memory doctor

A healthy install reports the destination, the embedding service and the schema fingerprint. doctor validates runtime discovery, manifest parsing, import and registration. For development installs, see development setup.

The release notes, supported Hermes/Python versions and the current limitations live in docs/releases/v0.1.0.md. main stays the development line.

For local development, symlink the repository into a disposable profile:

mkdir -p "$HERMES_HOME/plugins"
ln -s /path/to/hermes-plugin-qdrant-memory "$HERMES_HOME/plugins/qdrant-memory"
hermes memory setup
hermes config set memory.provider qdrant-memory

Restart the conversation after configuration changes. Existing system prompts and toolsets stay fixed for prompt caching. Packaged installations expose the hermes_agent.memory_providers entry point and keep cli.py and config_schema.py next to the package entry point.

Defaults use embedded Qdrant and Ollama qwen3-embedding:4b (2560 dimensions). Run the embedding service and provision that model before you activate the provider. For server/Cloud, configure the mode in $HERMES_HOME/qdrant-memory.json. Supply QDRANT_URL / QDRANT_API_KEY in the active profile's secret scope.

Capabilities

  • Embedded, self-hosted server and Cloud using the same Qdrant client.
  • Ollama /api/embed and OpenAI-compatible /v1/embeddings, with strict probe, vector-count/dimension validation and pipeline fingerprint checks.
  • Main LLM inheritance, plugin auxiliary task routing and operator-trusted overrides.
  • User/agent scope filtering for recall, exact-ID update and deletion.
  • Turn persistence to the plugin's private SQLite ledger after Hermes admits the provider callback. Serialized writes, cached session recall and builtin memory mirroring use authoritative previous_content.
  • SQLite WAL event/operation ledger, transport retries and restart recovery.
  • Source-ID-only Mem0 JSON/Qdrant migration, re-embedding, dry runs, resumable manifests, supplemental updates, and verification of IDs and payload hashes.
  • Read-only list inventory, portable export (Mem0-importable JSON) and a durable scoped delete-all with prepared-write fencing.

Unlike hosted memory services, your memory data lives in your own Qdrant destination. The plugin makes no calls to external memory services. Its private SQLite ledger (pending operations, dedupe/retry bookkeeping and session mappings) stays in the local Hermes home. Back up that home together with your Qdrant data. Migration from Mem0 is one-way, and version 0.1 has no vector reuse or hybrid retrieval.

Explicit add deduplicates only canonical text in the same scope and never calls an LLM. Different texts are saved regardless of similarity. Update replaces only the authorized exact ID. For automatic Hermes extraction, similarity is a candidate-selection signal, not proof that two facts are identical. SAME skips, SUPERSEDES updates, CONFLICT creates a linked record, and UNRELATED adds a record. Migration uses source IDs instead of semantic merging.

The four agent tools are qdrant_memory_search, qdrant_memory_add, qdrant_memory_update, and qdrant_memory_delete. Maintenance stays in the CLI:

hermes qdrant-memory status
hermes qdrant-memory init
hermes qdrant-memory doctor
hermes qdrant-memory stats
hermes qdrant-memory verify
hermes qdrant-memory retry

status is local-only. doctor and verify probe existing collections without creating or repairing them. Run init after first-time configuration to probe embeddings, create the collection, record its pipeline fingerprint and build Server/Cloud payload indexes. It makes no LLM calls and writes no conversation memories. Repeated runs validate the existing collection. Incompatible dimensions, distance or fingerprint fail without overwriting existing data. When the collection exists, init asks for use (the default on Enter) or clear. Reuse validates the named dense vector, dimensions, distance and pipeline identity, then checks every stored memory's payload, content hash and vector. A validation failure returns a nonzero exit code. The plugin cannot reuse a nonempty collection without a trusted fingerprint. Clear probes embeddings first, then deletes and rebuilds the target collection and discards that destination's local replay work and migration records. The plugin keeps other destinations and the transcript provenance quarantine. Clearing is irreversible, and deletion/recreation is not atomic. Rerun init if remote recreation fails. An interrupted clear leaves a durable reset intent. Other destination commands fail with reset_recovery_required. Rerun init for the same destination to resume the already authorized reset before you enable the provider. For scripts, explicitly pass --existing use or --existing clear. The clear choice authorizes deletion. --collection NAME overrides only this command's target, not the collection configured for subsequent agent sessions. init, migrate and retry require exclusive writer ownership in all deployment modes. The OS lease coordinates local processes that use that profile destination. It is not a distributed lock. Stop every Hermes session or gateway on every host that writes to the same destination before you run them. If doctor already reports ok: true, the collection is ready. Initialization is unnecessary. Remote doctor, stats and verify can inspect it while the writer runs. retry requeues failed events for the next provider startup and retries prepared operations. Stop the agent before you run maintenance on an embedded store. Qdrant's local persistence permits only one client process.

Memory inventory, export and scoped deletion

hermes qdrant-memory list                        # read-only inventory
hermes qdrant-memory export --output backup.json # portable JSON for re-import
hermes qdrant-memory delete-all --user alice --confirm

list reports stored memories with scope, provenance and timestamps. It also reports the destination's pending/failed operation counts. Use --user and --agent to filter. Omitting both covers the whole collection. --limit bounds the output, and the command refuses --agent without --user. export writes every stored memory, optionally one scope, as portable JSON in the shape the Mem0 importer accepts. hermes qdrant-memory migrate mem0 --source-json backup.json then restores it into a fresh destination (imports re-embed, and version 0.1 has no vector reuse). Round trips preserve text, scope, categories and timestamps. Mem0-migrated memories re-import to the same points, and native memories keep their original point UUID in the exported record for provenance. The plugin writes exports owner-only and refuses to overwrite without --force. An export covers stored memories only. Pending events, retry history and crash-recovery state stay in the local ledger. Back up the profile home for a full recovery point.

delete-all durably deletes stored memories and pending work for one scope (--user required). It records a reset-style intent first. Then it fences every enumerated point and every prepared write for that scope, including writes whose points were never stored. It invalidates admitted-but-unprocessed turn events for the scope, deletes the scope in one filtered operation, and clears the intent only after the scope becomes empty. A scope is exactly one (user, agent) pair. Omitting --agent selects the no-agent scope, and the default profile scope uses an agent (hermes). Pass --agent hermes to target it, or --all-agents to delete every agent scope of the user. Without --all-agents, the result reports other_agent_scopes when other agent scopes still hold memories. A literal * is an ordinary agent id, not a wildcard. --dry-run previews the per-scope counts. --confirm authorizes deletion. An interrupted deletion fails closed: other commands and provider startup return scope_delete_recovery_required until delete-all --confirm resumes it. Deletion intents are versioned and explicit. A pre-versioned intent cannot show whether * is a single agent or all agents, so the plugin refuses it (scope_delete_legacy_intent). Resolve it with --resolve-legacy single_agent, or with --resolve-legacy all_agents when the record's agent is * or absent. Turns admitted after the deletion can still add new memories. Everything admitted before it, including stored memories, prepared writes and unprocessed turn events, is removed or invalidated. list, export and delete-all do not require the embedding service.

Data flow and privacy

This provider sends data only toward services you configure. What each component carries and where it can go:

Component Carries Destination
Chat / agent turns Your conversation The model configured for the Hermes session
Memory extraction (llm.mode: inherit) The turn's user and assistant text The same session model. With a cloud model, turn text reaches that cloud
Relation checks The candidate memory and the similar stored memory Same routing as extraction. It runs only when similarity selects a review candidate
Embeddings (embedding) Memory and search text Ollama by default, or your OpenAI-compatible endpoint
Storage (qdrant) Memory payloads and provenance. The ledger stays local Embedded local path, self-hosted server, or Qdrant Cloud

Three common deployments:

Deployment Chat model Extraction LLM Embeddings Storage
Fully offline local (for example Ollama) inherits the local model local Ollama embedded local
Hybrid cloud inherits the cloud model by default local Ollama embedded local
Full cloud cloud cloud OpenAI-compatible endpoint Qdrant Cloud

A fully offline setup needs enough local compute for the chat model and the embeddings together. On a 24 GB host, a 27B local chat model plus local embeddings exceeded comfortable VRAM during validation. Local-model turns can take minutes each. Budget accordingly or use a smaller local model.

In the hybrid layout, extraction and relation checks inherit the session model. Route them elsewhere with llm.mode: task (the plugin's auxiliary task on a local model) or llm.mode: override (an explicit provider and model). Extraction instructions exclude obvious credentials and transient statuses, but any configured LLM or Qdrant destination can see the memories it processes. Treat them accordingly. Logical scrubbing of the local ledger is not secure erasure. See operations and security.

Extraction and relation checks run as Hermes auxiliary calls. Their per-task timeout defaults to 30 seconds, and a slow local model can exceed it easily. Raise auxiliary.qdrant_memory_extraction.timeout (seconds) for fully local deployments. A timed-out extraction becomes failed work, and hermes qdrant-memory retry requeues it.

Configuration and migration

Behavior lives in $HERMES_HOME/qdrant-memory.json. Credentials belong in the active profile's Hermes secret scope. Defaults use embedded Qdrant. During setup, the wizard reuses existing QDRANT_URL and QDRANT_API_KEY from the active profile's environment without another prompt. Setup reports their presence without showing values, asks only for missing settings and saves environment references rather than copying supplied values or keys. An environment URL replaces any older explicit URL in the saved plugin settings. For server or Cloud, set qdrant.mode, collection and endpoint. Cloud requires HTTPS and a Database API key. Configuration examples and defaults cover Ollama, OpenAI-compatible embeddings, LLM routing and explicit fallbacks.

Use a separate target collection and keep the Mem0 source unchanged:

hermes qdrant-memory migrate mem0 --source-json /path/to/export.json --dry-run
# Stop CLI/foreground writers; for an installed background gateway:
hermes gateway status
hermes gateway stop
hermes qdrant-memory migrate mem0 --source-json /path/to/export.json \
  --target-collection hermes_qdrant_memory --resume --verify
hermes qdrant-memory verify --collection hermes_qdrant_memory

Re-embedding is the default. --resume needs the same snapshot and pipeline. Add --retry-failed to retry failed operations from that manifest. Migration verification checks exact IDs, scope and payload hashes, not just record count. Canceled migration records become terminal SUPERSEDED work. They never count as successful writes. Resume preserves later deletion intent. --verify reports the conflict as migration_superseded with a nonzero exit code. While failed records remain, --verify reports migration_incomplete instead. Correct and resume the failures before any conflict review or deliberate fresh import. Only a fresh import or changed snapshot authorizes replanning. Recovery reads operations and events in finite bounded pages. Retained ledger history still needs disk-capacity monitoring. Before a real import, stop all sessions/gateways writing to the target, including for Server/Cloud. writer_busy requires stopping the active writer, not deleting lock or ledger files. A successful dry-run does not check writer ownership. Read the migration guide for executable gateway stop/start, migration, verification and interrupted-import recovery commands.

Operations and security

The private SQLite ledger can contain raw turn events and prepared payloads. It logically scrubs committed event bodies and committed/superseded operation bodies, except operations still needed by an incomplete migration manifest. Identity/status rows and manifests remain. Pending/failed work retains its body for recovery. There is no time-based expiry for ledger rows or manifests. Deleting a Qdrant memory does not purge pending or failed ledger work. Treat state.db, SQLite WAL/SHM sidecars, copied snapshots and backups as sensitive. Stop the agent before you back up the ledger with the embedded store. init --existing clear clears the selected collection's ledger rows, but logical scrubbing/reset is not secure erasure from disk pages or previously copied backups. Do not delete state.db to recover failed work. Changing embedding identity requires a new collection.

The durability guarantee starts only after Hermes calls the provider's sync_turn callback and the plugin commits the event to SQLite. Hermes currently submits that callback to an in-memory background queue. An abrupt host exit or its bounded shutdown can abandon work that has not reached plugin admission. After ledger admission, the plugin replays pending events and prepared operations after restart. This plugin ledger does not make the earlier host queue durable.

Tool arguments cannot override user/agent scope. Automatic writes exclude bot and non-primary-agent turns. Treat recalled content as untrusted data. See security, operating procedures, troubleshooting and architecture.

Compatibility and scope

Version 0.1 implements dense retrieval. Hybrid sparse vectors, RRF/DBSF, reranking and recency weighting remain future capabilities. The plugin rejects unsupported config. Named dense vectors preserve a path to future sparse vectors.

The plugin feature-detects embedding inherit and requires an explicit inherit_fallback. The future host facade must provide dimensions, fingerprint, embed_documents() and embed_query(). Current Hermes has no documented global embedding facade.

Compatibility requires Hermes MemoryProvider, checkpoint v2, trusted turn authors, authoritative builtin previous_content, scoped secrets and context threads. Earlier tags have incomplete contracts. The minimum supported release is v0.21.5 (v2026.9.24). See validation for tested environments and remaining live-service checks. Read configuration, migration, security and operations before deployment.

Development

Run Ruff lint and format checks before you commit. Install the repository pre-commit hook as described in development setup. The hook checks the staged snapshot. CI runs lint, both Python versions, Snyk and SonarCloud. See CI services for the tested host versions and lanes.

Build isolated dependency environments with Hermes PM. Then run the host's canonical test runner against this repository's tests. The tests import the real host and use a temporary HERMES_HOME.

cd /path/to/hermes-agent
python -m pm.build_env --source /path/to/hermes-agent --group test \
  --export-requirements /tmp/hermes-qdrant-test-requirements.txt
python -c 'import sys, tomllib; from pathlib import Path; p = tomllib.loads(Path(sys.argv[1]).read_text()); print("\n".join(p["project"]["dependencies"] + p["dependency-groups"]["test"]))' \
  /path/to/hermes-plugin-qdrant-memory/pyproject.toml >> /tmp/hermes-qdrant-test-requirements.txt
python -m pm.build_env --out /path/to/hermes-plugin-qdrant-memory/.test-env \
  --requirements /tmp/hermes-qdrant-test-requirements.txt
HERMES_PYTHON=/path/to/hermes-plugin-qdrant-memory/.test-env/bin/python \
  scripts/run_tests.sh /path/to/hermes-plugin-qdrant-memory/tests -j 1 --file-retries 0

The build reads the plugin's test development dependency group from pyproject.toml. The tested host PM exports runtime requirements only. Append the plugin runtime dependencies and test group before you build the combined environment.

Run the real embedding pilot from the plugin checkout with the host import path:

PYTHONPATH=/path/to/hermes-agent .test-env/bin/python scripts/evaluate.py

It uses a temporary embedded collection and UTF-8 JSON dataset. A custom dataset contains memories objects with id/text, and queries with query/relevant_ids. The default fixture now contains 24 labeled queries, including Chinese, English, mixed-language and hard-negative cases. The original 12-query recording is a historical synthetic regression baseline. Rerun the current fixture for current measurements. These fixtures do not establish production recall quality. See the recovery benchmark for a separate synthetic replay and retained-storage measurement.

CI runs tests, SonarCloud quality gates and Snyk dependency/code scans. See CI service setup and validation evidence.

License

MIT. Copyright © 2026 Kang Liu. See LICENSE.

Metadata

Release files for hermes-plugin-qdrant-memory 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hermes-plugin-qdrant-memory 0.2.1
File Size Uploaded
hermes_plugin_qdrant_memory-0.2.1.tar.gz 126.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermes-plugin-qdrant-memory 0.2.1
File Interpreter ABI Platform
hermes_plugin_qdrant_memory-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 202.4 kB

Release files / hermes_plugin_qdrant_memory-0.2.1.tar.gz

Download URL hermes_plugin_qdrant_memory-0.2.1.tar.gz
Size 126.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e027300c0d4b6b0ac2166a2e36c9d41c71c7b3213b29964b91474a261a9cc843
BLAKE2b-256 checksum
How to use checksums
8832733f63406c6934ab90d128cb3998810a7e67438da89c08dc5651b46ee312
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / hermes_plugin_qdrant_memory-0.2.1-py3-none-any.whl

Download URL hermes_plugin_qdrant_memory-0.2.1-py3-none-any.whl
Size 75.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2810af33d9de9d3829537a3a2434c4dc2b4ac272d4d4c9ef6f559b4a6d0f688c
BLAKE2b-256 checksum
How to use checksums
3108dcca16f496f954b0c7ab2038c0fb792062767920577b7728ae3204d08777
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page