OnMind-RAG

OnMind-RAG

A lightweight knowledge base MCP server that enables full-text search and retrieval of markdown documents from indexed sites using Orama BM25.

Category
访问服务器

README

OnMind-RAG

A complementary and independent project from OnMind-PUB: a lightweight knowledge base (light RAG) that exposes an MCP server so an agent (MCP client) can query the content of one or more sites.

It is not part of the init → index → build → publish workflow. It only reads the _index.json already generated by a site and, on demand, the markdown.

Idea

  1. On startup, the server loads docs/public/_index.json from each configured site.
  2. Normalizes in memory (stable IDs, clean tags, visibility, path to .md).
  3. Body cache: reads each .md once, stores bodyText (no frontmatter) and logs time/size to stderr.
  4. Search engine: Orama BM25 full-text by default; hybrid/vector modes opt-in with embeddings.
  5. Exposes compact MCP tools: summary → search (meta + body) → document reading.

No _catalog.json is written. If the site re-indexes externally, use the reload_catalog tool.

Requirements

  • Node.js ≥ 18 (or Bun with Node compatibility)
  • At least one site with docs/public/_index.json (e.g. sites/know from OnMind-PUB)

Setup

cd rag
cp .env.example .env   # optional; you can also export vars
bun install            # or: npm install

Variables (see .env.example):

Variable Meaning
RAG_SITES Paths to site roots, comma-separated (required)
RAG_SITE_NAMES Optional labels (same order)
RAG_VISIBILITY public (default) | protected | all
RAG_MAX_BODY Max chars returned by read_document (default 50000; increase for very long docs)
RAG_CACHE_BODY 1 (default) caches body at startup → Orama indexes body → full-text on markdown. 0 = metadata only (title/desc/tags) → no body search; read_document falls back to disk.
RAG_SEARCH_MODE fulltext (default, BM25) | hybrid | vector (last two require RAG_EMBEDDINGS=1)
RAG_EMBEDDINGS 1 enables local hash embeddings for hybrid/vector; 0 (default)
RAG_EMBED_DIMS Vector dimensions (default 384)
RAG_SNAPSHOT 1 saves/loads Orama snapshot to disk; 0 (default)
RAG_SNAPSHOT_PATH Snapshot path (default ./data/orama-snapshot.json)

Example:

export RAG_SITES=../sites/know
# or multiple:
# export RAG_SITES=../sites/know,../sites/andrey

Smoke test (no MCP)

RAG_SITES=../sites/know bun run smoke

With embeddings + hybrid:

RAG_SITES=../sites/know RAG_EMBEDDINGS=1 RAG_SEARCH_MODE=hybrid bun run smoke

With snapshot (2nd load ~100 ms):

RAG_SITES=../sites/know RAG_SNAPSHOT=1 bun run smoke   # first: saved
RAG_SITES=../sites/know RAG_SNAPSHOT=1 bun run smoke   # second: loaded

Start MCP server (stdio)

RAG_SITES=../sites/know bun run mcp

MCP Client (Cursor / Claude Desktop / Grok / Jan)

{
  "mcpServers": {
    "onmind-rag": {
      "command": "bun",
      "args": ["/absolute/path/to/pub/rag/src/server.js"],
      "env": {
        "RAG_SITES": "/absolute/path/to/pub/sites/know",
        "RAG_VISIBILITY": "public",
        "RAG_SEARCH_MODE": "fulltext",
        "RAG_EMBEDDINGS": "0",
        "RAG_SNAPSHOT": "0"
      }
    }
  }
}

You can also use node instead of bun

{
  "command": "node",
  "args": ["/absolute/path/to/pub/rag/src/server.js"],
  "env": { "RAG_SITES": "/absolute/path/to/pub/sites/know" }
}

Tools

Tool Purpose
list_sites Loaded sites, body-cache stats, search-engine status (Orama, embeddings, snapshot)
catalog_summary Stats by category / language / tags (orientation)
search_content Full-text Orama (BM25) by default on title/description/tags/body. mode: fulltext|hybrid|vector optional. Returns cards with match.score and match.snippet.
get_entry One record by id (site:url)
read_document Markdown body (preferably from cache; truncatable)
list_series Series ordered by filename within a category
reload_catalog Re-reads _index.json + body cache + rebuilds index

Typical agent flow:

catalog_summary → search_content → get_entry / list_series → read_document

Relation to OnMind-PUB

OnMind-PUB onmind-rag
Generates _index.json and the static site Only consumes it
Publish workflow Outside that flow
Lives in monorepo for convenience Movable: just point RAG_SITES to any folder with docs/public/_index.json

Body cache (startup)

In stderr you'll see something like:

[onmind-rag] index: 289 entries from 1 site(s) in 3ms at ...
[onmind-rag] body cache: 289 docs, 3533.3 KiB in 59ms (missing path=0, read errors=0)
[onmind-rag] search engine: orama · mode=fulltext · embeddings=off · 289 docs · 450ms

With RAG_CACHE_BODY=1 (default): Orama indexes the body field → search_content performs full-text BM25 over the entire markdown. read_document answers from memory (fromCache: true).

With RAG_CACHE_BODY=0: Orama only indexes metadata (title, description, tags) → search_content does not find matches in the document body. read_document falls back to disk reads.

Disable only if RAM is very tight or corpus > 50 MB and you accept metadata-only search.

Search engine (Orama)

Mode What it does
fulltext (default) BM25 with stemming, typo tolerance, field boosting. Fast, no external deps.
hybrid BM25 + vector (cosine) — needs RAG_EMBEDDINGS=1
vector Vector similarity only — needs RAG_EMBEDDINGS=1

Embeddings (opt-in)

RAG_EMBEDDINGS=1 uses local feature-hashing (no TensorFlow, no API keys) — a portable baseline to exercise the vector/hybrid path. Not a SOTA semantic model. For real quality, replace embed.js with a provider (OpenAI, Xenova/transformers.js, etc.) keeping the embedText(text, { dims }) interface.

Snapshot (opt-in)

RAG_SNAPSHOT=1 serializes the Orama index to disk (data/orama-snapshot.json + .meta.json). On subsequent starts, if the corpus fingerprint (ids, titles, body length, hide, embeddings flag/dims) matches, it loads the snapshot in ~100 ms instead of re-indexing (~450 ms).

Limits (by design)

  • Lexical/BM25 retrieval + hash vectors (no SOTA embeddings unless you plug them in).
  • No knowledge graph / neighbors yet (next step: markdown links).
  • Designed as a useful, portable base — not a managed vector engine.

Why Spanish tokenizer?

The corpus is predominantly Spanish (~80%). Orama's default English tokenizer treats short technical codes like "XDB", "IAM", "UCDM" as stop-words/noise. Setting language: 'spanish' in the tokenizer indexes them correctly.


Based on onmind-rag v0.2.0 — MCP server for knowledge retrieval with Orama BM25 + opt-in hybrid/vector + snapshot

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选