Back to Nodes

n8n-nodes-logosdb

v1.0.3
Last updated Oct 10, 2026

n8n node for LogosDB semantic vector database — insert, search, delete, info

4 Weekly Downloads
77 Monthly Downloads

Description

image

![CI](https://github.com/jose-compu/logosdb/actions/workflows/ci.yml)
![Python](https://github.com/jose-compu/logosdb/actions/workflows/python.yml)
![PyPI](https://pypi.org/project/logosdb/)
![Python versions](https://pypi.org/project/logosdb/)

LogosDB is the SQLite for AI Agents.

LogosDB is a fast semantic vector database written in C/C++ that provides approximate nearest-neighbor search over embedding vectors with associated text metadata.

Authors: Jose (@jose-compu)

Contributing: See CONTRIBUTING.md for build instructions, style guide, and PR workflow.

Features

* Vectors and metadata are stored as flat binary files, memory-mapped for zero-copy reads.
* Approximate nearest-neighbor search via HNSW (hnswlib), O(log n) query time.
* Each vector row carries optional text and ISO 8601 timestamp metadata (JSONL sidecar).
* The basic operations are Put(embedding, text, timestamp) and Search(query, top_k).
* Timestamp range filtering: search within a time window (e.g., “last 24 hours”).
* Multiple distance metrics: inner product, cosine similarity (auto-normalized), or L2 Euclidean.
* Bulk vector access for direct tensor construction (e.g. loading into GPU memory).
* Thread-safe API on a single open handle: an internal mutex serializes operations that touch the index and metadata (including search).
* Crash recovery: HNSW index is automatically backfilled from the append-only vector store on open.
* Scales to millions of vectors.
* Framework integrations: LangChain and LlamaIndex VectorStore adapters.
* MCP server: first-class Claude Code integration via logosdb-mcp-server.

Documentation

The public interface is in include/logosdb/logosdb.h. Callers should not include or rely on the details of any other header files in this package. Those internal APIs may be changed without warning.

Planning a deployment? See docs/sizing.md for disk/RAM estimates based on N×dim, or run python -m logosdb.sizing --rows 1000000 --dim 768.

Guide to header files:

  • include/logosdb/logosdb.h: Main interface to the DB. Start here. Contains:
  • – C API with opaque handles and errptr convention (RocksDB/LevelDB style)
    – C++ convenience wrapper (logosdb::DB) with RAII and exceptions
    – logosdb::Options for HNSW tuning and distance metric selection
    – logosdb::SearchHit result struct
    – logosdbsearchts_range() for timestamp-filtered search

    Limitations

    * This is not a general-purpose vector database. It is purpose-built for embedding-based memory retrieval in LLM inference (funes.cpp).
    * Only a single process (possibly multi-threaded) can access a particular database at a time.
    * There is no client-server support built into the library. An application that needs such support will have to wrap their own server around the library.
    * For inner-product distance (LOGOSDBDISTIP, the default), vectors must be L2-normalized before insertion. Use LOGOSDBDISTCOSINE for automatic normalization.
    * Embedding generation is external — the caller provides pre-computed float vectors.

    Roadmap

    Work is tracked in open issues. 1.0.0 shipped on 2026-05-17; the public C API and supported language bindings follow Semantic Versioning on the 1.x line:

    | Bump | When |
    |——|——|
    | Patch (1.0.Z) | Bug fixes, security fixes, documentation, CI/build-only changes, and internal tooling that does not alter the supported contract of the public C API in include/logosdb/logosdb.h or the stable surface of language bindings. |
    | Minor (1.Y.z) | Backward-compatible additions: new functions or options, new storage or index behaviors behind explicit settings, new integrations, new platforms, and additive file-format upgrades with automatic or guided migration. |
    | Major (2.0.0) | Breaking changes to the public C API, on-disk format without a migration path, or binding contracts that cannot remain compatible. |

    Target versions and issue assignment match GitHub milestones (each open roadmap issue has exactly one milestone).

    Milestones → issues

    Past releases are summarized in the CHANGELOG and the closed milestones.

    SHIPPED 0.9.0 — minor — throughput and scale

    * #87 — Streaming NDJSON import/export (logosdbexportndjson / logosdbimportndjson in C / C++ / Python) with chunk_size, byte-offset --checkpoint, and --resume. Parquet output is a follow-up.
    * #80 — Batch ingest v2: logosdbputbatch is now chunked and WAL-aware (LOGOSDBBATCHCHUNKSIZE, default 1024). Durability matches per-row logosdbput; speed-up vs single put is workload-dependent (≈1.4× at dim=64 on the bench; HNSW per-row cost dominates at larger dims).

    SHIPPED 0.10.0 — minor — search and metadata

    * #85 — Hybrid retrieval mode: ANN score + lexical score fusion
    * #84 — Filter API v2: structured metadata predicates beyond timestamp range

    SHIPPED 0.11.0 — minor — multi-tenancy and tooling

    * #86 — Multi-tenant namespaces: quota and isolation within one DB root
    * #89 — Recall benchmarking utility for HNSW tuning

    SHIPPED 0.12.0 — minor — integrations

    * #78 — Feature: Codex plugin marketplace integration for LogosDB

    SHIPPED 1.0.0 — first stable release

    * Smart chunking, UTF-8/NFC policy, path-hardening, and expanded security tests (#98, #108–#112). See CHANGELOG 1.0.0.

    SHIPPED 1.0.1 — patch — release hygiene

    * #116 — Sync CHANGELOG, version macros, package metadata, and post-1.0 docs.

    Open — platform / hardening (post-1.0)

    * #10 — Windows support: abstract POSIX file I/O behind a portable layer
    * #111 — Finish Python integration-adapter security audit (partially addressed in 1.0.0 for vibe.py)

    Stability (since 1.0.0)

    As of 1.0.0, the project commits to stable semver for the public C API and supported language bindings:

    * Breaking changes to include/logosdb/logosdb.h or on-disk layout require a future major version, with migration notes.
    * Tier-1 platforms for 1.x are Linux and macOS; Windows remains tracked in #10.
    * Backup/restore and doctor tooling shipped in earlier 0.x releases; further hardening continues on the 1.x line.

    Getting the Source

    git clone --recurse-submodules 
    cd logosdb
    

    Building

    This project supports CMake out of the box.

    Quick start:

    mkdir -p build && cd build
    cmake -DCMAKEBUILDTYPE=Release .. && cmake --build .
    

    This builds:

    | Target | Description |
    |——–|————-|
    | logosdb | Static library (liblogosdb.a) |
    | logosdb-cli | Command-line tool for put, search, info |
    | logosdb-bench | Benchmark: HNSW vs brute-force, with ChromaDB comparison |
    | logosdb-test | Unit tests |

    Usage (C API)

    #include 

    char *err = NULL; logosdboptionst *opts = logosdboptionscreate(); logosdboptionsset_dim(opts, 2048);

    logosdbt *db = logosdbopen("/tmp/mydb", opts, &err); logosdboptionsdestroy(opts);

    float vec[2048] = { / ... unnormalized vector ... / };

    // L2-normalize for inner-product distance (returns 0 on success, -1 if zero norm) if (logosdbl2normalize(vec, 2048) == 0) { logosdb_put(db, vec, 2048, "My commute is 42 minutes", "2025-06-25T10:00:00Z", &err); }

    logosdbsearchresultt *res = logosdbsearch(db, query_vec, 2048, 5, &err); for (int i = 0; i < logosdbresultcount(res); i++) { printf("#%d score=%.4f text=%sn", i, logosdbresultscore(res, i), logosdbresulttext(res, i)); } logosdbresultfree(res); logosdb_close(db);

    Search with timestamp range filter

    #include 

    char *err = NULL; logosdboptionst *opts = logosdboptionscreate(); logosdboptionsset_dim(opts, 2048);

    logosdbt *db = logosdbopen("/tmp/mydb", opts, &err);

    // Search for top-5 matches within the last 24 hours logosdbsearchresultt *res = logosdbsearchtsrange( db, query_vec, 2048, 5, "2025-04-21T10:00:00Z", // from (inclusive), NULL for no lower bound "2025-04-22T10:00:00Z", // to (inclusive), NULL for no upper bound 50, // candidatek: internal fetch multiplier (10x topk recommended) &err);

    for (int i = 0; i < logosdbresultcount(res); i++) { printf("#%d score=%.4f ts=%s text=%sn", i, logosdbresultscore(res, i), logosdbresulttimestamp(res, i), logosdbresulttext(res, i)); } logosdbresultfree(res); logosdb_close(db);

    Using different distance metrics

    #include 

    char *err = NULL; logosdboptionst *opts = logosdboptionscreate(); logosdboptionsset_dim(opts, 2048);

    // Use cosine similarity (automatically normalizes vectors) logosdboptionssetdistance(opts, LOGOSDBDIST_COSINE);

    // Or use L2 Euclidean distance // logosdboptionssetdistance(opts, LOGOSDBDIST_L2);

    // Default is LOGOSDBDISTIP (inner product on L2-normalized vectors)

    logosdbt *db = logosdbopen("/tmp/mydb", opts, &err); logosdboptionsdestroy(opts);

    // For cosine: vectors are automatically normalized on put/search float vec[2048] = { / ... unnormalized vector ... / }; logosdb_put(db, vec, 2048, "entry", "2025-04-22T10:00:00Z", &err);

    logosdb_close(db);

    Usage (C++ wrapper)

    #include 
    #include 

    // Basic usage with default inner-product distance logosdb::DB db("/tmp/mydb", {.dim = 2048});

    // L2-normalize your vectors before insertion (required for inner-product distance) std::vector embedding = loadsomevector(); // unnormalized if (logosdb::l2_normalize(embedding)) { db.put(embedding, "My commute is 42 minutes", "2025-06-25T10:00:00Z"); }

    // Or use l2_normalized() to get a normalized copy auto normalized = logosdb::l2_normalized(query); auto results = db.search(normalized, 5); for (auto &r : results) { printf("id=%llu score=%.4f text=%sn", r.id, r.score, r.text.c_str()); }

    C++: Search with timestamp filter

    #include 

    logosdb::DB db("/tmp/mydb", {.dim = 2048});

    // Search within a time window auto results = db.searchtsrange( query, 5, "2025-04-21T00:00:00Z", // from timestamp "2025-04-22T00:00:00Z", // to timestamp 50); // candidatek (optional, defaults to 10x topk)

    for (auto &r : results) { printf("id=%llu score=%.4f ts=%sn", r.id, r.score, r.timestamp.c_str()); }

    C++: Using cosine or L2 distance

    #include 

    // Cosine similarity - vectors are automatically normalized logosdb::DB db("/tmp/mydb", {.dim = 2048, .distance = LOGOSDBDISTCOSINE});

    // Put unnormalized vectors - they will be normalized automatically db.put(unnormalized_embedding, "entry", "2025-04-22T10:00:00Z");

    auto results = db.search(query, 5); // scores are cosine similarities in [0, 1]

    // L2 Euclidean distance // logosdb::DB db("/tmp/mydb", {.dim = 2048, .distance = LOGOSDBDISTL2});

    Python

    LogosDB ships Python bindings built with pybind11 and scikit-build-core.

    Install from PyPI (binary wheels provided for Linux x8664/aarch64 and macOS x8664/arm64 on CPython 3.9–3.13):

    pip install logosdb
    

    Or build from source in a clone:

    pip install .
    

    Usage:

    import logosdb
    from sentence_transformers import SentenceTransformer

    Local Hugging Face embeddings model (runs on your machine)

    model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") dim = model.getsentenceembedding_dimension()

    Use cosine distance so LogosDB auto-normalizes vectors

    db = logosdb.DB("/tmp/agentmemory", dim=dim, distance=logosdb.DISTCOSINE)

    Three learnings captured by an AI agent

    learnings = [ ("Retrying API calls with exponential backoff reduced transient failures by 42%.", "2026-05-06T09:00:00Z"), ("Splitting long tasks into smaller batches improved throughput and lowered memory spikes.", "2026-05-06T09:05:00Z"), ("Adding idempotency keys prevented duplicate writes during network retries.", "2026-05-06T09:10:00Z"), ]

    for text, ts in learnings: emb = model.encode(text).astype("float32") db.put(emb, text=text, timestamp=ts)

    Ask a natural-language question

    question = "How can we avoid duplicate writes when retries happen?" q_emb = model.encode(question).astype("float32")

    hits = db.search(qemb, topk=3) for h in hits: print(f"{h.score:.4f} {h.text}")

    Python: Using cosine distance (no manual normalization needed)

    import numpy as np
    import logosdb

    With cosine distance, vectors are automatically normalized

    db = logosdb.DB("/tmp/mydb", dim=128, distance=logosdb.DIST_COSINE)

    No need to normalize - just put raw vectors

    v = np.random.randn(128).astype(np.float32) rid = db.put(v, text="unnormalized vector", timestamp="2025-04-22T10:00:00Z")

    Search also works with unnormalized queries

    query = np.random.randn(128).astype(np.float32) hits = db.search(query, top_k=5)

    Python: Batch ingest and streaming NDJSON (0.9.0)

    import numpy as np
    import logosdb

    db = logosdb.DB("/tmp/mydb", dim=128, distance=logosdb.DIST_COSINE)

    Chunked, WAL-aware batch insert (LOGOSDBBATCHCHUNK_SIZE controls fsync cadence).

    embeddings = np.random.randn(10_000, 128).astype(np.float32) ids = db.putbatch(embeddings, texts=[f"row {i}" for i in range(10000)])

    Bounded-memory NDJSON export/import; --resume from a checkpoint on interruption.

    db.export_ndjson("/tmp/rows.ndjson") restored = logosdb.DB("/tmp/restored", dim=128, distance=logosdb.DIST_COSINE) restored.importndjson("/tmp/rows.ndjson", chunksize=1024, checkpoint_path="/tmp/rows.cp", resume=False)

    Run the Python tests and examples:

    pip install ".[test]"
    pytest tests/python/

    python examples/python/basic_usage.py

    sentence-transformers demo (optional heavy dep)

    pip install ".[examples]" python examples/python/sentencetransformersdemo.py

    Memory-Efficient On-Prem RAG

    LogosDB is designed for memory-efficient retrieval-augmented generation (RAG) that runs entirely on your hardware.

    RAM Model

    LogosDB uses mmap() for zero-copy access. Your RAM usage scales with query patterns, not dataset size:

    | Dataset | Dim | Disk | Typical Query RAM |
    |———|—–|——|——————-|
    | 100K | 384 | 153 MB | <20 MB | | 1M | 384 | 1.5 GB | <100 MB | | 10M | 384 | 15 GB | <200 MB |

    The OS caches hot index pages; cold data stays on disk. No explicit loading/unloading needed.

    Quick RAG Example

    import numpy as np
    import logosdb
    from sentence_transformers import SentenceTransformer

    1. Load model (runs locally)

    model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2") dim = model.getsentenceembedding_dimension()

    2. Create DB with cosine distance (auto-normalizes)

    db = logosdb.DB("/data/knowledge", dim=dim, distance=logosdb.DIST_COSINE)

    3. Index documents

    for text in documents: emb = model.encode(text) db.put(emb, text=text) # Auto-normalized with cosine distance

    4. Query (only touched pages load into RAM)

    query_emb = model.encode("What is HNSW?") for hit in db.search(queryemb, topk=3): print(f"{hit.score:.4f} {hit.text}")

    See docs/rag-on-prem.md for complete guide including:

  • Time-sharding for infinite retention
  • External quantization patterns
  • Architecture patterns for production
  • See docs/sizing.md for detailed disk/RAM formulas and the python -m logosdb.sizing calculator.

    Run the memory-efficient RAG example:

    pip install ".[examples]"
    python examples/python/memoryefficientrag.py
    

    Python: LlamaIndex VectorStore

    pip install 'logosdb[llama-index]'
    
    from logosdb import LogosDBIndex
    from llama_index.core import Document
    from llama_index.core.schema import TextNode
    from llamaindex.core.vectorstores import VectorStoreQuery
    import numpy as np

    Create the vector store

    db = LogosDBIndex(uri="/tmp/mydb", dim=128)

    Add nodes with pre-computed embeddings

    node = TextNode( text="My commute is 42 minutes", embedding=np.random.randn(128).astype(np.float32).tolist(), metadata={"timestamp": "2025-04-28T10:00:00Z"} ) db.add([node])

    Query

    query_emb = np.random.randn(128).astype(np.float32).tolist() query = VectorStoreQuery(queryembedding=queryemb, similaritytopk=5) results = db.query(query)

    for node, score in zip(results.nodes, results.similarities): print(f"Score: {score:.4f}, Text: {node.text}")

    Timestamp range filtering

    results = db.query(query, tsfrom="2025-04-01T00:00:00Z", tsto="2025-04-30T23:59:59Z")

    The LogosDBIndex class implements LlamaIndex’s VectorStore interface, supporting:

  • add(nodes) – Add nodes with embeddings
  • delete(node_id) – Delete by node ID
  • query(VectorStoreQuery) – Similarity search by vector
  • count() / len(store) – Number of live documents
  • Timestamp filtering via tsfrom and tsto kwargs
  • CLI

    Database info

    logosdb-cli info /tmp/mydb

    Search with a binary query vector file

    logosdb-cli search /tmp/mydb --query-file q.bin --top-k 5

    Streaming NDJSON export / import (#87) — bounded memory, optional resume

    logosdb-cli export /tmp/mydb --output rows.ndjson [--start-id N --end-id M] logosdb-cli import /tmp/mydb --dim 768 --input rows.ndjson --chunk-size 1024 --checkpoint rows.cp [--resume]

    Node.js

    MCP Server — Claude Code integration

    logosdb-mcp-server is a Model Context Protocol server that
    exposes LogosDB to Claude Code (and any other MCP client) over stdio. It lets Claude index
    files, persist knowledge across sessions, and do semantic search without leaving the conversation.

    Claude Code: complete recipe

    Follow these steps in order. Claude Code spawns the MCP server with working directory = your project root (the folder you opened); paths in mcp.json and LOGOSDB_PATH are resolved relative to that cwd unless you use absolute paths.

    #### 1. Prerequisites

  • Node.js 18 or newer on your PATH (node -v, npm -v). For the published package you also need npx.
  • Claude Code installed and signed in (overview).
  • Decide where the DB lives: LOGOSDB_PATH (default ./.logosdb) is created under the project root; add the directory to .gitignore if you do not want it committed.
  • #### 2. Install the server (pick one)

    Option A — This repository (local node, no npx). From the repository root:

    npm install
    

    That installs the mcp workspace and runs prepare, which compiles TypeScript to mcp/dist/index.js. After you change MCP sources, run npm run mcp:build at the root or npm run build inside mcp/.

    Option B — Any other project (published logosdb-mcp-server). In your app’s root:

    npm install logosdb-mcp-server
    

    You can still invoke it without a project dependency via npx -y logosdb-mcp-server (see Option C).

    #### 3. Register the MCP server in Claude Code

    Project-local config lives in .claude/mcp.json at the repository root. User-wide config is ~/.claude.json (same mcpServers shape). Only one definition named logosdb is needed.

    If you use Option A (this clone): the repo already contains .claude/mcp.json:

    {
      "mcpServers": {
        "logosdb": {
          "command": "node",
          "args": ["./mcp/dist/index.js"],
          "env": {
            "LOGOSDB_PATH": "./.logosdb"
          }
        }
      }
    }
    

    Open this folder as the Claude Code project so ./mcp/dist/index.js resolves. If the client’s cwd is not the repo root, set "args" to an absolute path to mcp/dist/index.js (see Installing locally — Option C).

    If you use Option B or prefer always-latest from npm (Option C): create or merge .claude/mcp.json:

    {
      "mcpServers": {
        "logosdb": {
          "command": "npx",
          "args": ["-y", "logosdb-mcp-server"],
          "env": {
            "LOGOSDB_PATH": "./.logosdb"
          }
        }
      }
    }
    

    Default embeddings are local Transformers.js (no API keys); first run may download model weights. Optional Ollama / OpenAI / Voyage env vars are documented in mcp/README.md.

    #### 4. Path rules for logosdbindexfile

    The server only indexes files that resolve under process.cwd() or LOGOSDBINDEXROOT (if set). Symlinks that escape those roots are rejected. Keep indexing paths inside the project you opened, or set LOGOSDBINDEXROOT to an absolute allowed root (details in Environment variables and mcp/README.md.

    #### 7. Optional: agent instructions

    Copy the CLAUDE.md template block from Agent instructions (CLAUDE.md and similar) into your project so the agent indexes and searches without being reminded every session.

    #### 8. Troubleshooting

    | Symptom | What to try |
    |——–|—————-|
    | MCP fails to start / “Cannot find module” | From the same cwd Claude uses, run node ./mcp/dist/index.js (Option A) or npx -y logosdb-mcp-server (Option C) in a terminal; fix missing npm install or broken path. |
    | Relative ./mcp/dist/index.js not found | Use an absolute args path to index.js, or open the correct folder as the project root. |
    | logosdbindexfile rejects a path | Path is outside cwd / LOGOSDBINDEXROOT; use a path inside the project or set LOGOSDBINDEXROOT. |
    | Search looks wrong after changing model | New embeddings must use a fresh LOGOSDB_PATH or new namespace; dimensions must match. |

    Google Antigravity: same stdio MCP pattern (node + local script, or npx + package). Step-by-step: mcp/README.md — Google Antigravity.

    Claude Code slash commands

    This repo ships project slash commands under .claude/commands/ (in addition to .claude/mcp.json for the MCP server):

    | Command | Role |
    |———|——|
    | /index | Index a file or directory via logosdbindexfile with incremental: true (new/changed files only; commands/index.md) |
    | /search | Semantic search; optional ISO tsfrom / tsto on the MCP tool (commands/search.md) |
    | /forget | Delete by row id or by natural-language query (commands/forget.md) |

    Agent instructions (CLAUDE.md and similar)

    The MCP server does not index the repository by itself: the agent must call the tools (or you rely on slash commands / hooks). To make LogosDB feel automatic without typing /index every time, add a block like the following to your project’s CLAUDE.md (or any instructions file your agent reads on every session). Adjust namespaces and paths to your repo.

    LogosDB (semantic memory via MCP)

    The logosdb MCP server is configured. Data lives on disk under LOGOSDB_PATH (see .claude/mcp.json); it persists across sessions.

    Namespaces: Use separate namespaces for different concerns (e.g. code for src/, docs for docs/, decisions for short architectural notes). Search only the namespace that matches the user’s task.

    When starting substantive work on this codebase: 1. If the user has not indexed recently and you need broad code context, call logosdbindexfile with incremental: true on the smallest useful path (e.g. src/ or a package directory), not the whole monorepo unless asked. 2. Before answering “where is X implemented?” or similar, call logosdbsearch with a tight natural-language query, namespace set appropriately, and topk between 3 and 8. Do not paste entire trees into the chat—retrieve, then read only the cited files. 3. For “what did we decide recently?” style questions, use logosdbsearch with optional tsfrom / ts_to (ISO 8601 inclusive bounds) on the decisions or docs namespace when timestamps matter. 4. When the user states a durable fact worth remembering (API contract, policy, workaround), call logosdb_index into the right namespace with concise text (timestamps are stored automatically; optional metadata can label the source).

    After large refactors or dependency upgrades: Re-run logosdbindexfile with incremental: true on affected paths so search stays aligned without duplicating chunks for unchanged files.

    Deletion: Use logosdbdelete with id from a prior search hit, or with query + optional matchrank / searchtopk to remove a semantically matched row when the user asks to forget something.

    Environment variables

    | Variable | Default | Description |
    |—|—|—|
    | LOGOSDB_PATH | ./.logosdb | Root directory for all namespace databases |
    | EMBEDDING_PROVIDER | (local) | Omit for Transformers.js on-device; or ollama, openai, voyage |
    | TRANSFORMERS_MODEL | Xenova/all-MiniLM-L6-v2 | Local embedding model (bundled MCP path) |
    | OLLAMA_* | — | See mcp/README.md when using Ollama |
    | OPENAIAPIKEY | — | Required when EMBEDDING_PROVIDER=openai |
    | VOYAGEAPIKEY | — | Required when EMBEDDING_PROVIDER=voyage |
    | LOGOSDBCHUNKSIZE | 800 | Target characters per chunk for "legacy" and "section" chunking modes |
    | LOGOSDBCHUNKMODE | auto | Chunking strategy: auto (per-extension), line (code), section (markdown/rst), legacy (original paragraph/char). See mcp/README.md — Chunking strategies. |

    Voyage AI (voyage-3, dim=1024) is Anthropic’s recommended cloud embedding model:

    "env": {
      "LOGOSDB_PATH": "./.logosdb",
      "EMBEDDING_PROVIDER": "voyage",
      "VOYAGEAPIKEY": ""
    }
    

    Available tools

    | Tool | Description |
    |—|—|
    | logosdb_index | Embed and store a text snippet in a namespace |
    | logosdbindexfile | Chunk, embed, and store a file or tree; optional incremental: true (skip unchanged, replace changed, prune deleted under a directory). When the path lives inside a Git working tree the walker honours .gitignore (root + nested + .git/info/exclude + global excludes) by default; disable with respectgitignore: false or LOGOSDBRESPECT_GITIGNORE=0. |
    | logosdbsearch | Semantic search; optional tsfrom / ts_to (ISO 8601) for timestamp-window filter |
    | logosdb_list | List all namespaces |
    | logosdb_info | Stats for a namespace (count, dimension, path) |
    | logosdbdelete | Delete by row id, or by natural-language query (searchtopk, matchrank) |

    Installing locally (without npx)

    Option A — global CLI on your machine

    npm install -g logosdb-mcp-server
    

    In .claude/mcp.json, point the server at the global binary:

    "logosdb": {
      "command": "logosdb-mcp-server",
      "args": [],
      "env": { "LOGOSDB_PATH": "./.logosdb" }
    }
    

    Ensure the directory containing the global npm binaries is on your PATH when Claude Code spawns the process (same shell you use for npm install -g).

    Option B — project-local node_modules (no global install)

    From your app repo:

    npm install logosdb-mcp-server
    

    Then use npx so the binary resolves from ./node_modules:

    "logosdb": {
      "command": "npx",
      "args": ["-y", "logosdb-mcp-server"],
      "env": { "LOGOSDB_PATH": "./.logosdb" }
    }
    

    Omit -y if you prefer a fixed local install only. You can also call the entry script explicitly:

    "command": "node",
    "args": ["./node_modules/logosdb-mcp-server/dist/index.js"],
    "env": { "LOGOSDB_PATH": "./.logosdb" }
    

    Option C — development build from a LogosDB clone

    cd mcp && npm install && npm run build
    

    This repository’s checked-in .claude/mcp.json uses a relative path ./mcp/dist/index.js after npm install from the repo root (workspace prepare). For other clients or if the process cwd is not the repo root, use an absolute path to mcp/dist/index.js:

    "logosdb": {
      "command": "node",
      "args": ["/absolute/path/to/logosdb/mcp/dist/index.js"],
      "env": { "LOGOSDB_PATH": "./.logosdb" }
    }
    

    The same env block (LOGOSDB_PATH, embedding variables) applies to every option. Restart Claude Code or reload MCP config after editing .claude/mcp.json.

    Performance

    Here is a performance report from the included logosdb-bench program. The results are somewhat noisy, but should be enough to get a ballpark performance estimate.

    Setup

    We use databases with 1K, 10K, and 100K vectors. Each vector has 2048 dimensions (matching typical LLM embedding sizes). Vectors are L2-normalized random unit vectors.

    (Numbers below are illustrative ballparks; absolute values depend on hardware and build flags. Relative HNSW vs brute-force behavior is what to focus on.)

    LogosDB: version 1.0.1
    CPU: Apple M-series (ARM64)
    Dim: 2048
    HNSW M: 16, efconstruction: 200, efsearch: 50

    Write performance

    put (1K vectors): ~50 µs/op (~20,000 inserts/sec)
    put (10K vectors): ~80 µs/op (~12,500 inserts/sec)
    put (100K vectors): ~120 µs/op (~8,300 inserts/sec)

    Each “op” above corresponds to a write of a single vector + metadata + HNSW index update.

    Search performance

    HNSW top-5 (1K): ~0.1 ms/query
    HNSW top-5 (10K): ~0.3 ms/query
    HNSW top-5 (100K): ~1.2 ms/query

    Brute-force top-5 (1K): ~0.3 ms/query
    Brute-force top-5 (10K): ~2.5 ms/query
    Brute-force top-5 (100K): ~25 ms/query

    HNSW maintains sub-linear scaling while brute-force grows linearly with database size. At 100K vectors, HNSW is roughly 20x faster.

    VectorDB Bench

    VectorDB Bench is the standard open-source harness for comparing vector databases at realistic scale (load, optimize, serial/concurrent search, recall). LogosDB is integrated as a first-class backend:

    | Location | Role |
    |———-|——|
    | vectordb_bench/backend/clients/logosdb/ | Client: config.py, logosdb.py, cli.py |
    | vectordbbench/backend/clients/init.py | DB.LogosDB enum + initcls / configcls / caseconfig_cls mappings |
    | vectordb_bench/cli/vectordbbench.py | CLI subcommand logosdb |
    | pyproject.toml | Optional extra logosdb (installs the Python bindings used by the client) |

    Results — Performance1536D50K (2026-05-17)

    OpenAI embeddings, 50K vectors, 1536 dimensions, cosine distance. Serial search only (--skip-search-concurrent). Absolute timings depend on hardware; recall/NDCG are the primary cross-database comparators.

    | Metric | Value |
    |——–|——-|
    | Load duration | 340.4 s |
    | Insert duration | 339.6 s |
    | Optimize duration | 0.8 s |
    | Serial latency p99 | 4.6 ms |
    | Serial latency p95 | 4.0 ms |
    | Recall@100 | 0.9347 |
    | NDCG | 0.9464 |

    Raw JSON: vectordbbench/results/LogosDB/result20260517_*.json (under your VectorDB Bench checkout).

    Re-run

    From a VectorDB Bench tree with the LogosDB client installed (pip install -e '.[logosdb]' or equivalent):

    .venv/bin/python3.12 -m vectordb_bench.cli.vectordbbench logosdb 
      --uri /tmp/vectordbbench_logosdb 
      --case-type Performance1536D50K 
      --skip-search-concurrent
    

    Use a fresh --uri directory per run. Set OPENAIAPIKEY (or the embedding provider your case expects) before starting.

    Results — glove-25-angular (qdrant/vector-db-benchmark)

    Standard qdrant/vector-db-benchmark harness, 1.18M × 25 vectors, cosine distance (angular). Serial search.

    | Metric | Value |
    |——–|——-|
    | Upload time | 345 s |
    | Mean precision@10 | 0.939 |
    | RPS | 9,401 |
    | Mean latency | 0.092 ms |
    | p99 latency | 0.146 ms |

    Source: qdrant/vector-db-benchmark.

    Benchmark vs ChromaDB

    logosdb-bench --dim 2048 --counts 1000,10000,100000
    

    | Metric | ChromaDB | LogosDB |
    |——–|———-|———|
    | Language | Python + C (hnswlib) | Pure C/C++ |
    | Search algorithm | HNSW | HNSW (same hnswlib) |
    | Storage | SQLite + Parquet | Binary mmap + JSONL |
    | Startup overhead | Python runtime + deps | Zero (linked library) |
    | Embedding generation | Built-in (Sentence Transformers) | External (caller provides vectors) |
    | Target use case | General-purpose vector store | Embedded LLM inference memory |
    | Search latency (100K, dim=2048) | ~5-10 ms | ~1-3 ms |
    | Memory footprint (100K, dim=2048) | ~1.5 GB (Python + SQLite) | ~800 MB (mmap) |
    | Cold start | ~2-5 s (Python imports) | <10 ms | | Dependencies | Python, NumPy, SQLite, hnswlib | hnswlib (header-only, vendored) |

    LogosDB uses the same HNSW implementation as ChromaDB (hnswlib) but eliminates Python overhead, SQLite serialization, and Sentence Transformer coupling. The result is a leaner library optimized for the single use case of embedded semantic memory for LLM inference.

    Repository contents

    include/logosdb/logosdb.h Public C/C++ API (start here)
    src/logosdb.cpp Core engine: wires storage + index + metadata
    src/storage.h / storage.cpp Fixed-stride binary vector file with mmap
    src/metadata.h / metadata.cpp Append-only JSONL text + timestamp store
    src/hnsw_index.h / .cpp Thin wrapper around hnswlib
    tools/logosdb-cli.cpp Command-line interface
    tools/logosdb-bench.cpp Benchmark tool
    tests/test_doctest.cpp C++ unit tests (doctest, incl. CLI integration)
    tests/test_stress.cpp Stress/property tests (opt-in via –test-suite=stress)
    tests/python/test_smoke.py Python smoke tests (pytest)
    python/src/bindings.cpp pybind11 Python bindings
    python/logosdb/ Python package (logosdb._core + stubs)
    examples/python/ Python usage examples
    pyproject.toml Python build/config (scikit-build-core)
    third_party/hnswlib/ Vendored hnswlib (header-only)
    package.json / package-lock.json Private npm workspace (MCP + nodejs logosdb); npm install at repo root only
    mcp/ MCP server (logosdb-mcp-server npm package)
    .claude/mcp.json Claude Code MCP config (local node ./mcp/dist/index.js)
    .claude/commands/ Slash command prompts (/index, /search, /forget)
    CHANGELOG Release history
    LICENSE MIT license text

    Contributing

    We welcome contributions. See CONTRIBUTING.md for:

  • Building from source
  • Running tests and benchmarks
  • Code style and PR workflow

Please review our Security Policy.

License

MIT — see LICENSE for the full text.