Ollqd——MCP客户端-服务器RAG系统
本地第一个RAG系统,将代码库和文档索引到 Qdrant 使用 奥拉玛 嵌入。揭露一切 主控程序 (模型上下文协议),因此AI助手可以通过工具调用搜索您的代码。
建筑
┌──────────────────────────────────────────────────────────────────┐
│ User Interface │
│ ┌─────────────┐ ┌─────────────────────────────────────────┐ │
│ │ ollqd-chat │ │ Claude Desktop / any MCP host │ │
│ │ (CLI / REPL) │ │ (connects to ollqd-server directly) │ │
│ └──────┬───────┘ └────────────────┬────────────────────────┘ │
└─────────┼──────────────────────────┼────────────────────────────┘
│ stdio JSON-RPC │ stdio JSON-RPC
┌─────────▼──────────────────────────▼────────────────────────────┐
│ Ollqd MCP Server (FastMCP) │
│ ┌───────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │
│ │index_codebase │ │index_documents │ │semantic_search │ │
│ │index docs │ │markdown/text/rst│ │embed query → Qdrant │ │
│ └───────┬───────┘ └────────┬────────┘ └──────────┬──────────┘ │
│ ┌───────┴──────┐ ┌───────┴────────┐ │ │
│ │list_collections│ │delete_collection│ │ │
│ └──────────────┘ └────────────────┘ │ │
└─────────┬──────────────────────────────────────────┼────────────┘
│ /api/embed │
┌─────────▼──────────┐ ┌──────────▼─────────┐
│ Ollama │ │ Qdrant │
│ nomic-embed-text │ │ cosine similarity │
│ + chat models │ │ payload indexes │
└────────────────────┘ └────────────────────┘运作原理
- 发现 --浏览代码库,按语言(40+扩展名)过滤,跳过锁文件/构建工件/供应商目录。
- 代码感知分块 --在自然代码边界(函数定义、类声明、impl块)拆分文件,而不是盲目地在令牌限制处切割。重叠的窗口可以保留上下文。
- 嵌入 --把大块食物送到奥利玛家
/api/embed分批。每个块都以文件路径+语言+行范围作为前缀,以更好地进行语义基础。
- 存储 --上传到Qdrant,带有完整的元数据有效载荷。有效载荷指数
file_path,language,以及content_hash启用过滤搜索和增量重新索引。
- RAG回路 --客户端使用附带的MCP工具向Ollama发送用户查询。Ollama决定什么时候打电话
semantic_search,从服务器获取结果,并将最终答案与代码引用进行合成。
设置
先决条件
- 奥拉玛 在本地运行,并拉取嵌入模型
- Qdrant 正在运行(推荐使用Docker)
- Python 3.10+
# Pull the embedding model
ollama pull nomic-embed-text
# Pull a chat model (any that supports tool-calling)
ollama pull qwen2.5:14b
# Start Qdrant (and optionally Ollama via Docker)
docker compose up -d安装
# With uv (recommended)
uv venv && source .venv/bin/activate
uv pip install -e ".[client,dev]"
# Or with pip
pip install -e ".[client,dev]"用法
启动MCP服务器(独立)
ollqd-server服务器使用JSON-RPC(MCP协议)通过stdio进行通信。它旨在由MCP客户端启动,而不是直接使用。
交互式RAG聊天
# Interactive REPL — ask questions about your codebase
ollqd-chat --interactive
# Single query
ollqd-chat "how does the auth middleware work?"
# Use a different chat model
ollqd-chat --interactive --model llama3.1
# Debug mode
ollqd-chat -v "find the database connection setup"REPL命令:
:quit/:q--出口:model--即时切换聊天模式
与Claude Desktop一起使用
添加到您的 claude_desktop_config.json:
{
"mcpServers": {
"ollqd": {
"command": "ollqd-server",
"args": []
}
}
}然后在Claude Desktop中,问以下问题:
- “将我的项目索引到/path/to/codebase”
- “搜索如何实现身份验证”
- “使用了哪些错误处理模式?”
- “列出所有索引集合”
MCP工具
| 工具 | 说明 |
|---|---|
index_codebase | 从目录中漫游+组块+嵌入+上传代码文件 |
index_documents | 分块+嵌入+追加销售文档文件(markdown、text、rst) |
semantic_search | 嵌入自然语言查询和搜索Qdrant |
list_collections | 列出所有Qdrant集合及其点数 |
delete_collection | 删除收藏(需要 confirm=true) |
配置
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
OLLAMA_URL | http://localhost:11434 基础 URL | |
QDRANT_URL | http://localhost:6333 | Qdrant REST URL |
OLLAMA_CHAT_MODEL | qwen2.5:14b | RAG的聊天模式 |
OLLAMA_EMBED_MODEL | nomic-embed-text | 嵌入模型 |
OLLAMA_TIMEOUT_S | 120 | 请求超时(秒) |
CHUNK_SIZE | 512 | 每个区块的近似令牌 |
CHUNK_OVERLAP | 64 | 块之间的重叠标记 |
MAX_TOOL_ROUNDS | 6 | 每个查询的最大工具调用轮次 |
ollqd.toml
[ollama]
host = "http://localhost:11434"
chat_model = "qwen2.5:14b"
embed_model = "nomic-embed-text"
timeout = 120
[qdrant]
host = "http://localhost:6333"
default_collection = "codebase"
[indexing]
chunk_size = 512
chunk_overlap = 64
max_file_size_kb = 512
[server]
name = "ollqd-rag-server"
transport = "stdio"
[client]
max_tool_rounds = 6项目结构
src/ollqd/
├── __init__.py
├── config.py # AppConfig dataclass + env var overrides
├── errors.py # Exception hierarchy
├── models.py # FileInfo, Chunk, SearchResult, IndexingStats
├── chunking.py # Code-aware + document chunking
├── discovery.py # File discovery (40+ languages)
├── embedder.py # OllamaEmbedder wrapping /api/embed
├── vectorstore.py # QdrantManager (upsert, search, incremental)
├── server/
│ └── main.py # FastMCP server with 5 tools
└── client/
├── mcp_bridge.py # MCP session over stdio
├── ollama_agent.py # Ollama chat with tool-calling
├── rag_loop.py # RAG loop runner
└── main.py # CLI entry point支持的语言
Python、Go、JavaScript、TypeScript、Rust、Java、Kotlin、Scala、C、C++、C#、Ruby、PHP、Swift、Lua、Shell、SQL、R、HTML、CSS、SCSS、YAML、TOML、JSON、Markdown、reStructuredText、Terraform、HCL、Dockerfile、Protobuf、GraphQL。
嵌入模型
任何支持Olama的型号 /api/embed 作品。推荐:
| 型号 | 尺寸 | 备注 |
|---|---|---|
nomic-embed-text | 768 | 质量和速度的良好平衡(默认) |
mxbai-embed-large | 1024 | 质量更高,速度更慢 |
all-minilm | 384 | 速度快,占地面积小 |
snowflake-arctic-embed | 1024 | 强大的代码理解能力 |
设计决策
为什么选择MCP? --模型上下文协议允许任何兼容的AI助手(Claude Desktop、自定义客户端、IDE扩展)使用ollqd的索引和搜索工具,而无需自定义集成代码。
为什么不找个保姆来帮忙砍树呢? --Tree sitter提供了完美的基于AST的拆分,但增加了每种语言的严重依赖性。启发式边界检测覆盖了约90%的无额外设置的情况。
为什么是确定性点ID? — md5(file_path::chunk_N) 意味着重新索引同一文件会覆盖现有点,而不是创建重复点。这使得增量模式可靠。
为什么要在块前加元数据? --当给定上下文时,嵌入模型会产生更好的向量。“文件:auth/middleware.go |语言:go |第45-82行”后面的代码会产生语义上更有意义的向量。
遗留脚本
v0.1中的独立脚本仍然可用:
# Bulk index (standalone, no MCP)
python codebase_indexer.py /path/to/project --collection myproject
# Search (standalone, no MCP)
python codebase_search.py "auth middleware" --interactive看 设计.md 完整的体系结构文档,包括图表、安全分析(STRIDE)和详细的API参考。
