通过35秒YellowPages抓取任务追踪JSON-RPC流量,发现长时MCP工具返回RUNNING状态加4个helper工具,Agent需轮询get-actor-run等待结果。
大多数 MCP 演示都展示一个在 1 秒内返回结果的工具。实际工具往往不是这样:爬虫、批量抓取或报表任务可能需要几分钟。我们在 Apify 上构建网页爬虫,所以这是我们每天都会遇到的问题。我们想知道,当远程 MCP 工具运行时间超过一次调用时,agent 实际收到的是什么,因此我们在 2026 年 10 月 2 日对 Apify 托管的 MCP 服务器(mcp.apify.com,当时版本为 0.17.1)进行了原始 JSON-RPC 流量追踪。任务是一个 YellowPages 爬虫读取一页搜索结果,大约需要 35 秒。
在 initialize 之后,tools/list 返回了每个我们通过服务器 URL 允许的爬虫对应的一个工具,外加四个专门针对长时间运行任务才有意义的辅助工具:
这些辅助工具是第一个信号:服务器预期 agent 会回来获取结果。
Agent 调用爬虫工具,传入普通参数:
{ "searchKeyword": ["plumbers"], "location": "Austin, TX", "maxPages": 1 }
响应在大约 30 秒后到达,此时任务仍在运行。响应包含两个 content 部分。第一部分是结构化的:
{
"runId": "…",
"status": "RUNNING",
"storages": { "datasets": { "default": { "id": "…", "itemCount": 23 } } }
}
第二部分是面向模型的纯文本:
RUNNING for 30s. In progress. 23 results so far.
Use get-actor-run with runId=… and waitSecs=30 to poll for completion.
第二部分才是有趣的设计选择。服务器既返回机器可读的状态,也用普通英文告诉模型下一步该做什么。只解析 JSON 的 agent 能正常工作;只读文本的 agent 也知道要去轮询。
我们第一次让 get-actor-run 等待 60 秒,然后尝试 120 秒。两次都返回了 JSON-RPC 错误,而不是工具结果:
MCP error -32602: Invalid arguments for tool "get-actor-run".
Validation errors: /waitSecs: must be <= 45.
使用 waitSecs: 30 后调用返回了 SUCCEEDED,以及运行时间(约 35 秒)和数据集项数(37)。结果还携带了一个 _meta 块,包含该运行在平台上的资源使用量,客户端可以在启动更大任务之前向用户展示。
这里有两件事需要处理:
验证问题作为协议错误(-32602)返回,而不是 isError 标记为 true 的工具结果。如果你的客户端只检查 isError,就会漏掉它们。
等待时间有上限,所以一个 5 分钟的任务意味着需要多次轮询。循环需要一个总体的截止时间,而不只是每次调用的等待时长。
get-dataset-items 接收数据集 ID 加上 offset 和 limit,返回:
{ "datasetId": "…", "items": [ … ], "itemCount": 37, "totalItemCount": 37, "offset": 0, "limit": 100 }
对于大型任务,用 offset 分页读取,而不是一次性把所有数据拉进模型的上下文窗口。
当晚第二个测试任务——一个 Google Maps 爬虫,运行了约 157 秒,最终状态为 SUCCEEDED,但 get-dataset-items 返回了空结果:
{ "items": [], "itemCount": 0, "totalItemCount": 0, "offset": 0, "limit": 100 }
上游依赖出了问题,任务干净地结束了,没有任何数据可以展示。如果你的 agent 把 SUCCEEDED 当作"完成了,报告成功",它会告诉用户一切正常。检查 item count,把"成功但为空"当作用户需要知道的结果来处理。
你的 MCP 客户端如何处理超过一次调用时长的工具:轮询、进度通知,还是其他方式?我们很好奇什么方案在生产环境中真正经得住考验。
Written with AI assistance. Every request and response above comes from real calls we made on Oct 2, 2026.