关于 Paparats MCP: Self-Hosted Semantic Code Search
Paparats MCP 是面向多仓库团队的可自托管语义代码搜索服务。它结合 AST 感知索引、符号关系、Git 历史和由 Agent 维护的架构记忆,提供代码与设计背景。
主要功能
- 01支持 11 种语言的 AST 感知索引
- 02跨代码块符号图
- 03Git 历史与工单元数据
- 04支持查询扩展的语义搜索
- 05由 Agent 维护的架构记忆
适用场景
- 01搜索多个仓库中的代码
- 02追踪代码块之间的符号关系
- 03查看架构决策与经验
- 04通过受限端点搜索精选文档
MCP 相关
通过独立的 MCP 端点提供编码和支持工具,并可选提供仅限文档的端点。MCP 客户端可通过 Streamable HTTP 连接,也支持旧版 SSE 路由。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
@paparats/server
Paparats MCP 的 MCP 服务——支持跨多个代码库进行语义代码搜索,具备 AST 感知分块、跨块符号图、每个块的 git 历史,以及由 Agent 维护的架构记忆层。
未发布到 npm。 此软件包由
@paparats/indexer作为库使用,并以 Docker 镜像形式发布:ibaz/paparats-server。 最终用户通过@paparats/cli安装。
此软件包的功能
在一个进程中完成三项工作:
- 索引器。 AST 感知分块(tree-sitter,支持 11 种语言)、逐块符号提取、单次解析流水线、使用 SQLite 缓存的 llama-server 嵌入,以及批量 Qdrant 写入。索引完成后的处理会附加 git 历史、工单引用和跨块符号边(calls / called_by / references / referenced_by)。
- 搜索器。 任务前缀嵌入(
nl2code/code2code/techqa)、为支持工具扩展查询(缩写、大小写变体、复数形式、移除填充词)、带分组失效机制的内存 LRU 查询缓存、置信度评分、令牌节省遥测。 - MCP 服务。 三个端点——
/mcp(编码)、/support/mcp(支持)和可选启用、仅限文档的/knowledge/mcp(知识)——各自具有独立的工具集和系统指令。所有客户端均支持 Streamable HTTP,同时保留旧版 SSE 路由。另有由 Agent 维护的架构记忆层。
端点
http://<host>:9876/health – liveness probe
http://<host>:9876/metrics – Prometheus (PAPARATS_METRICS=true)
http://<host>:9876/ui – operator console
http://<host>:9876/api/analytics/... – analytics REST API (UI backend)
http://<host>:9876/mcp – MCP, coding mode (Streamable HTTP)
http://<host>:9876/sse – MCP, coding mode (SSE / Cursor)
http://<host>:9876/messages – MCP, coding mode (SSE message channel)
http://<host>:9876/support/mcp – MCP, support mode
http://<host>:9876/support/sse – MCP, support mode (SSE)
http://<host>:9876/support/messages – MCP, support mode (SSE message channel)
http://<host>:9876/knowledge/mcp – MCP, knowledge mode (stateless, bearer auth,
POST only; mounted only when configured)
POST /api/index 用于注册项目;POST /api/file-changed 和 POST /api/file-deleted 用于更新单个文件。
请参阅工具完整列表,了解各端点对应的工具。
知识模式
面向另一个网络中使用方的仅限文档的 MCP 端点——例如,负载均衡器后方的 Agent 后端,它只能搜索精选文档,不做其他操作。只有同时设置 PAPARATS_KNOWLEDGE_TOKENS 和 PAPARATS_KNOWLEDGE_AUDIENCE 才会启用;仅设置其中一个会导致服务在启动时停止。
- 工具: 仅有
search_docs和get_document。没有术语表区块、资源或工作流提示词。search_docs返回带有outputSchema的structuredContent,因此包装服务可以无需解析 markdown 即可生成引用。 - 身份验证: 使用
Authorization: Bearer <token>,以恒定时间进行比较,并在读取请求正文前完成检查。否则返回401和WWW-Authenticate: Bearer。 - 范围: 文档必须带有
PAPARATS_KNOWLEDGE_AUDIENCE中指定的受众标签(不能是internal);如果设置了PAPARATS_KNOWLEDGE_PROJECTS,则还必须属于其中的项目。如果设置了PAPARATS_DOCS_AUDIENCE/PAPARATS_PROJECTS,这两项还会与它们取交集。范围外的文档与不存在的文档读取结果完全相同。 - 传输: 无状态 Streamable HTTP——每次
POST都创建新的服务和传输,不使用会话 ID;GET/DELETE返回405。请求正文上限为 64 kB,查询长度上限为 1000 个字符。
文档的受众标签在索引时确定:优先使用 frontmatter 中的 audience:,其次使用 .paparats.yml / projects.yml 中的 docs.audience,否则设为 internal。无效的 frontmatter 值会被记录,并存储为 internal。请参阅文档搜索指南。
设置 PAPARATS_KNOWLEDGE_PROJECTS——否则,某个代码库的 README 中意外出现 audience: 就足以扩大此端点提供的内容范围。
仅暴露此路径,并且只允许 POST。例如,使用 nginx:
location = /knowledge/mcp {
limit_except POST { deny all; }
client_max_body_size 64k;
proxy_pass http://paparats:9876;
proxy_http_version 1.1;
proxy_buffering off; # responses stream as text/event-stream
}
location / {
return 404;
}
架构记忆
代码搜索会告诉 Agent 代码的功能。架构记忆层会告诉它原因——并且 Agent 会自行维护这些知识,跨会话延续,无需你编写任何文档。
每个组在单独的 Qdrant 集合(paparats_<group>_arch)中存储三种卡片,使用 qwen3-embedding-0.6b 进行嵌入(1024 维,最后池化):
| 类型 | 字段 | 幂等性 |
|---|---|---|
| 组件 | name、summary(Markdown:功能/负责内容/不负责内容/何时修改)、files、neighbours、anchors | 按 name(结构化) |
| 决策 | title、context、decision、alternatives_rejected、consequences、scope、supersedes | 服务端相似度门槛 |
| 经验 | rule、why、when、scope、severity、evidence | 服务端相似度门槛 |
相似度门槛(基于 qwen3-embedding-0.6b 的余弦相似度):
>= 0.85→ 重复。决策会被拒绝,因此 Agent 必须协调内容或取代旧决策。经验卡片会更新现有卡片的updatedAt(Reflexion“规则已确认”)。0.70 – 0.85→ 相似。不写入任何内容;Agent 应优化措辞或传入supersedes。< 0.70→ 接受为新卡片。
supersedes 会绕过门槛,并将先前的决策标记为 status=superseded,使其不再出现在默认搜索结果中,但仍保留在历史记录里。
通过 arch_context 读取时,可接受 min_score(默认值为 0.45)。每张返回的卡片都带有 updated N ago 时间戳和余弦相似度分数,供 Agent 判断结果是否过时或置信度较低。
使用 init_arch_memory 初始化——这是类似于 Claude Code 中 /init 的工作流提示词。它会遍历代码仓库,按领域边界识别 8-20 个组件,并写入卡片。之后可运行 audit_architecture(清理过时卡片)和 record_lesson_from_correction(将用户纠正转化为结构化经验)。
MCP 资源:
arch://schema— 完整的卡片架构参考。arch://stats/{group}— 实时计数(总数/按类型/按状态)以及最早/最新的updatedAt。
Prometheus 指标(PAPARATS_METRICS=true):
paparats_arch_context_calls_total{group}— 计数器paparats_arch_write_total{kind, status}— 按门槛结果标记的计数器paparats_arch_search_score—arch_context余弦相似度分数的直方图paparats_arch_collection_size{group, kind, status}— 仪表
两个 MCP 端点上的 arch_context 都是只读的。arch_record_* 仅用于支持——记录工作属于架构审查工作流。
模块图
| 模块 | 职责 |
|---|---|
types.ts | 共享接口 |
lib.ts | 公共库入口(重新导出供程序化使用) |
config.ts | .paparats.yml 读取器、11 种语言配置文件、autoProjectConfig() |
app.ts | Express 应用工厂、HTTP API 路由、请求接线 |
index.ts | 服务启动引导——启动 HTTP 服务、连接组件、优雅关闭 |
ast-chunker.ts | 通过 tree-sitter 进行基于 AST 的分块 |
chunker.ts | 正则分块回退方案(4 种策略) |
ast-symbol-extractor.ts | 基于 AST 提取每个分块中的符号 |
ast-queries.ts | 各语言对应的 Tree-sitter S 表达式查询 |
tree-sitter-parser.ts | WASM tree-sitter 管理器——按需加载语法 |
symbol-graph.ts | 跨分块符号边 |
embeddings.ts | llama-server 提供方 + SQLite 缓存 + 缓存包装器 |
indexer.ts | 感知分组的 Qdrant 索引——createQdrantClient()、toCollectionName()、单次解析的 chunkFile() |
searcher.ts | 带查询扩展、缓存和指标的向量搜索 |
query-expansion.ts | 缩写/大小写/复数/填充词扩展 |
task-prefixes.ts | 查询类型检测 + bge-code-v1/Qwen3 查询指令 |
query-cache.ts | 带 TTL 和按组失效功能的内存 LRU 缓存 |
metrics.ts | Prometheus 指标(prom-client)+ NoOpMetrics 回退 |
metadata.ts | 标签解析 + 根据目录结构自动检测 |
metadata-db.ts | 用于存储 Git 提交、工单和符号边的 SQLite 数据库 |
git-metadata.ts | Git 历史提取——将差异块映射到分块 |
ticket-extractor.ts | Jira/GitHub/自定义工单解析 |
mcp-handler.ts | MCP 协议——编码、支持和知识端点,使用隔离的工具集和指令 |
knowledge-mode.ts | 知识模式——环境变量解析、Bearer 身份验证、请求体大小限制、作用域交集 |
arch/types.ts | 架构记忆类型 |
arch/collection.ts | 每个组的 paparats_<group>_arch 集合生命周期 |
arch/text-embeddings.ts | 通过 llama-server 提供的 qwen3-embedding-0.6b 文本嵌入器 |
arch/store.ts | CRUD + 服务端相似度门限 + stats() 聚合 |
arch/context.ts | arch_context 查询——跨类型获取前 N 项,包含 min_score 和时间戳 |
配置(环境变量)
| 变量 | 默认值 | 说明 |
|---|---|---|
PORT | 9876 | HTTP 端口 |
QDRANT_URL | http://localhost:6333 | Qdrant 端点(https → 端口 443,http → 6333) |
QDRANT_API_KEY | — | Qdrant Cloud API 密钥 |
EMBED_URL | http://127.0.0.1:18434 | 嵌入服务端点(llama-swap;生成的堆栈中,内部端口为 8080,主机端口为 18434) |
EMBED_BATCH_SIZE | — | 每次 llama-server 调用的嵌入数量 |
EMBED_TTL | 0 | 模型卸载前的空闲秒数;0 = 永不卸载(默认值) |
EMBEDDING_PROVIDER | llama | 代码嵌入提供方:llama | openai | voyage |
EMBEDDING_MODEL | bge-code-v1 | 代码嵌入模型 |
EMBEDDING_DIMENSIONS | 1536 | 代码嵌入维度 |
TEXT_EMBEDDING_PROVIDER | llama | 用于架构层的 llama 或 openai |
TEXT_EMBEDDING_MODEL | qwen3-embedding-0.6b | 架构层文本嵌入模型 |
TEXT_EMBEDDING_DIMENSIONS | 1024 | 架构层文本嵌入维度 |
PAPARATS_METRICS | false | 设为 true 以开放 /metrics |
PAPARATS_PROJECTS | — | 以逗号分隔的项目名称允许列表 |
PAPARATS_DOCS_AUDIENCE | — | 用于编码和支持端点上 search_docs / get_document 的以逗号分隔的受众上限 |
PAPARATS_KNOWLEDGE_TOKENS | — | /knowledge/mcp 的以逗号分隔的 Bearer 令牌(≥ 16 个字符)。需与 PAPARATS_KNOWLEDGE_AUDIENCE 同时设置,或两者均不设置 |
PAPARATS_KNOWLEDGE_AUDIENCE | — | /knowledge/mcp 的受众上限;不允许使用 internal |
PAPARATS_KNOWLEDGE_PROJECTS | — | /knowledge/mcp 的可选项目允许列表——建议设置 |
PAPARATS_UI_BASIC_AUTH | — | /ui 和 /api/analytics/... 的 user:pass;格式错误的值会导致启动失败 |
PAPARATS_CORS_ORIGINS | — | 以逗号分隔的精确来源(例如 https://app.example.com),浏览器可从这些来源调用服务。未设置 = 不发送 CORS 标头;任何 Origin 既不是此服务,也不在列表中的请求都会收到 403。不带 Origin 的请求(MCP 客户端、curl)不受影响 |
OTEL_* | — | 标准 OpenTelemetry 环境变量(Tempo / Honeycomb / Datadog / Elastic APM) |
程序化使用(库)
package.json 的 exports 映射指向 dist/lib.js,而非服务启动入口。
导入 @paparats/server 不会启动 HTTP 服务——@paparats/indexer
会利用这一点将 Indexer 类作为库嵌入:
import { Indexer, createQdrantClient } from '@paparats/server';
const qdrant = createQdrantClient({ url: process.env.QDRANT_URL! });
const indexer = new Indexer({ qdrant, /* ... */ });
await indexer.indexProject(group, project);
Docker
docker pull ibaz/paparats-server:latest
docker run --rm -p 9876:9876 \
-e QDRANT_URL=http://qdrant:6333 \
-e EMBED_URL=http://embed:8080 \
ibaz/paparats-server:latest
完整堆栈(Qdrant + 嵌入服务 + 服务 + 索引器)请参阅 examples/docker-compose。
开发
yarn install
yarn workspace @paparats/server build
yarn workspace @paparats/server test
yarn workspace @paparats/server typecheck
相关软件包
| Package | 用途 |
|---|---|
| @paparats/cli | 一键安装、项目管理、搜索 |
| @paparats/indexer | 自动化多仓库索引器(将此软件包用作库) |
| @paparats/shared | 共享实用工具(路径验证、gitignore、排除项) |
| ibaz/paparats-embed | 预置 bge-code-v1 和 qwen3-embedding-0.6b 的 llama.cpp llama-server + llama-swap |
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。