【MCP】从一个天气查询服务带你了解MCP

1. 前言

这篇文章将通过一个集成高德天气查询的 MCP Server 用例,带你上手开发自己的 MCP Server ,文章将通过以下三种方式(自己编写 Client 端代码,使用 mcp-cli 自带页面,集成到 Claude 桌面版等)带你测试自己的 MCP Server。

PS:文章中的每一步都经过自己亲自上手。整理不易,请不要令色你的赞和收藏。

2. MCP介绍

2.1 什么是MCP?

MCP (Model Context Protocol) 是一个开放协议,由 Anthropic 公司推出的开放标准,用于标准化应用程序如何向 LLM 提供上下文。它可以比作 AI 应用程序的 USB-C 接口,提供了一种标准化方式将 AI 模型连接到不同的数据源和工具。

2.2 架构介绍

MCP 遵循 client-server (客户端-服务端) 架构,并允许一个主机应用程序同时连接多个服务器。下面是其核心架构图:

2.3 传输机制

MCP 中 Server 和 Client 之间主要支持以下两种通信方式,并且都使用 JSON-RPC 2.0 (一种轻量级的远程过程调用(RPC)协议) 交换消息:

  • Stdio 传输:使用标准输入/输出,适合本地通信。

  • SSE 传输:使用 Server-Sent Events 和 HTTP POST 请求,实现响应式输出,适合远程通信。

2.4 你的疑问?

2.4.1 什么是MCP Servers?

MCP Servers 是提供上下文、工具和提示给 AI 客户端的系统。它们可以暴露数据源,如文件、文档、数据库和 API 集成,允许 AI 助手以安全的方式访问实时信息

2.4.2 MCP Servers能提供什么?

MCP Servers 可以共享资源(文件、文档、数据)、暴露工具(API 集成、操作)并提供提示(模板交互)。它们控制自己的资源并维护清晰的系统边界以保障安全。

2.4.3 MCP Servers是如何工作的?

MCP Servers 通过简单的客户端-服务器架构工作。它们通过标准协议公开数据和工具,与主机应用程序(如 Claude 桌面)中的客户端保持安全的 1:1 连接。

2.4.4 MCP Servers安全吗?

是的,安全性已内置到 MCP 协议中。服务器控制自己的资源,无需与LLM提供商共享 API 密钥,并且系统保持清晰的边界。每个服务器管理自己的身份验证和访问控制。

3. 前提条件

这篇文章使用 Python 来开发 MCP Server ,使用高德地图的 API 来查询天气。阅读之前,你需要具备以下条件:

  • 已安装 Python 3.10 或更高版本。

  • 已申请高德 web 服务 API_KEY,访问  高德开放平台 申请。

我使用的 Python 版本是 3.12,我的系统是 win11。

拓展:目前官方已提供以下几种语言的 SDK:Python、TypeScript、Java、C#、Kotlin等,详情可访问文末的参考文档。

4. 开发

4.1 创建一个Pyhon项目

推荐使用 uv 做为 Python 包管理工具。

1. 安装 uv:

pip install uv

 2. 使用uv创建一个 mcp-demo 项目:

uv init mcp-demo

 3. 创建uv虚拟环境:

# 进入到刚创建的项目目录下
cd .\mcp-demo\# 创建uv虚拟环境
uv venv .venv

执行完上述命令后,当前目录下会创建一个名为 .venv 的虚拟环境文件夹。 

4.  激活虚拟环境:

.\.venv\Scripts\activate

5. 安装 python mcp 依赖: 

uv add "mcp[cli]"

6. PyCharm中引入该项目:

使用 PyCharm 打开这个项目,并在【Settings - Python Interpreter】中查看python解释器是否正确(地址为项目路径下的".venv\Scripts\python.exe")。

4.2 MCP Server开发

4.2.1 核心功能

MCP 主要提供一下三种功能:

  • 资源(Resources):客户端可读取的文件类数据(如 API 响应或文件内容)。

  • 工具(Tools):LLM 可调用的函数(需要用户批准)。

  • 提示(Prompts):帮助用户完成特定任务的预编写模板。

通过这篇文章,你可以快速构建一个 MCP Server,使 LLM 能够访问实时天气数据。​MCP 提供了统一的接口,可以简化 LLM 与外部数据源的集成过程。

4.2.2 代码

这篇文章主要关注工具(Tools)的使用。

4.2.2.1 创建.env文件

首先在项目路径下创建一个 .env 的文件,用来存储配置信息:

AMAP_API_KEY=<你的高德API_KEY>
4.2.2.2 创建weather-mcp-server.py文件

这篇文章使用官方的 FastMCP 框架构建 MCP 服务端和客户端。

完整代码:

import os
from typing import Dict, Any, Optionalimport httpx
from dotenv import load_dotenv
from mcp.server.fastmcp import FastMCP# 定义一个 FastMCp 实例
mcp = FastMCP("LocalWeatherServer")# 高德天气API配置信息
load_dotenv()
AMAP_WEATHER_API_BASE_URL = "https://restapi.amap.com/v3/weather/weatherInfo"
AMAP_API_KEY = os.getenv("AMAP_API_KEY")async def get_amap_weather(city: str) -> Optional[Dict[str, Any]]:"""调用高德天气接口,获取天气数据"""params = {"city": city,"key": AMAP_API_KEY,"extensions": "all",  # all:预报天气,base:实况天气"output": "JSON",}try:async with httpx.AsyncClient(timeout=5.0) as client:response = await client.get(AMAP_WEATHER_API_BASE_URL, params=params)response.raise_for_status()return response.json()except httpx.HTTPError as e:return {"error": f"天气服务请求失败:{e}"}def parse_forecast(cast: Dict[str, str]) -> str:""" 格式化单日天气信息 """return (f"日期:{cast.get('date', '未知')},"f"星期:{cast.get('week', '未知')},"f"白天天气:{cast.get('dayweather', '未知')},"f"夜晚天气:{cast.get('nightweather', '未知')},"f"温度:{cast.get('nighttemp', '未知')}~{cast.get('daytemp', '未知')}℃,"f"风向:{cast.get('daywind', '未知')}~{cast.get('nightwind', '未知')},"f"白天风力:{cast.get('daypower', '未知')}级,"f"夜晚风力:{cast.get('nightpower', '未知')}级。")def format_weather_data(weather_data: Dict[str, Any]) -> str:"""格式化天气响应数据"""if "error" in weather_data:return weather_data["error"]forecasts = weather_data.get("forecasts", [])if not forecasts:return "未找到该城市的天气信息。"forecast = forecasts[0]city = forecast.get("city", "未知城市")casts = forecast.get("casts", [])if not casts:return "未找到该城市的天气信息。"today = parse_forecast(casts[0])future = "\n".join(parse_forecast(c) for c in casts[1:])result = [f"{city}今天的天气:{today}"]if future:result.append(f"未来几天天气:\n{future}")return "\n".join(result)@mcp.tool()
async def fetch_weather(city: str) -> str:"""获取城市天气"""weather_data = await get_amap_weather(city)return format_weather_data(weather_data)if __name__ == "__main__":# 运行 MCP 服务器,默认传输协议 stdiomcp.run(transport="stdio")

5. 测试

5.1 通过编写Client端代码测试

5.1.1 客户端实现完整代码:

创建一个 mcp-client.py 的文件:

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client# 创建标准输入输出(stdio)连接的服务器参数配置
server_params = StdioServerParameters(command="python",  # 要执行的命令/可执行文件args=["weather-mcp-server.py"],  # 传递给命令的参数列表env=None,  
)async def run():"""主运行函数,处理客户端会话逻辑"""# 使用stdio_client建立连接,获取读写通道async with stdio_client(server_params) as (read, write):# 创建客户端会话async with ClientSession(read, write) as session:# 初始化连接(握手协议等)await session.initialize()# 列出所有可用的提示模板# prompts = await session.list_prompts()# 获取特定提示模板,可传入参数# prompt = await session.get_prompt(#     "example-prompt",  # 提示模板名称#     arguments={"arg1": "value"}  # 模板参数# )# 列出所有可用资源# resources = await session.list_resources()# 列出所有可用工具tools = await session.list_tools()print(f"工具列表:{tools}")# 读取特定资源内容# content, mime_type = await session.read_resource(#     "file://some/path"  # 资源URI# )# 调用指定工具result = await session.call_tool("fetch_weather",  # 工具名称arguments={"city": "南京"}  # 工具参数)print(f"查询结果:{result}")if __name__ == "__main__":import asyncio# 运行主异步函数asyncio.run(run())

5.1.2  启动服务端

首先需要启动 MCP 服务端,PyCharm 中右键启动:

5.1.3 测试

以同样的方式运行客户端测试,其结果如下:

5.2 使用mcp-cli自带页面测试

该方式需要安装 node.js 。

5.2.1 启动服务端

命令行键入:

 mcp dev weather-mcp-server.py

运行结果:

5.2.2 测试

浏览器打开 http://127.0.0.1:6274 

 5.3 集成到 Claude 桌面端测试

首先你需要 下载 Claude 桌面端 。

5.3.1 启动服务端

同 5.2.1 

5.3.2 配置claude_desktop_config.json文件

打开 Claude 桌面端 - File- Settings - Developer - Edit Config(我这里已经配置,这个界面会不同)。

点击 Edit Config,进入 Claude 运行目录,找到 claude_desktop_config.json 文件,键入以下配置,将 AMAP_API_KEY 值替换为你的高德 API_KEY:

{"mcpServers": {"LocalWeatherServer": {"command": "uv","args": ["--directory","F:\\workspace\\python\\demos\\mcp-demo","run","weather-mcp-server.py"],"env": {"AMAP_API_KEY": "<your_api_key>"}}}
}

配置完成后,重启 Claude 桌面端(需要在任务管理器杀掉 Calude 进程)。

重启后,对话框下方会出现如下锤子按钮。

5.3.3 测试

在聊天对话框输入 ‘ 南京天气 ’,首次调用会出现如下是否使用工具的提示,点击同意即可。

结果:

到这里,MCP的简单用例就开发完了。如果你想发现、分享和学习各种适用于 AI 应用的 MCP 服务器,可以访问 MCP Servers 。

6. 参考文档

  • Model Context Protocol 官网
  • MCP Python SDK

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/77429.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SHCTF-REVERSE

前言 之前写的&#xff0c;一直没发&#xff0c;留个记录吧&#xff0c;万一哪天记录掉了起码在csdn有个念想 1.ezapk 反编译 快速定位关键函数 package com.mycheck.ezjv;import adrt.ADRTLogCatReader; import android.app.Activity; import android.content.Context; impo…

安卓触摸事件分发机制分析

1. 前言 &#x1f3af; 一句话总结&#xff1a; 触摸事件&#xff08;TouchEvent&#xff09;会从 Activity 层开始&#xff0c;按从外到内的方式传递给每一个 ViewGroup/View&#xff0c;直到某个 View 消费&#xff08;consume&#xff09; 它&#xff0c;事件传递就会停止…

Spring MVC 多个拦截器的执行顺序

一、流程总览 该流程图描述了一个多层拦截器链的业务处理流程&#xff0c;核心逻辑为&#xff1a; 前置拦截&#xff1a;通过 predHandler1 和 predHandler2 逐层校验请求合法性。核心处理&#xff1a;通过校验后执行核心业务逻辑 handler()。后置处理与清理&#xff1a;按反…

django filter 排除字段

在Django中&#xff0c;当你使用filter查询集&#xff08;QuerySet&#xff09;时&#xff0c;通常你会根据模型的字段来过滤数据。但是&#xff0c;有时你可能想要排除某些特定的字段&#xff0c;而不是过滤这些字段。这里有几种方法可以实现这一点&#xff1a; 使用exclude方…

ByeCode,AI无代码开发平台,拖拽式操作构建应用

ByeCode是什么 ByeCode 是一款先进的 AI 无代码平台&#xff0c;旨在帮助企业迅速创建数字名片、网站、小程序、应用程序及内部管理系统&#xff0c;无需繁杂的编码或开发工作。ByeCode 采用直观的可视化界面和拖拽式操作&#xff0c;使得非技术用户能够轻松上手。同时&#x…

AI日报 - 2025年04月28日

&#x1f31f; 今日概览(60秒速览) ▎&#x1f916; 能力进展 | Gemini 2.5 Pro成功挑战《口袋妖怪红》8道馆&#xff1b;AI推理器具备自我纠错能力&#xff1b;LLM在游戏、多模态理解、代码迁移等方面展现新能力。 ▎&#x1f4bc; 商业动向 | Google回应DOJ反垄断案&#xff…

在Java中实现List按自定义顺序排序的几种方案

在Java中实现List按自定义顺序排序的几种方案 在实际开发中&#xff0c;我们经常需要对集合中的对象按照特定字段进行排序。当排序规则不是简单的字母或数字顺序&#xff0c;而是自定义的顺序时&#xff0c;我们需要采用特殊的方法。本文将以一个List<Person>按省份特定…

微服务架构在云原生后端的深度融合与实践路径

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:后端架构的演变,走向云原生与微服务融合 过去十余年,后端架构经历了从单体应用(Monolithic)、垂直切分(Modularization)、到微服务(Microservices)的演进,每一次变化都是为了解决…

Python中的Walrus运算符分析

Python中的Walrus运算符&#xff08;:&#xff09;是Python 3.8引入的一个新特性&#xff0c;允许在表达式中同时赋值和返回值。它的核心作用是减少重复计算&#xff0c;提升代码简洁性。以下是其适用的典型场景及示例&#xff1a; 1. 在循环中避免重复计算 当循环条件需要多次…

用Node.js施展文档比对魔法:轻松实现Word文档差异比较小工具,实现Word差异高亮标注(附完整实战代码)

引言&#xff1a;当「找不同」遇上程序员的智慧 你是否经历过这样的场景&#xff1f; 法务同事发来合同第8版修改版&#xff0c;却说不清改了哪里 导师在论文修改稿里标注了十几处调整&#xff0c;需要逐一核对 团队协作文档频繁更新&#xff0c;版本差异让人眼花缭乱 传统…

前端浏览器窗口交互完全指南:从基础操作到高级控制

浏览器窗口交互是前端开发中构建复杂Web应用的核心能力&#xff0c;本文深入探讨23种关键交互技术&#xff0c;涵盖从传统API到最新的W3C提案&#xff0c;助您掌握跨窗口、跨标签页的完整控制方案。 一、基础窗口操作体系 1.1 窗口创建与控制 // 新窗口创建&#xff08;现代浏…

Git和Gitlab的部署和操作

一。GIT的基本操作 1.GIT的操作和查看内容 [rootmaster ~]# yum install git -y [rootmaster ~]# git config --list&#xff1a;查看所有配置 2.GIT仓库初始化 [rootmaster ~]# mkdir /gittest&#xff1a;创建目录 [rootmaster ~]# cd /gittest/&#xff1a;进入目录 [rootm…

Linux中线程池的简单实现 -- 线程安全的日志模块,策略模式,线程池的封装设计,单例模式,饿汉式单例模式,懒汉式单例模式

目录 1. 对线程池的理解 1.1 基本概念 1.2 工作原理 1.3 线程池的优点 2. 日志与策略模式 2.1 日志认识 2.2 策略模式 2.2.1 策略模式的概念 2.2.2 工作原理 2.2 自定义日志系统的实现 3. 线程池设计 3.1 简单线程池的设计 3.2 线程安全的单例模式线程池的设计 3…

量子力学:量子通信

量子通信是利用量子力学原理对信息进行编码、传输和处理的新型通信方式&#xff0c;以下是其详细介绍及业界发展现状&#xff1a; 基本原理 量子叠加态 &#xff1a;量子系统可以处于多个状态的叠加&#xff0c;如光子的偏振方向可以同时处于水平和垂直方向的叠加态&#xff…

企业架构之旅(1):TOGAF 基础入门

大家好&#xff0c;我是沛哥儿。今天我们简单聊下TOGAF哈。 文章目录 一、TOGAF 是什么定义与核心定位发展历程与行业地位与其他架构框架的区别 二、TOGAF 核心价值企业数字化转型助力业务与 IT 的协同作用降本增效与风险管控 三、TOGAF 基础术语解析架构域&#xff08;业务、…

CSS 内容超出显示省略号

CSS 内容超出显示省略号 文章目录 CSS 内容超出显示省略号**1. 单行文本省略&#xff08;常用&#xff09;****2. 多行文本省略&#xff08;如 2 行&#xff09;****3. 对非块级元素生效****完整示例****注意事项** 在 CSS 中实现内容超出显示省略号&#xff0c;主要通过控制文…

路由器重分发(OSPF+RIP),RIP充当翻译官,OSPF充当翻译官

路由器重分发&#xff08;OSPFRIP&#xff09; 版本 1 RIP充当翻译官 OSPF路由器只会OSPF语言&#xff1b;RIP路由器充当翻译官就要会OSPF语言和RIP语言&#xff1b;则在RIP中还需要将OSPF翻译成RIPOSPF 把RIP路由器当成翻译官&#xff0c;OSPF路由器就只需要宣告自己的ip&am…

AlexNet网络搭建

AlexNet网络模型搭建 环境准备 首先在某个盘符下创建一个文件夹&#xff0c;就叫AlexNet吧&#xff0c;用来存放源代码。 然后新建一个python文件&#xff0c;就叫plot.py吧&#xff0c;往里面写入以下代码&#xff0c;用于下载数据集&#xff1a; # FashionMNIST里面包含了…

【计算机网络】网络基础概念

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 这是博主计算机网络的第一篇文章&#xff0c;本文由于是基础概念了解&#xff0c;引用了大…

在Spring Boot项目中实现Word转PDF并预览

在Spring Boot项目中实现Word转PDF并进行前端网页预览&#xff0c;你可以使用Apache POI来读取Word文件&#xff0c;iText或Apache PDFBox来生成PDF文件&#xff0c;然后通过Spring Boot控制器提供文件下载或预览链接。以下是一个示例实现步骤和代码&#xff1a; 1. 添加依赖 …