Labsco
joesaby logo

doctree-mcp

โ˜… 1

from joesaby

BM25 search + tree navigation over markdown docs for AI agents. No embeddings, no LLM calls at index time.

๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅ๐Ÿ”ฅโœ“ VerifiedFreeQuick setup

doctree-mcp

Agentic document retrieval over markdown, CSV, and JSONL. BM25 + tree navigation via MCP โ€” no vector DB, no embeddings, no LLM calls at index time.

The pitch: MCP provides the structural primitives (a navigable tree, BM25, glossary, row lookup). The bundled skills provide the procedural knowledge (how to walk that tree). Together the agent behaves like a trained research librarian โ€” not a one-shot searcher. See The Skill + MCP Pattern.


Operation Modes

ModeUse whenGuide
stdio (default)Local dev, agent on your machineClient setup
HTTP (Streamable HTTP)Teams, CI, hosted agentsDeployment โ€” Railway ยท Fly ยท Render ยท Cloudflare Containers ยท Docker
CLIinit, lint, debug-indexOperation modes

Full decision tree: Operation Modes.


How It Works โ€” Retrieve ยท Curate ยท Add

Agent: "How does token refresh work?"

โ†’ search_documents("token refresh")
  #1  auth/middleware.md ยง Token Refresh Flow       score: 12.4
  #2  auth/oauth.md       ยง Refresh Token Lifecycle  score: 8.7

โ†’ get_tree("docs:auth:middleware")
  [n1] # Auth Middleware
    [n4] ## Token Refresh Flow
      [n5] ### Automatic Refresh

โ†’ navigate_tree("docs:auth:middleware", "n4")   โ† n4 + descendants

Core read tools (always on):

ToolPurpose
search_documentsBM25 keyword search + facet filters + glossary expansion (markdown ยท CSV ยท JSONL)
get_treeTable of contents โ€” headings, word counts, summaries
get_node_contentFull text of a specific section by node ID
navigate_treeA section plus all descendants in one call
lookup_rowO(1) exact-key lookup for structured data rows (e.g. PROJ-44)

Wiki write tools (opt-in with WIKI_WRITE=1):

ToolPurpose
find_similarDuplicate detection with overlap ratios
draft_wiki_entryScaffold: suggested path, inferred frontmatter, glossary hits
write_wiki_entryValidated write: path containment, schema, duplicate guards, dry-run

Safety: path containment ยท frontmatter validation ยท duplicate detection ยท dry-run ยท overwrite protection.

Deprecated aliases (list_documents, find_files, find_symbol) are superseded by search_documents โ€” still functional, no longer recommended.


The Skill + MCP Pattern

Most retrieval tools hand the agent a search box and hope for the best. doctree-mcp hands it a tree, and the bundled skills teach it how to walk one.

  • MCP = structural primitives. search_documents, get_tree, navigate_tree, get_node_content, lookup_row return tree positions the agent reasons over โ€” not finished answers.
  • Skills = procedural knowledge. /doc-read, /doc-write, /doc-lint encode breadcrumb drill-down: search โ†’ outline โ†’ navigate โ†’ retrieve. The agent learns the policy, not just the API.

That pairing doesn't exist cleanly elsewhere:

ApproachPrimitiveSkill teachesGap
Managed hybrid RAG (Cloudflare AI Search, Nia)Flat chunks + similarityโ€”Black-box score, no audit trail
Tool-returns-answer (Context7)2 tools returning answersQuery shapeAgent can't reason about skipped content
Skill-over-CLI (QMD)CLI over flat searchQuery expansionNo tree to navigate
doctree-mcp + /doc-readNavigable treeBreadcrumbs, multi-instance routing, wiki compilationโ€”

Why iterative retrieval wins:

  • Context rot. Stuffing a 1M-token window with chunks degrades output. Breadcrumb navigation keeps working memory small.
  • Auditability. search_documents โ†’ get_tree โ†’ navigate_tree โ†’ get_node_content is a replayable trail. A cosine score is not. Regulated domains can ship the former.
  • Progressive disclosure. Fewer navigable primitives beat tool sprawl (cf. Cloudflare Code Mode).

Multi-instance = client-side federation. Register several doctree servers under different names; the /doc-read skill encodes the routing policy. Add or remove instances without touching the skill. See Client setup โ†’ Multi-instance routing.


The LLM Wiki Pattern

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Raw Sources    โ”‚     โ”‚  The Wiki        โ”‚     โ”‚  The Schema     โ”‚
โ”‚  (immutable)    โ”‚ โ”€โ”€โ†’ โ”‚  (LLM-maintained)โ”‚ โ†โ”€โ”€ โ”‚  (you define)   โ”‚
โ”‚  notes ยท logs   โ”‚     โ”‚  runbooks ยท refs โ”‚     โ”‚  CLAUDE.md rules โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Inspired by Karpathy's LLM Wiki. Full walkthrough: docs/LLM-WIKI-GUIDE.md.


Performance

OperationTimeToken cost
Full index (900 docs)2โ€“5s0
Incremental re-index~50ms0
Search5โ€“30ms~300โ€“1K tokens
Tree outline<1ms~200โ€“800 tokens

Docs

Setup & operation

  • Operation Modes โ€” stdio ยท HTTP ยท CLI
  • Client Setup โ€” Claude Code ยท Cursor ยท Windsurf ยท Codex ยท OpenCode ยท Claude Desktop
  • Deployment โ€” Railway ยท Fly.io ยท Render ยท Cloudflare Containers ยท Docker
  • Configuration โ€” env vars, frontmatter, ranking tuning

Patterns & concepts

Source


Standing on Shoulders