@cqjjb/project-mcp-server
v1.4.0
Published
项目地图 MCP:GitLab 组/项目查询 + 本地项目定位,项目地图 JSON 落盘(越用越聪明)
Maintainers
Readme
@cqjjb/project-mcp-server —— 项目地图 MCP
让 AI 一句话找到公司项目:GitLab 组/项目查询 + 本地项目定位,项目地图 JSON 落盘,越用越聪明。
特性
- 一张地图:项目地图 JSON 是唯一数据层——组规则(路径前缀)+ 全量项目快照 + 本地路径 + 别名。
- 规则分组,不逐条维护:项目组用路径规则覆盖全部项目;特殊项目(建错组、别名)用
overrides单独定义。 - 文件即权威:组的增删改直接编辑地图 JSON 的
groups数组(顺序即优先级),重启生效。 - 组带描述:每个组有
description字段告诉 AI 这组是干啥的。 - 用到才对齐:find/clone 在地图里 miss 时自动实时搜 GitLab 并学进地图;另有
refresh全量对齐。 - 纯本地项目也进地图(v1.4.0):没有
.git、但有package.json的目录会被收录为项目,同样能被 find 检索。 - 中英混排可搜(v1.4.0):
项目地图MCP这类无空格写法会按中英边界切词;稀有词权重高于mcp这类大众词(IDF)。 - 零命中就澄清,不瞎试(v1.4.0):find 全图零命中时返回【兜底澄清协议】——结构性诊断 + 4 条可选线索 + 明确停止条件,把"无限换词"变成"有界收敛"。
- 可检索性体检(v1.4.0):
project_memory直接报"结构性不可达(文本零中文)"项目数——这批项目对纯中文查询数学上不可能命中,只能靠补描述/别名解决。 - 本地定位:工作区扫描 + 地图记忆,clone 自动登记,下次直接命中;扫描会自动清理已消失的目录条目。
快速开始
# 1. 安装
npm install -g @cqjjb/project-mcp-server
# 2. 配置环境变量(或写 .env)
# GITLAB_URL 你的 GitLab 实例,如 http://gitlab.example.com
# GITLAB_USERNAME / GITLAB_PASSWORD 登录账号(或 GITLAB_TOKEN 个人令牌)
# LOCAL_ROOT 本地工作区根目录(clone/scan 都基于它)
# (数据目录固定为 用户主目录/.project-mcp-server,由 os.homedir() 跨平台自动判断,无需也不能配置)
# 3. 首次建图(可选,两个途径)
# a) 全量:node scripts/fetch-all.js 抓全量 → 在地图 JSON 里定义 groups → node scripts/build-map.js
# b) 按需:什么都不做,直接用——find/clone 时自动实时搜 GitLab 并学习
# 4. 挂进你的 MCP 客户端(stdio),如 DSH / Claude Desktop:
# command: project-mcp-server工具(4 个)
| 工具 | 说明 |
|---|---|
| projects_group_by_gitlab | GitLab 项目地图:list / find / branches / branch / clone / create / refresh,group 参数选组 |
| projects_group_by_local | 本地项目:find(记忆优先)/ list / scan / register。收录 git 仓库 + 无 .git 但有 package.json 的纯本地项目 |
| project_map_edit | 编辑项目地图:show / add_group / update_group / remove_group / add_override / remove_override / add_alias / remove_alias / remove_project / reload——带校验、立即落盘生效、免重启。add_alias 的 project 也接受本地绝对路径(给纯本地项目起中文别名) |
| project_memory | 查看地图状态(各组项目数、本地仓库数、别名)+ 可检索性体检(结构性不可达项目数) |
零命中时的兜底协议(v1.4.0)
地图里确实没有时,find 不再返回"可换关键词"这种会诱发无限重试的提示,而是返回:
❌ 没找到「XXX」——不要再换关键词重试了,换词不会改变结果。
已检索:…共 N 个项目 → 0 命中;GitLab 实时搜索 → 0 命中。
🔍 诊断:你搜的是纯中文,而地图里 M / N 个项目(X%)的可检索文本里一个中文字符都没有
—— 纯中文查询对它们数学上不可能命中。
这类项目的名字长这样:xxx、yyy、zzz …
请从下面给我任意一条线索(给一条就能定位):
A. 你记得的英文单词/缩写 B. 所属组 key(回一个我就列出该组全部项目)
C. 一句话功能描述/中文俗称 D. 本地目录大概叫什么
💡 也可以直接说「列 tools 组」。✅ 定位到后我会记成别名,下次一句话直接命中。设计要点:MCP 工具不能直接问用户,所以它把"该问什么"返回给 AI,由 AI 去问。收敛次数有界:典型 2 次调用,最坏 1+1+ceil(最大组/60) 次。
项目地图 JSON
~/.project-mcp-server/project-map.json(固定路径,跨平台自动判断:Windows C:\Users\<用户>\.project-mcp-server,macOS/Linux /Users|home/<用户>/.project-mcp-server)。组定义示例:
{
"groups": [
{
"key": "train", // 组 key(group 参数用)
"name": "培训产品组", // 中文名(AI 展示/匹配用)
"description": "培训产品线:学员端、管理端、H5", // 告诉 AI 这组是干啥的
"gitlabPath": "your-ns/train", // create 动作建项目的位置
"rules": ["your-ns/train/**"], // 路径规则(前缀匹配,顺序即优先级)
"aliases": ["培训", "training"]
}
// ... 最后放兜底组 { "key": "other", "name": "其他", "rules": ["**"] }
],
"overrides": { // 单项目纠错(建错组的项目)
"your-ns/train/xx": { "group": "train", "aliases": ["某个中文名"] }
},
"projects": { /* 全量快照,自动维护 */ },
"local": { /* 本地仓库记忆,自动维护 */ },
"aliases": {}
}- 新增组:两种方式——① AI 用
project_map_edit的add_group(默认插到兜底组之前,带校验);② 人工编辑 JSON 后调reload(或重启)。越靠前优先级越高。 - 改组:
update_group改 rules/name/aliases/description,改 rules 自动重算全部项目归属。 - 单项目纠正:
add_override(project + group),remove_override撤销。 - 删除:
remove_group(项目自动落到其它组)/remove_project/remove_alias均支持。
v1.4.0 变更
| 变更 | 说明 |
|---|---|
| 收录纯本地项目 | 无 .git 但有 package.json 的目录成为可检索项目;register 不再要求 .git |
| 收录无 remote 的 git 仓库 | v1.3 里这些仓库被 if (ns) 静默丢弃,现在按本地项目收录 |
| 中英边界分词 | 项目地图MCP → 项目地图 + mcp(修复无空格混排整串零命中) |
| IDF 加权 | 稀有词权重高、mcp 这类大众词权重低,减少"top10 被同一个词刷屏" |
| 长词 n-gram 兜底 | 仅当整词零命中、且中文块 ≥5 字时拆词,并要求 ≥2 个碎片命中 —— 短词不拆,避免误命中 |
| 兜底澄清协议 | 零命中时返回诊断 + 线索 + 停止条件(见上) |
| 别名可挂本地路径 | add_alias 的 project 支持本地绝对路径,纯本地项目也能被中文别名命中 |
| 可检索性体检 | project_memory 报"结构性不可达(零中文)"项目数与占比 |
| 脏条目清理 | 扫描时清理工作区内已消失的目录条目 |
| 一次性迁移 | 升级后第一次 find 会自动重扫一次(local.scanVersion 标记,约 20 ms),此后不再重扫 |
已知边界
- 同一项目的多份拷贝会各占一条:例如把项目备份到工作区内,备份目录(有 package.json)也会被收录为一条本地项目。建议把备份放在工作区之外。
- 中文语义桥不在算法能力内:项目名是英文/拼音、描述为空时,纯中文查询无法命中它——这是数据问题,请补
description或加中文别名。体检指标就是为量化这批项目而加的。
脚本
| 脚本 | 用途 |
|---|---|
| scripts/fetch-all.js | 全量抓取 GitLab 组+项目 → all-projects.json / all-projects.csv(Excel 可开) |
| scripts/build-map.js | 按组规则生成项目地图 |
| scripts/analyze-structure.js / analyze-deep.js | 结构分析(分组决策用) |
| scripts/smoke-test.js | 冒烟测试(npm run smoke,无公司数据时自动降级为通用检查) |
安全边界
clone/切分支/commit/push 属于正常开发动作;合并、删远端一律人工确认。 建议给 MCP 使用专用账号或 PAT(只读+受限),而非管理员账号。
License
MIT
