本文将面向没有接触过mcp的用户,说明如何快速的在(windows)本地启动一个mcp server。
本文主要翻译自官方的quick start文档,您也可直接阅读英文文档:For Server Developers - Model Context Protocol
什么是mcp
MCP,全称为“模型上下文协议”(Model Context Protocol),是Anthropic开源的一项标准协议。打个比方,它就好比AI世界里的“USB-C”接口。大家都知道USB-C吧?一根线就能轻松连接手机、电脑、充电器等设备,十分方便。MCP的作用也类似,它能让AI模型(比如Anthropic的Claude)轻松与外部的数据源和工具连接起来,像数据库、文件系统、API等都不在话下。
以前若要让AI访问你的数据库或者调用某个工具,得专门编写一大堆代码,很麻烦。现在有了MCP,就像插上USB-C线一样简单,AI模型通过这个标准协议就能直接获取数据或执行操作。如此一来,开发AI应用就变得更快、更省事了。
MCP核心概念
MCP采用的是客户端 - 服务器模式。
- MCP Client:是嵌在AI应用里面的,就像Claude Desktop里就有它。这个客户端的主要任务就是和服务器进行“交流沟通”,它会告诉服务器自己“需要什么样的数据”或者“请求服务器帮忙做些什么事情”。
- MCP Server:其实就是一个轻量级的程序,每个server使用mcp协议约定的统一格式,对外提供一定的能力。它能够连接到各种各样的具体数据源或者工具,像你本地的文件、GitHub仓库、各种工具、api接口等。它会按照客户端提出的请求,为客户端提供相应的数据或者去执行相关的任务。
它们之间是通过一种标准的消息格式来进行交流的,这种消息格式是基于JSON - RPC的。通过这些消息,AI模型能够实现不少功能。比如说,它可以获取数据,像从数据库里查询特定的信息,或者从文件里面读取相关的内容;它还可以执行操作,比如调用API来发送消息,或者对代码仓库进行管理等;
MCP(模型上下文协议)服务器有三种主要能力:
- 资源(Resources):AI可读取的数据,如文件内容、数据库查询结果、API响应等,如获取日历事件列表。
- 工具(Tools):AI可调用的函数,用于执行特定操作(如添加任务、发邮件),使用时通常需用户批准。
- 提示词(Prompts):服务器提供给AI的预写消息或模板,帮助AI理解如何用资源和工具,间接辅助用户完成任务 。
如何开发MCP Server
在本教程中,我们将构建一个简单的MCP天气服务器,并将其连接到Claude for Desktop。我们将从基本设置开始,然后进行更复杂的用例。
电脑端安装uv
uv是一个python 包管理工具,类似前端的npm,可以自动下载依赖。
uv的官方文档是:Installation | uv
在windows上,运行以下命令即可安装:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
创建项目、安装依赖
# 电脑打开一个文件夹,打开命令行
# 使用uv创建名为weather的项目
uv init weather
# 执行命令后将创建weather文件夹,进入该文件夹
cd weather
# 创建虚拟环境
uv venv
# 激活环境(注意,如果关掉命令行,需重新执行以下命令)
.venv\Scripts\activate
# 首次需要安装依赖
uv add mcp[cli] httpx
# 创建一个weather.py文件,也可手动创建
new-item 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.tool() 注解的函数,就是需要对外暴露的工具。mcp会利用python的编程特性,自动生成传给llm需要的参数,所以无需编写function calling的参数
运行mcp server
可以使用uv run weather.py运行,不会输出日志。
推荐使用mcp dev weather.py运行,使用该方式运行提示安装mcp inspector,输入y接受,等待片刻,会打印启动。
然后访问:http://localhost:5173/ 即可打开mcp inspector。
mcp inspector的使用:
mcp inspectors使用非常简单,点击左边的connect。连接成功后点击tools,再点击list tools,然后选择某个tool,即可输入参数,然后点击run tool 运行。在history板块也可以看到运行记录,参数和返回值。

在Claude for Desktop中测试
挂梯子下载claude for desktop,然后登录或者注册claude账号。和注册openai一样,也需要验证海外手机号,可以使用某些验证码平台。
安装Claude for Desktop并登录后,需要修改配置文件:claude_desktop_config.json。
点击客户端左上角进入setting页面,点击develop,可以找到claude_desktop_config.json文件位置。

配置文件默认为空,填入一下内容:
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"E:\\你的文件路径\\weather",
"run",
"weather.py"
]
}
}
}
重启claude desktop。要从桌面右下角完全关闭claude再启动。

看到小锤子就是运行成功。然后就可以提问了,可以提以下问题:
What’s the weather in Sacramento?
What are the active weather alerts in Texas?
会询问是否允许使用工具,允许即可。
当你问一个问题时,内部执行过程如下:
- client将您的问题发送给Claude
- Claude分析可用的工具并决定使用哪一个
- client通过MCP server执行所选工具
- 结果将发送回Claude
- Claude组织一个自然语言的回答
- 将响应显示出来

169

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



