游乐游手机版
首页/AI热点日报/热点详情

MCP协议动态发现能力机制与实现详解

类型:热点整理2026-07-04
MCP协议与传统API最大的区别是什么?核心答案就是动态发现能力。这一特性让AI模型能够在运行时动态发现并调用可用工具,无需像传统方式那样为每个集成点预先编写固定代码。下面我们来详细拆解: 动态发现工具:在指定的MCP服务器上,客户端可随时拉取工具列表,该能力始终可用。 动态发现服务:更进一步,客户

MCP协议与传统API最大的区别是什么?核心答案就是动态发现能力。这一特性让AI模型能够在运行时动态发现并调用可用工具,无需像传统方式那样为每个集成点预先编写固定代码。下面我们来详细拆解:

  • 动态发现工具:在指定的MCP服务器上,客户端可随时拉取工具列表,该能力始终可用。
  • 动态发现服务:更进一步,客户端还能自动发现并连接到远程MCP服务器,根据官方路线图,该功能计划于2025年上半年落地。

MCP协议的动态发现能力

一、工具的动态发现与更新

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,大模型即可自主判断是否需要与该工具集成以及何时使用。

具体流程大致如下:

  1. Agent 接收到一个自定义URI,如 mcp://api.myservice.com
  2. Agent 解析URI,并向预定义端点发送HTTP GET请求,例如 https://api.myservice.com/llms.txt
  3. 服务端返回JSON或文本文件,其中包含所有相关元数据,如身份认证、服务与功能描述、提供的工具/资源列表、完整API文档、定价与支付方式等。
  4. Agent 根据这些信息执行权限验证、功能映射,然后启动交互。

如此,该服务便实现了动态发现。整个过程无需预注册,完全由Agent自主完成。

总结:动态发现是MCP协议的关键能力

从本质上说,MCP的价值在于:当您希望为不受自己控制的Agent引入工具时,它便能发挥巨大作用。而如何让这些“不受控”的Agent主动发现您的服务,动态发现便成为必须攻克的关键关卡。从当前的发展态势来看,MCP在这方面的能力即将完善,确实值得期待。

来源:https://www.53ai.com/news/LargeLanguageModel/2025032696531.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。