Small, fast retrieval primitive for local Markdown — FTS + on-device vector search + MCP server. local-first, no cloud.
Rust
1
216 commits
updated Sep 18, 2026
English / 日本語
A small, fast search primitive for your local Markdown collections. BM25 full-text search, on-device vector search, and a hybrid that fuses both — exposed through two entry points: a CLI and an MCP server.
mdya is a search primitive. It indexes local Markdown, and returns search results over a CLI and an MCP server. That is all it does.
mdya is not a search agent and not an LLM query-rewriting front-end. It has no query expansion, no reranker, and no multi-stage agent pipeline. Workflows that want those things are expected to layer a separate tool on top of mdya via its CLI or MCP interface.
It is local-first by construction. There is no path to any cloud LLM API; inference runs entirely on-device; distribution is a single binary.
What it can do:
cl-nagoya/ruri-v3-30m, 256 dimensions).mdya mcp (stdio / HTTP) exposes the search tools to MCP clients..pdf files go through the same ingest path as .md. They are converted to plain text at ingest time and then chunked and embedded with the same pipeline as Markdown.
# Linux / macOS
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/yoshihirosuzuki/mdya/releases/latest/download/mdya-installer.sh | sh
# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/yoshihirosuzuki/mdya/releases/latest/download/mdya-installer.ps1 | iex"
Or grab an archive from the releases page and put the mdya binary on your PATH.
Rust users can install from crates.io instead. This builds from source, so it needs the build-from-source prerequisites below (notably protoc):
cargo install mdya
Prerequisites:
rust-toolchain.toml at the repo root)just (cargo install just)protoc (Protocol Buffers compiler, a build dependency of the lance storage library). On macOS brew install protobuf; on Linux apt install -y protobuf-compiler; on Windows choco install protoc.git clone https://github.com/yoshihirosuzuki/mdya.git
cd mdya
cargo build --release # produces ./target/release/mdya
# or install onto your PATH:
cargo install --path . # installs mdya into ~/.cargo/bin
The shortest path is init → collection add → update-all → search.
mdya init # create ~/.mdya/ (config.yml + data directories for the index)
mdya collection add ~/notes # register a directory as a collection (name = basename, here: notes)
mdya update-all # walk every registered collection, ingest .md / .markdown / .pdf, build the index
mdya search fts "release plan" # BM25 full-text search
mdya search vector "release plan" # vector search
mdya search hybrid "release plan" # hybrid (RRF)
The first
mdya update-all(and vector / hybrid searches) automatically downloads the embedding model (cl-nagoya/ruri-v3-30m, about 140 MB) into~/.mdya-models/, and reuses that cache afterwards.
Search results are printed to stdout in a human-readable format.
notes/release.md score=0.812
> The release procedure is as follows
> 1. Update the version number
---
notes/checklist.md score=0.751
> Pre-release checklist
---
2 doc hits (showing 20 max)
Common flags:
-c, --collections <NAMES...> — restrict to specific collections (default: all)-n, --limit <N> — top N hits (default 20)--format <FORMAT> — output format (default human). json (machine-friendly envelope), md (Markdown, suitable for pasting or LLM input), and xml (structurally equivalent to JSON, also for LLM input) are also available.mdya can run as an MCP (Model Context Protocol) server, so clients like Claude Code or Claude Desktop can call its search tools.
mdya mcp # start the MCP server over stdio
Registering with Claude Code:
claude mcp add mdya -- mdya mcp
For configuration, individual subcommands, and MCP details, see the user manual.
Configuration lives in a single file at ~/.mdya/config.yml (a template is generated by mdya init). Minimal example:
collections:
notes:
path: ~/notes
embedding:
model: cl-nagoya/ruri-v3-30m
runtime:
memory_limit_mb: 8192 # upper bound on this process's RSS, in MB. 0 to disable.
embed_parallelism: 8 # number of files embedded in parallel during update-all. 0 for sequential.
mdya collection add <path> rewrites the collections section, so you usually do not need to edit it by hand. The configuration directory can be moved with --config-dir <path>, and the embedding model cache with --model-cache-dir <path> (default $HOME/.mdya-models/).
just check # fmt-check + clippy (-D warnings) + cargo test (full workspace) + cargo audit
just smoke # smoke tests only
just # list available recipes
just check needs the build-from-source prerequisites — Rust, just, protoc — plus cargo install cargo-audit --locked and network access, since the advisory database is fetched on every run. Offline, run cargo audit --no-fetch --stale instead.
Contributions are welcome on a best-effort basis (one-person maintainer; no formal SLA). Please read the following before opening an issue or PR:
Dual-licensed under MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.
172 commits
44 commits
Rust
99.4%
Small, fast retrieval primitive for local Markdown — FTS + on-device vector search + MCP server. local-first, no cloud.
Rust
1
216 commits
updated Sep 18, 2026
English / 日本語
A small, fast search primitive for your local Markdown collections. BM25 full-text search, on-device vector search, and a hybrid that fuses both — exposed through two entry points: a CLI and an MCP server.
mdya is a search primitive. It indexes local Markdown, and returns search results over a CLI and an MCP server. That is all it does.
mdya is not a search agent and not an LLM query-rewriting front-end. It has no query expansion, no reranker, and no multi-stage agent pipeline. Workflows that want those things are expected to layer a separate tool on top of mdya via its CLI or MCP interface.
It is local-first by construction. There is no path to any cloud LLM API; inference runs entirely on-device; distribution is a single binary.
What it can do:
cl-nagoya/ruri-v3-30m, 256 dimensions).mdya mcp (stdio / HTTP) exposes the search tools to MCP clients..pdf files go through the same ingest path as .md. They are converted to plain text at ingest time and then chunked and embedded with the same pipeline as Markdown.
# Linux / macOS
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/yoshihirosuzuki/mdya/releases/latest/download/mdya-installer.sh | sh
# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/yoshihirosuzuki/mdya/releases/latest/download/mdya-installer.ps1 | iex"
Or grab an archive from the releases page and put the mdya binary on your PATH.
Rust users can install from crates.io instead. This builds from source, so it needs the build-from-source prerequisites below (notably protoc):
cargo install mdya
Prerequisites:
rust-toolchain.toml at the repo root)just (cargo install just)protoc (Protocol Buffers compiler, a build dependency of the lance storage library). On macOS brew install protobuf; on Linux apt install -y protobuf-compiler; on Windows choco install protoc.git clone https://github.com/yoshihirosuzuki/mdya.git
cd mdya
cargo build --release # produces ./target/release/mdya
# or install onto your PATH:
cargo install --path . # installs mdya into ~/.cargo/bin
The shortest path is init → collection add → update-all → search.
mdya init # create ~/.mdya/ (config.yml + data directories for the index)
mdya collection add ~/notes # register a directory as a collection (name = basename, here: notes)
mdya update-all # walk every registered collection, ingest .md / .markdown / .pdf, build the index
mdya search fts "release plan" # BM25 full-text search
mdya search vector "release plan" # vector search
mdya search hybrid "release plan" # hybrid (RRF)
The first
mdya update-all(and vector / hybrid searches) automatically downloads the embedding model (cl-nagoya/ruri-v3-30m, about 140 MB) into~/.mdya-models/, and reuses that cache afterwards.
Search results are printed to stdout in a human-readable format.
notes/release.md score=0.812
> The release procedure is as follows
> 1. Update the version number
---
notes/checklist.md score=0.751
> Pre-release checklist
---
2 doc hits (showing 20 max)
Common flags:
-c, --collections <NAMES...> — restrict to specific collections (default: all)-n, --limit <N> — top N hits (default 20)--format <FORMAT> — output format (default human). json (machine-friendly envelope), md (Markdown, suitable for pasting or LLM input), and xml (structurally equivalent to JSON, also for LLM input) are also available.mdya can run as an MCP (Model Context Protocol) server, so clients like Claude Code or Claude Desktop can call its search tools.
mdya mcp # start the MCP server over stdio
Registering with Claude Code:
claude mcp add mdya -- mdya mcp
For configuration, individual subcommands, and MCP details, see the user manual.
Configuration lives in a single file at ~/.mdya/config.yml (a template is generated by mdya init). Minimal example:
collections:
notes:
path: ~/notes
embedding:
model: cl-nagoya/ruri-v3-30m
runtime:
memory_limit_mb: 8192 # upper bound on this process's RSS, in MB. 0 to disable.
embed_parallelism: 8 # number of files embedded in parallel during update-all. 0 for sequential.
mdya collection add <path> rewrites the collections section, so you usually do not need to edit it by hand. The configuration directory can be moved with --config-dir <path>, and the embedding model cache with --model-cache-dir <path> (default $HOME/.mdya-models/).
just check # fmt-check + clippy (-D warnings) + cargo test (full workspace) + cargo audit
just smoke # smoke tests only
just # list available recipes
just check needs the build-from-source prerequisites — Rust, just, protoc — plus cargo install cargo-audit --locked and network access, since the advisory database is fetched on every run. Offline, run cargo audit --no-fetch --stale instead.
Contributions are welcome on a best-effort basis (one-person maintainer; no formal SLA). Please read the following before opening an issue or PR:
Dual-licensed under MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.
172 commits
44 commits
Rust
99.4%