我们有工具、skills 和连接器。那么为什么 MCP 存在?乍一看它像是一个堆叠在 API 之上的第二个 API。合理的问题——答案归结为谁维护集成代码。
假设你的 agent 需要从 Asana 拉取任务、检查 Google 日历并搜索 Slack——全部一次完成。使用自定义工具,你必须编写三个集成。那部分是可以做到的。痛苦的部分在之后:你还必须 维护 这些集成,每当其中一个服务更改其 API 时——这经常发生。恭喜,你现在维护一堆第三方 API 包装器。
MCP 将维护转移到服务提供商。Asana 发布一个 MCP 服务器。Slack 发布一个。Google 发布一个。每个服务器通过标准协议暴露自己的工具——带有描述、模式和身份验证。当他们的 API 更改时,他们更新他们的服务器。你什么都不改。
这三个功能做不同的工作:
简短版本:工具用于你的东西,skills 用于你的流程,MCP 用于其他人的东西。
感受 MCP 的最干净方式是将 Claude 指向任何 MCP 服务器并让其发现那里有什么。在这个例子中,我们将使用 Linear MCP 服务器,连接详情和身份验证令牌存储在 .env 文件中。
两个部分在请求中协同工作。mcp_servers 键声明连接——类型、URL、引用它的名称,以及可选的身份验证令牌。然后一个类型为 mcp_toolset 的工具配置 Claude 可以从该服务器使用哪些工具。默认是全部,但如果你想缩小范围,这就是你这样做的地方。
import os
import anthropic
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "What tools do you have available?"}
],
mcp_servers=[
{
"type": "url",
"url": "https://mcp.linear.app/mcp",
"name": "linear",
"authorization_token": os.environ["LINEAR_MCP_TOKEN"],
}
],
tools=[
{
"type": "mcp_toolset",
"mcp_server_name": "linear",
}
],
betas=["mcp-client-2025-11-20"],
)
print(response)
注意我们从未编写过单个工具模式。Claude 自省 服务器,获取工具列表及其模式,并为提示选择正确的工具。截至本课,MCP 连接器处于测试版——注意请求中的 beta 头。
运行它,如果你的 MCP URL 指向 Linear 的 MCP 端点,Claude 会列出 Linear 的工具然后调用一个。同样的方式适用于基本上任何合规服务器。我们没有定义单个工具。我们没有编写 Linear 客户端。Linear 维护着它。
MCP 服务器经常暴露很多很多工具——你并不总是想让 Claude 使用全部。也许你不想给它写权限,或者你只是不想让所有这些工具定义占用上下文。
解决方案:默认禁用一切,然后只启用你需要的特定工具。这是使用 Slack MCP 服务器的模式:
tools=[
{
"type": "mcp_toolset",
"mcp_server_name": "slack",
"default_config": {
"enabled": False,
},
"configs": {
"search_messages": {"enabled": True},
"list_channels": {"enabled": True},
},
}
]
登录 参与讨论
现在 Claude 可以搜索 Slack 和列出频道,但它不能发布或删除。当你信任一个服务进行读取但不想让 Claude 意外地代表你写入时,这很有用。
mcp_servers 中声明连接(类型、URL、名称、可选身份验证令牌)并在 tools 中使用 mcp_toolset 条目授予权限。Claude 自省服务器并自行发现工具——无需编写模式。default_config: {"enabled": False} 并在 configs 中启用特定工具来缩小访问范围——对于将服务器设为只读很有用。