教程Claude Code系列第 13 / 21 篇

Claude API 的服务器端工具:联网搜索、抓取网页、代码执行、工具搜索、顾问和 MCP 连接器

这几个工具由 Anthropic 的服务器执行,你只管在请求里打开。本文整理各自的用法、计费和限制,以及工具太多时怎么省上下文。通过中转站实测:联网搜索、工具搜索、顾问能用;抓取网页、MCP 连接器被拒,代码执行被悄悄忽略。

发布 · 约 22 分钟读完 · 经人工审核()· 本站的内容怎么来的

本站已实测,测试日期:2026-10-13。

本页目录(12 节)
  1. 一、服务器端工具共同的几件事
  2. 二、联网搜索
  3. 三、抓取网页(按文档整理)
  4. 四、代码执行(按文档整理)
  5. 五、工具太多时:工具搜索
  6. 六、顾问:干活的模型中途请教更强的模型
  7. 七、MCP 连接器(按文档整理)
  8. 八、工具和结果太占上下文时,用哪一招
  9. 九、通过中转站实测到的
  10. 和 Claude Code 的关系
  11. 花费
  12. 这次实测没有覆盖到的

这篇教程解决一个问题:想让 Claude 联网查资料、读一个网页、跑一段代码,但不想自己搭搜索接口和沙箱,怎么办?

用服务器端工具。前两篇讲的工具都要你自己执行;这一篇的工具由 Anthropic 的服务器执行,你在请求里把它打开,回来的响应里已经带着结果。

工具调用的基本概念见《Claude API 工具调用入门》。

实测环境
日期 2026-10-13
方式 Python:anthropic SDK 1.13.0,部分实验直接发 HTTP 请求
模型 Sonnet 5.5,顾问用 Opus 5.5
连接方式 通过酷站AI 中转站,不是直连官方

先说实测的结论。 通过这家中转站:

工具 结果
联网搜索 能用,带引用
工具搜索 单次请求能用;带着历史继续对话时报 400
顾问 能用
抓取网页 400,不支持
代码执行 被悄悄忽略:返回 200,模型说自己没有这个工具
程序化调用工具 400,不支持
MCP 连接器 400,不支持

所以抓取网页、代码执行、程序化调用、MCP 连接器这四节是按文档整理的,没有跑通过。

一、服务器端工具共同的几件事

响应里多了两种块

你不用回 tool_result。响应里会直接出现一对块:

  • server_tool_use:Claude 发出的调用。它的 id 以 srvtoolu_ 开头,和你自己的工具(toolu_ 开头)区分开。
  • 结果块:每个工具有自己的类型,比如联网搜索是 web_search_tool_result。它用 tool_use_id 和上面那个调用对上。

下一轮对话时,把这些块原样放回 messages,不要挑着留。

服务器那边自己在循环

一次请求里,模型可能搜好几次、读好几次结果,才给出回答,这些都在服务器那边完成。这个循环有次数上限。到了上限还没做完,响应的 stop_reason 会是 pause_turn,意思是“还没完,暂停一下”。处理办法是把这条回复原样追加到 messages 里,带着同样的 tools 再发一次,让它接着做;继续之后还可能再暂停,所以要循环,并且给循环设上限。

本站的测试里没有遇到 pause_turn。

同一轮里又有你自己的工具

Claude 可以在同一批并行调用里,既调服务器端工具,又调你自己的工具。这时接口不会先执行服务器端工具,而是立刻把响应还给你:

  • stop_reason 是 tool_use,不是 pause_turn。
  • content 里有 server_tool_use 块,但没有它的结果块。
  • 没有别的标记。判断办法就是找“有调用、没结果”的服务器端调用。

你要做的是:执行自己的工具,回一条只有 tool_result 块的用户消息,tools 保持不变。接口收到后才去执行那个服务器端工具,下一次响应以它的结果块开头。

这个流程实测跑通了。让模型同时“联网搜 Python 最新版本”和“用工具查服务器上的 Python 版本”:

第一次: HTTP 200 tool_use
  块: [('server_tool_use', 'web_search'), ('tool_use', 'get_local_python_version')]
  服务器端调用 1 个,其中已有结果的 0 个
第二次: HTTP 200 end_turn
  块: [('web_search_tool_result', ''), ('text', ''), ('text', ''), …]

这里有一个容易踩的地方:那条用户消息里如果在工具结果后面加了文字,接口会认为这一轮结束了,而服务器端工具还悬着,请求就会报 400。想补充别的话,等这一轮结束后另发一条消息。

限制它能访问哪些网站

联网搜索和抓取网页都接受两个参数,二选一:

参数 意思
allowed_domains 只允许这些域名
blocked_domains 不许这些域名

规则:

  • 不带 https://,写 example.com。
  • 子域名自动包含:example.com 管得到 docs.example.com。
  • 联网搜索可以带路径,例如 example.com/blog。抓取网页只按域名匹配,带路径的条目永远匹配不上。
  • 两个参数不能同时写。实测同时写会报 400:Only one of allowed_domains and blocked_domains can be provided.
  • 域名只用 ASCII 字符。用西里尔字母冒充拉丁字母的域名看起来一样,实际是另一个站。

二、联网搜索

用法

下面这段代码在服务器上原样跑过:

import anthropic

client = anthropic.Anthropic()

reply = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1500,
    tools=[{
        "type": "web_search_20250305",
        "name": "web_search",
        "max_uses": 2,                          # 这一次请求最多搜几次
        "allowed_domains": ["python.org"],      # 只看这些站
    }],
    messages=[{"role": "user", "content": "Python 3.15 的正式版是哪天发布的?"}],
)

print(reply.stop_reason, reply.usage.server_tool_use)
for block in reply.content:
    if block.type == "server_tool_use":
        print("搜索:", block.input["query"])
    elif block.type == "web_search_tool_result":
        for r in block.content[:3]:
            print("  结果:", r.title, r.url)
    elif block.type == "text":
        print(block.text, end="")
        for c in block.citations or []:
            print(f"〔{c.url}〕", end="")
print()

输出(后半有删节):

end_turn ServerToolUsage(web_fetch_requests=0, web_search_requests=1)
搜索: Python 3.15 release date final
  结果: PEP 790 https://peps.python.org/pep-0790/
  结果: Python Release Python 3.15.0rc2 https://www.python.org/downloads/release/python-3150rc2/
  结果: Python Release Python 3.15.0 https://www.python.org/downloads/latest/python3.15/
Python 3.15.0 正式版发布于 **2026 年 10 月 9 日**(星期五)。

- python.org 上标注的发布日期是 2026 年 10 月 9 日。〔https://www.python.org/downloads/latest/python3.15/〕
- 这一天比原计划晚了一周。……〔https://www.python.org/downloads/release/python-3150rc3/〕

回答被切成了很多个 text 块,带引用的那几块各自挂着 citations。每条引用里有 url、title 和 cited_text(最多 150 个字符的原文)。官方的要求是:把回答直接展示给最终用户时,必须带上指向原始来源的引用。

搜索结果的每一条有 url、title、page_age,还有一个 encrypted_content。正文是加密的,你读不到,它是留给下一轮对话用的。

其他参数:

参数 作用
max_uses 一次请求最多搜几次。超了的那次搜索返回 max_uses_exceeded 错误
user_location 按用户所在地调整结果,可以给城市、地区、国家代码、时区
allowed_callers 见下面“三个版本”

Claude 什么时候会搜:问题涉及最近的事、会变的数据,或者你明说了要查。问常识、让它写东西、分析对话里已有的内容,它不搜。实测带着搜索工具问“1 加 1 等于几”,它直接回答,没有搜。

三个版本

type 多了什么
web_search_20250305 基础版
web_search_20260209 动态过滤:Claude 先写代码把搜索结果筛一遍,只把有用的放进上下文
web_search_20260318 再加一个 response_inclusion 参数,可以让被代码消化掉的搜索块不出现在响应里

动态过滤靠的是代码执行,接口会自动替这次请求准备好,你不用另外加代码执行工具,也不为它另外付费。后两个版本默认只从代码执行里调搜索;想让模型直接搜、不过滤,给工具加 "allowed_callers": ["direct"]。

本站试了基础版、最新版、最新版加 direct 三种写法,都返回了正常的搜索结果,响应的形状没有区别。动态过滤有没有真的发生,从响应里看不出来。这家中转站不支持代码执行(见第四节),本站猜测没有发生,但无法确认。

多轮对话:搜索块要原样带回

官方文档说,encrypted_content 缺了或者被改过,请求会报 400。本站试了三种带回的方式,问的是同一个追问:

上一条回复怎么带回 通过中转站的结果
原样带回 正常,模型根据上一轮的搜索结果回答
把 encrypted_content 改掉几个字符 没有报错。模型说“我其实没有做过任何搜索”,并且撤回了上一轮的回答
只留文字,去掉搜索块和引用 同上,模型说上一轮的内容“没有可靠来源,请不要采信”

后两种的结果是一致的:搜索块没了,模型就不再认上一轮答案里的那些事实。所以存对话历史的时候,把整条助手消息完整存下来。只存文字省了空间,但下一轮模型会反过来否定自己。

计费

  • 官方价是每 1,000 次搜索 10 美元,另外照常收 token 的钱。出错的搜索不收费。用了多少次,看 usage 里 server_tool_use 下的 web_search_requests。
  • 搜索结果算输入 token,而且不少。 本站另一次同样限定 python.org 的请求,搜了一次,返回 10 条结果,输入合计 12,611 个 token。这些结果留在历史里,后面每一轮都要再付一次(可以配缓存)。
  • 只是带着这个工具、一次都没搜,也有开销:实测“1 加 1 等于几”那次请求的输入是 2,855 个 token,不带工具时同样长短的问题只有五十个左右。

通过中转站时,搜索次数怎么计费由中转站决定,本站没有核对账单。

报错

搜索出错时接口仍然返回 200,错误在结果块里:content 变成一个错误对象,带一个错误码。常见的有 too_many_requests(限流)、max_uses_exceeded、query_too_long、unavailable。搜索成功但没有结果不算错,content 是一个空列表。

三、抓取网页(按文档整理)

通过这家中转站,带上抓取网页工具的请求直接返回 400,下面是文档的内容。

抓取网页让 Claude 读取指定网址的完整内容,支持网页和 PDF。

tools = [{
    "type": "web_fetch_20250910",
    "name": "web_fetch",
    "max_uses": 5,
    "allowed_domains": ["docs.python.org"],
    "max_content_tokens": 20000,            # 抓回来的内容最多占多少 token,超了就截断
    "citations": {"enabled": True},         # 引用默认是关的
}]

几条和联网搜索不一样的地方:

  • 只能抓对话里出现过的网址。 用户消息里的、你自己的工具结果里的、之前搜索或抓取结果里的网址都算;只出现在 Claude 自己输出里的不算,只写在系统提示词里的也不算。这是为了防止它被诱导着把数据拼进网址发出去。
  • 不执行 JavaScript。 靠脚本渲染的页面抓不到正文,这类页面用上一篇讲的浏览器操作工具。
  • 引用默认关闭,要自己打开。
  • 不另外收费,只收抓回来的内容占的 token。文档给的参考:普通网页约 2,500 个 token,大的文档页约 25,000 个,一篇论文 PDF 约 125,000 个。所以 max_content_tokens 最好设上。
  • 结果有缓存,不一定是最新的。web_fetch_20260309 及之后的版本可以用 "use_cache": false 强制重新抓。
  • 网址最长 250 个字符。

文档特别提醒:在既处理不可信内容、又接触敏感数据的环境里开这个工具,有数据被带出去的风险。担心这一点,就不开,或者用 allowed_domains 限死。

同时开了搜索和抓取时,用户只说“读一下某某项目的 README”而不给网址,Claude 会先搜到网址,再抓下来读。

四、代码执行(按文档整理)

通过这家中转站,这个工具被悄悄忽略了。 本站带着它发请求,要模型“用代码执行工具算 2 的 100 次方各位数字之和”,拿到的是 200 和这样一段回答:

我这里没有代码执行工具,没法真正运行代码,所以下面的结果不是运行输出,而是我手算的。

没有报错,响应里也没有任何代码执行的块。模型这次老实说了没有运行;如果它不说,你会把一个心算的结果当成跑出来的。用这个工具时,检查响应里是不是真的有 server_tool_use 块,不要只看文字。

下面是文档的内容。

代码执行给 Claude 一个 Anthropic 托管的沙箱容器,它可以在里面跑 Bash 命令、建文件改文件、写 Python 并运行。

tools = [{"type": "code_execution_20250825", "name": "code_execution"}]
项目 内容
环境 Linux 容器,Python 3.11,1 个 CPU,5 GiB 内存,5 GiB 磁盘
网络 完全没有。不能联网,也就装不了新的包
预装的库 pandas、numpy、scipy、scikit-learn、matplotlib、sympy,以及读写 Excel、PDF、Word、PPT 的一批库
容器的寿命 默认每次请求一个新容器。响应里有容器的 id,下次请求带上它就能接着用,里面的文件还在。容器最多保留 30 天
你自己的文件 先用 Files API 上传,再在消息里引用
它生成的文件 要它把文件放进 $OUTPUT_DIR,结果里才会有文件的 ID,再用 Files API 下载

三个版本:code_execution_20250825 是基础版;code_execution_20260120 加了解释器状态的保留和下一节的程序化调用;code_execution_20260521 运行环境相同,只是在工具说明里告诉了模型每段 Python 有 90 秒的时限。

计费:按执行时间算,每次最少算 5 分钟。每个组织每月有 1,550 小时的免费额度,超出的部分每个容器每小时 0.05 美元。和联网搜索或抓取网页的新版本(20260209 及之后)一起用时,代码执行不另外收费。

如果你同时还给了自己的 bash 工具,Claude 面对的就是两台互不相通的机器:一台是 Anthropic 的沙箱,一台是你的环境。文档建议在系统提示词里把这件事讲清楚,免得它在一边建了文件,到另一边去找。

程序化调用工具

普通的工具调用,每调一次都要过一遍模型:模型发出调用,你回结果,结果进上下文,模型再想下一步。要查 20 个员工的报销记录,就是 20 个来回,几千行明细全进了上下文。

程序化调用是另一条路:Claude 写一段 Python,在代码执行的沙箱里用代码调你的工具。循环、筛选、汇总都在代码里做,中间结果不进上下文,只有最后的输出回到模型那里。

打开的办法是给你的工具加一个字段,并且带上 code_execution_20260120 或之后的版本:

tools = [
    {"type": "code_execution_20260120", "name": "code_execution"},
    {"name": "get_expenses", "description": "…(把返回的格式写清楚,模型要在代码里解析它)",
     "input_schema": {"…": "…"},
     "allowed_callers": ["code_execution_20260120"]},
]

之后的流程:

  1. 代码跑到调你的工具那一行时暂停,接口返回 stop_reason: tool_use 和一个 tool_use 块。这个块的 caller 字段不再是 direct,而是指向发起调用的那次代码执行。
  2. 你执行工具,回 tool_result。这条消息里只能有 tool_result,一个字的文字都不能加;请求里要带上响应给的容器 id。
  3. 代码接着跑,可能再次暂停要下一个结果,也可能跑完,由 Claude 给出最后的回答。

要知道的限制:

  • 结果要在大约 4 分钟内送回,否则代码里会抛超时错误。
  • 开了 strict 的工具不能被程序化调用;MCP 连接器提供的工具、电脑和浏览器工具集也不能。
  • allowed_callers 只是引导,不是硬性限制。你的代码仍然要能处理模型直接调这个工具的情况。
  • 工具结果会被代码当成字符串处理。结果来自外部的话,要防它里面夹带能被执行的内容。

文档给的效果:在一个 75 个工具的项目管理测试集上,打开程序化调用后计费的输入 token 少了大约 38%,任务正确率不变。

五、工具太多时:工具搜索

工具一多,有两个问题。一是定义本身占上下文:文档举的例子是同时接了 GitHub、Slack、Sentry、Grafana、Splunk 五个服务,光定义就约 5.5 万个 token。二是选不准:工具超过三五十个,模型选对工具的能力会下降。

工具搜索的做法是:定义照样全部发给接口,但给大部分工具标上 defer_loading: true,它们就不进模型的上下文。模型需要时先搜一下,接口把搜到的那几个工具的定义补进来。

下面这段代码跑过。15 个工具全部延迟加载,只留工具搜索这一个直接可见:

import anthropic

client = anthropic.Anthropic()

SERVICES = {"billing": "账单", "orders": "订单", "inventory": "库存", "shipping": "物流", "users": "用户"}
ACTIONS = {"get_status": "查询{}服务的运行状态。", "restart": "重启{}服务。", "get_logs": "读取{}服务最近的日志。"}

tools = [{"type": "tool_search_tool_regex_20251119", "name": "tool_search_tool_regex"}]   # 它自己不能延迟
for service, zh in SERVICES.items():
    for action, text in ACTIONS.items():
        tools.append({
            "name": f"{service}_{action}",
            "description": text.format(zh),
            "defer_loading": True,              # 定义照样要发,但不进模型的上下文
            "input_schema": {"type": "object",
                             "properties": {"env": {"type": "string", "enum": ["prod", "staging"]}},
                             "required": ["env"]},
        })

reply = client.messages.create(
    model="claude-sonnet-5-5", max_tokens=800, tools=tools,
    messages=[{"role": "user", "content": "生产环境的物流服务现在状态怎么样?"}],
)
print(reply.stop_reason)
for block in reply.content:
    if block.type == "server_tool_use":
        print("搜索:", block.input)
    elif block.type == "tool_search_tool_result":
        print("找到:", [ref.tool_name for ref in block.content.tool_references])
    elif block.type == "tool_use":
        print("调用:", block.name, block.input)

输出:

tool_use
搜索: {'limit': 20, 'pattern': 'logistics|物流|status|health|monitor|service|shipping|deploy'}
找到: ['billing_get_status', 'orders_get_status', 'inventory_get_status', 'shipping_get_status', 'shipping_restart', 'shipping_get_logs', 'users_get_status']
调用: shipping_get_status {'env': 'prod'}

一次请求里它先搜、再调。响应以 tool_use 结束,接下来和普通工具一样:你执行 shipping_get_status,回结果。搜索用的那个 srvtoolu_ 开头的调用不用回结果,回了反而会被拒。

两种搜法

type 模型写的是 上限
tool_search_tool_regex_20251119 Python 正则,不区分大小写 200 个字符
tool_search_tool_bm25_20251119 自然语言的查询 500 个字符

两种都会搜工具名、说明、参数名和参数说明。默认最多返回 5 个工具,模型可以自己在搜索里加 limit。

工具说明是中文时,BM25 这一种在本站的测试里搜不到东西。 30 个工具、同一个问题,四种组合各一次:

说明用中文 说明用英文
正则 找到了,调对了工具 找到了,调对了工具
BM25 搜了两次,都是空的,最后回答“查不了” 英文查询找到了,中文查询是空的

正则那一种里,模型自己会把中文和英文的词都写进去(上面输出里的 logistics|物流|…),工具名又是英文的,所以总能撞上。只各跑了一次,不能下定论;但如果你的工具说明是中文,先用正则这一种,或者在说明里带上英文关键词。

它省不省 token

看规模。同样 30 个小工具,全部直接加载,一次请求的输入是 3,379 个 token;用正则搜索,输入是 3,592 个(服务器端的两步加在一起算的),因为这一次模型把 limit 写成了 20,搜到的 20 个定义都被补了进来。工具只有几十个、每个定义又很短时,工具搜索不省。 文档说的适用场景是工具有几十上百个、单个定义也长的时候,并建议把最常用的三五个工具留着不延迟。

其他要点

  • 至少要有一个工具不延迟,工具搜索工具自己永远不能延迟。全延迟会报 400。
  • 延迟加载的工具不在缓存的前缀里,所以加减这类工具不会让提示词缓存失效。
  • 你也可以自己实现搜索(比如用向量检索):定义一个普通工具,在它的 tool_result 里返回 tool_reference 块,接口会用同样的办法把定义补进来。
  • 通过 MCP 连接器接进来的工具,延迟加载设在工具集上,不是一个一个设。

通过中转站:带着历史继续时报 400

上面那次请求之后,本站按文档的做法把助手消息原样放回、加上工具结果、带着完全相同的 tools 再发,返回的是:

HTTP 400 Tool reference 'billing_get_status' not found in available tools

也就是说,通过这家中转站,工具搜索目前只能用在一次请求就结束的地方;拿到工具调用后想把结果送回去继续,走不通。这一条已经连同复现条件记下来,修好后会复测。

六、顾问:干活的模型中途请教更强的模型

顾问工具让一个便宜、快的执行模型在干活的中途,向一个更强的顾问模型请教一次。顾问读完整段对话,给一个方案或纠正方向,执行模型接着干。大部分 token 仍然是按执行模型的价钱生成的。

适合的场合是步骤多的智能体任务:大多数回合是机械的,但有一个好方案很关键。不适合单轮问答,也不适合每一步都需要强模型的任务。

下面这段代码跑过。顾问目前是 beta,要带 beta 头:

import anthropic

client = anthropic.Anthropic()

reply = client.beta.messages.create(
    model="claude-sonnet-5-5",                   # 执行模型:干活、写最后的回答
    max_tokens=1500,
    betas=["advisor-tool-2026-03-01"],
    tools=[{
        "type": "advisor_20260301",
        "name": "advisor",
        "model": "claude-opus-5-5",              # 顾问模型:只出主意
        "max_uses": 1,                           # 这一次请求最多问几次
        "max_tokens": 2048,                      # 顾问每次最多输出多少
    }],
    messages=[{"role": "user", "content": "我要给一个每秒 2000 次请求的公开 API 加限流,按用户限。"
                                          "先向顾问要一个方案,再给我 5 行以内的结论。"}],
)
for block in reply.content:
    print(block.type, getattr(block, "name", ""))
for it in reply.usage.iterations or []:
    print(it.type, getattr(it, "model", ""), "输入", it.input_tokens + it.cache_read_input_tokens
          + it.cache_creation_input_tokens, "输出", it.output_tokens)

输出:

server_tool_use advisor
advisor_tool_result 
text 
message None 输入 1070 输出 26
advisor_message claude-opus-5-5 输入 2675 输出 942
message None 输入 1822 输出 354

从这个输出能看清它是怎么工作的:

  1. 执行模型(Sonnet 5.5)先输出 26 个 token,发出一个 advisor 调用。这个调用的 input 永远是空的,顾问看到的内容由服务器从整段对话里组出来。
  2. 服务器用顾问模型(Opus 5.5)单独跑一次:输入 2,675,输出 942。
  3. 执行模型拿到建议,写出最后的回答:输出 354。

整件事在一次请求里完成。

钱怎么算

  • 顾问那一步按顾问模型的价钱算,在 usage.iterations 里是 type 为 advisor_message 的那一项。
  • 顶层的 usage 只算执行模型,不含顾问的 token。只看顶层会少算。
  • 请求里的 max_tokens 只管执行模型。要限制顾问,用工具定义里的 max_tokens(最小 1024)。
  • 文档说顾问一次的输出一般是 400 到 700 个 token 的正文,连思考一起 1,400 到 1,800 个。上面实测是 942 个。

这个例子里,顾问那一步的花费(按官方价约 0.03 美元)比执行模型的两步加起来(约 0.01 美元)还多。它值不值,要看任务够不够长:顾问省下的是执行模型走弯路的那些回合。

你看不到建议的内容

用 Opus 5.5 做顾问时,结果块里是一段加密的内容(advisor_redacted_result),实测是 2,860 个字符的密文。执行模型在服务器那边读得到明文,你的程序读不到。文档说 5 系和 5.5 系的模型做顾问都是这样;用 Opus 4.8 这类较早的模型做顾问,返回的是明文(advisor_result)。

不管是哪种,下一轮都要把结果块原样带回。

谁能给谁当顾问

顾问至少要和执行模型一样强,而且不能低于 Sonnet 4.6。Sonnet 5.5 做执行模型时,顾问可以是 Sonnet 5.5、Opus 5、Opus 5.5、Fable 和 Mythos 各版本。反过来不行,实测让 Sonnet 5.5 给 Opus 5.5 当顾问:

HTTP 400 tools.0.model: 'claude-sonnet-5-5' cannot be used as an advisor
when the request model is 'claude-opus-5-5'.

其他要点

  • max_uses 是一次请求内的上限,不是整段对话的。要限制整段对话里问几次,自己数,到数了就把顾问工具从 tools 里拿掉,历史里的结果块不用删。
  • 流式输出时,顾问那一步不流式:执行模型的输出会停一阵,然后建议整块到达。实测整个请求用了 17 到 21 秒。
  • 对话里顾问要被问三次以上时,给工具定义加 caching 才划算;少于三次,写缓存的钱比省下的多。
  • 写代码的任务上,执行模型常常问得不够。文档建议在系统提示词里明确两个时机:先读几个文件、摸清情况之后问一次;难的任务在改完、跑完测试之后再问一次。
  • 这个工具只在 Claude API 和 Claude Platform on AWS 上有,Bedrock、Google Cloud、Foundry 上没有。

七、MCP 连接器(按文档整理)

通过这家中转站,带 mcp_servers 的请求返回 400。下面是文档的内容。

MCP 连接器让你在一次接口请求里直接接上远程的 MCP 服务器,不用自己写 MCP 客户端。连接、列工具、调工具都由 Anthropic 的服务器做。

请求里要写两处,并带 beta 头 mcp-client-2025-11-20:

reply = client.beta.messages.create(
    model="claude-sonnet-5-5", max_tokens=1000,
    betas=["mcp-client-2025-11-20"],
    mcp_servers=[{                        # 一、服务器在哪里、怎么认证
        "type": "url",
        "url": "https://mcp.example.com/mcp",
        "name": "example",
        "authorization_token": "…",       # 需要认证的服务器才写
    }],
    tools=[{                              # 二、用这个服务器的哪些工具
        "type": "mcp_toolset",
        "mcp_server_name": "example",
    }],
    messages=[{"role": "user", "content": "…"}],
)

限制:

  • 服务器必须能从公网用 HTTPS 访问。 本机上用标准输入输出通信的那种 MCP 服务器接不了。
  • MCP 的功能里只支持工具调用,资源、提示词模板这些不支持。
  • 每个服务器必须恰好对应一个 mcp_toolset。
  • OAuth 的流程要你自己走完、自己刷新令牌,把拿到的访问令牌填进 authorization_token。

选工具用 default_config 和 configs:

{"type": "mcp_toolset", "mcp_server_name": "example",
 "default_config": {"enabled": False},                  # 默认全关
 "configs": {"search_events": {"enabled": True}}}       # 只开这一个

反过来(默认全开,关掉个别的)也行。做只读助手,或者想在改数据之前加人工确认时,文档建议把会写、会删的工具关掉。工具很多时,可以在这里设 defer_loading,配合上一节的工具搜索。

响应里 MCP 的调用和结果是另外两种块:mcp_tool_use 和 mcp_tool_result。

MCP 服务器的工具列表随时可能变。新的 beta 头 mcp-client-2026-09-15 会把服务器当时返回的工具列表记在响应里,你可以把它固定下来,免得对话进行到一半工具变了。

官方另有一页列了一些公司自己架设的远程 MCP 服务器,并说明这些是第三方服务,不归 Anthropic 所有和运营,接之前要自己看它们的安全做法和条款。

如果你用的是 Claude Code,接 MCP 服务器不用走这里,见《Claude Code 接入 MCP》。

八、工具和结果太占上下文时,用哪一招

官方有一页专门讲这个,把四种办法放在一起比:

办法 减少的是什么 什么时候用
工具搜索 一开始就加载的工具定义 工具多(20 个以上),多数每轮用不上
程序化调用 工具结果的来回 一连串小的工具调用,可以写成一段脚本
提示词缓存 重复的工具定义花的钱(token 数不变) 工具固定,请求很多
上下文编辑 历史里旧的工具结果 对话很长,早期的结果已经没用

四种不冲突,可以一起用。文档建议的顺序是:第一天就给工具定义开缓存;工具超过 20 个左右再加工具搜索;对话长到早期结果没用了,加上下文编辑;发现总有一串重复的小调用时,考虑程序化调用。

缓存见《提示词缓存》,上下文编辑见《压缩和上下文编辑》。

九、通过中转站实测到的

项目 官方文档 通过中转站实测
联网搜索(三个版本) 可用 可用,结果、引用、用量字段都有
搜索和自己的工具混在同一轮 先还给你,回了结果再搜 一致
改掉 encrypted_content 再带回 400 200,搜索结果被丢掉,模型否认搜过
抓取网页 可用 400
代码执行 可用 参数被忽略,返回 200,模型说没有这个工具
程序化调用 可用 400
工具搜索,单次请求 可用 可用
工具搜索,带着历史继续 可用 400:Tool reference … not found in available tools
顾问 要带 beta 头 可用;不带 beta 头的请求也没有被拒
顾问模型比执行模型弱 400 400,一致
MCP 连接器 可用(beta) 400

最要小心的是代码执行那一条:没有任何报错,只是工具不存在了。

通过这家中转站要做同样的事,目前可行的替代办法:

  • 读网页:自己写一个抓网页的客户端工具(上一篇的写法),或者用联网搜索。
  • 跑代码:用上一篇的 bash 工具,在你自己的环境里执行。
  • 接 MCP 服务器:自己在程序里当 MCP 客户端,把它的工具转成普通的工具定义。官方 SDK 带了做这个转换的辅助函数(Python 装 anthropic[mcp]),本站没有试。或者直接用 Claude Code、Agent SDK。

和 Claude Code 的关系

Claude Code 里有同类的能力:WebSearch 和 WebFetch 两个内置工具;MCP 服务器由 Claude Code 在你的机器上当客户端去连;工具太多时也会延迟加载。在 Claude Code 里这些开箱即用,配置的地方和本文不一样。

本文的工具是给“自己直接调接口写程序”用的。用 Agent SDK 的话,工具搜索的用法见《工具搜索、文件检查点和待办清单》。

花费

这一篇一共发了 32 次请求,其中 6 次真的执行了联网搜索。token 的大头是搜索结果(每次搜索一万个上下的输入 token)。按官方标价粗算约 0.5 美元,其中搜索次数按每千次 10 美元算是 0.06 美元,顾问的三次 Opus 调用约 0.1 美元。

这次实测没有覆盖到的

  • 官方接口没有测。 第九节“官方文档”一栏是文档的说法。
  • 抓取网页、代码执行、程序化调用、MCP 连接器都没有跑通,这一家中转站不支持。这四节的参数、限制、计费全部是按文档整理的,示例代码没有运行过。
  • pause_turn 没有遇到,续跑的写法没有验证。
  • 动态过滤有没有生效,无法确认。
  • 联网搜索的 user_location、blocked_domains、超过 max_uses 的情况没有单独验证效果;流式和批量没有试。
  • 工具搜索只各跑了一次,BM25 搜不到中文说明这一条需要更多次数才能下结论;自己实现搜索、和缓存的配合没有试。
  • 顾问只测了一次调用:多次调用、caching、流式时的停顿、明文结果(需要 Opus 4.8 做顾问)都没有试。
  • 中转站对搜索次数和顾问调用怎么计费,没有核对。
  • 只测了一家中转站、一天。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章

  • Claude Agent SDK 进阶:工具太多时的工具搜索、把改过的文件退回去、显示任务进度教程 · Claude Code · 约 10 分钟

    做应用迟早碰到的三件事,本站用 Python 逐样实测。工具搜索通过中转站默认是关的,打开之后如果像前几篇那样写了 tools=[],它照样不生效,而且没有任何提示。文件检查点能把编辑工具改过的文件退回去,用 Bash 改的退不回来。任务清单在新模型上默认不开,开了它也不一定用,用了轮数是原来的三倍多。

  • 给 Claude Agent SDK 的智能体加自己的工具:让它查你的数据库、调你的接口教程 · Claude Code · 约 11 分钟

    内置工具只会读写文件和跑命令。要让智能体查订单、办退款,得把你自己的函数做成工具。本站用 Python 实测了一个只用自定义工具的客服助手:三个工具、七组运行,包括订单号不存在、工具内部抛异常、退款没被批准。两点要留意:没接住的异常会把内部信息带到回答里;去掉内置工具后一次运行只要两分钱。

  • CLAUDE.md、skill、hook、子代理、MCP、插件:Claude Code 的六种扩展各管什么,先用哪个教程 · Claude Code · 约 9 分钟

    Claude Code 的扩展方式有六七种,名字相近,容易用错地方。按官方的选型说明整理:每一种解决什么问题、什么信号出现时该加哪一种、相近的几种怎么区分、各占多少上下文。占用的数字用的是本站这个系列实测到的。

  • Claude Code 接 MCP 服务器实战:接一个现成的,自己写一个,再分享给团队教程 · Claude Code · 约 11 分钟

    MCP 让 Claude Code 用到内置工具以外的东西:查文档、查工单、查数据库。本站实测了三件事:一条命令接上官方的文档服务器;用三十多行代码写一个自己的服务器并接上;改成项目级配置给团队共用,以及第一次打开时的批准提示。附每一步的真实输出和排错办法。