当前位置: 首页 > news >正文

保姆级教程:用Python和uv从零搭建你的第一个MCP服务器(附天气查询实战)

从零构建Python驱动的MCP天气服务:现代AI开发实战指南

1. 环境配置与工具链搭建

在开始构建MCP(Model Context Protocol)服务之前,我们需要配置高效的开发环境。Python生态中新兴的uv工具链将成为我们的得力助手。

1.1 UV工具链详解

UV是新一代Python依赖管理工具,相比传统pip具有显著优势:

# 安装uv(两种方式任选) curl -LsSf https://astral.sh/uv/install.sh | sh # 或 pip install uv

关键特性对比:

特性UV传统pip
安装速度快5-10倍较慢
依赖解析增量更新全量解析
虚拟环境管理内置轻量方案需venv辅助
跨平台支持全平台一致体验Windows兼容性问题

1.2 项目初始化实战

创建项目目录并初始化虚拟环境:

# 创建项目目录 mkdir mcp-weather && cd mcp-weather # 初始化UV虚拟环境 uv venv .venv # 激活环境(Linux/macOS) source .venv/bin/activate # Windows使用 .venv\Scripts\activate

提示:UV会自动识别项目目录结构,无需手动指定venv路径

2. MCP核心架构解析

2.1 MCP三层通信模型

现代AI服务架构通常包含以下组件:

  1. 客户端(Client):处理用户交互
  2. 协议层(Protocol):标准化通信
  3. 服务端(Server):提供具体能力
graph LR A[用户设备] -->|请求| B(Client) B -->|MCP协议| C[Server] C -->|OpenWeather API| D[第三方服务]

2.2 协议设计要点

MCP通信需要关注三个核心维度:

  • 传输层:HTTP/SSE/WebSocket选择
  • 数据格式:JSON-RPC 2.0规范
  • 错误处理:标准化错误码体系

典型请求示例:

{ "jsonrpc": "2.0", "method": "get_weather", "params": {"city": "Beijing"}, "id": 1 }

3. 天气服务实现

3.1 服务端核心代码

创建weather_server.py文件:

import httpx from mcp.server import FastMCP app = FastMCP("WeatherService") @app.tool() async def get_weather(city: str) -> dict: """获取指定城市天气数据""" async with httpx.AsyncClient() as client: resp = await client.get( "https://api.openweathermap.org/data/2.5/weather", params={ "q": city, "appid": "YOUR_API_KEY", "units": "metric", "lang": "zh_cn" } ) return resp.json() if __name__ == "__main__": app.run(transport="stdio")

关键组件说明:

  1. FastMCP:快速构建MCP服务的装饰器
  2. @app.tool():声明可调用工具方法
  3. transport="stdio":使用标准输入输出通信

3.2 客户端实现

创建client.py

import asyncio from mcp.client import ClientSession async def main(): async with ClientSession() as session: # 调用天气服务 result = await session.call_tool( "get_weather", {"city": "Beijing"} ) print(f"当前天气:{result}") asyncio.run(main())

4. 高级功能扩展

4.1 多模型集成方案

通过MCP可以轻松集成不同AI模型:

# 模型路由配置 MODEL_MAP = { "gpt-4": OpenAIClient, "claude": AnthropicClient, "local": LocalLLMClient } async def route_request(model_type, query): client = MODEL_MAP[model_type]() return await client.process(query)

4.2 性能优化技巧

  1. 连接池管理
from httpx import AsyncClient async with AsyncClient(timeout=30.0) as client: # 复用连接
  1. 结果缓存
from cachetools import TTLCache weather_cache = TTLCache(maxsize=100, ttl=3600)
  1. 异步批处理
async def batch_requests(cities): tasks = [get_weather(city) for city in cities] return await asyncio.gather(*tasks)

5. 部署与监控

5.1 生产环境部署

推荐使用Docker容器化部署:

FROM python:3.10-slim WORKDIR /app COPY . . RUN pip install uv && \ uv pip install -r requirements.txt CMD ["uvicorn", "weather_server:app", "--host", "0.0.0.0"]

5.2 监控指标配置

Prometheus监控示例:

from prometheus_client import start_http_server, Counter REQUEST_COUNT = Counter( 'weather_requests_total', 'Total weather API requests' ) @app.tool() async def get_weather(city: str): REQUEST_COUNT.inc() # ...

典型监控维度:

  • 请求成功率
  • 响应时间P99
  • 并发连接数
  • 缓存命中率

6. 安全最佳实践

  1. 认证鉴权
from fastapi.security import APIKeyHeader api_key_header = APIKeyHeader(name="X-API-KEY") async def verify_key(key: str = Depends(api_key_header)): if key != os.getenv("API_KEY"): raise HTTPException(status_code=403)
  1. 输入验证
from pydantic import BaseModel, constr class WeatherRequest(BaseModel): city: constr(min_length=2, max_length=50)
  1. 限流保护
from slowapi import Limiter from slowapi.util import get_remote_address limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter @app.tool() @limiter.limit("10/minute") async def get_weather(city: str): # ...

在实际项目中,我发现最容易被忽视的是连接超时设置。特别是在调用第三方天气API时,合理的超时配置(建议15-30秒)能显著提高系统稳定性。另一个实用技巧是使用UV的--resolution=lowest-direct参数,可以避免依赖冲突问题。

http://www.jsqmd.com/news/575875/

相关文章:

  • Pi0机器人WebRTC视频传输:低延迟监控系统
  • 告别繁琐配置,用快马ai一键生成win10 opencl环境验证脚本
  • 开源启动器如何提升你的游戏体验?
  • 文脉定序快速上手:HuggingFace Spaces免费体验BGE-v2-m3重排序
  • ComfyUI性能榨干指南:RTX 3060/4060等甜品卡如何设置启动参数和节点,速度翻倍
  • 3D打印机/CNC雕刻机静音升级:手把手调教A4988驱动电流(VREF)与细分设置
  • macOS Big Sur M1芯片运行Keil C51的替代方案探索(非虚拟机)
  • 【架构实战】热点数据架构:本地缓存+多级缓存
  • 华为交换机流量统计配置避坑指南:为什么你的统计结果总是0?(GigabitEthernet接口实战)
  • Graphormer科研级部署:Supervisor自动重启+日志tail -f监控配置
  • ChatGPT_JCM版本控制策略:项目迭代与版本管理方法
  • 造相-Z-Image-Turbo与Vue.js构建AI绘图平台:前端工程化实践
  • iOS 15+ 越狱实战:A8-A11设备高效解锁与专业部署指南
  • Whisky实战指南:5大核心场景下的Windows程序跨平台运行解决方案
  • tweets_analyzer 进阶技巧:如何自定义过滤器和导出高级分析报告
  • Attu:Milvus可视化管理工具如何颠覆传统向量数据库操作流程?
  • Realistic Vision V5.1 惊艳作品集:基于卷积神经网络的人像摄影风格迁移
  • PLC与变频器通信的三种高效控制方案解析
  • ArduRemoteID:基于ESP32的无人机远程识别开源解决方案
  • Qwen3.5-2B效果展示:服装设计稿→识别风格/面料/剪裁→生成电商详情页文案
  • 生信小白也能搞定的实验室内部工具:手把手教你用SequenceServer+Docker搭建专属BLAST查询网站
  • 效率倍增:用快马AI一键生成互联网电商商品筛选组件代码
  • 2026年AI趋势监控平台能力榜:主流站点效能与覆盖度解析
  • 漫画脸描述生成保姆级教程:如何调试生成结果提升SD绘图匹配度
  • iOS 15+ 设备越狱实战指南:A8-A11 芯片全流程适配方案
  • B站视频收藏难?开源工具BilibiliDown通过多线程技术实现批量下载,效率提升85%
  • 红外图像处理实战:基于DifIISR的超分辨率重建保姆级教程(附CVPR 2025最新方法)
  • 实战指南:基于快马平台快速构建opencode协作应用界面
  • Lychee-rerank-mm模型服务网格化:基于Istio的微服务部署
  • Python原生AOT编译实战指南(2026 LTS版正式启用倒计时)