x_search 超时的主因是默认 30 秒超时过短(该查询实测约 49~56 秒),并且当前 chat/completions 请求未显式传 stream:false,网关默认返回 SSE 流,导致当前 JSON-only 解析路径在超时放宽后会触发“非 JSON 数据”错误。
- MCP Inspector 可成功连接并
list_tools。 - 调用
x_search后返回:TIMEOUT/请求超时(>30000ms)。 - 用户疑问:
GROK_BASE_URL是否需要带/v1,模型名大小写是否有问题。
Hypothesis: 工具调用链中存在固定 30 秒超时或 URL 拼接问题。
Findings:
src/config.ts默认超时是30_000。src/httpClient.ts用AbortController在timeoutMs到期时中断请求。src/grokClient.ts调 chat endpoint 使用/v1/chat/completions。src/tools.ts的x_search未传stream:false。 Evidence:src/config.tslines 5, 31-41src/httpClient.tslines 24-30, 72-75src/grokClient.tslines 70-72src/tools.tslines 117-136 Conclusion: Confirmed(代码层面存在 30s 硬超时 + 默认未关闭 stream)
Hypothesis: Base URL 是否含 /v1 可能导致路由错误。
Findings: 当前实现 new URL('/v1/chat/completions', baseUrl + '/') 的结果:
https://host->https://host/v1/chat/completionshttps://host/v1->https://host/v1/chat/completionshttps://host/proxy->https://host/v1/chat/completions(/proxy被丢弃)https://host/proxy/v1->https://host/v1/chat/completions(/proxy/v1被丢弃) Evidence: runtime URL matrix script output. Conclusion:- 对“仅 host 或 host/v1”两种形式都可工作。
- 但若未来 base URL 带路径前缀(如
/proxy),当前代码会丢前缀,存在潜在路由风险。
Hypothesis: 网络/鉴权/模型名问题导致超时。
Findings:
- 无效 token 调
/v1/chat/completions返回401(约 7.6s),说明网络可达。 - 有效 token +
stream:false+ 简单ping返回200(约 20s)。 - 有效 token + 用户查询(
请总结今天宝玉发布的内容)+stream:false返回200(约 49.4s)。 - 有效 token + 用户查询 + 默认 stream(未传 stream)返回 SSE(
data:chunk),总时长约 56.4s。 - 模型名改成大写
GROK-4.20-BETA,快速返回400 model_not_found(约 9.3s)。 Evidence: curl probes tohttps://api-grok-21.beta.localcan.dev/v1/chat/completions. Conclusion: - 超时主要不是鉴权、DNS 或模型大小写问题。
- 主要是请求耗时 >30s;且默认 stream 行为与当前 JSON 解析模型不匹配。
Hypothesis: 现有 MCP 代码可稳定复现该现象。
Findings:
- 用当前
dist代码直接调用x_search:30 秒稳定报请求超时(>30000ms)。 - 将同一路径 timeout 提高到 70 秒后,转为
Grok API 返回了非 JSON 数据(对应 SSE 响应)。 Evidence: Node scripts importingdist/httpClient.js,dist/grokClient.js,dist/tools.js. Conclusion: Confirmed(与用户在 Inspector 中表现一致)
Hypothesis: 最近提交引入了回归。
Findings: 当前目录不是 git 仓库,无法获取提交历史。
Evidence: fatal: not a git repository。
Conclusion: Eliminated(本地无历史可查)
- 主因:超时阈值过短
GROK_REQUEST_TIMEOUT_MS默认 30000ms,而目标查询实测耗时约 49~56s。
- 次因:chat 默认流式响应未处理
- 当前
x_search/general_search未显式传stream:false。 - 网关默认返回 SSE(
data: ...),而当前客户端仅按 JSON 一次性解析。 - 所以 timeout 增大后会暴露为“非 JSON 数据”错误。
- 当前
- 非主因(本次环境)
- Base URL 是否含
/v1:在当前域名下两者都可用;不是本次直接原因。 - 模型大小写:当前代码使用的小写模型名是正确的;大小写错误会快速 400,不会表现为 30s TIMEOUT。
- Base URL 是否含
- 立刻修复 chat 请求参数
- 在
x_search/general_search/video_generation的 chat/completions 请求中显式设置stream:false。
- 在
- 提高默认超时并支持按工具覆盖
- 建议默认至少 90s(或 120s)。
- 增加
GROK_X_SEARCH_TIMEOUT_MS/GROK_GENERAL_SEARCH_TIMEOUT_MS。
- 增强错误可观测性
- TIMEOUT/HTTP 错误里返回 URL(去敏)、elapsed、timeout、request id(如果有)。
- 修复 URL 拼接鲁棒性(预防)
- 采用相对路径拼接并处理
/v1去重,避免 base URL 带路径前缀时被吞掉。
- 采用相对路径拼接并处理
- 启动日志打印(脱敏)base URL、超时、模型名。
- 增加一个“连通性自检”工具或启动自检(可选)验证 chat endpoint 响应类型。
- 为 chat 响应增加 content-type 检查:若
text/event-stream则提示 stream 配置问题。