前言
在前两篇文章中,我们已经介绍了MCP(模型上下文协议)的基本概念和技术架构。本篇文章将从理论走向实践,通过一个简单但完整的案例,手把手教你如何搭建和调试一个基于MCP的应用。我们将一起构建一个天气查询和活动推荐的MCP服务器,并将其与AI助手集成。
无论你是AI开发者、工具创建者,还是对MCP感兴趣的技术爱好者,通过本文的实践,你将能够掌握MCP的基本开发流程,为后续开发更复杂的MCP应用打下基础。
准备工作
在开始实践之前,我们需要准备好开发环境和相关工具。
环境要求
- Python 3.8+(我们将使用Python实现MCP服务器)
- 基本的命令行和代码编辑器使用经验
- 初步的Python编程知识
- 对JSON和API的基本了解
安装依赖
我们将使用Anthropic提供的MCP Python SDK来简化开发过程。首先,创建一个新项目文件夹,然后安装必要的依赖:
# 创建项目文件夹
mkdir mcp-weather-demo
cd mcp-weather-demo
# 创建虚拟环境
python -m venv venv
source venv/bin/activate # Windows上使用: venv\Scripts\activate
# 安装MCP SDK和其他依赖
pip install mcp-python requests
项目概述
在本教程中,我们将构建一个包含以下功能的MCP服务器:
- 天气查询工具:根据城市名称返回当前天气信息
- 活动推荐工具:根据天气情况推荐适合的活动
- 城市信息资源:提供城市基本信息作为上下文资源
这个服务器将通过Server-Sent Events (SSE)协议与MCP客户端通信,允许任何符合MCP标准的AI应用调用我们的服务。
步骤一:设计MCP服务器的基本结构
首先,让我们设计MCP服务器的基本结构。创建一个名为weather_server.py
的文件:
# weather_server.py
from mcp.server.fastmcp import FastMCP
import asyncio
import logging
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# 创建MCP服务器实例
mcp_server = FastMCP(
name="weather-assistant",
description="天气查询和活动推荐服务",
host="0.0.0.0",
port=1234
)
# 主函数
async def main():
logger.info("启动MCP天气服务器,监听地址: http://localhost:1234")
await mcp_server.run_sse_async()
if __name__ == "__main__":
asyncio.run(main())
这段代码创建了一个基本的MCP服务器,它将监听1234端口,等待MCP客户端的连接。我们使用FastMCP
类,这是MCP Python SDK提供的便捷服务器实现。
步骤二:实现天气查询工具
接下来,让我们实现天气查询工具。在真实应用中,你可能会调用外部天气API,但为了简化教程,我们将使用硬编码的天气数据:
# 在weather_server.py中添加
# 模拟的天气数据库
WEATHER_DATA = {
"北京": {
"condition": "晴", "temperature": 25, "humidity": 40},
"上海": {
"condition": "多云", "temperature": 27, "humidity": 60},
"广州": {
"condition": "雨", "temperature": 30, "humidity": 80},
"深圳": {
"condition": "多云", "temperature": 29, "humidity": 70},
"杭州": {
"condition": "晴", "temperature": 26, "humidity": 50}
}
@mcp_server.tool(name="get_weather", description="获取指定城市的天气信息")
async def get_weather(city: str) -> str:
"""
获取指定城市的天气信息
参数:
city: 城市名称,如"北京"、"上海"
返回:
天气信息描述
"""
logger.info(f"获取天气信息: {
city}")
if city in WEATHER_DATA:
weather = WEATHER_DATA[city]
return f"{
city}:{
weather['condition']},{
weather['temperature']}°C,湿度{
weather['humidity']}%"
else:
return f"抱歉,未找到{
city}的天气信息"
这段代码定义了一个名为get_weather
的工具,它接受一个城市名称参数,返回该城市的天气信息。我们使用@mcp_server.tool
装饰器将函数注册为MCP工具,这样MCP客户端就能发现并调用它。
步骤三:实现活动推荐工具
接下来,让我们实现活动推荐工具:
# 在weather_server.py中添加
# 基于天气的活动推荐
ACTIVITY_RECOMMENDATIONS = {
"晴": ["户外散步", "骑自行车", "野餐", "参观公园", "户外运动"],
"多云": ["参观博物馆", "购物", "咖啡馆休息", "室外摄影", "城市探索"],
"雨": ["室内电影", "博物馆参观", "购物中心", "室内游泳", "图书馆阅读"],
"雪": ["室内活动", "温泉", "热饮", "电影院", "室内游戏"]
}
@mcp_server.tool(name="suggest_activity", description="根据天气状况推荐适合的活动")
async def suggest_activity(weather_condition: str) -> str:
"""
根据天气状况推荐适合的活动
参数:
weather_condition: 天气状况描述,如"晴"、"多云"、"雨"
返回:
推荐活动列表
"""
logger.info(f"推荐活动: 基于天气 {
weather_condition}")
# 提取天气关键词(简单处理)
for key in ACTIVITY_RECOMMENDATIONS:
if key in weather_condition:
activities = ACTIVITY_RECOMMENDATIONS[key]
return f"基于当前{
key}天气,推荐的活动:{
', '.join(activities[:3])}"
return "无法根据提供的天气状况推荐活动,建议选择适合当地气候的活动"
这个工具接受天气状况作为输入,根据天气关键词推荐适合的活动。这展示了MCP工具如何实现基于一个工具输出的结果来调用另一个工具的模式。
步骤四:添加城市信息资源
除了工具外,MCP还支持资源(Resources),这些是只读的信息,可以帮助模型更好地理解上下文。让我们添加一些城市信息作为资源:
# 在weather_server.py中添加
# 城市信息资源
CITY_INFO =