That stability is the design decision worth having: an agent written against `search` today still works after you add three more sources, because the tool surface does not grow with them. Local embeddings by default means the first run costs nothing and sends nothing anywhere.
A configuration-driven RAG MCP server. One YAML file defines the sources, chunking strategy, embedding model and vector store; the server indexes them, watches them for changes, and exposes a small, source-agnostic tool surface on top.
- Five tools that stay the same as sources come and go: `search`, `list_sources`, `get_document`, `get_index_status`, `reindex`
- search — semantic search across one source or all of them, with optional metadata filtering, returning normalized [0, 1] scores
- get_document — the full document once search surfaces a chunk from it
- get_index_status and `reindex` — freshness and health per source, and a forced re-scan when you need one
- Source types: `folder` for a local directory of text, PDF and Markdown files with gitignore-style include and exclude globs, and `website` for a fixed list of pages, fetched rather than crawled
- Live reload — filesystem watching and polling keep the index current, and editing the config itself applies without a restart
- Tools return structured `{"error": "..."}` objects rather than raising, so a calling agent can recover in conversation
Run it with `uvx ragsync --config /abs/path/to/config.yaml` — no clone, no install step. Give `--config` an absolute path; paths inside the config resolve against the config file's own directory, so a repo config can use `path: ./docs`. Embeddings default to local `fastembed`, which needs no API key; `openai` and `voyage` are per-source alternatives and read their key from the environment variable named by `api_key_env`, never from the config. First launch downloads the local embedding model, so it is slower than later ones. Access scoping is by running separate instances with separate configs — there is no cross-instance search.
One command — uvx ragsync --config <path>
