Skip to main content
Glama

docrag

Local RAG over folder trees of markdown documents. One persistent index, two front ends: a CLI research loop backed by a local Ollama model, and an MCP server that exposes the same index to Claude Code.

Everything runs on-device. No network egress at query time.

See docs/project-plan.md for the full design.

Status: Phase 1 complete — chunker, store, embedder, indexer, and the index / status commands. search and ask land in Phase 2; the MCP server in Phase 3.

Setup

Requires Ollama and uv.

ollama pull nomic-embed-text
uv sync

Point docrag.toml at the markdown trees you want indexed, then:

uv run docrag index

Re-run it whenever the corpus changes — only files whose content hash moved are re-embedded, so a no-op run costs about a tenth of a second per 200 files.

uv run docrag status --pending

Related MCP server: MCP-RAG

Commands

Command

What it does

docrag index

Incremental index of every configured root

docrag index --root NAME

Limit to one root (repeatable); other roots are left untouched

docrag index --force

Re-embed everything, ignoring content hashes

docrag index --dry-run

Report what would change, write nothing

docrag index --reset

Drop the collection first — use after changing chunk params or the embedding model

docrag index -v

Print each added/changed file

docrag status

Roots, file counts, chunk counts, last index time, orphaned roots

docrag status --pending

Also report how many files an index run would touch

Configuration

All tunables live in docrag.toml. Paths are resolved relative to that file, so the commands work from any directory in the tree.

[[roots]]              # repeatable; at least one required
name = "docs"          # optional, defaults to the directory name
path = "./docs"        # relative to docrag.toml, or absolute; ~ is expanded

[chroma]
path = ".chroma"       # where the persistent index lives
collection = "docrag"  # 3-512 chars, [a-zA-Z0-9._-]

[models]
embed = "nomic-embed-text"
generate = "qwen3:8b"  # unused until Phase 2

[embedding]
batch_size = 32
document_prefix = "search_document: "   # nomic task prefixes; "" for other models
query_prefix = "search_query: "

[chunking]
max_chunk_chars = 1500  # hard cap on chunk length
overlap_chars = 200     # carried from the tail of the previous part when a section splits
min_chunk_chars = 40    # a trailing sliver smaller than this folds into the previous part

[files]
extensions = [".md", ".markdown"]
exclude = ["**/.git/**", "**/node_modules/**"]

[ollama]
host = "http://localhost:11434"  # optional; omit to use the ollama client default

Model tags live only here (DD6) — nothing is hardcoded. Verify current tags on ollama.com/library before changing them.

How indexing works

  • Chunks are heading sections. A chunk is a heading plus everything under it up to the next heading of any level. Sections over max_chunk_chars split again on blank-line boundaries, with overlap_chars carried across the seam. Fenced code blocks are never split; one too large to fit is cut on line boundaries with each piece re-fenced.

  • Every chunk is self-locating. The stored text is prefixed with a breadcrumb — project-plan.md › 4. Key Design Decisions › Open Questions — so a retrieved chunk names its own source without a second lookup.

  • The diff is content-based. Each file's SHA-256 (over BOM- and EOL-normalized text) is stored on its chunks. Unchanged hash, no work; changed hash, that file's chunks are dropped and rebuilt; gone from disk, its chunks are purged. docrag index is idempotent and cheap to run often.

  • Chunk ids are deterministic: {root}/{relpath}#{ordinal}.

Measured throughput and chunk shape: docs/phase1-baseline.md.

Development

uv run pytest

Chunking edge cases are pinned in tests/test_chunker.py (code fences, indented code, setext headings, front matter, oversized sections); the incremental diff in tests/test_indexer.py.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    -
    quality
    D
    maintenance
    Enables real-time indexing and semantic search of local documents (PDF, Word, text, Markdown, RTF) using vector embeddings and local LLMs. Monitors folders for changes and provides natural language search capabilities through Claude Desktop integration.
    Last updated
    22
    MIT
  • A
    license
    -
    quality
    -
    maintenance
    Turns Claude Desktop into a personal document question-answering system using local vector search. Index PDF, TXT, and Markdown documents into collections and get answers based strictly on your documents with zero hallucination.
    Last updated
    12
  • A
    license
    -
    quality
    D
    maintenance
    Enables Claude to perform hybrid search across local documents by combining semantic vector retrieval and BM25 keyword matching for optimal context recovery. It supports multiple file formats including PDF, CSV, and Markdown, leveraging local Ollama models for private and efficient document querying.
    Last updated
    4
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    Turns any folder of Markdown files into a searchable, structured knowledge base for Claude Code, enabling persistent memory across sessions via tools like list, read, write, edit, search, and summarize.
    Last updated
    MIT

View all related MCP servers

Related MCP Connectors

  • Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.

  • Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.

  • Connect your team's living knowledge base — docs, data, issues, CRM — to Claude and ChatGPT.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jimpark/docrag'

If you have feedback or need assistance with the MCP directory API, please join our Discord server