MCP终极指南(进阶篇)知识点框架与内容
一、视频概述
- 是MCP终极指南系列的进阶篇,承接基础篇内容
- 进阶篇分为三个部分:
- 动手编写MCP server
- 截获MCP server的输入和输出并逐行分析,演示不借助MCP host和编程语言直接与MCP server沟通
- 探讨MCP(模型上下文协议)的含义及在大模型相关应用中的角色

二、编写第一个MCP server
(一)开发准备
- 开发语言选择:可使用Python、Node、Java、C#等,本次选择Python(考虑使用人数和编程难度)
- 安装Python:
- macOS用户:系统自带Python,需确保版本为3.10及以上
- Windows用户:需到Python官方网站下载安装
- 所需工具:
- UV:Python的包管理器
- Vs Code:代码编写软件
- Client:Vs Code的插件
- (以上工具在基础篇已提及,需自行安装)
(二)具体开发步骤
- 打开终端,使用
uv init weather新建名为weather的项目 - 进入项目目录,执行
uv venv新建虚拟环境(防止依赖影响系统环境) - 执行
source .venv/bin/activate(windows中VSCODE终端输入: .\.venv\Scripts\activate.ps1 进入虚拟环境)进入虚拟环境(终端显示括号内的weather表示已进入) - 执行
uv add “mcp[cli]" httpx安装开发MCP必备的依赖:- mcp[cli]:开发MCP的核心依赖
- httpx:用于调用HTTP接口(查询天气需调用HTTP)
- 用Vs Code打开weather项目目录,新建
weather.py文件,在该文件中完成主要工作:
这里代码和上一篇一样(每一个带有@mcp.tool()的函数都会被仍为是工具函数,如:get_alerts中的注释 都会转换为tool的信息,传递给大模型
"""Get weather alerts for a US state.
Args:
state: Two-letter US state code (e.g. CA, NY)
""")
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Initialize FastMCP server
mcp = FastMCP("weather", log_level="ERROR")
# 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)
import os
import time
@mcp.tool()
def take_screenshots() -> str:
"""每隔5秒截图一次,保存到当前目录的 pick 文件夹,累计10张后停止。"""
try:
import pyautogui
except ImportError:
return "请先安装 pyautogui 库:pip install pyautogui"
save_dir = os.path.join(os.getcwd(), "pick")
os.makedirs(save_dir, exist_ok=True)
for i in range(1, 11):
img = pyautogui.screenshot()
filename = os.path.join(save_dir, f"screenshot_{i:02d}.png")
img.save(filename)
time.sleep(5)
return "截图已完成,已保存10张图片到 pick 文件夹。"
if __name__ == "__main__":
# Initialize and run the server
mcp.run(transport='stdio')
mcp.run(transport='stdio')
这里mcp是下面构建的mcp对象,这里代表对象开始工作,传输方式为stdio
mcp = FastMCP("weather", log_level="ERROR")
(三)功能测试
注册mcpserver,可以参考上一篇流程,这里也贴出注册代码
{
"mcpServers": {
"weather": {
"disabled": false,
"timeout": 60,
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"D:/work/test1_weather/weather",
"run",
"weather.py"
]
}
}
}
- 新建对话,输入问题“纽约明天的天气怎么样”
- 模型会找到对应的MCP server及其中的
get_forecasttool,点击approve同意调用 - 模型会拿到
get_forecast的调用结果并整理成答案返回,说明MCP server编写成功
三、MCP协议分析

(一)获取MCP server输入输出的方法
- 大部分MCP server通过输入和输出与client沟通,若在终端启动可直接看到,但由client启动时用户无法直接看到
- 解决方案:编写
mcp_log.py脚本,该脚本的参数为启动MCP server的命令,功能是截取MCP server的输入和输出并写入外部文件 - 操作方式:在client的MCP server配置中修改启动参数,在原启动命令前加上
python mcp_log.py,输入输出会写入与mcp_log.py同目录的mcpiolog.log文件

这个不是重点,主要是要明白他们之间是怎么交互的
(二)MCP server与client交互内容分析

第一个工具:


- 日志内容说明:每行最前面的“输入”“输出”及后面的冒号是
mcp_log.py脚本添加的,不属于交互内容,交互内容为后面的JSON,标识输入输出是为了方便查看数据流向(输入是client到MCP server的数据,输出是MCP server到client的数据) - 具体交互过程及内容:
- client向MCP server打招呼:告知自身是client,软件版本,使用的MCP协议版本(2024年11月5号出品)
- MCP server回复:表示使用相同的协议版本,说明自身不支持的能力,告知名称(weather)和版本号(1.6.0)
- client回复收到
- client询问MCP server包含的tool:MCP server返回两个tool(
get_alerts和get_forecast),其定义遵循同一套格式,以get_forecast为例:-
功能:获取某个地区的天气预告
-
包含参数信息(纬度latitude和经度longitude,类型为number)
-
描述信息来自函数注释(Python中称为doc string),由
@mcp.tool装饰器提取并放在description字段 -

-
input_schema:定义了参数规范,由@mcp.tool装饰器从参数定义中提取,遵循JSON schema规范(本身是一段JSON,用于描述另一个JSON的结构),模型会根据此规范提取参数,以确保调用成功
-
- client询问MCP server是否有资源和资源模板:MCP server回复均为无(空列表)
- 等待合适时机使用MCP server:当用户再次询问“纽约明天的天气怎么样”并允许调用后,client通知MCP server使用
get_forecasttool,参数为纽约的纬度(40.7128)和经度(-74.006),符合input_schema规范 - MCP server执行对应函数后输出结果:核心是text字段的值,包含未来几天的天气信息(由
get_forecast函数返回) - client拿到执行结果后,与MCP server的交互结束,将结果发给模型总结,最终展示模型总结的结果(在client中可找到每次tool的请求参数和结果,与日志内容一致)
四、直接与MCP server沟通(不经过client)
-
条件:理解MCP协议细节,保证发给MCP server的数据符合格式
-

-
操作步骤:
- 在终端运行MCP server(使用配置中的命令,不加
mcp_log.py) - 直接在终端输入符合格式的信息与MCP server沟通:
- 发送打招呼信息(可修改名称和版本号),MCP server会回复
- 发送表示收到消息可以开始工作的信息,MCP server不回复(与日志表现一致)
- 发送请求工具列表的信息,MCP server会返回工具列表
- 发送调用工具的信息,MCP server会返回工具调用结果
- 在终端运行MCP server(使用配置中的命令,不加
-
结论:无需MCP host也可直接与MCP server交互,此时用户自己就是MCP host
五、MCP协议的本质与定位

-
MCP协议规定的交互环节不涉及模型,主要规定两部分内容:
- 每个MCP server有哪些函数可以用
- 如何调用这些函数(可总结为函数的注册与使用,暂忽略MCP server内部的资源)
-
MCP协议脱离大模型也能使用(只是实际中无人如此使用),本身不规定与模型的交互方式
-
不同的MCP host与模型的交互存在差异(注意:这里不是和mcp和cline的交互,是右边和大模型的交互,注意看图和注意区分):例如client用XML与模型沟通,cherry studio用OpenAI提出的function calling格式与模型沟通
-

-
MCP(模型上下文协议)的含义:让模型感知外部环境(周围可调用的用于获取外界信息的函数,如获取天气、网络、文件信息等)的协议
-
对MCP名称的评价:
- 有误导性,易让人以为规定了与模型的交互内容,实际最多是给模型服务
- 过于玄妙,初看难以理解
下一篇整理HOST和大模型之间的交互流程和细节
1777

被折叠的 条评论
为什么被折叠?



