Version: 0.3.1
License: MIT
Node: >= 18.0.0
Package: markdown-matters on npm
Token-efficient markdown analysis and search for LLM consumption. Parses documentation into structured indexes, then serves content via a CLI or an MCP server, respecting token budgets.
markdown-matters ingests a directory of markdown files and builds three queryable artifacts:
- Structural indexes (documents, sections, links) stored as JSON in
.mdm/ - BM25 keyword index for exact-term and boolean search
- HNSW vector index for embedding-based semantic search (optional, requires an embedding provider)
Consumers retrieve content through either the mdm CLI or the mdm-mcp MCP server. Both interfaces share the same underlying indexes; the CLI formats output for humans, the MCP server formats it for AI agents.
| Command | Description |
|---|---|
init |
Interactive setup wizard for .mdm.toml configuration |
index |
Index markdown files; optionally build embeddings (--embed) |
search |
Search by keyword, semantic, or hybrid mode |
context |
Emit token-budget-aware compressed summaries of a file |
tree |
Show document heading outline or directory listing |
links |
Show outgoing links from a file |
backlinks |
Show incoming links to a file |
duplicates |
Detect duplicate content across files |
stats |
Show index statistics (documents, sections, tokens, embeddings) |
config |
Manage configuration (init, show, check) |
embeddings |
Manage embedding namespaces (list, switch, remove, current) |
Exposes 7 tools over stdio transport for Claude and other MCP clients.
| Tool | Description |
|---|---|
md_search |
Semantic search by meaning; returns relevant sections |
md_context |
Token-compressed file summaries at brief, summary, or full detail |
md_structure |
Heading hierarchy with token counts |
md_keyword_search |
Structural search by heading, code, list, or table presence |
md_index |
Build or rebuild the index |
md_links |
Outgoing links from a file |
md_backlinks |
Incoming links to a file |
Directory walk
-> File filtering (.gitignore / .mdmignore / mtime cache)
-> remark AST parse + gray-matter frontmatter extraction
-> Section extraction (heading hierarchy, line ranges, token counts)
-> Parallel writes:
.mdm/indexes/documents.json
.mdm/indexes/sections.json
.mdm/indexes/links.json
.mdm/bm25.json
-> Optional: embedding batches -> HNSW build
.mdm/embeddings/{namespace}/vectors.bin
Parsed ASTs are cached in .mdm/cache/parsed/ so unchanged files are skipped on subsequent runs. SHA256 hashes detect silent content changes alongside mtime checks.
Keyword (BM25)
- Full boolean query parser: AND, OR, NOT, parentheses, quoted phrases
- ReDoS validation before regex compilation
- Fuzzy matching with match-context line extraction (grep-style
-A,-B,-Cflags)
Semantic (HNSW)
- Optional query preprocessing (normalize, lowercase) for improved recall
- Optional HyDE expansion: generates a hypothetical answer document, then embeds it as the query vector, improving complex queries by 10-30% at 1-2s latency cost
- Configurable search quality:
fast(efSearch=64),balanced(100),thorough(256) - Per-heading and per-file importance boosts applied post-search
Hybrid
- Runs BM25 and semantic in parallel
- Merges via Reciprocal Rank Fusion:
score = sum(weight / (k + rank)), k=60 - Optional cross-encoder re-ranking for a further precision lift (~20-35%)
| Provider | Model | Dimensions |
|---|---|---|
| OpenAI | text-embedding-3-small / 3-large | 384 / 3072 |
| Voyage AI | voyage-3 | 1024 |
| Ollama | configurable | configurable |
| LM Studio | configurable | configurable |
| OpenRouter | configurable | configurable |
Namespaced storage isolates vector indexes per provider+model combination. Dimension mismatches are detected at load time with typed errors before any search occurs.
Search results can be passed through an AI summarizer. Two execution modes:
- CLI mode: spawns
claudeorcopilotas subprocesses (free, no API key required) - API mode: calls OpenAI, Anthropic, or other providers via Vercel AI SDK
| Concern | Library |
|---|---|
| CLI framework | @effect/cli + @effect/platform-node |
| Functional runtime | effect (services, errors, config, DI) |
| MCP server | @modelcontextprotocol/sdk |
| Markdown parsing | remark + remark-gfm + unified |
| Frontmatter | gray-matter |
| Token counting | tiktoken |
| Keyword search | wink-bm25-text-search |
| Vector search | hnswlib-node (native HNSW) |
| Binary serialization | @msgpack/msgpack |
| File watching | chokidar |
| Build | tsup (ESM only) |
| Test | vitest |
| Lint/format | @biomejs/biome |
| Releases | release-please |
Config resolves in this precedence order:
- CLI flags
- Environment variables
.mdm.tomlin the project root- Built-in defaults
Key configurable surfaces:
- Index:
maxDepth,excludePatterns,fileExtensions,followSymlinks - Search:
defaultLimit,minSimilarity(default 0.35),includeSnippets - Embeddings:
provider,model,baseURL,batchSize,dimensions - Summarization:
budgetTokens,truncationStrategy,mode,model - Output:
verbose,debug,noColor,format
Full reference: docs/CONFIG.md and docs/USAGE.md
All errors are typed via Effect's Data.TaggedError. Error codes follow a domain taxonomy:
| Range | Domain |
|---|---|
| E1xx | File system |
| E2xx | Parsing |
| E3xx | API / auth |
| E4xx | Index |
| E5xx | Search |
| E6xx | Vector store |
| E7xx | Config |
| E8xx | Watch |
| E9xx | CLI validation |
Technical detail lives in the message field. User-facing text is generated only at the CLI boundary.
src/
cli/ CLI commands, argument handling, help, error formatting
mcp/ MCP server, tool definitions, handlers, adapters
index/ Indexer, storage, document/section/link types
parser/ remark pipeline, section extraction, section filtering
search/ BM25, semantic, hybrid search, RRF, re-ranking, query parser
embeddings/ Provider abstraction, HNSW store, namespacing, HyDE, ranking
summarization/ CLI and API summarizer provider implementations
summarize/ Summarization orchestration
core/ Shared domain types (9 exports, 13 downstream dependents)
config/ Schema, file loader, precedence, Effect service layer
errors/ Typed error catalog
duplicates/ Duplicate content detection
utils/ Shared utilities
types/ Shared TypeScript types
tests/ Integration tests (search-context, search-semantic, embed-index)
docs/ Extended documentation (CONFIG, USAGE)
scripts/ Build and utility scripts
pnpm install
pnpm build # compile to dist/ (ESM only)
pnpm test # run integration tests
pnpm test:all # include semantic tests (requires OPENAI_API_KEY)
pnpm check # format + lint + typecheckSemantic tests are skipped unless OPENAI_API_KEY is set or INCLUDE_EMBED_TESTS=true. Set REBUILD_TEST_INDEX=true to force index regeneration before tests.
Part of the Helioy ecosystem.
| Component | Role |
|---|---|
attention-matters |
Geometric memory engine |
context-matters |
Structured context store |
fmm |
Code structural intelligence |
nancyr |
Multi-agent orchestrator (Rust) |
helioy-plugins |
Claude Code plugin |
helioy-bus |
Inter-agent message bus |