Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ name: CI
on:
push:
branches: [main]
tags: ['v*']

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Check the package version before skipping publish

With this new v* tag trigger, release tags now reach the publish job, but that job's check runs npm view <repo> "$VERSION"; npm view treats arguments after the package spec as fields ([<package-spec>] [<field>...]), not as the version to test. Once the npm package exists, this command can exit successfully even when $VERSION is unpublished, causing already_published=true and skipping npm publish for new tags. Use the package spec from package.json, e.g. agent-search-mcp@$VERSION, and query version instead.

Useful? React with 👍 / 👎.

pull_request:
branches: [main]

jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22]
node-version: [18, 20, 22]

steps:
- uses: actions/checkout@v7
Expand All @@ -31,9 +33,48 @@ jobs:
- name: Test
run: npm test

quality:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v7

- name: Use Node.js 22
uses: actions/setup-node@v7
with:
node-version: 22
cache: 'npm'

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Lint
run: npm run lint

- name: TypeScript check
run: npx tsc --noEmit

- name: Verify frozen benchmark fixture
run: npm run benchmark:verify

windows-build:
runs-on: windows-latest

steps:
- uses: actions/checkout@v7

- name: Use Node.js 22
uses: actions/setup-node@v7
with:
node-version: 22
cache: 'npm'

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Build
run: npm run build

publish:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
Expand Down Expand Up @@ -73,4 +114,4 @@ jobs:
uses: softprops/action-gh-release@v2
with:
body_path: CHANGELOG.md
generate_release_notes: true
generate_release_notes: true
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dist/
.pi/
.github/prompts
coverage/
benchmarks/fixtures/live-latest.json
# Claude Code hooks (不要提交到 repo, 因为路径可能不同)
.claude/hooks/
.claude/session_state/
Expand Down
20 changes: 12 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ tags:
---
# Agent Search MCP — 多引擎统一搜索 MCP Server

一句话:11 引擎搜索(ddg/sogou/bing/baidu/brave/tavily/exa/wikipedia/startpage/yandex/mojeek),MCP 协议接入,**免费 + 多源验证 + Token 优化**。
一句话:12 个搜索适配器(8 个零密钥 + 4 个可选 API),MCP 协议接入,**中文原生 + 多源聚合 + Token 可控**。

## 当前阶段

**版本**: v3.1.0(已发布 npm + GitHub Release)— [查看完整路线图](docs/superpowers/plans/2026-07-22-iteration-roadmap.md)

**测试**: 438 passed, 38 files | **引擎**: 11 (8 免费, 3 付费) | **Python**: 可选(DDG 自动 HTML 回退)
**测试**: 510 passed, 43 files | **适配器**: 12(8 零密钥, 4 可选 API)| **Python**: 可选(DDG 自动 HTML 回退)

当前优先事项:
1. **Phase A: Agent UX** — `setupFetchTools` 拆分、MCP annotations、错误区分度
2. **Phase C: 性能** — DDG News HTML 回退、lite.ddg 第三层回退
3. **Phase D: 测试** — brave/tavily mock、E2E 集成测试、SSRF 安全测试
4. **分发推广** — awesome-mcp-servers PR、掘金文章(持续)
1. **搜索质量证据** — 在稳定网络 runner 上捕获真实 fixture 并增加人工相关性标签
2. **HTTP 部署指南** — Bearer 密钥轮换、Origin allowlist 与反向代理配置
3. **信号校准** — 用真实失败查询持续校准 relevance/confidence/source_count
4. **分发推广** — 发布已校准口径的掘金/Reddit/V2EX 素材(持续)

## 常用命令

Expand Down Expand Up @@ -55,7 +55,7 @@ fasm extract "https://..." # CLI 提取

## 架构

`src/` 下按职责分层:`tools/`(MCP 工具定义)、`engines/`(11 引擎适配)、`aggregation/`(评分/去重/丰富)、`synthesis/`(结果合成)、`infrastructure/`(安全/缓存/限速)。Agent 自己探索 `src/` 目录获取最新结构。
`src/` 下按职责分层:`tools/`(MCP 工具定义)、`engines/`(12 个引擎适配器)、`aggregation/`(评分/去重/丰富)、`synthesis/`(结果合成)、`infrastructure/`(安全/缓存/限速)。Agent 自己探索 `src/` 目录获取最新结构。

## 编码规范

Expand Down Expand Up @@ -92,12 +92,16 @@ vitest,`tests/` 按功能目录组织。公共函数 + 新功能必须有测

- **Bing/Baidu 测试**: 实际搜索需要网络,单测用 mock 模拟 HTTP 响应
- **ddgs 依赖**: Python 库 `ddgs` 为可选依赖。未安装时 DDG 引擎自动回退到 Node.js HTML 引擎(cheerio 解析)。Docker 镜像不含 Python,仅使用 HTML 引擎。`isDdgsAvailable()` 检测可用性,结果缓存在进程生命周期内
- **cheerio 依赖**: DuckDuckGo HTML 引擎依赖 cheerio(纯 JS,无 native binding),npm install 自动安装
- **cheerio 依赖**: DuckDuckGo HTML 引擎依赖 cheerio(纯 JS,无 native binding)。必须固定在 `1.0.0` 以维持 Node 18 支持;Cheerio 1.2+ 要求 Node 20.18.1+
- **中文搜索**: Sogou + Baidu 专供中文搜索,不要用 Google Translate 翻译替代
- **请求合并**: 相同查询在 100ms 内自动合并,避免并发重复请求
- **Env 变量**: API key 通过环境变量传入,不走配置文件
- **npm publish**: 当前 registry 是腾讯镜像(mirrors.tencentyun.com),publish 前必须切到 registry.npmjs.org
- **工具可见性**: `ENABLED_TOOLS` / `DISABLED_TOOLS` 环境变量控制 MCP 工具注册。`DISABLED_TOOLS` 优先级高于 `ENABLED_TOOLS`。默认全部启用。资源(capabilities/health)不受此策略影响。
- **路由能力面**: 12 个适配器已统一进入 MCP / CLI / 瀑布路由;You.com 必须有 `YDC_API_KEY`,不要把“包内存在”与“当前凭证可用”混淆。
- **Benchmark 口径**: 可保留 2026-07-24 历史 30 查询实测的 28.7% / 35.5% / 75%,但必须限定当时查询集和环境。当前冻结 fixture + `gpt-tokenizer` 用于可重现的格式化回归,不代表搜索质量。
- **HTTP 安全默认值**: HTTP / both 模式必须配置 `HTTP_AUTH_TOKEN`;只有显式 `HTTP_ALLOW_UNAUTHENTICATED=true` 才允许无认证运行。带 Origin 的浏览器请求必须命中 `ALLOWED_ORIGINS`。
- **stdio 日志**: stdout 只用于 MCP JSON-RPC。运行日志必须走 `logger`(stderr)或 `console.error`,禁止在服务路径使用 `console.log`。

## 文档索引

Expand Down
34 changes: 32 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ tags:
---
# Changelog

## Unreleased

### Features

- Unified all 12 search adapters across MCP, advanced search, CLI, and waterfall routing.
- Split result signals into `relevance`, normalized `confidence`, and independent `source_count`; retained `score` as a deprecated compatibility alias and mapped legacy `MIN_CONFIDENCE=2/3` values to source count.
- Added a capture/replay benchmark with production execution telemetry, frozen fixtures, locked `gpt-tokenizer`, and a CI regression gate. Historical 30-query measurements remain published with their environment scope.
- Secured HTTP MCP mode with required Bearer authentication and browser Origin allowlisting. Unauthenticated mode now requires explicit `HTTP_ALLOW_UNAUTHENTICATED=true`.

### Documentation

- Restored the historical 28.7% / 35.5% token and 75% engine-call measurements in README and promotion drafts with explicit query-set and environment boundaries.

## v3.3.0 (2026-07-24)

> **Headline: Semantic dedup + rerank via Model2Vec. <10ms latency. Optional, opt-in.**
Expand All @@ -21,6 +34,23 @@ tags:
- **Zero dependency by default**: Semantic features are OFF by default. No Python/model2vec required unless explicitly enabled.
- **Graceful degradation**: If the Python bridge is unavailable (no model2vec installed, process crash, etc.), results pass through unchanged — no broken searches.

### 🔧 Fixes

- **Restored zero-Python DDG fallback**: The search orchestrator no longer rejects DuckDuckGo before its Node.js HTML fallback can run.
- **Protected stdio JSON-RPC**: Circuit-breaker transitions now use the stderr logger instead of writing to stdout.
- **Closed CSDN SSRF path**: `fetch_csdn_article` now accepts only HTTPS `blog.csdn.net` URLs and rejects redirects.
- **Cross-platform build**: Replaced POSIX-only `mkdir`/`cp` commands with a Node.js build helper; `npm run build` now works on Windows.
- **CI coverage**: Restored Node.js 18/20/22 runtime coverage, added a Node.js 22 quality gate, disabled matrix fail-fast, and added a Windows build job.
- **Node.js 18 compatibility**: Pinned Cheerio to its Node 18-compatible release and close idle HTTP connections during shutdown.
- **Lint compatibility**: Pinned TypeScript to the supported 6.x API until `typescript-eslint` supports TypeScript 7.
- **Runtime metadata**: MCP initialization, HTTP health, and capabilities now report v3.1.3 / Apache-2.0 consistently with the published package.

### 📚 Documentation

- Replaced volatile competitor pricing claims with a capability-based comparison linked to official repositories.
- Marked historical benchmark percentages as exploratory until engine-call telemetry and frozen fixtures are implemented.
- Added a reusable English/Chinese promotion kit and rewrote the Juejin draft around verified capabilities.

### 🔧 Env vars

| Variable | Default | Description |
Expand All @@ -34,8 +64,8 @@ tags:

### 📊 Stats

- **Tests**: 480 passing (+17: 6 semantic + 11 config)
- **Files**: 42 test files (+1: semantic.test.ts)
- **Tests**: 498 passing
- **Files**: 43 test files

## v3.2.0 (2026-07-24)

Expand Down
29 changes: 22 additions & 7 deletions HANDOVER.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
type: HandoverDoc
title: agent-search-mcp HANDOVER
timestamp: '2026-07-24T09:10:00+08:00'
timestamp: '2026-07-25T04:30:00+08:00'
description: 会话日志和项目状态
tags:
- agent-search-mcp
Expand All @@ -11,15 +11,24 @@ tags:

## 项目状态

**版本**: v3.3.0(P2 语义层已完成,待发布)
**引擎**: 11 个(ddg/sogou/bing/baidu/brave/tavily/exa/yandex/mojeek/wikipedia/startpage)
**测试**: vitest — 480 passed, 42 test files
**最后更新**: 2026-07-24
**版本**: npm v3.1.3;main 含 v3.3.0 候选功能,尚未发布
**引擎**: 12 个适配器;`free_search`/`free_search_advanced`/CLI/瀑布模式已全部统一路由
**测试**: vitest — 510 passed, 43 test files
**最后更新**: 2026-07-25
**npm**: https://www.npmjs.com/package/agent-search-mcp
**Python 依赖**: 可选(DDG 自动回退到 cheerio HTML 引擎;语义层需 `pip install model2vec`)

## 最近活动

- [2026-07-25] ✅ 宣传层级定稿:“免费 + 省 Token”作为第一卖点,“Agent 搜索路由器”作为独特机制和长期路线
- [2026-07-25] ✅ 统一 12 适配器路由,拆分 relevance/confidence/source_count 契约
- [2026-07-25] ✅ Benchmark v3:真实执行遥测、冻结 fixture、锁定 tokenizer 与 CI 回归门禁
- [2026-07-25] ✅ HTTP Bearer 认证 + Origin allowlist;无认证模式必须显式开启

- [2026-07-25] ✅ Node 18 兼容:Cheerio 固定到 1.0.0;HTTP 关闭时主动清理 keep-alive 空闲连接
- [2026-07-25] ✅ CI 分层:Node 18/20/22 各自 build/test;Node 22 独立执行 lint/typecheck,矩阵不再 fail-fast
- [2026-07-25] ✅ 产品加固:DDG HTML fallback、stdio 日志隔离、CSDN SSRF 防护、Windows 构建
- [2026-07-25] ✅ 市场口径校准:竞品对比改为能力矩阵,历史 benchmark 标为探索性,新增推广素材包
- [2026-07-24] ✅ P2 语义层:Model2Vec 语义去重 + 语义重排(SEMANTIC_DEDUP/SEMANTIC_RERANK,默认 off)
- [2026-07-24] ✅ P0 渐进披露 + 置信度过滤(MAX_FULL_RESULTS/MIN_CONFIDENCE,compact 模式)
- [2026-07-22] ✅ v3.1.1: Streamable HTTP + Capabilities 声明 + MCP annotations + EngineError + DDG News HTML 回退
Expand All @@ -36,10 +45,16 @@ tags:

**已完成 (v3.1.1)**: A1/A2/A3 + C1 + D1/D2/D3 + B1/B2 — 全部绿色 ✅

**下一阶段 (v3.2.0+)**: C2 第三层回退 / C3 引擎惰性加载 / O1 awesome-mcp-servers PR / O2 掘金文章
**下一阶段**:

1. 在稳定网络 runner 上捕获非空真实 fixture,并补人工相关性标签
2. 在真实反向代理环境验收 Bearer 密钥轮换、Origin 策略和限流
3. 合并加固分支后,按“Agent 搜索路由器”独特路线发布掘金文章和短帖素材

## 已知限制

- **DDG HTML 限流**:POST 大量请求触发 HTTP 202,Python 路径不受此限制
- **DDG News 无 HTML 回退**:News 搜索仅支持 Python 路径
- **无分页**:所有引擎目前只返回第一页结果
- **Benchmark 边界**:冻结 fixture 只验证格式和 token 回归,暂无人工相关性标签;历史精确数字必须带当时查询集/环境限定
- **HTTP 部署**:已有 Bearer/Origin 防护,但生产环境仍需 TLS、密钥轮换和反向代理限流
- **依赖审计**:本次安装报告 5 项(1 low / 2 moderate / 2 high);当前 runner 访问 npm audit endpoint 被 EACCES 拦截,未能刷新 advisory 明细。不要为清零审计而盲目降级 MCP/测试协议栈。
Loading