mcp服务器混合搜索
 
用于混合文档搜索的MCP服务器(Qdrant矢量搜索+Tantivy BM25),具有SSE传输功能。
建筑
- MCP服务器 (
mcp-server-hybrid-search):端口7070上的基于SSE的MCP服务器提供search和get工具 - 命令行界面 (
ragctl):将md/txt/pdf/xlsx/docx文件导入Qdrant和Tantivy的文档索引器 - Qdrant:用于语义搜索的矢量数据库
- 突进:BM25排名全文搜索引擎
先决条件
- 防锈工具链(1.75+)
- Docker(适用于Qdrant)
- OpenAI API密钥(用于嵌入,不需要
--features local-embed) - python
markitdown(PDF/Excel/Word支持):pip install markitdown
快速开始
1.启动Qdrant
docker compose up -d2.设置环境
cp .env.example .env
# Edit .env and set your OPENAI_API_KEY3.建造
# Default build (OpenAI embeddings, whitespace-based BM25 tokenizer)
cargo build --release
# With Japanese tokenizer for BM25 full-text search
cargo build --release --features ja
# With local embedding (no OpenAI API key needed)
cargo build --release --features local-embed
# Combine features as needed
cargo build --release --features "ja,local-embed"4.初始化
创建默认源目录和数据目录:
./target/release/ragctl init这将创建:
~/.local/share/mcp-hybrid-search/--默认文档源目录~/.mcp-hybrid-search/tantivy/--Tantivy索引目录
5.放置文件
将文档复制或符号链接到默认源目录:
cp ~/my-docs/*.md ~/.local/share/mcp-hybrid-search/
cp ~/reports/*.pdf ~/.local/share/mcp-hybrid-search/
cp ~/data/*.xlsx ~/.local/share/mcp-hybrid-search/6.摄入文件
# Use default source directory (~/.local/share/mcp-hybrid-search)
./target/release/ragctl ingest
# Or specify source directories explicitly
./target/release/ragctl ingest \
--source /path/to/your/docs \
--source /path/to/more/docs7.启动MCP服务器
./target/release/mcp-server-hybrid-search服务器将监听 http://localhost:7070.
注: 使用时embedding_provider = "openai"(默认),服务器需要OPENAI_API_KEY因为每个搜索查询都通过OpenAI API转换为嵌入向量。确保.env文件存在于工作目录中,或者在启动服务器之前设置环境变量。
8.从克劳德代码连接
添加到您的Claude Code MCP配置中:
{
"mcpServers": {
"hybrid-search": {
"url": "http://localhost:7070/sse"
}
}
}CLI使用情况
初始化目录
ragctl init创建默认源目录(~/.local/share/mcp-hybrid-search/)以及Tantivy索引目录。首次使用前运行一次。
摄入文件
# Default source directory
ragctl ingest
# Custom source directories
ragctl ingest \
--source /path/to/docs \
--source /path/to/converted \
--qdrant http://localhost:6334 \
--index-dir ~/.mcp-hybrid-search/tantivy \
--chunk-size 1000 \
--chunk-overlap 200支持的文件类型:
- 直接:
.md,.txt - 通过markitdown:
.pdf,.xlsx,.xls,.docx,.pptx,.csv,.html
检查状态
ragctl status导出数据
将所有索引块(带嵌入)导出到JSON文件中,以便与其他工程师共享:
ragctl export --output ./exported-data.json导出的文件包含所有块有效载荷及其嵌入向量。其他工程师可以在不需要OpenAI API密钥的情况下导入。
导入数据
将以前导出的数据导入Qdrant和Tantivy:
ragctl import --input ./exported-data.json这将从导出文件中填充Qdrant(向量)和Tantivy(BM25索引)。
搜索(调试)
ragctl search --query "your search query" --top-k 10多项目支持
使用 --project 标记以隔离每个项目的集合。指定后,Qdrant集合名称和Tantivy索引目录将被覆盖:
# Ingest into project "my-proj"
ragctl --project my-proj ingest --source /path/to/docs
# Check status of project "my-proj"
ragctl --project my-proj status
# Start MCP server for project "my-proj"
mcp-server-hybrid-search --project my-proj当 --project my-proj 已指定:
- Qdrant集合名称→
"my-proj" - 坦蒂维索引目录→
~/.mcp-hybrid-search/tantivy/my-proj/
没有 --project,默认值来自 config.toml 使用(向后兼容)。
列出项目
ragctl list-projects列出所有Qdrant集合及其点数。
MCP工具
搜索
使用向量相似度+BM25排名和RRF融合在索引文档之间进行混合搜索。
输入:
query(字符串,必填):搜索查询top_k(数字,可选):结果数量(默认值:10)filters(对象,可选):
- source_type (string):按文件类型筛选(md/txt/pdf/xlsx) - path_prefix (字符串):按路径前缀筛选
得到
检索文档块的完整内容。
输入:
chunk_id(字符串,必填):块标识符
get_project_info
获取有关当前项目配置和索引状态的信息。
输入: 无需。
输出: JSON对象:
collection_name(string):当前Qdrant集合名称document_count(number):索引文档块的数量tantivy_index_dir(string):Tantivy索引目录路径embedding_provider(string):嵌入提供程序名称embedding_model(string):嵌入模型名称embedding_dimension(数字):嵌入向量维度
配置
编辑 config.toml:
| 密钥 | 默认值 | 描述 |
|---|---|---|
qdrant_url | http://localhost:6334 | Qdrant gRPC URL |
collection_name | docs | Qdrant集合名称 |
tantivy_index_dir | ~/.mcp-hybrid-search/tantivy | Tantivy索引目录 |
chunk_size | 1000 | 字符块大小 |
chunk_overlap | 200 | 字符中的块重叠 |
listen_port | 7070 | MCP服务器端口 |
embedding_provider | openai | 嵌入提供程序(见下文) |
embedding_model | text-embedding-3-small | OpenAI嵌入模型 |
embedding_dimension | 1536 | 嵌入向量维度 |
tokenizer | default | BM25标记器(见下文) |
默认源目录: ~/.local/share/mcp-hybrid-search/
分词器
这 tokenizer config控制Tantivy如何分割BM25全文搜索的文本。默认的标记器是基于空格的,这对英语很有效,但对CJK语言(日语、韩语、中文)效果不佳,因为这些语言中的单词没有用空格分隔。
| 值 | 特征标志 | 字典 |
|---|---|---|
default | *(无)* | 基于空白(内置) |
japanese | --features ja | ipad |
korean | --features ko | ko-dic |
chinese | --features zh | CC-CEDICT |
语言词典在构建时通过以下方式嵌入二进制文件中 林德拉。只启用您需要的功能——每个功能都会为二进制文件增加约50MB。
注: 更改标记器需要重建Tantivy索引。跑ragctl reset然后ragctl ingest在切换标记器之后。
嵌入提供者
| 提供程序 | 功能标志 | 模型 | 维度 | 需要API键 |
|---|---|---|---|---|
openai | *(无)* | text-embedding-3-small | 1536 | 是(OPENAI_API_KEY) |
local | --features local-embed | intfloat/multilingual-e5-base | 768 | 否 |
local | --features local-embed | intfloat/multilingual-e5-small | 384 | 否 |
本地提供商使用 禁食 使用ONNX运行时。模型在首次使用时会自动下载并缓存。
要使用本地嵌入,请执行以下操作:
# config.toml — multilingual-e5-base (recommended)
embedding_provider = "local"
embedding_model = "multilingual-e5-base"
embedding_dimension = 768# config.toml — multilingual-e5-small (lighter, faster)
embedding_provider = "local"
embedding_model = "multilingual-e5-small"
embedding_dimension = 384cargo build --release --features local-embed注: 切换嵌入提供程序会更改向量维度。跑ragctl reset然后ragctl ingest切换后。
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
OPENAI_API_KEY | 是(当 embedding_provider = "openai") | 用于在摄取时间(CLI)和搜索时间(服务器)嵌入生成。不需要 local-embed. |
OPENAI_API_BASE | 否 | 自定义OpenAI兼容的API终结点(默认值: https://api.openai.com/v1) |
重要提示: 这OPENAI_API_KEY不仅在以下期间需要ragctl ingest而且在运行MCP服务器时,因为每个搜索查询都是通过OpenAI API实时嵌入的。如果你想避免这种依赖性,请使用本地嵌入(--features local-embed).
搜索算法
- 使用配置的嵌入提供程序嵌入查询
- Qdrant向量搜索返回前30名候选者
- Tantivy BM25搜索返回前30名候选人
- 使用k=60的互易秩融合(RRF)合并结果
- 返回前N个结果(默认值10)
