手搓MCP全流程指南:从本地开发部署到PyPI公开发布

1、关于MCP

1.1、什么是MCP

MCP是一个由Anthropic公司推出的开源标准,旨在统一AI模型与外部工具及数据源的交互方式。在MCP出现之前,开发者需要为每一个AI需要接入的应用编写特定的集成代码,过程繁琐且难以扩展。MCP的出现改变了这一现状,它就如同一个为AI应用打造的"USB-C"接口,提供了一个标准化的连接方式,让AI模型可以轻松地与不同的数据源和工具进行连接和通信。

简而言之,MCP允许AI应用(作为客户端)与外部工具或数据源(作为服务器)之间建立安全的双向连接。这意味着,AI不仅可以从外部获取信息以生成更精准的回答,更可以"调用"这些工具去执行具体的操作,比如在您的代码库中进行搜索,或者向团队成员发送即时消息。对于开发者而言,无论是想要将自己的数据通过MCP服务器暴露给AI,还是开发能够连接这些服务器的AI应用,都变得更加简单和高效。

1.2、MCP的本质与价值

MCP 的核心价值在于提供一种标准化的方式,让 AI 模型与外部世界进行交互。在 MCP 出现之前,开发者需要为每个 AI 集成创建定制化的解决方案,这导致了严重的碎片化问题。

MCP 解决了这些问题,它提供了以下关键价值:

  • 统一集成标准:一个协议对接所有集成,降低开发难度
  • 实时数据更新:支持动态数据交互而非静态连接
  • 自动工具发现:支持动态工具发现和上下文处理
  • 隐私保护:数据和工具不需上传远端,保护数据隐私
  • 开发效率:显著减少开发时间,提高系统可靠性

1.3MCP原理

  • 结构化上下文整合:MCP 通过定义标准化的资源描述与调用机制(基于 JSON-RPC 2.0 协议),使模型能够自动获取结构化数据源,如本地文件系统、企业数据库或实时 API数据。相较于早期手动拼接非结构化数据的prompt 设计方式,这种动态上下文加载将信息获取延迟降低 90%以上,同时保证了数据完整性与时效性。

  • 双向交互机制创新:传统 Function Cal 仅支持单向请求-响应模式,而 MCP 允许服务器主动推送数据(如设备状态告警)或请求用户授权这种双向通信能力使模型在医疗诊断等场景中,能实时获取最新检测报告并触发二次确认流程,显著提升了复杂决策的可靠性。

  • 多模态上下文管理:MCP 支持对话上下文的标准化存储与跨会话继承。例如在客服场景中,模型可持久化用户历史订单信息,结合当前咨询内容生成精准回复,避免了传统方案中需要反复人工注入历史数据的低效操作

1.4MCP和API的区别

举个例子,例如:你要开发一个 AI 行程规划助手

用 API 开发:要单独接入 Google Calendar API、邮件 API、航司 API,每个都要写认证、错误处理使用

MCP:AI助手可以无缝查询日程、预订航班、发送确认邮件,而无需为每个工具编写特定集成。只接入 MCP 协以AI 能自动访问这些服务(如:看日历 → 改航班 → 发邮件)

MCP 是一个为 AI 而设计的"智能标准连接协议",让模型能像插 USB-C一样自由访问各种工具和数据源,而不再受限于一个个麻烦的 API 接口。

由于使用 MCP 还是需要有一定的技术基础,所以目前 MCP 基本都是开发者在使用,上手难度还是有点高。

2、手搓一个MCP

2.1、基础环境搭建

2.1.1、安装UV

uv是目前热度最高的python环境管理工具

官方网址:https://docs.astral.sh/uv/getting-started/installation/#__tabbed_1_2

我们这里使用的是Windows版本,选择对应的版本,然后复制对应的命令

bash 复制代码
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

打开电脑的PowerShell,以管理员的身份进行运行

在终端中输入上面的命令,当出现了Downloading就说明安装成功了

终端将uv安装在了C:\Users\27890\.local\bin这个路径下,接下来我们需要将这个路径加入到环境变量中,不然系统是识别不了这个命令的,出现下方的报错现象的

打开环境变量

点击环境变量

在系统变量中找到Path点击编辑

点击新建,将我们安装uv的路径填写进去,然后点击确定即可

这里为了检测是否安装成功了,需要进行测试操作,输入下方命令

bash 复制代码
uv python list

成功显示上方的文件,说明你安装成功了

2.1.2、新建MCP文件夹

接下来我们在D盘创建一个MCP文件夹来进行MCP的开发

然后在这个文件打开终端,对这个文件夹进行一个初始化操作

bash 复制代码
uv init . -p 3.13

初始化后文件夹会多出初始化文件

同样在终端中输入命令进行安装MCP的SDK,也就是开发工具包

bash 复制代码
uv add "mcp[cli]"

如果你出现了下面的报错,不要谎,只需要修改下文件夹的命令就成功运行了,因为我这里的文件夹的名称叫做MCP,我创建的项目的名字和您试图安装的库(SDK)的名字完全一样,都叫 mcp。
一个项目不能把自己作为自己的依赖项。 uv 为了防止这种循环依赖和混乱,直接报错并阻止了这次安装。

将文件夹改成了mcp_test之后重新输入下方命令进行安装MCP的SDK

bash 复制代码
uv add "mcp[cli]"

如果你还是出现同样的报错,你将整个项目文件夹删除,然后重新进行上面的初始化操作

在安装SDK的时候需要进行等待一会儿

安装好了如下:

2.1.2、安装trae拓展

将文件夹拖入到trae中

在拓展中安装PythonPython Debugger这两个插件

2.2、代码编写以及代码讲解

打开python-mcp官网https://github.com/modelcontextprotocol/python-sdk

这个官网里面就是关于如何搭建MCP的英文教程

将下方代码进行复制我们进行快速入门操作

Python 复制代码
# -*- coding: utf-8 -*-  
"""
FastMCP 快速入门示例。  
首先,请切换到 `examples/snippets/clients` 目录,然后运行以下命令来启动服务器:
    uv run server fastmcp_quickstart stdio
"""
# 从 mcp.server.fastmcp 模块中导入 FastMCP 类,这是构建 MCP 服务器的核心。
from mcp.server.fastmcp import FastMCP 
# 创建一个 MCP 服务器实例,并将其命名为 "Demo"。
# 这个名字会向连接到此服务器的 AI 客户端展示。
mcp = FastMCP("Demo")  
# 使用 @mcp.tool() 装饰器来定义一个"工具"。
# 工具是 AI 可以调用的具体函数,用于执行特定的操作。
@mcp.tool()
def add(a: int, b: int) -> int:
    """
    这个工具的功能是计算两个整数的和。
    文档字符串(docstring)会作为工具的描述,帮助 AI 理解其功能。
    """
    return a + b   
# 使用 @mcp.resource() 装饰器来定义一个"资源"。
# 资源代表 AI 可以访问的数据或信息。这里的路径 "greeting://{name}" 是动态的,
# {name} 部分可以被实际的名称替换,例如 "greeting://World"。
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """
    根据提供的名称,获取一句个性化的问候语。
    """
    # 使用 f-string 格式化字符串,返回包含名字的问候语。
    return f"Hello, {name}!"
# 使用 @mcp.prompt() 装饰器来定义一个"提示词模板"。
# 这个功能可以根据输入动态生成更复杂的、用于指导大语言模型(LLM)的指令(Prompt)。
@mcp.prompt()
def greet_user(name: str, style: str = "friendly") -> str:
    """
    根据给定的名字和风格,生成一句问候语的提示词。
    """
    # 定义一个字典,存储不同风格对应的提示词文本。
    styles = {
        "friendly": "Please write a warm, friendly greeting",
        "formal": "Please write a formal, professional greeting",
        "casual": "Please write a casual, relaxed greeting",
    }

    # 根据传入的 style 参数,从字典中获取对应的提示词。
    # 如果 style 参数无效或未提供,则默认使用 "friendly" 风格。
    # 最后,将选择的风格提示词与用户名组合,形成一个完整的指令。
    return f"{styles.get(style, styles['friendly'])} for someone named {name}."

将代码粘贴到main.py中,这个文件就是我们的开发文件了

一个MCP可以有多个功能,在对应的功能函数上面标识@MCP.tool()

比如说这个函数的作用就是输入两个整数,然后调用MCP获取这两个整数的和

下面的resourceprompt函数都是提供一个mcp体验感的

2.2.1、MCP协议讲解

关于这个代码

Python 复制代码
if __name__ == "__main__":

    mcp.run(transport="stdio")

其中mcp.run()中可以填写不同的协议,下面给大家简单解释下不同的协议之间的区别:
mcp.run()函数通过不同的"协议"参数,决定了你的 MCP 服务以何种方式暴露给外部以及如何与客户端通信。

MCP服务器:三种传输模式详解

  • 1、模式一:stdio(标准输入/输出)
    工作原理:通过命令行的标准输入(stdin)和标准输出(stdout)进行直接的进程间通信,无网络开销。
    适用场景:本地开发、单元测试、脚本集成。
  • 2.模式二: (http(标准Web API)- 通用与开放的行业标准
    工作原理:将服务器作为标准的Web API运行,通过"请求-响应"模式与客户端交互,通常使用JSON格式。
    适用场景:公共API、Web应用后端、通用微服务。
  • 3.模式三:SSE(Server-Sent Events)-实时流式响应的最佳选择
    SSE 是一种网页技术,它允许服务器在与客户端建立一个持久的HTTP连接后,单向地、持续地向客户端推送数据流。这与传统的"一次请求,一次完整响应"的HTTP模式完全不同。
    工作原理:
    • 1、客户端发起请求: 客户端(如浏览器)向MCP服务器的一个特定端点发起一个普通的HTTP请求。
    • 2、服务器保持连接: 服务器收到请求后,不立即关闭连接,而是返回一个特殊的响应头 content-Type:text/event-stream,并保持该连接处于打开状态。
    • 3、服务器推送数据:当MCP服务内部有新的数据产生时(例如,大语言模型生成了下一个词或一小段文本),服务器会立即将这些数据块通过这个打开的连接发送给客户端。
    • 4、客户端接收事件: 客户端会持续监听这个连接,每当收到一个数据块,就会触发一个事件,从而可以实时地处理和展示新数据。
      对于AI应用,这通常意味着:
      一个生成长文本的请求,用户不必等待几十秒看到全部结果,而是能像在ChatGPT中一样,看着文字一个一个地"流"出来。

核心优势

  • 极佳的流式体验: 这是 SSE 在AI领域最大的优势。对于LLM生成、文件处理等耗时任务,它可以实时反馈进度和结果,极大地提升了用户体验和应用的"响应感"
  • 基于标准HTTP:它构建在传统的HTTP之上,实现比WebSocket更简单,且能很好地兼容现有的网络基础设施(如反向代理、负载均衡器)
  • 内置重连机制:SSE标准包含了客户端在连接意外断开后自动重新连接的机制,增加了系统的健壮性。

局限性

  • 单向通信: 数据流只能从服务器到客户端。如果客户端在建立连接后还需要向服务器发送消息,SSE 则无能为力,此时需要考虑WebSocket
  • 连接数限制: 浏览器对单个域名下的并发HTTP连接数有限制(通常是6个),每个SSE连接都会计入其中,

最佳实践
SSE是实现AI模型流式输出的"杀手级"功能。

  • 大语言模型文本生成: 逐字或逐句返回生成的内容,
  • 任务状态实时更新: 如"模型加载中..."、"数据处理中..."、"生成完成"
  • 实时通知系统:向用户推送系统通知、新消息提醒等
    总结与选型对比
    好的,这是根据您提供的图片内容生成的Markdown格式表格:
特性 stdio (标准输入/输出) http (标准Web API) SSE (服务器发送事件)
交互模式 本地进程间通信 请求-响应 (Request-Response) 单向流式推送 (One-way Push)
数据格式 文本 (JSON Lines) 文本 (JSON) 文本 (Event-Stream Format)
核心用途 本地开发与测试 构建通用的、可调用的API 实现服务器到客户端的实时数据流
适用场景 本地脚本、调试 通用API、无状态任务 LLM流式输出、实时通知、进度更新
复杂度 非常低 较低 低于WebSocket,高于标准HTTP
实时性 - 差 (需轮询) 高 (服务器主动推送)
  • 本地开发:优先使用 Stdio,简单高效。
  • 单向数据推送:短期项目可考虑 SSE,长期建议迁移至 Streamable HTTP
  • 高并发分系统:必须使用 Streamable HTTP,尤其需双向交互时

2.3、本地MCP部署

2.3.1、stdio版本

这里先尝试stdio协议的测试,进行本地MCP部署的操作

将主函数修改为:

Python 复制代码
if __name__ == "__main__":

    mcp.run(transport="stdio")

在终端中输入命令运行main.py

Python 复制代码
python main.py

如果你输入完命令就直接退出了的话,点击这里的三角形进行程序运行,效果如下

这里本地就运行起来了,打开MCP添加界面

将下方命令输入进去

JSON 复制代码
{
  "mcpServers": {
    "mcp-plus": {
      "command": "D:\\mcp_test\\.venv\\Scripts\\python.exe",
      "args": [
        "D:\\mcp_test\\main.py"
      ]
    }
  }
}

这个样子我们就手搓成功了

如果你出现了下面的错误,说明你的 MCP 客户端在执行 main.py 脚本时,使用的是一个没有安装 mcp 库的 Python 环境。

简单来说,你电脑上可能装了多个 Python。虽然你在下方的终端里激活了 (mcp-test) 这个虚拟环境,并且 mcp 库也确实装在了这个环境里,

当它根据配置去执行命令时,它很可能调用了系统的全局 Python 解释器,而您的全局 Python 里并没有安装 mcp 库,所以它就报错说"找不到 mcp 这个模块"。

要解决这个问题,我们不能只告诉客户端运行 python,而是必须明确地告诉它使用哪个虚拟环境里的 python.exe

"command": "D:\mcp_test\.venv\Scripts\python.exe"

  • 我们将原来的 "command": "python" 修改为了一个绝对路径

  • 这个路径直接指向了您 mcp_test 项目中,由 uv 创建的虚拟环境 (.venv) 里的 python.exe 文件。

  • 这样做可以确保无论客户端从哪里调用,都必定会使用这个正确的、安装了 mcp 库的 Python 解释器来运行您的脚本。

这里我们就成功调用了这款mcp了

如果你在做测试的时候出问题了,你可以通过下面的绝对路径进行文件的执行,前面的是你的文件夹路径

bash 复制代码
d:/mcp_test/.venv/Scripts/python.exe d:/mcp_test/main.py

2.3.2、SSE版本

将主函数中的改成如下:

bash 复制代码
if __name__ == "__main__":

    mcp.run(transport="sse")

运行程序,他这里显示了一个本地的端口

将下面的代码加入到mcp中

bash 复制代码
{

  "mcpServers": {

    "plus": {

      "url": "http://127.0.0.1:8000/sse"

    }

  }

}

在trae中就显示连接成功了,我这里是将代码在codebuddy进行运行,然后在trae中进行测试链接,下面是codebuddy的终端信息,说明我们链接成功了

并且我们的http://127.0.0.1:8000/sse也是存在信息的

进行运算测试效果如下:

并且获得结果之后,这里是本地端口sse上是会显示ping的信息的

好了,到这里我们就完成了一个简单MCP的开发操作了

3、高级MCP搭建

这里我们搭建了两款MCP,纯ai,

项目地址如下:
图片素描化MCP GitHub地址
抖音数据分析MCP GitHub地址

如果你想使用的话可以来魔搭社区来使用
https://www.modelscope.cn/mcp/servers/Undoom/undoom-douyin-data-analysis
https://www.modelscope.cn/mcp/servers/Undoom/undoom-sketch-mcp

如果你现在本地有了一个搞好了的项目,你可以部署到pypi上,这个仅限于py代码实现的mcp,如果你的基础语言是java的话,就去npm上部署

这个部署的操作你可以去搜索,如何将本地项目进行打包并且发布到pypi

将您的本地MCP (Model Context Protocol) 项目打包并发布到PyPI,可以让其他开发者通过pip install命令轻松安装和使用您的代码。本教程将为您提供详细的步骤指导。

下面是一个简单的步骤

打包然后发布,整个过程你完全通过ai操作即可

最重要的就是注册pypi,然后进行token的获取,其他的无所谓

如果你在uv的时候出现了卡顿或者不能进行uv sync等等的操作,你直接让ai帮你基于清华源生成命令即可

下面的部署是ai生成的,仅供参考,实际还是以真实操作为主

第一步:准备您的项目结构

一个标准的Python项目结构对于打包至关重要。如果您的项目名为my_mcp_project,建议采用以下目录结构:

复制代码
my_mcp_project/
├── my_mcp_project/
│   ├── __init__.py
│   └── main.py
├── tests/
│   └── test_main.py
├── README.md
├── LICENSE
├── pyproject.toml
└── setup.py
  • my_mcp_project/my_mcp_project/: 这是您的Python包目录,其中包含项目的核心代码。
  • __init__.py: 这个空文件告诉Python该目录是一个包。
  • README.md: 项目的详细说明文件,使用Markdown格式编写。 它将显示在PyPI的项目页面上。
  • LICENSE: 包含您的项目许可证的文本文件。选择一个开源许可证很重要,例如MIT许可证。
  • pyproject.toml: 这个文件告诉构建工具(如pip)构建项目所需的内容。
  • setup.py: 这是setuptools的构建脚本,包含了项目的元数据,如名称、版本和依赖项。

第二步:创建必要的配置文件

  1. pyproject.toml

    在项目根目录下创建pyproject.toml文件,并添加以下内容。这指定了构建项目所需的依赖。

    toml 复制代码
    [build-system]
    requires = ["setuptools>=42", "wheel"]
    build-backend = "setuptools.build_meta"
  2. setup.py

    创建setup.py文件。这是打包的核心,它定义了项目的各种属性。

    python 复制代码
    import setuptools
    
    with open("README.md", "r", encoding="utf-8") as fh:
        long_description = fh.read()
    
    setuptools.setup(
        name="my_mcp_project",  # 替换为您的包名
        version="0.0.1",  # 您的包的初始版本
        author="Your Name",  # 您的名字
        author_email="your.email@example.com",  # 您的邮箱
        description="A small example package for MCP",  # 项目的简短描述
        long_description=long_description,
        long_description_content_type="text/markdown",
        url="https://github.com/yourusername/my_mcp_project",  # 项目的URL
        packages=setuptools.find_packages(),
        classifiers=[
            "Programming Language :: Python :: 3",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
        ],
        python_requires='>=3.10', # 指定项目依赖的Python版本 [12]
        install_requires=[
            # 在此列出您的项目依赖项,例如:
            # "requests",
            "mcp[cli]" # 如果您的项目依赖于MCP [12]
        ],
    )

    关键参数说明:

    • name: 您在PyPI上发布的包的名称,需要是唯一的。
    • version: 包的版本号。 每次更新时都需要增加版本号。
    • author, author_email: 作者信息。
    • description, long_description: 项目的简短和详细描述。
    • url: 通常是项目的GitHub仓库地址。
    • packages: setuptools.find_packages()会自动发现项目中的所有包。
    • install_requires: 列出您的项目正常运行所需的第三方库。

第三步:注册PyPI账户

您需要在PyPI (Python Package Index) 官网上注册一个账户才能发布您的包。

注册完成后,建议在您的账户设置中生成一个API令牌(API token)用于上传,这比直接使用用户名和密码更安全。

第四步:打包您的项目

  1. 安装构建工具

    确保您已经安装了setuptoolswheel

    bash 复制代码
    pip install --upgrade setuptools wheel
  2. 生成分发档案

    在您的项目根目录下(与setup.py同级),运行以下命令:

    bash 复制代码
    python setup.py sdist bdist_wheel

    该命令会生成两个文件在dist目录下:一个.tar.gz源码归档和一个.whl wheel文件。

第五步:上传到PyPI

  1. 安装Twine

    Twine是官方推荐的用于将包上传到PyPI的安全工具。

    bash 复制代码
    pip install --upgrade twine
  2. 使用Twine上传

    运行以下命令将dist目录下的文件上传到PyPI。

    bash 复制代码
    twine upload dist/*

    系统会提示您输入PyPI的用户名和密码。如果您使用的是API令牌,用户名为__token__,密码为您生成的令牌(包括pypi-前缀)。

第六步:验证您的发布

上传成功后,您应该能在PyPI上看到您的项目页面。等待几分钟后,您或其他用户就可以通过pip来安装您的包了:

bash 复制代码
pip install my_mcp_project

针对MCP Server的特别说明

根据搜索结果,MCP Server是一个特定的项目类型,可能需要依赖mcp包。 在这种情况下,请确保在setup.pyinstall_requires中加入了"mcp[cli]"或类似的依赖项。

此外,一些MCP Server的发布指南提到了使用uv这个工具链来管理Python项目。 虽然本教程使用的是更为通用的pipsetuptools,但uv也是一个值得了解的现代化Python打包和项目管理工具。

相关推荐
sanshanjianke6 小时前
微软开发的Unix系统——Xenix测评
microsoft
LZQqqqqo6 小时前
WinForm 对话框的 Show 与 ShowDialog:阻塞与非阻塞的抉择
服务器·windows·microsoft·winform
Access开发易登软件6 小时前
Access开发右下角浮窗提醒
microsoft·vba·access·access开发
FreeBuf_6 小时前
微软披露Exchange Server漏洞:攻击者可静默获取混合部署环境云访问权限
网络·安全·microsoft
AI创世纪7 小时前
微软XBOX游戏部门大裁员
游戏·microsoft·xbox
数据猿视觉8 小时前
宁商平台税务升级之路:合规为纲,服务为本
大数据·人工智能·microsoft
Leinwin1 天前
OpenAI 开源模型 gpt-oss 正式上线微软 Foundry 平台
gpt·microsoft·开源
天庭鸡腿哥1 天前
直连微软,下载速度达18M/S
microsoft
zh73143 天前
laravel在cli模式下输出格式漂亮一些
microsoft·php·laravel