Lightweight MCP server for semantic search over organizational markdown
Project description
context-server
A lightweight MCP server for semantic search over markdown knowledge bases.
One Rust binary. ONNX Runtime is statically linked (via ort / fastembed) — no separate libonnxruntime.so to ship. SQLite is bundled. Built for AI coding agents (Claude Code, Cursor, etc.).
Features
- Index markdown into a local SQLite vector database
- Chunk by
##/###headings (hierarchy kept in each chunk); oversized sections are split with overlap - Hybrid search: dense embeddings (All-MiniLM-L6-v2) + BM25, fused with reciprocal rank fusion
- MCP tools:
semantic_search,list_documents,answer_question - CLI for index / search / embed smoke tests
Input contract: feed searchable prose (markdown). Structured data (YAML, etc.) should be converted to markdown before indexing — raw YAML in code fences searches poorly.
Requirements
- Rust 1.75+ (edition 2021)
- Linux x86_64 (primary target today)
- At build/link time: a C++ standard library (
libstdc++) and OpenSSL development headers if your platform needs them fornative-tls
On Fedora/RHEL, if the linker cannot find -lstdc++ (only libstdc++.so.6 is installed):
mkdir -p .linker && ln -sfn /usr/lib64/libstdc++.so.6 .linker/libstdc++.so
export RUSTFLAGS="-L native=$(pwd)/.linker"
Install
pip install context-server
Platform wheels: Linux x86_64/aarch64 (manylinux_2_39, glibc 2.39+ / Ubuntu 24.04+) and macOS Apple Silicon.
Build
cargo build --release
The first embedding run downloads the MiniLM model into the local Hugging Face / fastembed cache (~tens of MB, once).
Linux wheels (Podman)
Same Containerfile CI uses (Ubuntu 24.04 / glibc 2.39 — required by current ORT prebuilts):
./scripts/build-wheel.sh # writes dist/*.whl
VERSION=2026.716.1 ./scripts/build-wheel.sh # optional CalVer override
Releasing (CalVer)
Versions are CalVer YYYY.MMDD.N (e.g. 2026.716.1) so they are valid for
both Cargo SemVer and PyPI. pyproject.toml takes the version from
Cargo.toml; release CI rewrites that from the git tag before building.
tag="$(./scripts/next-calver.sh)"
git tag -a "$tag" -m "$tag"
git push origin "$tag" # triggers Release workflow → PyPI
setuptools-scm is not used (maturin cannot consume it).
Usage
# Preview how documents will be chunked
./target/release/context-server index --input ./docs --dry-run
# Embed and write the database
./target/release/context-server index --input ./docs --db context.db
# Optional: store MCP server instructions in the DB (when to call this corpus)
./target/release/context-server index --input ./docs --db context.db \
--instructions-file ./mcp-instructions.txt
# or: --instructions 'Call semantic_search for questions about …'
# CLI search (hybrid by default; also --mode dense|lexical)
./target/release/context-server search --db context.db "how do we handle backports"
# MCP stdio server
./target/release/context-server serve --db context.db
MCP instructions in the DB
index --instructions / --instructions-file writes meta.instructions.
serve exposes that text as MCP ServerInfo.instructions so clients know when
to call this corpus (falls back to a generic blurb if unset).
serve and search accept a remote --db and download it into the local cache
($XDG_CACHE_HOME/context-server/dbs/..., or ~/.cache/...) before opening:
# Short form (globally unique bucket)
context-server serve --db 'gs://my-context-bucket/latest/context.db'
# Project-qualified (still requires gs://; stripped for the Storage API)
context-server serve --db \
'gs://projects/my-gcp-project/buckets/my-context-bucket/objects/latest/context.db'
Uses Application Default Credentials
(gcloud auth application-default login, or GOOGLE_APPLICATION_CREDENTIALS).
When a sibling {object}.sha256 exists (sha256sum format), the download is
skipped if the local cache already matches; otherwise the DB is re-fetched and
verified. index still writes a local path only.
Claude Code
claude mcp add --transport stdio --scope user context-server \
-- /absolute/path/to/context-server serve --db /absolute/path/to/context.db
Re-index when content changes, then restart the MCP session so serve reloads the DB into memory.
For a GCS-backed DB, point --db at a gs://... URI.
If Claude rarely calls the tools (tool search defers MCP tools), add "alwaysLoad": true to the server entry in your Claude MCP config so these tools stay visible every turn.
MCP tools
| Tool | Description |
|---|---|
semantic_search |
Ranked passages with similarity scores |
list_documents |
Indexed chunk listing |
answer_question |
Top passage for a question (retrieval only, no generative QA) |
Architecture
| Piece | Choice |
|---|---|
| Embeddings | fastembed → All-MiniLM-L6-v2, L2-normalized (model id stored in DB) |
| Inference | ort (static ONNX Runtime) |
| Storage | rusqlite (bundled SQLite), float32 blobs |
| Search | Hybrid: cosine dense + BM25 → reciprocal rank fusion |
| Chunking | ## / ### + split when text exceeds ~900 chars |
| MCP | rmcp stdio |
See PLAN.md for design notes and roadmap.
Development
cargo test
cargo build --release
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file context_server-2026.717.1.tar.gz.
File metadata
- Download URL: context_server-2026.717.1.tar.gz
- Upload date:
- Size: 57.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64e1d099e773c93365127c567ccef0de630dc1141c0b9a2df73d62db45c37da5
|
|
| MD5 |
7065770bbfdd93c856932e917a4a76e2
|
|
| BLAKE2b-256 |
fa88548bece5688f153dadf768c82d128ba49a2039d4ff446283c061cdd425c1
|
File details
Details for the file context_server-2026.717.1-py3-none-manylinux_2_39_x86_64.whl.
File metadata
- Download URL: context_server-2026.717.1-py3-none-manylinux_2_39_x86_64.whl
- Upload date:
- Size: 17.4 MB
- Tags: Python 3, manylinux: glibc 2.39+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7d724ec3d519a8fa2f9472c63a5f03726049cbd59f0362ddcfe19423a494237
|
|
| MD5 |
efd010b506ee90ed15193fc604d7529a
|
|
| BLAKE2b-256 |
0d425953d89e93b7127526a2dd8fc7f1d6b29fa5213da53ca6890386ff65a90b
|
File details
Details for the file context_server-2026.717.1-py3-none-manylinux_2_39_aarch64.whl.
File metadata
- Download URL: context_server-2026.717.1-py3-none-manylinux_2_39_aarch64.whl
- Upload date:
- Size: 17.8 MB
- Tags: Python 3, manylinux: glibc 2.39+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcff60ebdce6bfcf76f80aea062f01fcba5ed0ac861a75c764440ba4ac6b8630
|
|
| MD5 |
6290910949133fdd2338a7c96a8f422f
|
|
| BLAKE2b-256 |
ec8e294a072bb5884501e554635832ce9d20c04d1ad7083c549e51328876c29a
|
File details
Details for the file context_server-2026.717.1-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: context_server-2026.717.1-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 13.4 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0b78ad2339f0aca8d3065418da24bdef8e86008b220e1f61fb4f4db2fcd1721
|
|
| MD5 |
8a0c4ba2d5631a17ef8d97b3d1222c7e
|
|
| BLAKE2b-256 |
e59434bbc41ade0c154066aff5bb194bc303468a70d060df22fec58fd18a8793
|