codebase-qa MCP server
Commit Nov 13, 2026Enables AI clients to search, read, and analyze GitHub repositories using local embeddings and version-controlled code snapshots.
Also known as xyma2003/codebase-qa
- Stars
- 0
- Tools
- —
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 13, 2026
- License
- MIT
What is codebase-qa MCP?
codebase-qa enables AI clients to search, read, and analyze GitHub repositories using local embeddings and version-controlled code snapshots.
Summary generated from the project's README
About codebase-qa MCP server
Codebase-qa allows developers to connect AI clients to GitHub repositories for deep code analysis. It works by creating version-controlled snapshots from specific Git commits, ensuring that all searches, file reads, and historical Q&A sessions remain consistent with a single code version. This prevents the confusion that occurs when an AI references outdated or uncommitted local files.
Users set up the server locally using a Python virtual environment and configure an LLM via an OpenAI-compatible API key, such as SiliconFlow. The system uses local all-MiniLM-L6-v2 embeddings and ChromaDB for efficient retrieval. It provides specialized tools for finding Python symbols, analyzing file dependencies, and generating structured modification plans. By using fixed commit SHAs and SHA256 file verification, the server ensures that every answer can be traced back to exact lines of source code.
Written from the project's README. Every use case is checked against a quote from it.
Configuration
OPENAI_API_BASEOPENAI_API_KEYOPENAI_MODEL
| Name | Description | |
|---|---|---|
| OPENAI_API_BASE | — | |
| OPENAI_API_KEY | — | |
| OPENAI_MODEL | — |
README
View on GitHubCodebase Q&A
输入 GitHub 仓库地址,检索代码并提问。分析使用固定的 Git 代码版本,搜索、文件读取和历史问答保持在同一版本。
安全边界与安全计划单独列明已实现和待验证项。源码与向量入口会拒绝敏感文件和检测到的凭据,旧数据也重新检查;当前为本地单人产品,功能测试不代表 Prompt 攻击防御效果已经通过。
| 能力 | 实现与可检查结果 |
|---|---|
| Agent 工具调用 | Pydantic AI,六个源码工具,结构化修改规划,实际调用事件 |
| 代码检索 | ChromaDB、Sentence Transformers、Python AST,显式可选固定 RRF 融合及对照记录 |
| 来源核对 | Git 固定快照、文件 SHA256、真实行范围、回答引用回查 |
| 多轮与运行控制 | 原生模型历史、SQLite 事务保存、历史恢复、逐轮限制及用量 |
| 评测闭环 | 固定 16 题 / 19 轮、JSONL 判分、SDK 输入输出归档、独立人工评审与报告 |
| 接入 | Streamlit 问答与评审页面、九个 MCP 工具、无密钥自动测试 |

固定开发评测集与判分规则:16 题、19 轮,覆盖项目理解、实现定位、修改规划和无答案问题。本地运行归档、独立评审导入与报告均已跑通,参考标注与模型输入分开。本次评分样例为合成记录,真实模型评测和实际人工语义评审尚未进行。
当前功能
- 导入公开 GitHub 仓库,Python 按函数和类解析,其他支持的文本按窗口分块。
- 使用本地
all-MiniLM-L6-v2嵌入和 ChromaDB 检索代码。 - 通过 Agent 搜索代码、列出文件、按行读取;回答需要配置模型接口。
- 按文本、路径和 Python 函数或类名查找当前快照,覆盖导入语句和模块配置;支持路径过滤、大小写选择和分页。
- 查看静态项目概览:目录文件数、Python 模块定义与导入、配置文件、README 摘录,以及可回到原文的入口线索。
- 通过 Agent/MCP 双向定位 Python 导入候选,保留相对导入、别名、条件/函数上下文及未确定项。
- 从 Git 已提交内容建立快照,记录完整 Commit SHA 和文件 SHA256;不会把工作区的未提交文件混入快照。
- 更新索引时先构建、回读验证,再发布新版本。失败保留旧索引,旧版本可以重新选择。
- 历史问答按仓库和代码版本保存,避免直接复用其他版本的答案。
- 连续追问会传入前面的原生消息,包含问题、回答和工具结果;对话绑定仓库、Commit 和索引,可点击“新建对话”重新开始。
- 选择“修改规划”,输出当前实现、涉及文件、修改顺序、验证方法和待确认项,并检查源码引用、文件路径及步骤覆盖。
- 版本化问答使用本次工具读取生成的引用编号,核对原文后生成固定 Commit 的源码链接;页面可展开查看行号和原文。
- 提供 Streamlit 页面和 MCP 接口。
真实聊天模型问答仍待 SiliconFlow 密钥。环境、索引、MCP、页面及版本管理的验证范围见实施进度,尚未报告回答准确率。
安装与配置
本机已验证 Python 3.12,项目使用独立虚拟环境:
git clone https://github.com/xyma2003/codebase-qa.git
cd codebase-qa
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
复现本机原始环境时,使用阶段零依赖锁和运行说明。安全展示用的 markdown-it-py 补为直接依赖,版本仍与原环境一致,没有升级现有环境。
项目 .env 使用用户已选择的接口:
OPENAI_API_KEY=your-siliconflow-key
OPENAI_API_BASE=https://api.siliconflow.cn/v1
OPENAI_MODEL=Qwen/Qwen3-32B
.env 被 Git 忽略。原有 Anthropic 接口也保留在 config.py。模型和检索、记忆阈值保持原值;版本化问答新增引用格式指令,要求使用工具提供的编号。
streamlit run app.py
首次索引会下载原有的本地嵌入模型。
使用
- 输入
https://github.com/owner/repo,点击“克隆并索引”。 - 导入成功后,在“代码版本”中查看当前 Commit,并可选择已成功索引的旧版本。
- “更新索引”抓取远端默认分支的新提交。同一提交已索引时直接复用。
- 配置模型后,可以提问实现位置、执行流程或修改思路,并核对代码行号。
- 需要修改方案时,在“任务”中选择“修改规划”,输入需求;切回“问答”可以继续追问同一方案。
- 在侧栏“历史对话”选择已保存会话,恢复问题、回答、源码引用与工具记录;列表仅显示当前仓库、Commit 和索引下的完整会话。
导入后可点击“查看项目概览”,不需要聊天模型密钥。概览展示选定快照中的事实:目录、Python 模块、配置文件、README 原文,以及 Python 顶层启动判断、__main__.py 和 Streamlit 页面配置调用。入口线索可展开查看源码,也可打开固定 Commit 的链接;它们不证明对应程序已成功运行。用途与模块职责的分析说明仍需模型及后续验证。
概览文件数来自排除依赖、构建目录后的快照清单,包含未进入向量索引的文件,因此可能与“已索引文件数”不同。切换仓库或版本会清除旧概览。
当前导入和刷新针对远端默认分支;选择旧版本使用已索引的完整 SHA。任意分支选择仍在后续范围。
连续追问会使用同一会话前面的模型消息,工具调用和返回结果也会传入。切换仓库、代码版本或索引集合,以及点击“新建对话”,会清空当前显示的对话并开始独立上下文。请求失败保留已完成轮次,不自动重试。
对话原生消息和已核对的回答保存在 chroma_db/conversations.sqlite3,每个完整轮次一次写入。同一对话内,工具发出的引用编号连续递增;追问仍需重新读取源码,旧编号不会自动成为本轮证据。追问不写入独立问答缓存,原质量评分和阈值不变。
本版保存完整上下文,尚未压缩长对话。重新打开或刷新页面后,选择相同仓库与代码版本,再从侧栏“历史对话”继续;引用编号和原生工具消息随原会话保留。新建对话会清空当前显示,不删除已保存历史。Python 调用方可用 create_conversation 创建编号,并在 ask / ask_stream 传入 conversation_id 继续已保存的会话。MCP 客户端仍自行管理模型对话。页面完整生成回答后安全渲染,工具过程仍实时展示。
工具执行期间可看到实际工具名、参数、耗时和返回长度;完成后保存在回答的“工具调用”展开区。这里的“已返回”只说明工具返回了结果,不代表内容正确或测试通过;修改规划中的命令也不会执行。旧会话没有记录过的工具耗时保持缺失,不补造历史数据。
“运行设置”可关闭历史答案缓存、选择实验融合检索,并收紧每轮请求、工具、总 Token、超时和问题与历史字符上限。即使不开启自定义限制,也有服务端 50 次请求、50 次工具、300 秒等待及 1 MiB 字节上限,用户不能关闭或调高。失败不追加半轮历史;超限拒绝,不截断或总结已有对话。每个成功回答的“运行记录”保存本轮设置、生效上限、实际 SDK 请求数、工具数、用量和耗时。
Python 接口可传入 policy=RunPolicy(request_limit=5, tool_calls_limit=10, timeout_seconds=60.0) 和 use_answer_cache=False,类型定义见 agent/runtime.py。SDK 请求数不等于底层 HTTP 重试次数;Token 上限按模型响应报告检查,可能在单次响应后超过阈值,不能当作严格账单上限。输入字符限制不含系统指令、工具定义和本轮新工具结果;超时是异步取消等待,不是目标代码执行沙箱。缓存开关同时控制读取和保存,原规则评分未调参,回答质量仍待真实评测。
修改规划使用结构化输出。修改或删除已有文件必须引用本文件的源码;新增文件引用已有接入位置,路径不能与快照已有内容冲突。规划会检查实施步骤是否覆盖列出的文件,问题显示在“规划检查”中。文件和引用核对不代表方案逻辑正确,验证命令是待执行建议。
Python 接口传入 mode="plan" 生成规划,默认 mode="qa" 保持普通问答。ask_stream 的 on_result 回调可取得 CheckedAnswer.plan;规划随会话轮次保存,不写入独立问答缓存。生成规划不会改动目标文件或执行命令,结构化格式不合法时直接报错,不自动重试。MCP 工具仍供外部客户端自行组织规划流程。
版本与索引
GitHub 仓库 → 获取 Git 提交 → 源码快照和文件清单
↓
解析与新索引构建
↓
回读验证 → 发布版本
↓
同版本检索、源码和问答记录
快照保存在 repos/.snapshots/,来自 Git 对象而非可变工作区。符号链接和子模块不会展开。文件读取检查路径范围和快照内容,快照被改动时拒绝把它当作原版本读取。这些检查不等同于操作系统沙箱。
向量和版本元数据保存在 chroma_db/。每个已完成版本使用独立集合,SQLite 保存可用版本及当前发布位置;构建失败不会先删除旧集合。原有未版本化索引只有在全部代码内容和嵌入配置匹配时,才复用其向量到新集合,原集合保持不变。
历史问答按仓库和 Commit 隔离。原规则评分只决定是否形成待审核候选,经过人工批准及源码回读后才可复用;不会训练模型,批准也不能替代真实质量评测。
版本化问答另外要求有可核对的引用,且引用没有检查错误,才允许保存。工具为实际读到的完整源码行生成 [S1] 等编号;回答生成后再次检查快照、文件校验值、行号和原文。未知编号、缺少引用或源码被改动时,页面会在“源码引用”中列出问题。缓存中的旧回答仅作参考,必须重新读取源码才能获得本次编号。
检查只覆盖这些引用编号的位置和原文,不证明回答结论正确,也不把正文中自由书写的文件名或其他链接自动算作已核对引用。
工具
Agent 提供六个工具:
| 工具 | 功能 |
|---|---|
get_file_dependencies(file_path, direction="outgoing", source_root="", limit=20, offset=0) |
查导入候选或可能引用该文件的导入位置 |
get_repo_overview() |
查看当前快照的静态目录、Python 模块、README 和入口线索 |
find_code(query, mode="text", path_filter="", case_sensitive=False, limit=20, offset=0) |
按文本、路径或 Python 定义定位当前快照 |
search_code(query) |
在所选版本的索引中检索代码 |
list_repo_files(pattern="") |
列出所选版本已索引的文件 |
read_file(file_path, start_line=1, end_line=None) |
返回真实行号;首尾行均包含在内 |
读取保留单次 8000 字符内容上限,可用后续行范围续读。绝对路径、..、符号链接、Git 元数据及二进制内容会被拒绝。单行超限时明确标记部分显示。
find_code 的三种模式:
| 模式 | 查找范围与示例 |
|---|---|
text |
逐行查找字面文本,如 OPENAI_MODEL =、os.getenv(;每行只返回一条 |
path |
按文件路径子串定位,如 config.py、indexer/ |
symbol |
Python 函数、异步函数及类定义,支持 Class.method 和嵌套定义名 |
query 和 path_filter 都是字面子串,不解释正则或通配符。默认忽略大小写;limit 为 1–50,offset 从 0 开始,按 next_offset 继续分页。结果绑定 Commit,文本和符号查找会核对文件 SHA256;路径模式读取快照文件清单。查找预览是定位线索,仍需 read_file 获取可核对的引用编号。
Python 的 ask / ask_stream 可显式传入 retrieval_strategy="hybrid",MCP 的 search_code 也支持该参数及 use_answer_cache=False。默认仍为原向量方式 semantic。实验融合按代码名称补充字面定位后采用固定 RRF 排序,不引入新模型。固定开发集的部分证据命中从 1/47 到 4/47,完整覆盖均为 1/47;没有测得回答质量提升,见固定检索对照。
查找仅处理支持的扩展名,跳过依赖、构建等目录。单个文件超过 1 MiB、含二进制内容,或 Python 定义无法解析时会计入 skipped_count;skipped_examples 最多列出 10 个例子。单次最多检查 2000 个候选文件、读取 10 MiB 源码,触及上限会返回 scan_limited=True,可缩小 path_filter 后查找。预览最多 240 字符,截短时返回 preview_truncated=True。
get_file_dependencies 的 outgoing 返回文件中的导入引用,incoming 返回可能指向该文件的引用。file_path 始终是仓库相对路径;source_root 默认仓库根目录,src 布局需要明确传入 source_root="src"。查找不会读取当前解释器的 sys.path 或执行目标模块。
每个导入名称或识别到的动态调用计一条引用。结果提供候选文件、源码行号和原文;属性/子模块歧义、通配符、重导出成员及动态加载保留为未确定信息,不当作完整运行关系。unresolved_count 统计当前检查范围内的未完整定位引用,不是目标文件的缺失依赖数。module_not_located 只表示未在指定源目录找到支持的 .py 文件。
条数为 1–50,按 next_offset 分页。扫描沿用单文件 1 MiB、总源码 10 MiB、2000 个候选文件的上限,跳过与受限状态单独返回。单条自动原文最多 1000 字符,超出时 evidence_unavailable=True,可再用 read_file 定位需要的行。Agent 仍需读取取得本次引用编号。
MCP 另提供版本选择、查询和原文校验,共九个工具:
| 工具 | 功能 |
|---|---|
set_repo(repo_url, refresh=False, commit_sha=None) |
默认仅选择已就绪仓库及 SHA;网络导入由进程启动者单独开启 |
list_repo_versions() |
列出当前仓库可用版本 |
get_file_dependencies(file_path, direction="outgoing", source_root="", limit=20, offset=0) |
与 Agent 共用导入候选定位,返回原文及固定版本链接 |
get_repo_overview() |
返回静态概览及入口的源码原文、行号和固定版本链接 |
find_code(query, mode="text", path_filter="", case_sensitive=False, limit=20, offset=0) |
与 Agent 共用快照查找,返回定位结果及扫描范围信息 |
search_code(query) |
检索所选版本 |
list_repo_files(pattern="") |
列出所选版本文件 |
read_file(file_path, start_line=1, end_line=None) |
读取所选版本源码 |
verify_source_citation(file_path, start_line, end_line, source_text, commit_sha) |
核对指定完整 SHA、行号及逐行原文,返回固定版本链接 |
refresh=True 和 commit_sha 不能同时使用。选择失败会清空 MCP 当前选择,后续工具不会继续查询另一个仓库。
MCP 默认不联网导入或刷新。先在本地页面导入,再用 set_repo 选择已有版本。确需由 MCP 导入时,启动者在进程环境显式设置 CODEBASE_QA_MCP_ALLOW_IMPORT=1;模型工具不能修改该权限。源码工具仍只读,默认使用本地 stdio,每个客户端单独启动进程。不能把本服务直接当作公网多租户接口。
MCP 搜索把向量内容作为定位线索,返回前读取所选 Commit 的实际源码,拒绝跨版本结果;九个工具统一检查参数/返回字节数及凭据,错误脱敏。外部 MCP 客户端负责其自身模型权限及安全展示;本项目网页的 Markdown 限制不会自动保护其他客户端。
verify_source_citation 的 source_text 使用不带行号的原文,不包含范围之外的结尾换行。范围首尾均包含;越界、超过 8000 字符读取上限或原文不一致时拒绝通过,不模糊匹配。
MCP 客户端配置示例:
{
"mcpServers": {
"codebase-qa": {
"command": "/absolute/path/to/codebase-qa/.venv/bin/python",
"args": ["/absolute/path/to/codebase-qa/mcp_server.py"]
}
}
}
检查与开发
.venv/bin/python -m unittest discover -s tests -v
GitHub Actions 在推送 main 和 PR 时执行离线检查:uv 0.12.3 使用原已记录依赖及 SHA256 安装、核对固定标注、运行全量测试、独立回读已发布接口模拟归档,并保留检查文件。运行器为 macOS 15 arm64,Python 版本保留为 3.12.13;不配置聊天模型密钥,测试使用本地模型或内存传输及临时向量库,关闭 Hugging Face 在线下载。工作流中的 Actions 以完整 Commit 固定。安装依赖仍需网络,测试成功也不等于真实回答质量通过。
按行读取验收与版本管理验收分别保存记录。真实存储检查脚本为 scripts/check_repository_versions.py,新运行使用新的 --output 文件,避免覆盖已保存的证据。
源码引用验收记录本地框架工具调用、MCP、引用检查和页面样例。scripts/check_citations.py 不调用真实聊天模型,新运行也必须使用新的 --output 文件。
源码查找验收记录 70 项测试、真实快照查找、MCP 和本地模拟模型流程。scripts/check_code_search.py 使用已保存的快照,不更新索引;复查时指定新的 --output 文件。
静态概览验收记录 87 项测试、真实快照事实、MCP 和浏览器检查。scripts/check_overview.py 不调用真实模型、不更新索引,复查也需指定新输出文件。
跨文件依赖验收记录 100 项测试、双向定位、MCP 和本地模拟模型流程。scripts/check_dependencies.py 不更新索引;复查时指定新的 --output 文件。
每个功能点验收后独立提交,直接 push 到 main,保留逐项回滚的提交记录。阶段零原版检查点是 3aee328,按行读取检查点是 5a6b945;需要补原版真实模型基线时,应检出原版代码,不把后续实现的结果记作原版结果。
原集合保留,因此当前已有的阶段零索引仍可供旧代码使用。旧代码不会自动识别新增的版本索引格式;回滚代码不会删除这些新数据。
回答展示通过 Markdown AST 去除活动图片、原始 HTML 和未经核对的链接,保留代码、列表、表格及源码引用。问题、原生历史、模型输出和工具参数在传递前检查凭据;页面和 MCP 日志、评测错误档案进行脱敏。markdown-it-py==4.2.0 原已安装,本次补为直接依赖,没有升级环境。安全检查记录见 输出边界。
历史答案缓存先保存为待审核候选。侧栏进入“历史答案审核”,核对问题、回答和源码后主动批准或撤销。Agent 没有审核工具;复用前重新检查版本、内容绑定和原文。旧缓存缺少审核或依据时不返回,原记录保留。原质量评分只决定是否形成候选,不再直接决定可复用。详见缓存安全验收。
13 个固定攻击样例覆盖不可信上下文、凭据访问、越权、缓存批准、伪造引用、展示外传、MCP 和工具洪泛;进入 CI。scripts/check_prompt_attacks.py --output <新文件> 运行离线程序边界检查,真实模型攻击防御率保持未测。完整验收见安全回归记录。
codebase-qa MCP questions
How does the server handle different versions of a repository?
The server creates snapshots from Git commits, recording full Commit SHAs and file SHA256 hashes to ensure analysis stays within a fixed version.
Can I use this to plan code modifications?
Yes, the server includes a 'modification planning' feature that outputs current implementation details, involved files, modification order, and verification methods.