MCP协议与传统API最大的区别是什么?核心答案就是动态发现能力。这一特性让AI模型能够在运行时动态发现并调用可用工具,无需像传统方式那样为每个集成点预先编写固定代码。下面我们来详细拆解:
- 动态发现工具:在指定的MCP服务器上,客户端可随时拉取工具列表,该能力始终可用。
- 动态发现服务:更进一步,客户端还能自动发现并连接到远程MCP服务器,根据官方路线图,该功能计划于2025年上半年落地。

一、工具的动态发现与更新
MCP支持动态工具发现,这意味着客户端可实时掌握服务器端提供了哪些工具,无需写死代码。
1. 客户端可随时查询可用工具列表
下面通过一组代码示例,展示服务器端与客户端如何协同实现动态发现功能。
服务器端代码示例(server.py)
from mcp.server.fastmcp import FastMCP
# 创建一个MCP服务器
mcp = FastMCP("Demo")
# 添加一个加法工具
@mcp.tool()
def add(a:int, b:int)->int:
"""Add two numbers"""
return a + b
# 添加一个动态问候资源
@mcp.resource("greeting://{name}")
def get_greeting(name:str)->str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
# 运行服务器
if __name__ == "__main__":
mcp.run()
客户端代码示例(main.py)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
# 配置服务器
server_params = StdioServerParameters(
command="python",
args=["server.py"]
)
# 创建客户端会话
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 列出服务器提供的工具
tools = await session.list_tools()
print("A vailable tools:", tools)
# 执行工具
result = await session.call_tool("add", {"a":5, "b":3})
print("Result of add tool:", result)
# 获取动态问候
greeting = await session.read_resource("greeting://Alice")
print("Greeting:", greeting)
if __name__ == "__main__":
asyncio.run(main())
此处使用的是 Stdio 类型的服务器。MCP目前支持两种通信机制,具体区别可参考《MCP的通信机制》一文。
从上述代码可见,服务器端动态创建了工具与资源,客户端能够自动发现并调用这些工具,无需硬编码。
2. 服务器端主动通知客户端工具变更
工具列表并非固定不变,当服务器端新增、删除或修改工具时,可通过 notifications/tools/list_changed 通知客户端。
这样一来,运行时添加或删除工具变得异常灵活,甚至可以动态更新工具定义(当然,更新操作需谨慎)。
例如:服务器端最初仅有加法和问候资源,随后新增了乘法工具并通知客户端。代码演进如下:
服务器端变化后的代码示例
from mcp.server.fastmcp import FastMCP
from mcp import types
# 创建一个MCP服务器
mcp = FastMCP("Demo")
# 加法工具
@mcp.tool()
def add(a:int, b:int)->int:
"""Add two numbers"""
return a + b
# 动态问候资源
@mcp.resource("greeting://{name}")
def get_greeting(name:str)->str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
# 添加一个乘法工具
@mcp.tool()
def multiply(a:int, b:int)->int:
"""Multiply two numbers"""
return a * b
# 每次工具变化时通知客户端
async def notify_tool_changes():
await mcp.notify(types.ListToolsChangedNotification())
# 运行服务器
if __name__ == "__main__":
import asyncio
async def main():
await notify_tool_changes()
mcp.run()
asyncio.run(main())
客户端代码示例(main.py)
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def main():
# 配置服务器
server_params = StdioServerParameters(
command="python",
args=["server.py"]
)
# 创建客户端会话
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 列出服务器提供的工具
tools = await session.list_tools()
print("A vailable tools:", tools)
# 监听工具变化通知
async def on_tool_change(notification):
print("Tools ha ve changed:", notification)
# 列出更新后的工具
updated_tools = await session.list_tools()
print("Updated tools:", updated_tools)
session.subscribe("notifications/tools/list_changed", on_tool_change)
# 执行加法工具
result = await session.call_tool("add", {"a":5, "b":3})
print("Result of add tool:", result)
# 执行乘法工具
result = await session.call_tool("multiply", {"a":5, "b":3})
print("Result of multiply tool:", result)
# 获取动态问候
greeting = await session.read_resource("greeting://Alice")
print("Greeting:", greeting)
if __name__ == "__main__":
asyncio.run(main())
客户端订阅工具变化通知后,一旦服务器端新增了乘法工具,客户端便会自动感知并更新工具列表,进而顺利调用新工具。
二、服务的动态发现
根据官方路线图(https://modelcontextprotocol.io/development/roadmap),该功能预计2025年上半年完成。具体设计参考了GitHub讨论(https://github.com/modelcontextprotocol/specification/discussions/69),思路是:通过一种与MCP重叠的协议,配合自定义URI来突破限制。例如,在聊天界面粘贴一个URI,大模型即可自主判断是否需要与该工具集成以及何时使用。
具体流程大致如下:
- Agent 接收到一个自定义URI,如
mcp://api.myservice.com。 - Agent 解析URI,并向预定义端点发送HTTP GET请求,例如
https://api.myservice.com/llms.txt。 - 服务端返回JSON或文本文件,其中包含所有相关元数据,如身份认证、服务与功能描述、提供的工具/资源列表、完整API文档、定价与支付方式等。
- Agent 根据这些信息执行权限验证、功能映射,然后启动交互。
如此,该服务便实现了动态发现。整个过程无需预注册,完全由Agent自主完成。
总结:动态发现是MCP协议的关键能力
从本质上说,MCP的价值在于:当您希望为不受自己控制的Agent引入工具时,它便能发挥巨大作用。而如何让这些“不受控”的Agent主动发现您的服务,动态发现便成为必须攻克的关键关卡。从当前的发展态势来看,MCP在这方面的能力即将完善,确实值得期待。
