原文链接:MCP Server 开发实战指南(Python版)

资料

MCP 官方文档

https://modelcontextprotocol.io/introduction

各个 clients 对 MCP 的支持情况

https://modelcontextprotocol.io/clients

MCP Python SDK:MCP Client 和 Server 官方 SDK

https://github.com/modelcontextprotocol/python-sdk

前言

MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口。

Function Calling是AI模型调用函数的机制,MCP是一个标准协议,使AI模型与API无缝交互,而AI Agent是一个自主运行的智能系统,利用Function Calling和MCP来分析和执行任务,实现特定目标。

MCP 核心架构

  • MCP 主机(MCP Hosts):发起请求的 LLM 应用程序(例如 Claude Desktop、IDE 或 AI 工具)。
  • MCP 客户端(MCP Clients):在主机程序内部,与 MCP server 保持 1:1 的连接。
  • MCP 服务器(MCP Servers):为 MCP client 提供上下文、工具和 prompt 信息。
  • 本地资源(Local Resources):本地计算机中可供 MCP server 安全访问的资源(例如文件、数据库)。
  • 远程资源(Remote Resources):MCP server 可以连接到的远程资源(例如通过 API)。

MCP client 充当 LLM 和 MCP server 之间的桥梁,MCP client 的工作流程如下:

  • MCP client 首先从 MCP server 获取可用的工具列表。
  • 将用户的查询连同工具描述通过 function calling 一起发送给 LLM。
  • LLM 决定是否需要使用工具以及使用哪些工具。
  • 如果需要使用工具,MCP client 会通过 MCP server 执行相应的工具调用。
  • 工具调用的结果会被发送回 LLM。
  • LLM 基于所有信息生成自然语言响应。
  • 最后将响应展示给用户。

MCP 通信机制

MCP 协议支持两种主要的通信机制:基于标准输入输出 stdio 的本地通信和基于SSE(Server-Sent Events)的远程通信。这两种机制都使用 JSON-RPC 2.0 格式进行消息传输,确保了通信的标准化和可扩展性。

  • 本地通信:通过 stdio 传输数据,适用于在同一台机器上运行的客户端和服务器之间的通信。
  • 远程通信:利用 SSE 与 HTTP 结合,实现跨网络的实时数据传输,适用于需要访问远程资源或分布式部署的场景。

MCP Server

MCP Server 是 MCP 架构中的关键组件,它可以提供 3 种主要类型的功能:

  • 资源(Resources):类似文件的数据,可以被客户端读取,如 API 响应或文件内容。
  • 工具(Tools):可以被 LLM 调用的函数(需要用户批准)。
  • 提示(Prompts):预先编写的模板,帮助用户完成特定任务。

这些功能使 MCP server 能够为 AI 应用提供丰富的上下文信息和操作能力,从而增强 LLM 的实用性和灵活性。

MCP Server Demo 开发

开发语言:Python 3.13.2

环境:MacOS

MCP 客户端:Cursor、Cline、Claude Desktop

一、环境配置

安装 uv 命令

curl -LsSf https://astral.sh/uv/install.sh | sh

初始化项目

# 给项目创建一个文件夹
uv init weather
cd weather # 创建一个虚拟环境并激活
uv venv
source .venv/bin/activate # 安装依赖
uv add "mcp[cli]" httpx # 创建 server 文件
touch weather.py

二、编写Server 代码

from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP # Initialize FastMCP server
mcp = FastMCP("weather") # Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0" async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Make a request to the NWS API with proper error handling."""
headers = {
"User-Agent": USER_AGENT,
"Accept": "application/geo+json"
}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None def format_alert(feature: dict) -> str:
"""Format an alert feature into a readable string."""
props = feature["properties"]
return f"""
Event: {props.get('event', 'Unknown')}
Area: {props.get('areaDesc', 'Unknown')}
Severity: {props.get('severity', 'Unknown')}
Description: {props.get('description', 'No description available')}
Instructions: {props.get('instruction', 'No specific instructions provided')}
""" @mcp.tool()
async def get_alerts(state: str) -> str:
"""Get weather alerts for a US state. Args:
state: Two-letter US state code (e.g. CA, NY)
"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url) if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found." if not data["features"]:
return "No active alerts for this state." alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts) @mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get weather forecast for a location. Args:
latitude: Latitude of the location
longitude: Longitude of the location
"""
# First get the forecast grid endpoint
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url) if not points_data:
return "Unable to fetch forecast data for this location." # Get the forecast URL from the points response
forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url) if not forecast_data:
return "Unable to fetch detailed forecast." # Format the periods into a readable forecast
periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]: # Only show next 5 periods
forecast = f"""
{period['name']}:
Temperature: {period['temperature']}°{period['temperatureUnit']}
Wind: {period['windSpeed']} {period['windDirection']}
Forecast: {period['detailedForecast']}
"""
forecasts.append(forecast) return "\n---\n".join(forecasts) if __name__ == "__main__":
# Initialize and run the server
mcp.run(transport='stdio')

三、运行服务

MCP Inspector

mcp dev weather.py

当看到以下界面,说明服务运行成功。打开 http://localhost:5173/ 即可进行功能测试

Cursor

也可以通过一些支持 MCP Server 的客户端进行调试

设置 -> MCP → Add new MCP server

类型选择 command,名称可以自定义,执行的命令如下,需要指定路径

uv --directory /Users/ryanjhzheng/Documents/my_mcp/weather run weather.py

Cline

{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather",
"run",
"weather.py"
]
}
}
}

调试

https://modelcontextprotocol.io/docs/tools/debugging

调试工具

MCP Python SDK

创建 Tools

  • 提供清晰、描述性的名称和说明

  • 使用详细的 JSON Schema 定义参数

  • 在工具描述中包含示例,告诉模型应如何使用它们

  • 实施适当的错误处理和验证

  • 对长时间操作使用进度报告

  • 保持工具操作集中且原子化

  • 记录预期返回结果

  • 实施适当的超时

  • 考虑对资源密集型操作进行速率限制

  • 用于调试和监控的日志工具使用情况

常见问题

版本不兼容

ERROR: npm v11.2.0 is known not to run on Node.js v14.21.3.  This version of npm supports the following node versions: `^20.17.0 || >=22.9.0`. You can find the latest version at https://nodejs.org/.

遇到的错误表明当前使用的 npm 版本(v11.2.0)与 Node.js 版本(v14.21.3)不兼容。当前的 npm 版本仅支持 Node.js 版本 ^20.17.0 || >=22.9.0。将 Node.js 版本更新到支持的版本,如 ^20.17.0 || >=22.9.0

# 安装最新的 Node.js 版本
nvm install node # 或者安装指定的 Node.js 版本
nvm install 20.17.0 # 使用已安装的 Node.js 版本
nvm use 20.17.0

最后给如果需要购买服务器的,可以使用这里的优惠码,可以享受8折优惠

关于 MCP 的具体场景和玩法,可以查看这篇文章

https://www.cnblogs.com/ryanzheng/p/18879488

https://zhuanlan.zhihu.com/p/1895815215712547750

MCP Server 开发实战指南(Python版)的更多相关文章

  1. 推荐一本书:清华出版的《Modbus软件开发实战指南》

    前言: 最近在研究Modbus开发,如果只是简单的了解了一些modbus基础知识,但是不够系统和全面. 其实,modbus虽然比较简单,但是如果不注意有很多坑,特别是寄存器的位数,大小端处理,浮点数, ...

  2. HTML5 Canvas游戏开发实战 PDF扫描版

    HTML5 Canvas游戏开发实战主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读 ...

  3. HTML5移动Web开发实战 PDF扫描版​

    <HTML5移动Web开发实战>提供了应对这一挑战的解决方案.通过阅读本书,你将了解如何有效地利用最新的HTML5的那些针对移动网站的功能,横跨多个移动平台.全书共分10章,从移动Web. ...

  4. 【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章

    从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章  如何使用本书 1.1  本书的参考资料 本书参考资料为:<STM32 ...

  5. 《Django企业开发实战 高效Python Web框架指南》胡阳

    链接:https://pan.baidu.com/s/1NmN_IT5RvevCMt9bZCW1-g提取码:2ki9

  6. 【深入浅出Seata原理及实战】「入门基础专题」探索Seata服务的AT模式下的分布式开发实战指南(2)

    承接上文 上一篇文章说到了Seata 为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案.那么接下来我们将要针对于AT模式下进行分布式事务开发的原理进行介绍以及 ...

  7. (六)Spark-Eclipse开发环境WordCount-Java&Python版Spark

    Spark-Eclipse开发环境WordCount 视频教程: 1.优酷 2.YouTube 安装eclipse 解压eclipse-jee-mars-2-win32-x86_64.zip Java ...

  8. 【Python开发实战】Python环境的配置

    1. 安装Pythonsudo aptitude -y install python-dev 安装Distribute:支撑模块构建与导入的包sudo chmod -R 0775 /usr/local ...

  9. Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 1

    在开发Modbus程序的过程中,也可以发现经常需要使用诸如Modbus Poll和Modbus Slave等辅助调试工具, 用于验证MODBUS通讯消息是否正确.但是,Modbus Poll和Modb ...

  10. Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 2

    接上一篇文章的内容. 看了前面需求提到的复杂的命令行解析功能,很多人立马开始发怵,其实大可不必. 我们都知道,Linux下的程序往往都提供了复杂的命令行参数处理机制,因为这是与 其他程序或用户进行交互 ...

随机推荐

  1. 数据分析必备:GPS轨迹、软件签到、手机信令数据获取方式合集

      本文对目前主要的出租车.公交车.行人GPS轨迹.社交软件签到.手机信令等数据产品的获取网站加以整理与介绍. 目录 6 GPS轨迹与签到数据 6.1 个人GPS轨迹数据 6.1.1 GeoLife ...

  2. python学习课后练习

    此次爬虫学习的资源是B站所找,具体如下:Python课程天花板,Python入门+Python爬虫+Python数据分析5天项目实操/Python基础,该课程留了课后练习,我把自己的代码和想法单独整成 ...

  3. 关于学习率-----linearLR

    1. lr_scheduler综述 torch.optim.lr_scheduler模块提供了一些根据epoch训练次数来调整学习率(learning rate)的方法.一般情况下我们会设置随着epo ...

  4. SRM合同更新行项目(组件/SAPSRM/WDC_CTR_DOTC_IT)

    * Get the selected elements of the item table > lt_elem_set = lon_ctr_item->get_selected_eleme ...

  5. 物无弃材 —— 混闪机型部署 OceanBase 集群的探索

    本文作者:联通研究院 邱永刚 首先为大家推荐这个 OceanBase 开源负责人老纪的公众号 "老纪的技术唠嗑局",会持续更新和 #数据库.#AI.#技术架构 相关的各种技术内容. ...

  6. solana杂谈(1)

    solana杂谈(1) 本文适用于"只需大致了解 Solana"的读者,部分说法可能不够准确或不够深入.如需详细了解,建议阅读 Solana 的官方文档:https://solan ...

  7. pont生成api涉及泛型问题

    背景 pont是一款很好用的api生成工具. 我最近在用其生成swagger3的前端接口文件时,发现了个问题. 就是当我后端接口返回的是复杂类型的泛型的时候,生成的def类型有问题: 会直接写死泛型! ...

  8. 从Linux系统SSH到Windows系统。

    以管理员身份运行powershell. PS C:\Windows\system32> Get-WindowsCapability -Online | ? Name -like 'OpenSSH ...

  9. C++ linux 共享内存的学习

    简介 我经常被 无知所惊吓, 我的无知包含很多东西,或许是一段未开始已经结束的爱情,或许是掩盖不了对自己想去的公司的眼神, 或许就是共享内存这个名字.哈哈哈哈. 共享内存 简而言之就是 共享内存(sh ...

  10. printf \r \n

    简介 \r 回到这一行的开始处 \n 换下一行 参考链接 csdn