mcp-server-bm25-code-search
This server provides a BM25 code search tool over an indexed codebase.
Search indexed code chunks by keyword using SQLite FTS5 BM25 ranking.
Query in Japanese/CJK, camelCase, or snake_case with automatic tokenization.
Choose OR mode for maximum recall or AND mode to require all query tokens.
Limit results with
top_k(1–100, default 5).Get file-path matches boosted 3.0x over file content matches.
Receive a structured zero-match fallback suggesting grep/glob when nothing matches.
Offers a Function Calling adapter for Hermes Agent to use the BM25 code search engine in non-MCP environments.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-server-bm25-code-searchsearch for getUserProfile implementation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-server-bm25-code-search
English | 日本語
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 onsqlite3(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 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 forgetUserProfile(camelCase) andsession_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 weightingbm25(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.gitignorecompliance usinggit ls-fileswith ultra-fast incremental updates (0.1–0.5s during standard editing) viagit diff/ HEAD hash tracking. The index database.bm25_index.dbis 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 togrep/globwhen zero results are found.
Related MCP server: lynx-mcp
📁 Directory Structure
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 (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
Cursor: Cursor Plugins
GitHub Copilot: Copilot Agent Plugins
ChatGPT & Codex: OpenAI Plugin Developers
Kiro: Kiro Powers
Hermes Agent: Hermes Portable Plugins
OpenClaw: OpenClaw Plugin Bundles
Grok Bot: Grok Bot Automations
NanoClaw: NanoClaw Templates
2. Running Search via CLI
python bm25_search/search.py "<search query>" --top-k 5 --format markdown --max-bytes 4000Key Options:
<query>: Search query (supports Japanese, CJK, camelCase, snake_case)--top-k: Maximum number of search results to return (default:5)--format: Output format,markdownorjson(default:markdown)--max-bytes: Maximum output bytes; safely truncated preserving multibyte characters (default:4000)--mode: Token conjunction mode,ORorAND(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 |
| Target project root directory to index and search |
|
| Path to SQLite FTS5 index DB file |
|
| Disable automatic index synchronization on tool calls | Disabled (auto-sync active) |
| 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--rootexplicitly will take precedence).
① Using uvx (uv / Python)
{
"mcpServers": {
"bm25-code-search": {
"command": "uvx",
"args": ["mcp-server-bm25-code-search"],
"alwaysAllow": ["search"]
}
}
}② Using npx (Node.js / npm)
{
"mcpServers": {
"bm25-code-search": {
"command": "npx",
"args": ["-y", "mcp-server-bm25-code-search"],
"alwaysAllow": ["search"]
}
}
}③ Using Local Python Directly
{
"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
{
"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:
## 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 does not natively support the Agent Plugins 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 toCLAUDE.mdor placing the skill in.claude/skills/bm25-search/SKILL.mdensures 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):
# 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 --stdioVerify 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):
{
"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:
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:
pytest tests/📄 Documentation
📚 References & Links
Agent Plugins Specification: Agent Plugins Specification (agentplugins/agent-plugins-spec) / agent-plugins.org
Agent Skills Specification: Agent Skills Specification
Paper: Wang et al., "BM25 Wins at Scale: Evaluating Agentic Search over Enterprise Corpora" (2026)
https://arxiv.org/abs/2607.26497Article: Hidetoshi Sudo (KnowledgeSense, Inc.), "Using BM25 to reduce Codex token consumption by 30%" (Zenn, 2026)
https://zenn.dev/knowledgesense/articles/9e55a3bb67729c
⚖️ License
This project is licensed under the MIT License.
Available Tools
1 toolsearchBM25 Code SearchA
Search the indexed codebase with a SQLite FTS5 BM25 ranker. Returns the best-matching code chunks, ranked with the filepath column boosted 3.0x over the body. Works for Japanese (CJK) and camelCase/snake_case queries. When nothing matches, returns a structured zero-match fallback suggesting grep/glob.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | How query tokens are combined. 'OR' maximises recall; 'AND' requires every token to hit. | OR |
| query | Yes | The search query. Japanese, camelCase and snake_case are all tokenised the same way the index was built. | |
| top_k | No | Maximum number of results to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavior disclosure. It transparently reveals the ranking boost (filepath 3.0x), the zero-match fallback structure, and special tokenization behaviors, which are non-obvious details. It could have explicitly stated read-only safety, but 'search' strongly implies it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each carrying distinct information: ranking mechanism, tokenization support, and fallback behavior. It is front-loaded with the verb and resource, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains what is returned (best-matching code chunks) and the fallback, but doesn't detail the chunk structure or exact return format. It covers the main behaviors thoroughly for a search tool, though a bit more output detail would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage for all three parameters, including query tokenization and mode semantics. The description adds minor context about ranking (filepath boost) but doesn't meaningfully extend parameter understanding beyond the schema, warranting the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches the indexed codebase using a SQLite FTS5 BM25 ranker, specifying the action, resource, and ranking method. It goes beyond a generic 'search' by noting the filepath boost and language tokenization, making the purpose unambiguous even without siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when to use the tool: codebase search with BM25 ranking, supporting CJK and camelCase/snake_case queries. It also mentions a fallback to grep/glob when no matches occur, implying alternative tools for exact/pattern search, though it doesn't explicitly state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.0.0- First observed
search
TDQS
Scored across 1 tool
With only one tool, there is no possibility of confusion or overlap between tools. The search tool has a clear, unique purpose.
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.
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.
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
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Search GitHub, npm, PyPI, StackOverflow, ArXiv from one MCP — built for coding agents.
Shared memory for coding agents. Stop re-explaining your codebase every session.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA local, SQLite-backed code index for Claude Code, exposed over MCP, enabling targeted code retrieval without external APIs.1MIT
- AlicenseAqualityAmaintenanceA 100% local MCP server for semantic and lexical search over your code, library docs, and PDFs, featuring hybrid BM25 and dense retrieval, syntax aware chunking, and an optional code knowledge graph. It also ships a Coral integration, so you can expose your code search as SQL and join it with live data, all without anything leaving your machine.8169Apache 2.0
- AlicenseAqualityCmaintenanceEnables AI coding agents to intelligently index and search codebases with sub-20ms retrieval, 8x memory compression, and cross-encoder reranking via MCP stdio.5MIT
- AlicenseNot gradedqualityAmaintenanceLocal-first code intelligence MCP server that enables coding agents to search code, inspect structure, read exact ranges, and explore Git history with explicit token budgets.23Apache 2.0