0基础如何使用python快速搭建mcp server

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

        本文将面向没有接触过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?

会询问是否允许使用工具,允许即可。

当你问一个问题时,内部执行过程如下:

  1. client将您的问题发送给Claude
  2. Claude分析可用的工具并决定使用哪一个
  3. client通过MCP server执行所选工具
  4. 结果将发送回Claude
  5. Claude组织一个自然语言的回答
  6. 将响应显示出来

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值