mcp-server-bm25-code-search
by toaruR
README.md
# mcp-server-bm25-code-search
**English** | [ๆฅๆฌ่ช](README.ja.md)
Fast, low-token BM25 local code search plugin & MCP server backed by SQLite FTS5 for AI coding agents (VS Code, Cursor, GitHub Copilot, ChatGPT & Codex, Kiro, Hermes Agent, OpenClaw, Grok Bot, NanoClaw, etc.), fully compliant with the **Agent Plugins** specification.
---
## โจ Features
- ๐ฆ **Zero External Dependencies (Python Standard Library Only)**
Built entirely on `sqlite3` (FTS5) and the Python standard library. Runs out-of-the-box without requiring third-party package installations (`pip install`).
- ๐งฉ **Agent Plugins (v1.0.0) Compliant**
Conforms to the [Agent Plugins](https://agent-plugins.org/compatible-clients) standard. In supported clients (VS Code, Cursor, GitHub Copilot, ChatGPT & Codex, Kiro, Hermes Agent, OpenClaw, Grok Bot, NanoClaw), simply pointing to this repository automatically discovers and loads both the MCP server (`mcp.json`) and the search guidance skill (`skills/`) with zero configuration.
- ๐ค **Code Identifier & Japanese/CJK Hybrid Tokenization**
Pre-processes code identifiers with subword splitting for `getUserProfile` (camelCase) and `session_token` (snake_case), combined with Python-side CJK 2-gram (bigram) tokenization for technical documentation and comments. Automatically applied to both FTS5 indexing and search queries.
- ๐ **File Path Boost (3.0x)**
Leverages FTS5 column weighting `bm25(code_fts, 3.0, 1.0)` to weight file path matches 3.0x higher than file content matches, pinpointing target files in fewer search iterations.
- โก **Fast Incremental Indexing & Git Worktree Isolation**
Strict `.gitignore` compliance using `git ls-files` with ultra-fast incremental updates (0.1โ0.5s during standard editing) via `git diff` / HEAD hash tracking. The index database `.bm25_index.db` is stored locally within the worktree and automatically ignored by `.gitignore`.
- ๐ **MCP 2026-07-28 & Hermes Native Support**
- **MCP Native**: Stateless stdio JSON-RPC server adhering to the MCP 2026-07-28 specification, with deterministic tool sorting for prompt cache optimization.
- **Hermes Agent**: Includes a lightweight Function Calling adapter layer (`hermes_adapter.py`) for environments without native MCP support.
- ๐ก๏ธ **Context Overflow Protection & Fallback Guidance**
Safe byte-length truncation (`--max-bytes`) preserving UTF-8 multi-byte character boundaries. Returns structured fallback messages prompting agents to switch to `grep`/`glob` when zero results are found.
---
## ๐ Directory Structure
```text
mcp-server-bm25-code-search/
โโโ plugin.json # Agent Plugins v1.0.0 manifest
โโโ mcp.json # Agent Plugins v1.0.0 MCP configuration
โโโ skills/ # Agent Skills (agent search guidelines & prompt)
โ โโโ bm25-search/
โ โโโ SKILL.md
โโโ bm25_search/
โ โโโ db.py # SQLite FTS5 v2 schema (chunks / code_fts / triggers)
โ โโโ tokenizer.py # Pre-tokenizer (camelCase / snake_case / CJK 2-gram)
โ โโโ indexer.py # Indexer (git ls-files, 80/20 chunking, incremental sync)
โ โโโ search.py # Search engine & CLI interface
โ โโโ mcp_server.py # MCP 2026-07-28 stateless stdio server
โ โโโ hermes_adapter.py # Function Calling adapter for Hermes Agent
โโโ bin/
โ โโโ cli.js # Node.js CLI / npx runner wrapper
โโโ docs/
โ โโโ specification.md # Detailed specification
โ โโโ plans/ # Design documents
โโโ tests/ # pytest test suite
```
---
## ๐ Getting Started
### 1. Installation via Agent Plugins (Recommended / Zero-Config)
In [Agent Plugins compatible clients](https://agent-plugins.org/compatible-clients) (**VS Code, Cursor, GitHub Copilot, ChatGPT & Codex, Kiro, Hermes Agent, OpenClaw, Grok Bot, NanoClaw**), simply adding this repository directory or loading it as a plugin automatically recognizes **both the MCP server (`mcp.json`) and the search guidance skill (`skills/`)**:
Official setup documentation for supported clients:
- **VS Code**: [Agent Plugins in VS Code](https://code.visualstudio.com/docs/agent-customization/agent-plugins)
- **Cursor**: [Cursor Plugins](https://cursor.com/docs/plugins)
- **GitHub Copilot**: [Copilot Agent Plugins](https://docs.github.com/en/copilot/concepts/agents/about-plugins)
- **ChatGPT & Codex**: [OpenAI Plugin Developers](https://developers.openai.com/plugins)
- **Kiro**: [Kiro Powers](https://kiro.dev/docs/powers/)
- **Hermes Agent**: [Hermes Portable Plugins](https://hermes-agent.nousresearch.com/docs/developer-guide/plugins#portable-agent-plugins-v1-packages)
- **OpenClaw**: [OpenClaw Plugin Bundles](https://docs.openclaw.ai/plugins/bundles)
- **Grok Bot**: [Grok Bot Automations](https://docs.x.ai/grok-bot/skills-routines-and-automations)
- **NanoClaw**: [NanoClaw Templates](https://github.com/nanocoai/nanoclaw/blob/main/docs/templates.md)
### 2. Running Search via CLI
```bash
python bm25_search/search.py "<search query>" --top-k 5 --format markdown --max-bytes 4000
```
**Key Options:**
- `<query>`: Search query (supports Japanese, CJK, camelCase, snake_case)
- `--top-k`: Maximum number of search results to return (default: `5`)
- `--format`: Output format, `markdown` or `json` (default: `markdown`)
- `--max-bytes`: Maximum output bytes; safely truncated preserving multibyte characters (default: `4000`)
- `--mode`: Token conjunction mode, `OR` or `AND` (default: `OR`)
- `--db`: Path to SQLite index DB file (default: `.bm25_index.db`)
### 3. Running as a Standalone MCP Server (uvx / npx / Manual)
The server communicates via Stdio and automatically indexes the project codebase. You can launch it instantly with `uvx` or `npx`.
If arguments are omitted, the server automatically detects the current working directory as the project root and synchronizes the incremental index (`.bm25_index.db`).
#### CLI Options
| Option | Description | Default |
|---|---|---|
| `--root`, `-r` | Target project root directory to index and search | `.` (current directory) |
| `--db` | Path to SQLite FTS5 index DB file | `<root>/.bm25_index.db` |
| `--no-auto-sync` | Disable automatic index synchronization on tool calls | Disabled (auto-sync active) |
| `--stdio` | Run stdio JSON-RPC transport loop | Enabled |
> **๐ก Automatic Project Root Detection with `--db`:**
> When specifying `--db <path>` (e.g. `--db /path/to/project/.bm25_index.db`) without an explicit `--root`, **the parent directory of the DB file is automatically detected as the project root**.
> This allows global or shared agent configurations to easily target specific projects while maintaining seamless Auto Sync and search functionality (specifying `--root` explicitly will take precedence).
#### โ Using `uvx` (uv / Python)
```json
{
"mcpServers": {
"bm25-code-search": {
"command": "uvx",
"args": ["mcp-server-bm25-code-search"],
"alwaysAllow": ["search"]
}
}
}
```
#### โก Using `npx` (Node.js / npm)
```json
{
"mcpServers": {
"bm25-code-search": {
"command": "npx",
"args": ["-y", "mcp-server-bm25-code-search"],
"alwaysAllow": ["search"]
}
}
}
```
#### โข Using Local Python Directly
```json
{
"mcpServers": {
"bm25-code-search": {
"command": "python",
"args": [
"/path/to/mcp-server-bm25-code-search/bm25_search/mcp_server.py",
"--stdio"
],
"alwaysAllow": [
"search"
]
}
}
}
```
#### โฃ Specifying a Target Project DB via `--db`
```json
{
"mcpServers": {
"bm25-code-search": {
"command": "uvx",
"args": [
"mcp-server-bm25-code-search",
"--db",
"/path/to/my-project/.bm25_index.db"
],
"alwaysAllow": ["search"]
}
}
}
```
*Note: The parent directory `/path/to/my-project` is automatically recognized as the project root for indexing and synchronization.*
#### ๐ก Agent Instruction Guideline (`AGENTS.md` / `CLAUDE.md`)
To prevent AI agents from repeatedly spamming `grep` and wasting context tokens, adding the following instruction to your project's `AGENTS.md`, `CLAUDE.md`, or system prompt is strongly recommended:
```markdown
## Code Search Policy
- When exploring code or investigating features across the codebase, always prioritize the MCP tool `search` (BM25 Code Search) first.
- Only fall back to `grep_search` or `glob` if `search` returns zero results or when exact literal matches for a specific symbol are required.
```
### 4. Setup in Claude Code (Manual Configuration)
Because [Claude Code](https://docs.claude.com/en/docs/claude-code) does not natively support the [Agent Plugins](https://agent-plugins.org/) standard, automatic manifest discovery (`plugin.json` / `mcp.json`) is not available. Configure it using Claude Code's MCP server registration:
> **๐ก Note on Deferred Tools in Claude Code:**
> Claude Code treats MCP tools as "Deferred Tools" to conserve context. The agent will load the tool schema before execution. Adding the instruction above to `CLAUDE.md` or placing the skill in `.claude/skills/bm25-search/SKILL.md` ensures consistent tool selection.
#### Method A: `claude mcp add` CLI Command (Recommended)
Run one of the following commands in your project root (`--scope project` generates a `.mcp.json` file to commit to git; `--scope user` registers it globally):
```bash
# Using uvx (uv / Python)
claude mcp add bm25-code-search --scope project -- uvx mcp-server-bm25-code-search
# Using npx (Node.js / npm)
claude mcp add bm25-code-search --scope project -- npx -y mcp-server-bm25-code-search
# Using local Python directly
claude mcp add bm25-code-search --scope project -e PYTHONUTF8=1 -- python /path/to/mcp-server-bm25-code-search/bm25_search/mcp_server.py --stdio
```
Verify the configuration with `claude mcp list` or the `/mcp` command inside a Claude Code session.
#### Method B: Direct `.mcp.json` File
Place a `.mcp.json` file in your project root (identical schema to the MCP configuration above):
```json
{
"mcpServers": {
"bm25-code-search": {
"command": "uvx",
"args": ["mcp-server-bm25-code-search"]
}
}
}
```
### 5. Using Hermes Agent Adapter
For Hermes Agent environments without MCP support, use the `bm25_search.hermes_adapter` module:
```python
from bm25_search.hermes_adapter import hermes_function_schema, run_hermes_tool
# Get Hermes Tool Schema
schema = hermes_function_schema()
# Execute Function Call from Hermes
response = run_hermes_tool({
"name": "bm25_search",
"arguments": {
"query": "getUserProfile",
"top_k": 5
}
})
```
---
## ๐งช Running Tests
Run the unit and integration test suite using `pytest`:
```bash
pytest tests/
```
---
## ๐ Documentation
- [Specification (docs/specification.md)](docs/specification.md)
- [Design Specification (docs/plans/bm25-multi-agent-search-skill-design.md)](docs/plans/bm25-multi-agent-search-skill-design.md)
---
## ๐ References & Links
- **Agent Plugins Specification**: [Agent Plugins Specification (agentplugins/agent-plugins-spec)](https://github.com/agentplugins/agent-plugins-spec) / [agent-plugins.org](https://agent-plugins.org/)
- **Agent Skills Specification**: [Agent Skills Specification](https://agentskills.io/specification)
- **Paper**: Wang et al., *"BM25 Wins at Scale: Evaluating Agentic Search over Enterprise Corpora"* (2026)
[https://arxiv.org/abs/2607.26497](https://arxiv.org/abs/2607.26497)
- **Article**: Hidetoshi Sudo (KnowledgeSense, Inc.), *"Using BM25 to reduce Codex token consumption by 30%"* (Zenn, 2026)
[https://zenn.dev/knowledgesense/articles/9e55a3bb67729c](https://zenn.dev/knowledgesense/articles/9e55a3bb67729c)
---
## โ๏ธ License
This project is licensed under the [MIT License](LICENSE).
TDQS
A4.4/5.0
Scored across 1 tool
Disambiguation5/5
With only one tool, there is no possibility of confusion or overlap between tools. The search tool has a clear, unique purpose.
Naming Consistency5/5
The single tool is named 'search', which is a clear verb that directly matches its function. There are no conflicting naming conventions since only one exists.
Tool Count5/5
The server's stated purpose is BM25 code search, and a single search tool fully fulfills this scope. One tool is not too few; it is exactly what the server needs.
Completeness5/5
The search tool covers all aspects of the domain: it ranks results, supports multiple query types, and provides a structured fallback for zero matches. There are no obvious missing operations for a code search server.
Maintenance
ActivityMaintained
ResponsivenessNo issues