Skip to main content
Glama
Vita0818

CC98-SearchPro

by Vita0818
README.md
# CC98-SearchPro

面向“找讨论 → 判断相关性 → 阅读上下文 → 引用证据”的独立只读 MCP 与 Codex 插件。支持校园网或已有 VPN 直连。

[下载发行包](https://github.com/Vita0818/CC98-SearchPro/releases/latest) · [版本记录](CHANGELOG.md) · [隐私说明](PRIVACY.md)

## 搜索能力

- **多路召回**:完整关键词优先,结合中文分词和有限的查询变体补查;精确标题不足时参考相关标题中的高频片段。
- **证据排序**:标题完整短语、首帖正文完整短语、标题全词、正文全词、弱相关依次排列;反馈词只用于召回,不计作相关性证据。
- **正文核对与摘要**:按预算读取候选首帖,返回命中片段、验证状态、主题与楼层编号。
- **版面与日期筛选**:版内查询使用 CC98 的版内搜索接口;日期在已召回候选中按发帖时间筛选,支持相关性、最新、阅读数排序。
- **可续读**:搜索快照分页不重复发请求;帖子按楼层读取,单楼长正文可按字符位置继续,支持原始 UBB/Markdown。
- **有限请求**:请求串行且至少间隔 400 ms;搜索 403 或 API 429 冷却后最多重试一次;持续失败保留已有结果。

插件不含发帖、回帖、私信、点赞等写工具,不调用大模型 API,不需要任何 AI 供应商密钥。

## 安装

需要 Node.js **22.18+**,交互登录脚本需要 Python 3。仓库与发行包包含内置依赖的 `runtime/`,使用时无需 npm 安装或编译。

### 从 GitHub 安装到 Codex

```sh
codex plugin marketplace add Vita0818/CC98-SearchPro --ref v0.1.0
codex plugin add cc98-searchpro@cc98-searchpro
```

安装后打开新聊天,使用 **CC98-SearchPro** 检查登录状态。状态工具会返回当前安装位置的 `setup_command`,在本机终端运行它即可隐藏输入 CC98 账号密码。

仓库插件市场遵循 [Codex 官方插件分发格式](https://developers.openai.com/plugins/build/plugins#marketplace-metadata),位于 `.agents/plugins/marketplace.json`。这里提供的是 GitHub 仓库分发,不是官方公共插件目录上架。

### 下载 ZIP 或克隆源码

将 Release 中的 ZIP 解压到用户主目录下,或克隆仓库:

```sh
git clone https://github.com/Vita0818/CC98-SearchPro.git
cd CC98-SearchPro
python3 scripts/login.py
node runtime/cli.mjs status --check
python3 scripts/install-local.py --apply
```

安装器会注册现有目录并保留个人市场中的其他条目;安装后请保留该目录。同名插件指向其他目录时会停止,不覆盖原条目。只预览安装位置时省略 `--apply`。

## 登录与本地数据

在插件目录也可以使用 npm 命令配置和检查登录,无需先安装 npm 依赖:

```sh
npm run configure
npm run status
```

`configure` 在本机终端隐藏输入 CC98 密码,只通过子进程标准输入传给登录程序。密码不保存、不进入命令参数;新安装的会话令牌保存在 `~/.local/share/cc98-searchpro/session.json`(文件权限 `0600`)。设置 `CC98_SEARCHPRO_DATA_DIR` 可选择独立数据目录;兼容旧变量 `CC98_SEARCH_DATA_DIR`,未设置时也遵循 `XDG_DATA_HOME`。如果开发版目录 `cc98-search-mcp` 中已有会话而新目录尚无会话,会继续使用原会话。令牌过期自动刷新,刷新被拒绝后提示重新登录,不自动重试密码。

已持有会话 JSON 时可以导入(不把令牌粘进聊天):

```sh
node runtime/cli.mjs import-session < /path/to/session.json
npm run status
```

支持 `access_token` / `accessToken`、`refresh_token` / `refreshToken`,以及桌面端 `expires_at`(Unix 秒)、`expires_at_ms` 或网页 `accessToken_expirationTime`。兼容网页的 `str-` 包装和 `Bearer` 前缀。导入会为本插件创建独立副本,不会自动读取或修改其他客户端的会话;不同客户端共享刷新令牌可能受服务端令牌轮换影响,独立登录更稳定。

删除本插件会话:`node runtime/cli.mjs logout`。

## 通用 stdio MCP

将以下配置中的路径替换为实际目录,可供支持 stdio MCP 的客户端使用:

```json
{
  "mcpServers": {
    "cc98-searchpro": {
      "command": "node",
      "args": ["/absolute/path/CC98-SearchPro/runtime/server.mjs"]
    }
  }
}
```

## 五个工具

| 工具 | 用途 |
| --- | --- |
| `cc98_status` | 检查配置;`check=true` 读取当前账号验证连接 |
| `cc98_find_boards` | 按名称查找版面编号,支持分页 |
| `cc98_search` | 多路搜索、去重排序、正文验证,产生搜索快照 |
| `cc98_search_results` | 通过 `search_id`、`offset` 翻阅已有候选 |
| `cc98_read_topic` | 阅读主题与楼层,用 `next` 继续长正文或后续楼层 |

示例搜索参数:

```json
{
  "keyword": "保研经验",
  "terms": ["保研", "经验"],
  "depth": "balanced",
  "created_after": "2025-01-01",
  "sort": "relevance",
  "limit": 10
}
```

`terms` 可省略,由本地分词生成。日期均为北京时间,`created_before` 包含指定日期全天;上游时间缺少时区时不猜测,日期筛选会跳过并计入 `unknown_dates`。`limit` 只控制结果每页数量。

阅读工具接受含页码和楼层锚点的链接,例如 `/topic/42/3#7` 从第 27 楼开始;显式传 `from` 时以该偏移为准。引用链接按论坛每页 10 楼的规则生成。

| 深度 | 原词最多页数 | 首帖验证上限 | 业务 API 调用上限 | 单次搜索时间上限 |
| --- | ---: | ---: | ---: | ---: |
| `quick` | 1 | 5 | 10 | 12 秒 |
| `balanced`(默认) | 2 | 12 | 20 | 25 秒 |
| `deep` | 3 | 24 | 32 | 45 秒 |

每个补查词只取一页,每页请求 20 条;最多 3 个初始补查词和 2 个标题反馈词。调用统计按业务 GET 计数,不含令牌刷新及每次 GET 的有限重试。达到时间、请求预算或发生错误时返回 `partial` 和 `stop_reason`。

相同参数的完整搜索两分钟内复用快照,`refresh=true` 强制重新搜索。快照仅驻留内存,最多 20 份、15 分钟有效;翻页不会扩大召回范围。服务重启、登录切换或退出会使对应快照失效。多客户端使用时各自保有搜索快照。

## 覆盖范围与验证

官方主题索引决定候选范围,插件再对候选首帖做正文验证。它不是全站全文索引,不能保证召回正文命中但标题索引完全未召回的帖子,也不搜索全部回复、图片或附件。`coverage.exhaustive` 始终为 `false`,`total_candidates` 只是本次筛选后候选数量;`complete` 表示本次设定范围的执行完成,不表示搜索了整个论坛。

`match` 与 `first_post_verification` 分开返回:标题可以精确匹配而正文尚未读取;正文不可访问不会伪装成已验证。日期筛选和排序作用于已召回候选,因此“按最新”不是服务端完整的最新匹配列表。

离线测试使用模拟 CC98 响应。2026-10-22 已使用构建后的插件直连公开版面接口,读取到 12 个分区、267 个版面;账号登录、搜索和受限帖阅读尚未完成真实账号联调。真实验收先运行 `npm run status`,再用自己知道标题和正文的帖子测试搜索、版内限制、引用楼层和翻页。

## 开发与打包

```sh
npm ci --ignore-scripts
npm run check           # 类型、行为、安装器、构建与独立运行测试
npm run release:package # 在 release/v0.1.0/ 生成 ZIP、npm tgz 与 SHA256SUMS
```

`src/` 为源代码,`dist/` 为普通编译输出,`runtime/` 为包含运行依赖的发布文件。后者随仓库提交,支持 Git 插件市场安装。`npm-shrinkwrap.json` 锁定构建与运行依赖,`runtime/THIRD_PARTY_LICENSES.txt` 保留被打包依赖的许可文本。发布包不包含账号会话、环境文件、npm 缓存或 `node_modules`。

## 实现来源

查询变体、标题反馈与匹配策略基于 [CC98-SearchPlus](https://github.com/Vita0818/CC98-SearchPlus) 适配;UBB 解析来自本地 `cc98-desktop` 项目。登录、请求队列、搜索编排、快照、长帖阅读与 MCP 工具独立实现。详情见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct stage of the search workflow: board lookup, search execution, result pagination, topic reading, and auth status. The only potentially confusable pair is cc98_search vs cc98_search_results, but the descriptions clearly separate starting a new search from reading an existing snapshot by search_id.

Naming Consistency4/5

All tools use a consistent cc98_ snake_case prefix, which reads well as a set. Minor deviation: cc98_status and cc98_search_results are noun-oriented while the others begin with verbs, but the pattern remains predictable.

Tool Count5/5

Five tools is a tight, well-scoped surface for a search-and-retrieval server. Each tool maps to a necessary capability, with no filler or redundant operations.

Completeness4/5

The surface covers the core workflow end to end: find boards, run search, page results, read topics/floors for evidence, and verify auth. Minor gaps exist around richer filters or listing topics by board, but agents can work around them with the provided search flow.

Maintenance

ActivityMaintained
ResponsivenessNo issues