MCP 協議的動態發現能力
MCP(Model Context Protocol) 與傳統的 API 相比,一個重要的能力是動態發現:MCP 允許 AI 模型動態發現並與可用工具交互,無需預先設定每個集成的固定代碼。
這個動態發現分兩個層次:
-
動態發現工具:在指定的 MCP 服務器上發現工具,一直都支持。
-
動態發現服務:定義客戶端如何發現並連接遠程 MCP 服務器, 這個按照規劃是 25 年上半年要完成的。
一、工具發現和更新
MCP 支持動態工具發現。
https://modelcontextprotocol.io/docs/concepts/tools#tool-discovery-and-updates
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("Available 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 類型的 Server,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("Available tools:", tools)
# 監聽工具變化通知
async def on_tool_change(notification):
print("Tools have 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())
上述代碼示例展示瞭如何在服務器端添加一個新的乘法工具,並通知客戶端這些變化。客戶端會監聽這些通知,並動態更新工具列表。
二、動態發現服務
按照規劃是 25 年上半年要完成的,參看: https://modelcontextprotocol.io/development/roadmap。
按照 https://github.com/modelcontextprotocol/specification/discussions/69 這裏的討論,是準備:
用一種與 MCP 重疊的協議,並且使用自定義 URI 解決了這個限制,這樣就允許在聊天中粘貼 URI 等流程,並讓 LLM 決定是否需要與該工具集成、何時使用它等...
大致的流程是:
-
agent 遇到自定義 URI,例如 mcp://api.myservice.com
-
agent 解析 URI 並獲取有關服務的詳細信息。例如,它對預定義端點執行 HTTP GET 請求,例如: https://api.myservice.com/llms.txt
-
該服務以包含所有相關元數據的 JSON 或文本文件進行響應,其中包括:身份驗證、服務及其功能描述、提供的功能 / 工具 / 資源列表、完整的 API 文檔、定價、付款方式或支持的付款協議的詳細信息。
-
基於上面檢索到的信息,Agent 做權限驗證、功能映射、啓動交互。
通過上面方式,完成對服務的動態發現。
總結:動態發現是 MCP 的關鍵能力
從本質上講:當你想爲一個你不能控制的 Agent 引入工具時,MCP 就會派上用場。
而如何讓不能控制的 Agent 發現你的服務,動態發現就是必須的能力,從上面的講解看,MCP 這個能力將很快就健全了,非常值得期待。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/lZGIsQwdoXqhyorcwX4qWA