什么是MCP?
MCP(Model Connector Protocol)是一种用于构建多服务AI代理系统的协议,它允许我们将不同的功能模块以服务的形式提供给AI模型调用。通过MCP,我们可以让大型语言模型(LLM)访问多个不同的服务,实现更加复杂的功能组合。
MCP的核心优势
- 服务解耦:将不同功能封装为独立服务
- 多传输方式支持:支持stdio、HTTP SSE等多种传输方式
- 易于集成:简单的API设计,便于与现有系统集成
- 工具注册机制:轻松将Python函数注册为AI可调用的工具
实战案例:构建数学计算与天气查询系统
在本文中,我们将构建一个简单的系统,它包含两个MCP服务:
- 数学计算服务:提供基本的数学运算
- 天气查询服务:提供城市天气信息
然后,我们将创建一个客户端,使用LangChain和LangGraph来让LLM调用这些服务。
第0步:安装依赖库
pip install langchain-mcp-adapters langchain-openai
export OPENAI_API_KEY=<your_api_key>
第1步:创建数学服务
首先,我们创建一个简单的数学服务,提供加法和乘法功能:
# math_server.py
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Math")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
print('--add--',a,b)
return a + b
@mcp.tool()
def multiply(a: int, b: int) -> int:
"""Multiply two numbers"""
print('--multiply--',a,b)
return a * b
if __name__ == "__main__":
mcp.run(transport="stdio")
这个服务提供了两个工具:add
和multiply
,分别用于加法和乘法操作。我们使用@mcp.tool()
装饰器将这些函数注册为工具,使它们可以被AI模型调用。服务通过stdio传输方式运行。
第2步:创建天气服务
接下来,我们创建一个天气查询服务:
# weather_server.py
from typing import List
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Weather")
@mcp.tool()
async def get_weather(location: str) -> str:
"""Get weather for location."""
print('--get_weather--',location)
return "It's always sunny in New York"
if __name__ == "__main__":
mcp.run(transport="sse")
这个服务提供了一个get_weather
工具,用于获取特定位置的天气信息。这里使用的是模拟数据,实际应用中可以替换为真实的天气API调用。服务通过SSE(Server-Sent Events)传输方式运行,监听本地8000端口。
第3步:创建客户端
最后,我们创建一个客户端,用于连接这两个服务并使用LLM调用它们:
# mcp_client.py
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o")
async def main():
print('开始执行...')
print('初始化模型:', model)
async with MultiServerMCPClient(
{
"math": {
"command": "python",
"args": ["math_server.py"],
"transport": "stdio",
},
"weather": {
"url": "http://localhost:8000/sse",
"transport": "sse",
}
}
) as client:
print('已连接服务器,获取工具...')
tools = client.get_tools()
print(f'获取到 {len(tools)} 个工具')
agent = create_react_agent(model, tools)
print('已创建agent,开始调用...')
# 设置超时
import asyncio
math_response = await asyncio.wait_for(
agent.ainvoke({"messages": "what's (3 + 5) x 12?"}),
timeout=30
)
print('数学响应:', math_response)
weather_response = await agent.ainvoke({"messages": "what is the weather in nyc?"})
print('\n\n天气响应:', weather_response)
# 运行主函数
if __name__ == "__main__":
import asyncio
asyncio.run(main())
客户端使用MultiServerMCPClient
连接两个服务:
- math服务:通过stdio启动
math_server.py
- weather服务:连接到本地8000端口的SSE服务
然后,它创建一个ReAct代理,并用它来回答两个问题:一个数学计算问题和一个天气查询问题。
系统运行过程
运行这个系统的步骤如下:
- 运行客户端(它会自动启动数学服务器):
python mcp_client.py
当客户端运行时,它会:
- 连接到math和weather服务
- 获取这些服务提供的工具
- 创建一个ReAct代理并配置它使用这些工具
- 向代理发送一个数学问题"what’s (3 + 5) x 12?"
- 向代理发送一个天气问题"what is the weather in nyc?"
代理会:
- 分析问题
- 选择合适的工具(add和multiply或get_weather)
- 调用相应的工具
- 基于工具返回的结果生成回答
MCP工作原理
MCP的工作流程如下:
- 服务注册:服务使用
@mcp.tool()
装饰器注册工具函数 - 传输层:服务通过不同的传输方式(stdio、SSE等)提供接口
- 客户端连接:客户端使用相应的传输方式连接服务
- 工具发现:客户端获取服务提供的工具列表
- 代理集成:将工具列表提供给LLM代理
- 工具调用:代理根据用户问题选择合适的工具并调用
- 结果处理:代理处理工具返回的结果并生成回答
优势与应用场景
MCP的主要优势在于:
- 模块化设计:不同功能可以独立开发和部署
- 灵活扩展:容易添加新的服务和工具
- 多种部署方式:支持本地进程和远程服务
- 透明代理:LLM可以自然地选择和使用工具
适用场景包括:
- 复杂的AI助手系统
- 需要访问多种外部服务的应用
- 分布式AI系统
- 需要隔离不同功能模块的环境
总结
MCP为构建多服务AI代理系统提供了一种简单而强大的方法。通过将不同功能封装为独立服务,并使用统一的协议进行通信,我们可以轻松构建复杂的AI应用。
在这个简单的例子中,我们展示了如何创建和连接多个服务,以及如何让LLM自然地使用这些服务提供的工具。这只是MCP能力的冰山一角,在实际应用中,你可以创建更多种类的服务,实现更复杂的功能组合。