API 参考

服务器通过 stdio 暴露 4 个 MCP 工具。所有返回值都是 JSON 文本,所有失败都是带稳定 code 的结构化错误。 当前服务器版本 0.4.1。

工具一览

工具名必填参数是否联网返回
searchquery是搜索结果 JSON
researchquery是证据简报 JSON
fetch_pageurl 或 id是页面内容 JSON
status无否诊断 JSON

search

// 输入 schema
{
  "query":          string,              // 必填,1..∞
  "maxResults":     number  = 10,        // 1..20
  "site":           string,              // ≤ 100 字符,单域名
  "includeDomains": string[],            // 最多 5 项,每项 ≤ 100 字符
  "excludeDomains": string[],            // 最多 5 项,每项 ≤ 100 字符
  "region":         string,              // ≤ 10 字符,如 "cn-zh"
  "freshness":      "day" | "week" | "month" | "year",
  "timeRange":      string               // "YYYY-MM-DD..YYYY-MM-DD",≤ 40 字符
}

返回:

{
  "query": string,
  "queryRewritten": string,        // 仅当查询被改写时出现
  "queryYear": number,             // 仅当识别到「20xx 年」时出现
  "engine": string,
  "engineSwitched": boolean,
  "cached": boolean,
  "total": number,
  "deduped": number,
  "filtered": boolean,             // 是否应用了客户端侧域名兜底过滤
  "freshnessApplied": boolean,
  "freshnessAutoInferred": boolean,
  "timeRange": string,             // 仅当 freshnessApplied 为 true
  "results": [
    { "id": string, "title": string, "url": string, "snippet": string, "domain": string }
  ]
}

research

继承 search 的全部参数,另加三个:

// 追加参数
{
  "fetchTopN":     number = 2,      // 0..5,0 = 只返回概览不抓页
  "extractMode":   "summary" | "full",   // 默认 "summary"
  "maxPageLength": number           // 500..100000,默认取 FETCH_MAX_LENGTH
}

返回:

{
  "query": string,
  "engine": string,
  "engineSwitched": boolean,
  "cached": boolean,
  "freshnessApplied": boolean,
  "timeRange": string,          // 可选
  "overview": {
    "total": number,
    "deduped": number,
    "results": [ { id, title, url, snippet, domain } ]
  },
  "pages": [
    {
      "id": string,
      "url": string,
      "rank": number,
      "title": string,
      "description": string,
      "headings": [ { "level": number, "text": string } ],
      "content": string,
      "length": number,
      "truncated": boolean
    }
  ],
  "note": "Evidence brief ready. Summarize based on the page contents and cite source URLs."
}
pages 数组里的两种形状 成功项是完整的页面对象;失败项则是 { "id", "url", "rank", "error" } —— 消费方必须能处理这种稀疏形状,不能假设每一项都有 content。

fetch_page

{
  "url":         string,                    // 与 id 二选一
  "id":          string,                    // 与 url 二选一
  "extractMode": "summary" | "full",        // 默认 "summary"
  "maxLength":   number = 8000              // 默认取 FETCH_MAX_LENGTH
}
{
  "url": string,
  "title": string,
  "description": string,
  "headings": [ { "level": number, "text": string } ],
  "mainText": string,       // extractMode = summary 时填充
  "markdown": string,       // extractMode = full 时填充
  "length": number,
  "truncated": boolean,
  "cached": boolean
}

status

无参数。返回服务器运行状态、有效配置、缓存统计与逐引擎健康快照。

{
  "server": "ai-search-mcp",
  "uptimeSec": number,
  "config": {
    "engine": string,          // "auto" 或显式链
    "region": string,          // 未设置时为 "auto"
    "ratePerMinute": number,
    "cacheTtlMs": number,
    "langRouting": boolean,
    "selectorOverride": boolean
  },
  "cache": { "size": number, "hits": number, "misses": number },
  "engines": [
    {
      "engine": string,
      "status": "untested" | "healthy" | "degraded" | "cooling",
      "lastCode": string | null,
      "consecutiveFailures": number,
      "lastOkAt": string | null,
      "lastFailAt": string | null,
      "cooldownUntil": string | null
    }
  ]
}

错误码

所有面向模型的失败都是 McpSearchError,带一个稳定的机器可读 code,便于 Agent 分支处理。

INVALID_ARGUMENTS

参数不合法。例如 maxResults 超出 1–20,或 timeRange 不符合 YYYY-MM-DD..YYYY-MM-DD 格式。

ENGINE_NOT_FOUND

引擎名无法识别,或没有任何可用引擎(SEARCH_ENGINE 全部无效)。

ENGINE_ERROR

引擎返回了无法解析的内容、被反爬拦截,或全部引擎都失败。带 engineStatus 快照。

RATE_LIMITED

被目标引擎限流。附带 suggestedEngine 与 retryAfter 建议;引擎链会自动转移。

TIMEOUT

请求超过 SEARCH_TIMEOUT_MS(默认 10 秒)。属于可重试错误。

NETWORK_ERROR

网络层失败,例如 DNS 解析失败、连接被拒绝、代理不可用。

FETCH_ERROR

抓取页面失败,例如目标站返回 403、页面结构无法抽取,或响应体过大。

RATE_LIMITED、TIMEOUT、NETWORK_ERROR、ENGINE_ERROR 属于可重试错误:引擎链会在这些情况下继续尝试下一个引擎。 其余错误(如参数非法)会立即终止本次调用,不做无谓的引擎切换。

错误响应示例

限流

{
  "error": "RATE_LIMITED",
  "message": "bing rate limited",
  "suggestedEngine": "wait a few seconds, or switch engine (SEARCH_ENGINE=bing|baidu|sogou for CN users)",
  "retryAfter": 5
}

全部引擎失败

当所有引擎都失败时,错误里会带上一份引擎状态快照,消息中也包含逐引擎归因摘要, 并区分「全部处于冷却」(疑似网络受限 / IP 被临时限制)与普通失败:

{
  "error": "ENGINE_ERROR",
  "message": "全部引擎失败:bing=RATE_LIMITED (冷却至 13:45), baidu=验证码拦截。所有引擎均处于冷却/失败状态——可能是网络受限或 IP 被临时限制。建议等待片刻重试、配置 SEARCH_HTTP_PROXY,或设 SEARCH_ENGINE 指定可用引擎。",
  "engineStatus": [
    {
      "engine": "bing",
      "status": "cooling",
      "lastCode": "RATE_LIMITED",
      "consecutiveFailures": 2,
      "cooldownUntil": "2026-08-26T05:45:00.000Z"
    },
    {
      "engine": "baidu",
      "status": "degraded",
      "lastCode": "ENGINE_ERROR",
      "consecutiveFailures": 1,
      "cooldownUntil": null
    }
  ]
}
推荐的重试策略 遇到 RATE_LIMITED:等待 retryAfter 秒后重试,或先调 status 换一个健康引擎。 遇到「全部引擎冷却」:直接重试通常无效,应当等待冷却窗口结束或调整网络出口。

值域约束汇总

字段约束越界行为
query非空字符串INVALID_ARGUMENTS
maxResults整数 1–20回落到 SEARCH_MAX_RESULTS
site≤ 100 字符INVALID_ARGUMENTS
includeDomains数组,最多 5 项超出部分被丢弃
excludeDomains数组,最多 5 项超出部分被丢弃
region≤ 10 字符INVALID_ARGUMENTS
freshnessday / week / month / yearINVALID_ARGUMENTS
timeRangeYYYY-MM-DD..YYYY-MM-DD,起 ≤ 止INVALID_ARGUMENTS
fetchTopN整数 0–5回落到 2
extractModesummary / full回落到 summary
maxPageLength整数 500–100000回落到 FETCH_MAX_LENGTH

缓存键构成

理解缓存键有助于解释「为什么改了配置还是拿到旧结果」。

  • search查询(含域名操作符)+ maxResults + region + site + includeDomains + excludeDomains + freshness + timeRange + 引擎链
  • fetch_pageURL + extractMode
  • research独立的 research: 前缀键,包含查询、域名限定、时效与抓取参数

因此更换 SEARCH_ENGINE 或切换 extractMode 都不会命中旧缓存。

版本信息

  • server nameai-search-mcp
  • server version0.4.1
  • capabilitiestools.listChanged = false
已复制到剪贴板