Featured image of post Python使用FastMCP开发MCP服务端

Python使用FastMCP开发MCP服务端

Model Context Protocol (MCP) 是一个专门为 LLM(大语言模型)应用设计的协议,它允许你构建服务器以安全、标准化的方式向 LLM 应用程序公开数据和功能。FastMCP 作为 Python 生态中的一款轻量级框架,利用装饰器来简化路由与工具函数的开发,帮助开发者快速构建面向工具的服务端应用。1. Tool(工具)Tool 允许服务器公开可执行的函数,这些函数可由客户端调用并由 LLM 使用来执行操作。

MCP简介

Model Context Protocol (MCP) 是一个专门为 LLM(大语言模型)应用设计的协议,它允许你构建服务器以安全、标准化的方式向 LLM 应用程序公开数据和功能。FastMCP 作为 Python 生态中的一款轻量级框架,利用装饰器来简化路由与工具函数的开发,帮助开发者快速构建面向工具的服务端应用。 在这里插入图片描述

MCP Server 提供了 3 种核心原语,每种原语都有其特定的用途和特点:

1. Tool(工具)

  • Tool 允许服务器公开可执行的函数,这些函数可由客户端调用并由 LLM 使用来执行操作。Tool 不仅人让 LLM 能从外部获取信息,还能执行写入或操作,为 LLM 提供真正的行动力。
  • 模型控制:Tool 直接暴露给 LLM 可执行函数,让模型可以主动调用。

2. Resource(资源)

  • Resource 表示服务器希望提供给客户端的任何类型的只读数据。这可能包括:文件内容、数据库记录、图片、日志等等。
  • 应用控制:Resource 由客户端或应用管理,用于为 LLM 提供上下文内容。

3. Prompt(提示模板)

  • Prompt 是由服务器定义的可重用的模板,用户可以选择这些模板来引导或标准化与 LLM 的交互过程。例如,Git MCP Server 可以提供一个“生成提交信息”的提示模板,用户可以用它来创建标准化的提交消息。
  • 用户控制:Prompt 通常由用户自行选择。

MCP概述

MCP服务端当前支持两种与客户端的数据通信方式:标准输入输出(stdio) 和 基于Http的服务器推送事件(http sse)

标准输入输出(stdio)

原理: 标准输入输出是一种用于本地通信的传输方式。在这种模式下,MCP 客户端会将服务器程序作为子进程启动,双方通过约定的标准输入和标准输出(可能是通过共享文件等方法)进行数据交换。具体而言,客户端通过标准输入发送请求,服务器通过标准输出返回响应。 适用场景: 标准输入输出方式适用于客户端和服务器在同一台机器上运行的场景(本地自行编写服务端或将别人编写的服务端代码pull到本地执行),确保了高效、低延迟的通信。这种直接的数据传输方式减少了网络延迟和传输开销,适合需要快速响应的本地应用。

基于Http的服务器推送事件(http sse)

原理: 客户端和服务端通过 HTTP 协议进行通信,利用 SSE 实现服务端向客户端的实时数据推送,服务端定义了/see与/messages接口用于推送与接收数据。这里要注意SSE协议和WebSocket协议的区别,SSE协议是单向的,客户端和服务端建立连接后,只能由服务端向客户端进行消息推送。而WebSocket协议客户端和服务端建立连接后,客户端可以通过send向服务端发送数据,并通过onmessage事件接收服务端传过来的数据。

适用场景: 适用于客户端和服务端位于不同物理位置的场景,尤其是对于分布式或远程部署的场景,基于 HTTP 和 SSE 的传输方式更合适。如:Prometheus,MySQL,MongoDB 数据库等等

环境介绍

uv快速构建Python环境

Win打开 powershell 进行安装 参考文档:https://docs.astral.sh/uv/getting-started/installation/#standalone-installer

1
2
3
4
5
6
7
8
# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# With pip.
pip install uv

安装之后,可以通过uv help命令检查是否安装成功: 在这里插入图片描述

卸载

1
powershell -c "irm https://astral.sh/uv/install.ps1 | more"

基本使用方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建项目文件夹、同时初始化并指定python版本
uv init py-app -p 3.11.9
# 创建并激活虚拟环境
uv venv
source .venv/bin/activate

# 退出虚拟环境
deactivate
uv venv --seed  # 强制安装基础包(如pip, setuptools, wheel)

# 同步依赖
uv sync
# 安装 requirements.txt
uv pip install -r requirements.txt

# 安装包(使用清华源)
cd py-app
uv add pandas pillow --default-index "https://pypi.tuna.tsinghua.edu.cn/simple"

# 安装CUDA版的torch(使用南京大学源)
uv pip install torch torchvision torchaudio --index-url https://mirror.nju.edu.cn/pytorch/whl/cu126

# 执行python
uv run app.py

Python版本的安装和管理

1
2
3
4
5
6
7
8
# 显示当前已经安装的和可供安装的Python版本
uv python list

# 安装指定的Python版本(注意:安装的Python并非全局可用,在命令行工具中输入Python无反映)
uv python install 3.10 3.11 3.12

# 卸载指定的版本
uv python uninstall 3.10

https://www.cnblogs.com/wang_yb/p/18635441

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

版本推荐

Python 版本: 推荐使用 Python 3.10 及以上版本,以便更好地支持异步函数(async/await) 我的版本:Python 3.14

FastMCP 库: 该库需要通过 pip 或其他方式安装。安装指令如下:

1
pip install fastmcp

运行方式: 本示例采用标准输入/输出(stdio)作为传输层,可根据实际需求选择其他传输方式,如网络通信等。

实现步骤

下面按照步骤解析如何构建一个简单但功能完备的 MCP 服务端:

stdio

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo 🚀")


@mcp.tool()
def add(a: int, b: int) -> int:
    """两个数字相加"""
    return a + b


@mcp.tool()
async def calculate(expression: str) -> str:
    """
    计算一个简单的数学表达式。
    Args:
        expression: 要计算的数学表达式(如"1 + 2")
    Returns:
        str: 计算结果
    """
    try:
        result = eval(expression)
        return f"计算结果: {result}"
    except Exception as e:
        return f"计算错误: {str(e)}"


@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """获取个性化问候语"""
    return f"Hello, {name}!"


if __name__ == "__main__":
    mcp.run(transport='stdio')

启动调试:

1
mcp dev main.py

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述

错误报错:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Created web app transport
Created web app transport
Set up MCP proxy
file:///C:/Users/admin/AppData/Local/npm-cache/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js:103
            throw new Error("Not connected");
                  ^

Error: Not connected
    at SSEServerTransport.send (file:///C:/Users/admin/AppData/Local/npm-cache/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js:103:19)
    at Socket.<anonymous> (file:///C:/Users/admin/AppData/Local/npm-cache/_npx/5a9d879542beca3a/node_modules/@modelcontextprotocol/inspector/server/build/index.js:101:33)
    at Socket.emit (node:events:517:28)
    at addChunk (node:internal/streams/readable:368:12)
    at readableAddChunk (node:internal/streams/readable:341:9)
    at Readable.push (node:internal/streams/readable:278:10)
    at Pipe.onStreamRead (node:internal/stream_base_commons:190:23)

解决方案:

1
2
3
npm install -g @modelcontextprotocol/server-filesystem
npm install -g @modelcontextprotocol/server-memory
npm install -g @modelcontextprotocol/server-brave-search

sse模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Demo 🚀")


@mcp.tool()
def add(a: int, b: int) -> int:
    """两个数字相加"""
    return a + b


@mcp.tool()
async def calculate(expression: str) -> str:
    """
    计算一个简单的数学表达式。
    Args:
        expression: 要计算的数学表达式(如"1 + 2")
    Returns:
        str: 计算结果
    """
    try:
        result = eval(expression)
        return f"计算结果: {result}"
    except Exception as e:
        return f"计算错误: {str(e)}"


@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """获取个性化问候语"""
    return f"Hello, {name}!"


if __name__ == "__main__":
    mcp.run(transport='sse')

FastMCP 中,有几个可以设置 SSE 协议相关的参数:

  • host: 服务地址,默认为 0.0.0.0
  • port: 服务端口,默认为 8000。上述代码中,我设置为 9000
  • sse_path:sse 的路由,默认为 /sse

Vscode-Cline调用

安装Vscode和Cline

在这里插入图片描述

stdio模式调用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "E:\\Code\\Python\\weather",
        "run",
        "main.py"
      ],
      "timeout": 30
    }
  }
}

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

sse模式

在这里插入图片描述

1
2
3
4
5
6
7
{
  "mcpServers": {
    "weather": {
      "url": "http://192.168.96.19:8000/sse"
    }
  }
}

在这里插入图片描述 在这里插入图片描述

参考文档: https://github.com/GobinFan/python-mcp-server-client?tab=readme-ov-file

https://www.cnblogs.com/xiao987334176/p/18821197

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

https://www.cnblogs.com/xiao987334176/p/18822444

https://www.modb.pro/db/1878984329888542720

https://blog.moontak.com/id/522381/

https://github.com/liaokongVFX/MCP-Chinese-Getting-Started-Guide

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

未来的你,会感谢今天仍在努力奋斗的你