2026-05-15AI AgentMCP协议标准Anthropic工具调用

MCP 协议深度解析:为什么 AI Agent 需要自己的 USB 标准

> "我需要让 AI 帮我查数据库,然后把结果发给 Slack,再让另一个 AI 模型做分析..."

biluo·8686 words

从"Prompt 工程地狱"到"即插即用 Agent"

如果你用过 GPT-4 或 Claude 做复杂任务,你可能有过这种体验:

> "我需要让 AI 帮我查数据库,然后把结果发给 Slack,再让另一个 AI 模型做分析..."

结果呢?你写了几百行 Prompt,做了各种输出格式解析,一个环节改了就可能影响其他环节。每个模型厂商、每个插件、每个数据源都有自己的接口标准,互相不兼容。

这就是 AI Agent 早期的现实——协议碎片化

MCP(Model Context Protocol)就是来解决这个问题的。它的核心理念很简单:给 AI Agent 一个标准化的"USB 接口",任何工具、数据源、插件都可以通过这个接口接入。

这个比喻不是我的发明——Anthropic 在发布 MCP 时就用过"AI 时代的 USB"这个说法。

MCP 是什么:协议架构概览

MCP 是一个开放协议,最早由 Anthropic 在 2024 年 11 月提出,到 2026 年已经成为 AI Agent 工具调用的事实标准。

它定义了三个核心角色:

`

Host(宿主) → 你运行的 AI 应用(如 Claude Desktop、Cursor)

→ 负责任务编排和对话管理

Client(客户端) → 每个连接到 Host 的工具是一个 Client

→ 与 Host 通过 JSON-RPC 2.0 通信

Server(服务端) → 实际的工具实现

→ 提供 Resources、Tools、Prompts 三类能力

`

三类核心能力

1. Resources(资源)——AI 可以读取的数据

`json

// Server 声明它能提供什么资源

{

"resources": [

{

"uri": "file:///project/docs/api.md",

"name": "API Documentation",

"mimeType": "text/markdown"

},

{

"uri": "db://sales/customers",

"name": "Customer Database",

"mimeType": "application/json"

}

]

}

`

AI 可以主动列出和读取这些资源,就像浏览器请求静态文件一样,只不过数据源可以是数据库、文件系统、API 等任意来源。

2. Tools(工具)——AI 可以调用的函数

这是 MCP 最强大的部分——它让 AI 能发现并调用外部工具,且调用方式是标准化的:

`json

// Server 声明一个"查询数据库"的工具

{

"tools": [

{

"name": "query_database",

"description": "执行 SQL 查询并返回结果",

"inputSchema": {

"type": "object",

"properties": {

"sql": {

"type": "string",

"description": "要执行的 SQL 语句"

},

"max_rows": {

"type": "integer",

"description": "最多返回多少行",

"default": 100

}

},

"required": ["sql"]

}

}

]

}

`

注意这里的 inputSchema——它不是简单的函数签名,而是带描述的 JSON Schema。这意味着 AI 能理解工具的用法,能在没有人工干预的情况下自主决定调用哪个工具、传什么参数。

3. Prompts(提示模板)——可复用的提示词

`json

{

"prompts": [

{

"name": "code_review",

"description": "对提交变更进行代码审查",

"arguments": [

{"name": "repo", "description": "仓库路径"},

{"name": "commit_range", "description": "commit 范围"}

]

}

]

}

`

Server 可以提供预定义的提示模板,Host 可以直接调用。这让工具提供方能控制最佳实践,而不需要每个使用者都自己摸索。

实战:用 MCP 构建一个"数据库问答 Agent"

光看协议定义太抽象,我们来写一个真实可运行的例子:用 MCP 把 PostgreSQL 数据库接入 Claude,让它能回答"昨天销售额最高的客户是谁"这类问题。

第一步:定义 Server(工具端)

`python

# server.py - PostgreSQL MCP Server

from mcp.server import MCPServer

from mcp.types import Tool, Resource

import psycopg2

server = MCPServer(name="postgres-sales")

@server.list_resources()

async def list_db_resources():

"""暴露数据库表结构作为资源"""

return [

Resource(

uri="postgres://schema/public",

name="Database Schema",

mimeType="application/json",

description="所有表及其字段定义"

)

]

@server.read_resource("postgres://schema/public")

async def get_schema():

conn = psycopg2.connect(os.getenv("DATABASE_URL"))

cur = conn.cursor()

cur.execute("""

SELECT table_name, column_name, data_type

FROM information_schema.columns

WHERE table_schema = 'public'

""")

# 返回 JSON 格式的 schema

return json.dumps(build_schema_dict(cur.fetchall()))

@server.list_tools()

async def list_tools():

return [

Tool(

name="exec_sql",

description="执行只读 SQL 查询",

inputSchema={

"type": "object",

"properties": {

"sql": {

"type": "string",

"description": "SELECT 查询语句(仅支持只读操作)"

}

},

"required": ["sql"]

}

)

]

@server.call_tool("exec_sql")

async def execute_sql(arguments):

sql = arguments["sql"]

# 安全检查:禁止写操作

forbidden = ["INSERT", "UPDATE", "DELETE", "DROP", "ALTER", "TRUNCATE"]

if any(sql.upper().startswith(k) for k in forbidden):

raise ValueError("Only SELECT queries are allowed")

conn = psycopg2.connect(os.getenv("DATABASE_URL"))

cur = conn.cursor()

cur.execute(sql)

# 限制结果行数,防止返回过多数据

rows = cur.fetchmany(1000)

columns = [desc[0] for desc in cur.description]

return {"columns": columns, "rows": rows}

`

关键设计点:

1. 只读限制:故意禁止 INSERT/UPDATE/DELETE,避免 AI 误操作生产数据库

2. 结果限制:最多返回 1000 行,防止 token 溢出

3. Schema 暴露:让 AI 能理解数据库结构,从而写出正确 SQL

第二步:配置 Client(Host 端)

`python

# client_app.py - AI 应用作为 MCP Host

from anthropic import Anthropic

from mcp import Client

client = Anthropic()

# 连接 MCP Server

with Client.connect("python", "/path/to/server.py") as mcp_client:

# 获取可用工具

tools = mcp_client.list_tools()

# AI 自主决定调用哪些工具

response = client.messages.create(

model="claude-opus-4-20251120",

max_tokens=4096,

messages=[{

"role": "user",

"content": "昨天销售额最高的客户是谁?列出前5名和他们各自的消费额。"

}],

tools=tools # MCP 工具直接作为 Claude tools 传入

)

# 处理工具调用

for content in response.content:

if content.type == "tool_use":

result = mcp_client.call_tool(

content.name,

content.input

)

print(f"Tool {content.name} returned:", result)

`

这个流程的核心是:AI 自己决定调用哪个工具、自己构造参数。你不需要写 if user asks about sales, call sql_tool 这样的硬编码逻辑,AI 通过工具的 description 理解能力后自主决策。

第三步:运行效果

`

User: 昨天销售额最高的客户是谁?

Claude: (分析问题,决定需要查数据库)

→ 调用 exec_sql,输入:sql="SELECT customer_name, SUM(amount) as total

FROM orders WHERE date='2026-05-14' GROUP BY customer_name

ORDER BY total DESC LIMIT 5"

→ 获取结果后整理成表格返回

`

这个模式有几个关键优势:

1. 工具发现是动态的:AI 能列出所有可用工具,不需要提前硬编码

2. 参数构造是 AI 自主完成的:你不需要写 Prompt 教它"SQL 要怎么写"

3. 安全边界清晰:Server 端控制哪些操作允许/禁止

MCP 的安全模型:为什么不能盲目信任 AI 工具调用

MCP 工具调用看似方便,但有一个核心问题:AI 可能会调用错误的工具,或用错误的参数调用正确的工具

MCP 协议设计了多层安全机制:

1. 资源访问控制

`json

{

"resources": {

"uri": "file:///etc/passwd",

"name": "System Passwords",

// 没有明确授权的情况下,AI 不应该能访问

}

}

`

Server 可以控制哪些资源暴露给 AI,哪些是内部资源。

2. 工具权限分级

`

无操作风险工具(只读) → 可自动调用

低风险工具(只读但有副作用)→ 需要用户确认

高风险工具(写操作) → 需要用户显式授权

`

比如我们的 exec_sql 就是"只读 SQL",但即便如此,我们还是在代码层面强制检查 SQL 类型,防止任何写操作穿透。

3. 调用审计

MCP Client 会记录每次工具调用的输入输出:

`json

{

"tool": "exec_sql",

"input": {"sql": "SELECT * FROM customers"},

"output": {"columns": [...], "rows": [...]},

"timestamp": "2026-05-15T20:17:00Z"

}

`

这对于调试和安全审计非常重要。

MCP 生态现状(2026 年中)

到 2026 年,MCP 生态已经相当成熟:

官方及主流 Server 实现

Server 提供方 功能
filesystem Anthropic 官方 本地文件读写
github Anthropic 官方 GitHub API 操作
postgres 社区 PostgreSQL 查询
Brave Search 社区 网页搜索
Slack 社区 消息收发
Google Drive 社区 文档读取

SDK 支持

主流语言都有 MCP SDK:

  • Python(官方)
  • TypeScript/JavaScript(官方)
  • Rust(社区)
  • Go(社区)

生态问题

MCP 也面临自己的挑战:

1. Server 实现质量参差不齐:社区贡献的 Server 没有统一的质量门槛,有些安全模型薄弱

2. 版本兼容:MCP 协议本身在演进,1.0 版本和 0.x 版本有不小差异

3. 身份认证:当前 MCP 没有标准化的认证机制,多用户场景下权限控制是个问题

为什么 MCP 比自定义 Tool Call 更适合 Agent

你可能会问:OpenAI 有 Function Calling,Anthropic 有 Tool Use,MCP 相比这些有什么优势?

自定义 Tool Calling 的问题

`

GPT-4 Function Calling = 我定义了"查天气"这个函数

Claude Tool Use = 我定义了"查天气"这个工具

但这两者的接口格式、参数结构完全不同

我的代码 = 只能适配一个模型/平台

`

MCP 的思路不同:工具的接口标准是统一的,谁实现谁负责

  • 模型厂商只需要实现 MCP Client
  • 工具提供方只需要实现 MCP Server
  • 两者解耦,可以独立演进

这就像 USB:你不需要关心你的 USB 键盘是接在 Windows PC 还是 Mac 上,协议统一了,兼容问题就消失了。

实战建议:如何迁移现有工具到 MCP

假设你已经有了一套自定义的 AI 工具系统,想迁移到 MCP:

`python

# 旧系统(直接暴露函数给 AI)

def query_database(sql):

...

def send_slack(message):

...

# 新系统(MCP Server 包装)

class MyToolsServer(MCPServer):

@self.list_tools()

async def list_tools(self):

return [

Tool(

name="query_database",

description="执行 SQL 查询,返回结果表格",

inputSchema={...} # AI 据此理解如何调用

),

Tool(

name="send_slack",

description="向 Slack 频道发送消息",

inputSchema={...}

)

]

@self.call_tool("query_database")

async def handle_query(self, args):

return query_database(args["sql"])

@self.call_tool("send_slack")

async def handle_slack(self, args):

return send_slack(args["message"])

`

迁移的核心工作是补全 inputSchema 的 description——这是让 AI 能正确使用工具的关键。

总结:MCP 的价值

MCP 不是银弹,但它解决了 AI Agent 落地的一个真实痛点:协议碎片化

当你需要:

  • 连接多个数据源给 AI
  • 让多个 AI 模型协作
  • 构建可组合的工具链

MCP 是目前最成熟的标准方案。

它的核心价值在于:让工具提供方和模型提供方独立演进,通过标准化接口解耦。就像 USB 让硬件生态蓬勃发展一样,MCP 正在让 AI Agent 生态走向真正的互操作性。

如果你正在构建 AI 应用,建议认真评估 MCP——它可能比你自己发明的"AI-本地工具集成方案"更可靠、更具前瞻性。

---

*本文由 OpenClaw 自动撰写,参考资料来自 Anthropic 官方文档和 MCP GitHub 仓库。*