开放式代码搜索
opencodesearch 是一个具有模型上下文协议(MCP)服务器的异步Rust代码搜索系统。 它将大型存储库索引到矢量+关键字后端,并通过MCP工具提供搜索结果。
特性
- 完全异步运行时(
tokio) - 4个独立过程:
- 编排器(状态机+监督) - 背景故事 - MCP服务器进程 - git监视器进程
- 运行时代码中集成和使用的所需板条箱:
- opencodesearchparser - qdrant-client - ollama-rs - rmcp
- 混合检索:
- 语义搜索(Qdrant向量) - 关键字搜索(Quickwit HTTP+本地影子回退)
- MCP服务器与使用流式HTTP和stdio传输的MCP客户端兼容
建筑
编排器中的状态机:
SPINUP:负载config.jsonNORMAL:runingestor+mcp+watchdogUPDATE:保持watchdog,停止ingestor+mcp在更新窗口期间CLOSING:优雅地阻止所有孩子
更新流程:
- 看门狗跟踪自上次同步以来的git提交
- 当阈值(
commit_threshold)已达到:
- 发送 UPDATE_START 到编排器 - pull+计算更改/删除的文件 - 删除过时的文档 - 重新索引更改的文件 - 发送 UPDATE_END
需求
- 防锈工具链
- Docker+Docker组合
- 本地网络访问:
- 奥拉马(11434) - Qdrant(6333 HTTP, 6334 gRPC) - 机智(7280)
配置
config.json 架构:
{
"codebase": {
"directory_path": "/path/to/massive/repo",
"git_branch": "main",
"commit_threshold": 50,
"mcp_server_name": "My cool codebase",
"mcp_server_url": "http://localhost:9443",
"background_indexing_threads": 2
},
"ollama": {
"server_url": "http://localhost:11434",
"embedding_model": "qwen3-embedding:0.6b",
"context_size": 2000
},
"qdrant": {
"server_url": "http://localhost:6334",
"collection_name": "opencodesearch-code-chunks",
"api_key": null
},
"quickwit": {
"quickwit_url": "http://localhost:7280",
"quickwit_index_id": "opencodesearch-code-chunks"
}
}重要提示:
qdrant.server_url应以gRPC终结点端口为目标(6334)forqdrant-client.quickwit.quickwit_url应该以HTTP为目标(7280).
启动后端服务
运行所有本地依赖项:
docker compose up -d检查容器:
docker ps运行系统
1) 编排器模式(推荐)
启动并监督所有子进程。
cargo run -- orchestrator --config config.json2) 单个流程模式
您可以直接运行每个进程进行调试。
英格斯托:
cargo run -- ingestor --config config.jsonMCP服务器:
cargo run -- mcp --config config.json通过stdio的MCP服务器(用于本地MCP客户端):
cargo run -- mcp-stdio --config config.json看门狗(需要编排器IPC环境):
OPENCODESEARCH_IPC_SOCKET=/tmp/opencodesearch.sock cargo run -- watchdog --config config.jsonMCP服务器使用情况
MCP服务器支持:
- 通过流式传输HTTP
cargo run -- mcp --config config.json - stdio通过
cargo run -- mcp-stdio --config config.json
已实施的MCP工具:
search_code
- 输入: - query: string - limit?: number (默认值8,最大值50) - 输出(结构化JSON):对象数组 - snippet - path - start_line - end_line - score - source
工具输入示例
{
"query": "which function changes obj variable",
"limit": 5
}结果形状
{
"hits": [
{
"path": "/repo/module.py",
"snippet": "def mutate(obj): ...",
"start_line": 10,
"end_line": 22,
"score": 0.92,
"source": "qdrant"
}
]
}与MCP客户端一起使用
此服务器支持以下两种功能:
- 可流式传输HTTP(
cargo run -- mcp --config config.json) - 本地stdio(
cargo run -- mcp-stdio --config config.json)
OpenAI 代码专家
Codex支持stdio和可流式传输的HTTP MCP服务器。
标准(CLI):
codex mcp add opencodesearch -- \
cargo run --quiet --manifest-path /home/brosnan/opencodesearch/Cargo.toml -- \
mcp-stdio --config /home/brosnan/opencodesearch/config.json远程HTTP(~/.codex/config.toml 或 .codex/config.toml):
[mcp_servers.opencodesearch]
url = "http://localhost:9443/"然后验证:
codex mcp list开源代码
OpenCode配置使用 mcp 部分在 opencode.json (或 opencode.jsonc).
远程HTTP:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"opencodesearch": {
"type": "remote",
"url": "http://localhost:9443/",
"enabled": true
}
}
}本地标准:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"opencodesearch": {
"type": "local",
"command": [
"cargo",
"run",
"--quiet",
"--manifest-path",
"/home/brosnan/opencodesearch/Cargo.toml",
"--",
"mcp-stdio",
"--config",
"/home/brosnan/opencodesearch/config.json"
],
"enabled": true
}
}
}克劳德代码
Claude Code支持HTTP、SSE和stdio MCP传输。
远程HTTP:
claude mcp add --transport http opencodesearch http://localhost:9443/本地标准:
claude mcp add --transport stdio opencodesearch -- \
cargo run --quiet --manifest-path /home/brosnan/opencodesearch/Cargo.toml -- \
mcp-stdio --config /home/brosnan/opencodesearch/config.json然后验证:
claude mcp listTLS/HTTPS注释
- 默认本地配置使用
http://localhost:9443. - 对于
https://...,提供您的MCP客户端信任的证书。 - TLS证书和密钥默认值:
- certs/localhost-cert.pem - certs/localhost-key.pem
- 使用以下内容覆盖TLS文件路径:
- OPENCODESEARCH_TLS_CERT_PATH - OPENCODESEARCH_TLS_KEY_PATH
- 特别是对于Codex,您可以提供一个自定义CA包
CODEX_CA_CERTIFICATE.
参考文献
- 食品法典委员会MCP文件:https://developers.openai.com/codex/mcp
- OpenCode MCP文档:https://opencode.ai/docs/mcp-servers/
- 克劳德代码MCP文档:https://code.claude.com/docs/en/mcp
快速卷曲测试
使用附带的脚本:
./test_mcp_curl.sh可选:
MCP_URL=https://localhost:9443/ MCP_INSECURE=1 ./test_mcp_curl.sh
该脚本执行所需的MCP HTTP握手步骤:
initialize- 提取
mcp-session-id从响应标头 - 发送
notifications/initialized与相同mcp-session-id - 呼叫
tools/call为了search_code
手动卷曲顺序
初始化并捕获会话id:
curl -sS -D headers.txt http://localhost:9443/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl-test","version":"1.0"}}}'发送初始化通知:
SESSION_ID="$(awk 'tolower($1)=="mcp-session-id:"{print $2}' headers.txt | tr -d '\r' | tail -n 1)"
curl -sS http://localhost:9443/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "mcp-session-id: ${SESSION_ID}" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'调用MCP工具:
curl -N http://localhost:9443/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "mcp-session-id: ${SESSION_ID}" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_code","arguments":{"query":"which function mutates obj","limit":5}}}'Rust API文档
板条箱公开了可重用的模块,用于嵌入、索引、MCP服务和过程控制。
模块
config:解析类型化的应用程序配置(AppConfig)chunking:将源文件解析/拆分为块(chunk_file)indexing:索引运行时(IndexingRuntime)qdrant_store:矢量存储+语义查询(QdrantStore)quickwit:关键字存储/查询(QuickwitStore)mcp:MCP服务器类型(OpenCodeSearchMcpServer)watchdog:git更新监视器(WatchdogProcess)orchestrator:多流程主管(Orchestrator)
最小Rust索引示例
use opencodesearch::config::AppConfig;
use opencodesearch::indexing::IndexingRuntime;
#[tokio::main]
async fn main() -> anyhow::Result {
let config = AppConfig::from_path("config.json")?;
let runtime = IndexingRuntime::from_config(config)?;
runtime.index_entire_codebase().await?;
Ok(())
}最小Rust语义搜索示例
use opencodesearch::config::AppConfig;
use opencodesearch::indexing::IndexingRuntime;
#[tokio::main]
async fn main() -> anyhow::Result {
let config = AppConfig::from_path("config.json")?;
let runtime = IndexingRuntime::from_config(config)?;
let query_vec = runtime.embed_query("where is object mutated") .await?;
let hits = runtime.qdrant.semantic_search(query_vec, 5).await?;
for hit in hits {
println!("{}:{}-{}", hit.path, hit.start_line, hit.end_line);
}
Ok(())
}最小化Rust MCP服务器嵌入
use opencodesearch::config::AppConfig;
use opencodesearch::indexing::IndexingRuntime;
use opencodesearch::mcp::OpenCodeSearchMcpServer;
#[tokio::main]
async fn main() -> anyhow::Result {
let config = AppConfig::from_path("config.json")?;
let runtime = IndexingRuntime::from_config(config)?;
OpenCodeSearchMcpServer::new(runtime)
.run_streamable_http("http://localhost:9443")
.await
}测试
标准测试
cargo test活容器集成测试
需要运行Docker服务和本地git:
cargo test -- --ignored当前忽略的集成测试验证:
- Ollama连接
- Quickwit+Qdrant连接
- 生成的Python项目上的完整索引流
- 通过非精确查询短语的MCP搜索路径进行检索
- 看门狗阈值行为的100次提交重构场景
故障排除
- Quickwit健康端点:使用
http://localhost:7280/health/livez - 如果嵌入失败,请确认Ollama型号的可用性:
- qwen3-embedding:0.6b
- Qdrant客户端需要gRPC端口(
6334)在配置中 - 如果集成测试在启动竞赛中失败,请在短暂的容器预热后重新运行
