前言¶
在 DeepSeek Harness(DSH)里让模型查代码,常见做法是连 GitHub、读单个仓库,或依赖托管方自带的搜索 API。自建 Gitea 或 Forgejo 时,服务端代码索引往往默认关闭,Web 界面和 API 都无法按文件内容搜索。若代码都在私有实例上,智能体很难像对待公开 Git 托管那样「先搜再读」。
下面介绍社区插件 dsh-gitea-search(维护者 offzen,分类:客户端)。它把 token 能读到的仓库同步到本机 bare mirror,在镜像上用 git grep 跨仓库、跨分支检索,并通过 MCP 把结果交给 DSH;搜索与读文件不访问网络。插件在 SkillHub 目录 登记,源码与文档在 GitHub。
这是什么¶
dsh-gitea-search 面向「本地有一份 Gitea/Forgejo 镜像」的场景:唯一需要联网的步骤是 sync(拉取/更新镜像);之后模型侧调用的是三个 MCP 工具(在 DSH 中表现为 mcp__gitea_search__*):
search_gitea— 在全部已镜像仓库与分支中搜文件内容、路径或提交说明read_gitea_file— 从镜像读取单个文件,无需再 clonelist_gitea_repos— 列出镜像中的仓库,可按条件过滤
匹配方式本质是 grep(默认字面、可大小写不敏感,也可按需正则),不是语义或向量检索。npm 包当前版本为 0.1.1,许可证 MIT。
环境与依赖¶
安装与运行前需满足 README 中的要求:
- DeepSeek Harness 0.2.x(维护者在多种 0.2.x 预发布版本上做过兼容性验证,见仓库 README 表格)
- Node
^22.19.0 || >=24.0.0,以及系统里的 git - 可访问的自建 Gitea / Forgejo 实例
- 用于同步的只读 API Token(Gitea scope:
read:repository、read:user);私有实例同步时必需 - 磁盘空间与你要镜像的仓库体量相当
插件随 DSH profile 启动 MCP 服务时,以当前 dsh 进程 的权限与环境运行;安装前建议阅读源码与许可证,并按自己的安全策略保管 Token。
安装与启用¶
官方安装命令如下(--profile 必填):
dsh plugin --profile <profile> add dsh-gitea-search
包声明了 dsh.bundle.patch,因此 dsh plugin add 会安装依赖、把 bundle 写入 profile,并插入 MCP 客户端行,一般无需手写 YAML。若 profile 不支持配置热重载,安装后需重启 dsh,工具才会以 mcp__gitea_search__search_gitea、mcp__gitea_search__read_gitea_file、mcp__gitea_search__list_gitea_repos 等形式出现。
Bundle 通过 npx -y dsh-gitea-search mcp 启动 MCP(npm 预构建分发,通常不需要额外 build 权限)。
配置¶
MCP 客户端在拉起子进程前会清空继承的环境变量,bundle 通过 patch 显式把下列变量从 dsh 进程环境 传入(例如在 systemd 的 Environment= 或启动 dsh 的 shell 里 export):
| 变量 | 默认值 | 含义 |
|---|---|---|
GITEA_MIRROR_DIR |
~/.local/share/gitea-search/mirror |
bare 镜像目录 |
GITEA_BASE_URL |
— | Gitea/Forgejo 根 URL,sync 必需 |
GITEA_TOKEN |
— | 只读 Token,私有实例 sync 必需 |
GITEA_OWNER |
全部可读仓库 | 逗号分隔的 user/org,限制镜像范围 |
GITEA_MAX_RESULTS |
200 |
search_gitea 返回条数上限(最大 1000) |
GITEA_MAX_SEARCH_BYTES |
131072 |
单次搜索总输出预算 |
GITEA_MAX_LINE_BYTES |
2000 |
单行上限,超出会截断并标记 |
GITEA_MAX_READ_BYTES |
60000 |
单文件读取上限 |
GITEA_JOBS / GITEA_SYNC_JOBS |
6 |
搜索 / 同步时的并行仓库数 |
GITEA_TIMEOUT_MS |
120000 |
单次 git 调用超时 |
若日后要改配置,可为 dsh 进程 export 变量,或在自有 profile 的 cordis.patch.yml 里按 id(gitea-search)覆盖 MCP 行;注意覆盖会替换整个 config 对象,需把仍要保留的键一并写上。
建立并更新本地镜像¶
镜像不会由插件自动刷新,需要你先 sync,再用 cron 或 systemd timer 保持更新(示例见仓库 docs/MANUAL.md)。
export GITEA_BASE_URL=https://gitea.example.com
export GITEA_TOKEN=... # 只读 token
npx -y dsh-gitea-search sync # 首次同步,之后定期执行
sync 通过 Gitea HTTP API 枚举 token 可读仓库,对每个仓库执行 git clone --mirror,再用 git remote update --prune 更新。目录结构为 <mirror>/<owner>/<repo>.git;若只镜像单个 owner,也可能是扁平的 <mirror>/<repo>.git。
典型用法¶
在 DSH 里¶
完成安装、配置环境变量并完成至少一次 sync 后,在对话中由模型调用上述 MCP 工具即可;bundle 已将 toolCallTimeoutMs 设为 120000,以减轻大镜像上首次冷搜索超过默认 60s 的问题。可先缩小 repo 范围,或用 mode: "path" / files_only 探路。
命令行(同一套引擎)¶
不经过 DSH 也可直接用 CLI 调试镜像与检索:
dsh-gitea-search search <pattern> [-p|-m|-E|-s|-w|-l|-c] [-r repo] [-b branch] [-A] [-n N] [--json]
dsh-gitea-search repos
dsh-gitea-search read <repo> <path> [--ref]
dsh-gitea-search sync [--transport https|ssh]
dsh-gitea-search mirror
完整选项见 dsh-gitea-search --help。
适用场景与边界¶
适合:代码托管在自建 Gitea/Forgejo、需要 DSH 智能体跨多仓库 grep、且能接受「先同步镜像、再本地搜」 的团队。与依赖托管方全文索引或语义搜索的方案相比,这里明确是本地 mirror + git grep,延迟与新鲜度取决于你的 sync 节奏。
务必知晓的边界(来自官方 README):
- 可搜范围仅限已推送到服务器的内容,未推送的本地修改不在镜像里。
- 插件不会在搜索时触发
sync;结果是否过时,取决于你上次同步时间。 - 为保护模型上下文,单次搜索、单行、单文件读取都有上限;极大单行或压缩产物会被截断或限流。
- 仅
sync走网络;Token 经 APIAuthorization与GIT_ASKPASS使用,不会出现在命令行;搜索与读文件只读本地镜像。
卸载:
dsh plugin --profile <profile> remove dsh-gitea-search
之后可删除镜像目录并吊销 Token。
故障排查(摘要)¶
- 工具不出现:查
dsh日志中的gitea-search;常见原因包括npx无法访问 registry,或 Windows 上需将命令写成npx.cmd。 - 提示镜像下没有仓库:未
sync或GITEA_MIRROR_DIR指向错误;可先sync,再执行dsh-gitea-search mirror核对。 - 首次搜索很慢:缩小仓库范围或改用路径模式;必要时再调并行与超时相关环境变量。
结尾¶
dsh-gitea-search 把自建 Gitea/Forgejo 的「无法全文搜」补成「本地镜像 + 跨库 grep + MCP」,让 DSH 在私有代码托管上也能走「列举 → 搜索 → 读文件」的固定路径。社区目录页:https://www.skillhub.cn/plugins/offzen/dsh-gitea-search;源码与完整说明:https://github.com/offzen/dsh-gitea-search。