npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aylina_ankali/code-rag-mcp

v0.3.1

Published

Code RAG MCP server: semantic indexing and retrieval of a local codebase (declaration-aware chunking + bge-m3 embeddings + Qdrant hybrid search). Exposes search_code / index_codebase / index_status / index_cancel / set_root MCP tools and a CLI, plus a loc

Readme

code-rag — 本地代码库语义索引与检索(DSH 模式)

对本地代码库(C++ / Java 为主,支持中英文注释混合)做声明感知分块 → Ollama 向量化 → Qdrant 存储, 为 DSH 会话提供五个 MCP 工具 + 一个可视化索引面板:

| 工具(模型视角) | 作用 | |---|---| | mcp__code_rag__search_code | 自然语言检索代码,返回文件路径 / 函数名 / 行号 / 相似度 / 片段(按 root 隔离) | | mcp__code_rag__index_codebase | 异步索引:立即返回 taskId,后台执行,不受调用超时限制;full: true 只重建当前根 | | mcp__code_rag__index_status | 索引状态 + 运行中任务的实时进度(百分比/文件/分块/错误明细) | | mcp__code_rag__index_cancel | 取消当前根的运行中任务 | | mcp__code_rag__set_root | 切换当前代码库根(换工作区/项目后的第一步) |

工具名前缀 mcp__code_rag__ 由 DSH 的 MCP 桥接插件(@deepseek-ai/dsh-mcp-client)按 mcp__<serverName>__<rawName> 规则生成,search_code 等是 MCP 服务器侧的原始名。

索引面板(Roo Code 风格)

MCP 服务器内置本地 HTTP 端点(127.0.0.1:8756,占用自动上探),会话输入框上方的 Code RAG 索引状态条(动态 Cordis 插件)直接读取它:

  • 显示:当前根、索引状态、进行中任务的进度条(% / 文件 / 分块)、错误明细;
  • 按钮:开始索引(增量)/ 全量重建 / 取消;
  • 数据与按钮操作与 MCP 工具完全同源(同一任务管理器);
  • 目标根 = 当前会话工作区(面板默认对工作区操作;服务器根不同会提示);
  • 端口发现:探测 8756-8786 全部端口并选择 startedAt 最新(避免连到残留旧服务器);
  • 所有请求带 8s 超时,服务器无响应显示离线而非永久挂起。

设置与诊断页(插件 v1.1.0+):DSH 设置 →「Web 插件」区新增 Code RAG 卡片, 一键检测索引服务器 / Qdrant / Ollama / 模式预设 / 配置文件并列出问题清单;可在线修改 <root>/.code-rag/config.json(Qdrant/Ollama 地址、嵌入模型、维度、集合、端口、 分块行数)、启动/取消索引、一键重新生成预设(npm run setup)。数据经插件 host 半部的 /api/code-rag/* 环回端点(仅本机来源可访问,详见插件 README)。

插件源码(动态版):plugins/index-panel.client.js,可交给 cordis_define 临时启用。 已固化:plugins/dsh-code-rag-index-panel/ 是常驻版 npm 插件(ModuleLoader 格式), 由 npm run setup 以 file: 依赖装入 web profile 的 bundles 列表(~/.dsh/profiles/web/package.json), 重启 DSH 后所有会话生效;此后修改 lib/client.js 由 client-hmr 轮询自动热更新(无需刷新页面)。

没有写死的路径:仓库内所有机器相关路径都是占位符({{CODE_RAG_DIR}} 等), 由 npm run setup 在安装时替换为实际绝对路径。换机器/挪目录后重新运行一次即可。

目录结构

code-rag/
├── package.json              # npm 脚本:setup / build / serve / index / search / status / smoke
├── tsconfig.json
├── src/
│   ├── main.ts               # CLI 入口(serve | index | search | status)
│   ├── server.ts             # MCP 服务器:五工具(异步任务 + HTTP 面板端点)+ stdio
│   ├── config.ts             # 配置解析:默认值 < 配置文件 < 环境变量 < CLI
│   ├── taskfile.ts           # 任务状态共享文件(index-task.json / panel.json)
│   ├── walk.ts               # 文件扫描:ignore 规则、白名单、二进制/超大文件过滤
│   ├── chunker.ts            # 声明感知分块(花括号深度 + 签名识别,150/20 兜底)
│   ├── embedder.ts           # Ollama /api/embed 批量嵌入客户端(支持取消)
│   ├── qdrant.ts             # Qdrant REST 客户端(集合/upsert/检索/删除,UUIDv5 确定性 ID)
│   ├── indexer.ts            # 增量索引编排(进度回调 + 可取消 + 原子状态文件)
│   ├── searcher.ts           # 语义检索 + 结果格式化
│   └── state.ts              # 状态文件(<root>/.code-rag/state.json)读写
├── preset/                   # Code RAG 模式预设模板(占位符,由 setup 生成到 ~/.dsh)
│   ├── agent.cordis.yml
│   ├── preset.yml
│   └── skills/code-rag/SKILL.md
├── plugins/index-panel.client.js  # 索引面板动态版(cordis_define 用,Client 半部)
│   └── dsh-code-rag-index-panel/    # 索引面板常驻版(npm 插件:package.json + lib/;plugins/ 为市场 CI 认可的子包目录)
├── scripts/setup.mjs         # ★ 一键接入:生成预设 + 同步 web profile(幂等,零依赖)
├── scripts/smoke.mjs         # 端到端冒烟测试(真实 Qdrant/Ollama)
├── scripts/verify-async.mjs  # 异步索引/进度/取消/HTTP 端点验证
├── testdata/sample-repo/     # 演示代码库(Java + C++,中英注释)
├── testdata/big-repo/        # 压力测试代码库(1200 个生成文件)
├── code-rag.config.example.json
└── cordis.patch.example.yml  # 全局接入 DSH 的补丁片段(方案 B,占位符示例)

一、安装与构建

# 前置(用户已手动完成):Qdrant 容器(6333) + Ollama(11434)
# 默认嵌入模型 bge-m3(多语言 + 代码,1024 维,中文/英文查询均可靠):
ollama pull bge-m3
cd code-rag
npm install
npm run build          # tsc → dist/

若想用回 nomic-embed-text(英文/标识符查询可用,中文语义查询效果差), 改配置 embedModel: nomic-embed-text + dimensions: 768,然后全量重建索引。

二、接入 DSH(两种方案)

方案 A:code-rag 模式(推荐,一键完成)

cd code-rag
npm install && npm run build
npm run setup            # 生成预设 + 同步面板插件(幂等,可重复执行)

npm run setup(scripts/setup.mjs,零依赖)会根据自身实际位置自动完成:

  • 生成模式预设 ~/.dsh/.agent-presets/code-rag/(模板见 preset/,其中的 {{CODE_RAG_DIR}} / {{CODE_ROOT}} 占位符被替换为绝对路径);
  • 把索引面板插件 dsh-code-rag-index-panel 以 file: 依赖同步进 ~/.dsh/profiles/web/package.json(含 bundle 条目),并同步已安装副本;
  • 可选参数:--root <代码库根目录>(服务器默认根,仅兜底)、--no-panel。

换机器 / 挪目录后只需重新运行 npm run setup,无需手工改任何路径。

然后:

  1. 重启 DSH,在模式选择器里选 Code RAG 模式,新建会话(保持其运行——索引服务器随之启动);
  2. 换工作区时先让模型调用 mcp__code_rag__set_root(root 传当前工作目录绝对路径), 再执行 mcp__code_rag__index_codebase 建立索引(persona/技能会引导模型自动完成);
  3. 之后提问“哪里实现了 X / 找一下处理超时的代码”,模型自动调用 mcp__code_rag__search_code。

多根隔离:每个仓库的向量按 root 命名空间隔离(检索/删除/全量重建都只作用于 当前根),多个项目可共存于一个 Qdrant 集合;full: true 不会误删其他仓库。 集合未建立索引时工具返回友好提示(“请先调用 index_codebase”),不会 404 报错。

生成的 agent.cordis.yml 里的 mcp-code-rag 行(等价模板,占位符由 setup 替换):

- id: mcp-code-rag
  name: '@deepseek-ai/dsh-mcp-client'
  config:
    serverName: code_rag          # 工具名前缀
    transport: stdio
    command: node
    args: ['<CODE_RAG_DIR>/dist/main.js', 'serve', '--root', '<CODE_ROOT>']
    cwd: '<CODE_ROOT>'            # = 默认代码库根目录
    toolCallTimeoutMs: 300000     # 索引已异步化,此超时只影响 index_status/search_code 等轻量调用
    failOnStartupError: false

方案 B:全局接入(所有会话可见)

把 cordis.patch.example.yml 里的 insert 片段合并进 <DSH_HOME>/profiles/web/cordis.patch.yml(其中的 <CODE_RAG_DIR> / <CODE_ROOT> 占位符换成你的实际绝对路径),重启 DSH。

三、索引命令

# 增量索引(默认代码库根目录 = 进程 cwd,可 --root 指定;多个仓库互不干扰)
node dist/main.js index --root <代码库根目录>

# 全量重建(只清空该 root 的向量后重新索引,不影响其他仓库)
node dist/main.js index --full --root <代码库根目录>

# 只统计不写入(演练)
node dist/main.js index --dry-run

# 查看状态
node dist/main.js status --root <代码库根目录>

增量原理:<root>/.code-rag/state.json 记录每个文件的 (mtime, size) 指纹。 未变化跳过;变化/新增 → 删除旧点 → 重嵌(确定性的 UUIDv5(root:file:startLine) 保证幂等覆盖); 磁盘上消失 → 按 payload.file + payload.root 精确清理。进程中断不损坏状态(临时文件 + 原子 rename)。 CLI 索引进度实时打印到 stderr 并写入 <root>/.code-rag/index-task.json(索引面板同源读取)。

三·五、异步索引(会话内)

index_codebase 默认异步:立即返回 taskId,后台执行——大项目不再超时。 进度经 index_status 轮询(模型会每 30-60 秒汇报一次),index_cancel 可取消; 会话输入框上方的索引面板显示同样的进度并提供按钮。

四、检索(混合检索)

search_code 采用混合检索:查询文本同时生成稠密语义向量(bge-m3)+ BM25 稀疏向量(标识符拆分/CJK bigram tokenizer),Qdrant Query API 以 RRF 融合两条 通道——自然语言语义("蓝牙重连逻辑")与精确标识符/错误串/数字(reconnectDevice、 6333、C3861)一次调用同时覆盖,精确命中分数通常为 1.000。

node dist/main.js search "命令行参数解析" --limit 5
node dist/main.js search "reconnectDevice" --dir src --limit 5

五、分块策略(chunker.ts)

“穷人的 AST”——不依赖 tree-sitter:

  1. 轻量词法扫描逐行统计花括号深度(忽略字符串/注释内的括号);
  2. 逐行维护作用域栈,识别声明签名(支持 public/private 修饰符、template<>、 类/接口/struct/namespace、多行签名回溯 ≤4 行——回溯不越过已打开作用域, 排除 if/for/while 等控制流与 lambda);
  3. 每个命名声明(函数/类)是一个独立块,其前导文档注释(Javadoc/Doxygen)自动 并入块内,保证“文件 + 函数名”级别的检索精度;
  4. 超大声明(> 150 行)与无结构区域(文件头、命名空间外代码)内部用滑动窗口 150 行 / 重叠 20 行——即需求里的兜底策略;
  5. 纯结构碎块(孤立的右括号等)自动丢弃,避免污染检索;
  6. 每个块携带 file / function / class / start_line / end_line,嵌入文本带定位头 (// src/foo.cpp :: bar (lines 12-34)),提升检索精度。

分块回归测试:npm test(node:test,12 个用例固化历史边界——行尾注释回溯、 } else { 撕裂、多行签名、窗口切分、稀疏 tokenizer 等)。

六、配置

优先级:内置默认 < <root>/.code-rag/config.json < 环境变量 CODE_RAG_* < CLI。 把 code-rag.config.example.json 复制到 <root>/.code-rag/config.json 后修改。 常用项:qdrantUrl、ollamaUrl、embedModel、dimensions、 chunkSize/chunkOverlap、ignore(目录忽略)、extensions(语言白名单)、 httpPort(索引面板 HTTP 端点端口,默认 8756,占用自动上探;也可用环境变量 CODE_RAG_HTTP_PORT 覆盖。注意索引面板探测 8756-8786,改到区间外时需同步修改 面板插件 lib/client.js 里的 PORT_BASE)、 embedConcurrency/embedRetries(嵌入并发与失败重试,默认 4/3)。 (root 不在此配置:由启动参数 --root / 当前工作目录决定,多仓库用 set_root 切换。)

安全:面板 HTTP 端点只接受本机来源(127.0.0.1/localhost 的 Origin), 其他网页来源一律 403。

换嵌入模型:改 embedModel 与 dimensions 后 index(增量即可)会自动 检测到状态指纹与模型不匹配并全量重建。默认 bge-m3 = 1024 维; nomic-embed-text = 768 维。bge-m3 对中英混合注释的检索质量显著更好。

七、冒烟测试

npm run build && npm run smoke

依次验证:CLI 全量索引 → 中文查询「命令行参数解析」命中 App.parseArgs → 中文查询「指数退避重试算法」命中 engine.retryWithBackoff → MCP 握手(initialize / tools/list 四工具 / search_code / set_root / 空根 index_status 友好输出)。

八、工作原理速览

会话提问 ──> DSH 模型 ──> mcp__code_rag__search_code(MCP stdio)
                              │
                    code-rag 服务器(node dist/main.js serve)
                    ├─ 查询嵌入:Ollama /api/embed(bge-m3, 1024 维)
                    └─ 相似检索:Qdrant REST /points/search(Cosine)
                              │
                         返回 file + function + 行号 + 片段

索引路径:walk 扫描 → chunker 分块 → embedder 批量嵌入 → qdrant upsert(UUIDv5 幂等)→ state.json 指纹回写。删除路径:状态里有、磁盘上没有 → deleteByFile(payload.file 过滤)。

九、常见问题

| 现象 | 处理 | |---|---| | search_code 提示“尚未建立索引” | 调用 index_codebase(可加 root 指定仓库)后重试 | | 点“开始索引”没反应/卡住 | 旧版服务器残留会占端口:重启 DSH 让新服务器(stdin 关闭即退出)接管;面板已选最新实例 + 8s 超时兜底 | | 索引显示“0 个文件” | 服务器已加 0 文件防护:root 配错或 ignore 把源码目录排除了会明确报错;点击面板根名可切换 | | 大项目索引超时 | 已解决:index_codebase 默认异步立即返回,后台执行;用 index_status 看进度 | | 看不到索引进度 | index_status(模型会汇报);或启用索引面板(输入框上方状态条 + 按钮) | | 换工作区后检索的还是旧项目 | 先 set_root 切到当前工作目录,再 index_codebase | | 检索结果混入别的项目 | 多根已按 root 隔离;确认 index_status 的当前根是否正确 | | 索引任务卡住想停 | index_cancel 或面板的“取消”按钮 | | Ollama 找不到模型 | ollama pull bge-m3(默认)或 ollama pull nomic-embed-text | | 向量维度不匹配报错 | 模型换过 → 同步改 dimensions + index --full | | 中文检索不准 | 确认默认模型为 bge-m3(1024 维);nomic-embed-text 中文语义弱 | | 端口不通 | docker ps 看 Qdrant;curl localhost:11434/api/tags 看 Ollama | | MCP 工具没出现 | 检查 DSH 日志中 mcp-client(code_rag) 行;确认 dist/main.js 路径存在 | | 大仓库索引慢 | 先看是不是把生成/构建目录扫进去了:node dist/main.js index --dry-run --root <仓库> 看 scanned 数。VS C++ 项目默认已忽略 Temperat.*(MSBuild 中间目录)、x64、installer;其他项目的生成目录加到配置 ignore。真慢时调大 embedBatchSize / embedConcurrency(默认 32/4) | | 生成文件进了索引 | 在 <root>/.code-rag/config.json 的 ignore 里加目录模式(支持 *),然后 index --full |