npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cr7258/memory-elasticsearch

v0.0.3

Published

Elasticsearch-backed long-term memory plugin for OpenClaw with BM25 + vector hybrid retrieval.

Readme

memory-elasticsearch

Elasticsearch-backed memory plugin for OpenClaw.

It replaces the active OpenClaw memory slot with an Elasticsearch store that supports:

  • automatic memory recall before prompt construction
  • automatic memory capture after agent turns
  • manual memory search, add, list, update, delete, and triage tools
  • OpenAI-compatible LLM and embedding providers
  • app-level hybrid retrieval using vector search plus BM25
  • optional Jina reranking with jina-reranker-v3

All stored memories are persistent memories. The plugin does not split storage into session-scoped and long-term memories.

Prerequisites

  • OpenClaw with plugin support
  • Elasticsearch with dense_vector and kNN support
  • an OpenAI-compatible chat model
  • an OpenAI-compatible embedding model
  • optional Jina API key when reranking is enabled

The embedding model and Elasticsearch index dimensions must match. If you change the embedding model or embeddingDims, use a new index or recreate the old one.

For local development, a single-node Elasticsearch instance is enough:

docker run --name openclaw-memory-es \
  -p 9200:9200 \
  -e discovery.type=single-node \
  -e xpack.security.enabled=false \
  docker.elastic.co/elasticsearch/elasticsearch:8.15.5

Use your own secured Elasticsearch URL in production. The plugin supports no auth, API key auth, and basic auth.

Install

From npm:

openclaw plugins install npm:@cr7258/memory-elasticsearch

From GitHub:

openclaw plugins install git:github.com/cr7258/memory-elasticsearch@main

Uninstall

Remove the installed plugin package:

openclaw plugins uninstall memory-elasticsearch

Then restart the gateway:

openclaw gateway restart

Uninstalling the plugin does not delete Elasticsearch data. Delete the memory index only when you are sure you no longer need the stored memories:

curl -X DELETE 'http://localhost:9200/openclaw-memory'

Initialize

Run init after the plugin is installed. This command writes plugin config to ~/.openclaw/openclaw.json, stores provided API keys in ~/.openclaw/.env, and selects this plugin as the active memory backend.

Shared OpenAI-compatible endpoint:

export OPENAI_API_KEY=<your-api-key>
openclaw memory-es init \
  --base-url https://openrouter.ai/api/v1 \
  --api-key $OPENAI_API_KEY \
  --llm-model qwen/qwen3.6-plus \
  --embedding-model qwen/qwen3-embedding-8b \
  --embedding-dims 4096 \
  --elasticsearch-url http://localhost:9200 \
  --index openclaw-memory

Separate LLM and embedding endpoints:

openclaw memory-es init \
  --llm-base-url https://openrouter.ai/api/v1 \
  --llm-api-key <llm-api-key> \
  --llm-model qwen/qwen3.6-plus \
  --embedding-base-url https://api.openai.com/v1 \
  --embedding-api-key <embedding-api-key> \
  --embedding-model text-embedding-3-small \
  --embedding-dims 1536 \
  --elasticsearch-url http://localhost:9200 \
  --index openclaw-memory

Enable Jina reranking:

openclaw memory-es init \
  --reuse-values \
  --reranker \
  --reranker-api-key <jina-api-key> \
  --reranker-model jina-reranker-v3

Disable Jina reranking while keeping the rest of the current config:

openclaw memory-es init --reuse-values --reranker false

After initialization, restart the gateway so the plugin is loaded with the new config:

openclaw gateway restart

Configuration Written by Init

init stores API key references in OpenClaw config and writes the secret values to ~/.openclaw/.env.

Default environment variable names:

  • OPENAI_API_KEY: shared OpenAI-compatible key
  • OPENAI_LLM_API_KEY: LLM key when --llm-api-key is used
  • OPENAI_EMBEDDING_API_KEY: embedding key when --embedding-api-key is used
  • JINA_API_KEY: Jina reranker key when --reranker-api-key is used

Minimal generated config shape:

{
  "plugins": {
    "entries": {
      "memory-elasticsearch": {
        "enabled": true,
        "hooks": {
          "allowConversationAccess": true
        },
        "config": {
          "userId": "alice",
          "autoRecall": true,
          "autoCapture": true,
          "topK": 5,
          "searchThreshold": 0.05,
          "elasticsearch": {
            "url": "http://localhost:9200",
            "index": "openclaw-memory"
          },
          "openaiCompatible": {
            "llm": {
              "baseUrl": "https://api.openai.com/v1",
              "apiKey": "${OPENAI_API_KEY}",
              "model": "gpt-4o-mini"
            },
            "embedding": {
              "baseUrl": "https://api.openai.com/v1",
              "apiKey": "${OPENAI_API_KEY}",
              "model": "text-embedding-3-small",
              "dims": 1536
            }
          },
          "search": {
            "mode": "hybrid",
            "semanticWeight": 0.6,
            "keywordWeight": 0.4
          },
          "reranker": {
            "enabled": false,
            "provider": "jina",
            "baseUrl": "https://api.jina.ai",
            "model": "jina-reranker-v3"
          }
        }
      }
    },
    "slots": {
      "memory": "memory-elasticsearch"
    }
  }
}

Use Memory from the CLI

openclaw memory-es status
openclaw memory-es status --json

Search memories:

openclaw memory-es search "what languages does the user know"

List memories:

openclaw memory-es list
openclaw memory-es list --user-id alice --top-k 20

Add an explicit memory:

openclaw memory-es add "User prefers Elasticsearch for OpenClaw memory"

Preview durable memory candidates without storing them:

openclaw memory-es triage "Remember this: user prefers qwen/qwen3-embedding-8b for embeddings"

Delete by exact memory ID:

openclaw memory-es delete --memory-id <memory-id>

Delete by query. The plugin searches first and deletes only literal text matches:

openclaw memory-es delete --query "User prefers Elasticsearch"

Delete all memories for a user:

openclaw memory-es delete --all --confirm --user-id alice

Any command can return JSON when it supports --json:

openclaw memory-es search "preferences" --json
openclaw memory-es list --json
openclaw memory-es status --json