使用 Python 轻松构建 MCP 服务,完整示例免费分享给你
模型上下文协议 MCP 是一种开放协议,旨在标准化 AI 应用程序与外部数据源和工具的连接方式。其核心目标在于简化大型语言模型 LLM 与各种上下文和工具的集成,从而解决将多种 LLM 与多种工具相集成的复杂性问题。
之前的文章介绍了一个挺不错的 MCP 应用案例,
用 MCP 让大模型自动批量下载文献,太香了!
但你有没有想过,自己动手打造一个 MCP 服务呢?想象一下,亲手设计一个智能工具,无论是处理数据、调用外部 API,还是生成自定义报告。这种创造力和掌控力的体验,会不会更香呢?
MCP 本身是一个通用的协议,设计上是为了跨语言和跨平台的,因此可以使用各种语言来编写服务,比如常用的 Node.js。但如果不熟悉 Web 开发,也想自己写一写呢?Python 自然是不二之选。只是 MCP 具体的协议挺复杂的,很难快速上手。
不过,现在好了,因为有了 FastMCP,它是一个 Python 软件开发工具包 (SDK),专门设计用于简化构建 MCP 服务的过程。它提供了一个高级且符合 Python 语言习惯的接口,用于定义工具、资源和提示。FastMCP 的核心优势在于其能够帮助开发者更轻松地创建符合 MCP 规范的服务,而无需深入了解底层的协议细节。
但值得注意的是,你看网上代码会涉及两个 FastMCP 包,其中一个是,
https://github.com/jlowin/fastmcp另一个则是官方的,
https://github.com/modelcontextprotocol/python-sdk这两个什么关系呢?其实是官方收编了上面第一个包,但官方集成的是 fastmcp 的 v1.0 版本。然而,jlowin 继续开发 fastmcp,还发布了 v2.0 版本,其中包含代理和客户端采样等新功能。
使用的话这两个都可以,先看第一个的安装和导入,
pip install fastmcpfrom fastmcp import FastMCP官方的安装和导入如下所示,
pip install mcpfrom mcp.server.fastmcp import FastMCP本文使用官方 Python SDK 里的 FastMCP 来构建自己的 MCP 服务。
我们先来看一个最简单的例子。
./demo/server.pyfrom mcp.server.fastmcp import FastMCPmcp = FastMCP("Demo 🚀")@mcp.tool()def add_2_numbers(a: int, b: int) -> int: """两个数字相加""" return a + bif __name__ == "__main__": mcp.run(transport=stdio)这个例子展示了如何使用 FastMCP 库来创建一个简单的 MCP 服务器,它提供一个基本的工具(工具名:add_2_numbers),用于两个数字相加。这是一个非常简单的入门示例,适合理解 MCP 服务器的工作原理和 FastMCP 的基本用法。
- 首先,从
mcp.server.fastmcp 模块中导入了 FastMCP 类。接着,创建了一个 FastMCP 类的实例,命名为 mcp。FastMCP 是服务器的核心类,它负责管理工具、资源和通信。参数「Demo 🚀」是服务器的名称,用于标识这个 MCP 服务器。 - 然后,
@mcp.tool() 是一个装饰器(decorator),它告诉 FastMCP 将add_2_numbers 函数注册为一个可供客户端调用的工具。文档字符串("""两个数字相加"""):这是函数的描述,客户端(如MCP Inspector)会显示这个描述,帮助用户理解工具的功能。 - 这个工具可以被外部客户端调用,例如通过 MCP 协议发送请求,传入两个整数 a 和 b,服务器会返回它们的和。例如,如果客户端调用
add_2_numbers(3, 5),服务器会返回 8。 -
mcp.run(transport=stdio) 启动 MCP 服务器,进入监听状态,等待客户端的连接和请求。transport=stdio 指定了通信方式为标准输入输出(Standard I/O)。这意味着服务器通过命令行的标准输入(stdin)和标准输出(stdout)与客户端通信,适合本地开发和测试。如果需要远程通信,可以更改为其他传输方式(如sse,Server-Sent Events)。
运行效果:
运行 python ./demo/server.py,服务器会启动并监听 stdio。任何支持 MCP 协议的客户端(例如 MCP Inspector 或 Claude Desktop)都可以连接到它,调用 add_2_numbers 工具。
比如,可以通过 MCP Inspector 测试一下这个工具。
% mcp dev ./demo/server.pyNeed to install the following packages:@modelcontextprotocol/inspector@0.8.2Ok to proceed? (y) y
浏览器中打开 http://127.0.0.1:6274,可以测试一下上面这个 mcp 服务里提供的 tool。

这个 mcp 过于简单,咱们就不安装来用了。下面我们手撸一个稍微复杂一点的 mcp 服务,并安装上真正使用起来。
记账 mcp 服务
我们基于 MCP 开发了一个轻量级(玩具级)记账服务 Money Track MCP,旨在帮助用户管理和跟踪财务数据。该服务利用 Python 和 FastMCP 框架,提供了三种核心功能类型(工具、资源和提示),为用户提供一个灵活、高效的解决方案来记录收入和支出、查询账户状态以及生成格式化的财务报告。
项目虽小,但涉及环境变量的设置和读取,用户数据的存储等多个方面,对于开发更强大服务来说是一个不错的基础。完整代码的地址见文末。
核心功能
- 工具 (
@tool):服务提供了一个名为record_transaction 的工具,允许用户动态输入当天的收入和支出,如「今天赚了 500 元,花了 250 元」。工具会自动更新累积的总收入、总支出,并计算当前余额。这些数据持久化存储在用户指定的文件中,确保数据不会丢失。 - 资源 (
@resource):通过get_account_status 资源,用户可以安全地检索当前账户的最新状态,包括总收入、总支出和余额。资源数据存储在 JSON 文件中,文件路径可以由用户通过环境变量或配置文件自定义,默认位于./accounting_data/accounting_data.json。 - 提示 (
@prompt):format_account_report 提示负责将账户状态格式化为易读的报告。
技术架构
- 框架:基于
FastMCP,一个高效的 Python 库,简化了 MCP 服务器的开发。 - 存储:数据保存在 JSON 文件中,支持用户自定义存储路径(如通过环境变量
ACCOUNTING_WORKING_DIR 或配置文件)。 - 通信:默认使用标准输入输出 (
stdio) 传输协议,方便本地开发和测试。 - 日志:支持
INFO 和DEBUG 级别的日志记录,帮助开发者监控服务运行状态和调试问题。
使用场景
MoneyTrack MCP 适用于多种场景,包括但不限于:
- 个人财务管理:个人用户可以通过客户端记录日常收支,并随时查看余额。
- 企业/团队记账:小型企业或团队可以集成此服务到更大的财务系统中,快速统计现金流。
- 教育与开发示例:开发者可以作为 MCP 服务的学习示例,了解工具、资源和提示的协同工作。
具体代码如下,
# ./src/server.pyfrom mcp.server.fastmcp import FastMCPimport osimport jsonfrom typing import Dict, Optionalimport logging# 配置日志logging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)# 从环境变量或默认值获取工作目录DEFAULT_WORKING_DIR = "~/accounting_data"WORKING_DIR = os.getenv("ACCOUNTING_WORKING_DIR", DEFAULT_WORKING_DIR)# 确保目录存在os.makedirs(WORKING_DIR, exist_ok=True)# 数据文件路径DATA_FILE = os.path.join(WORKING_DIR, "accounting_data.json")# 初始数据(如果文件不存在)INITIAL_DATA = { "total_income": 0, "total_expense": 0, "balance": 0}def load_data() -> Dict: """从文件中加载数据,如果文件不存在则创建默认数据""" try: if os.path.exists(DATA_FILE): with open(DATA_FILE, "r", encoding="utf-8") as f: return json.load(f) else: with open(DATA_FILE, "w", encoding="utf-8") as f: json.dump(INITIAL_DATA, f, indent=4) return INITIAL_DATA except Exception as e: logger.error(f"Failed to load data: {str(e)}") return INITIAL_DATAdef save_data(data: Dict) -> None: """将数据保存到文件""" try: with open(DATA_FILE, "w", encoding="utf-8") as f: json.dump(data, f, indent=4) except Exception as e: logger.error(f"Failed to save data: {str(e)}")# 创建 MCP 服务器mcp = FastMCP("money-track-mcp", log_level="ERROR")# 工具:记录收入和支出@mcp.tool()def record_transaction(income: Optional[int] = 0, expense: Optional[int] = 0) -> Dict: """记录今天的收入和支出,更新账户余额""" ifnot isinstance(income, (int, float)) ornot isinstance(expense, (int, float)): return {"error": "Income and expense must be numbers"} data = load_data() data["total_income"] += income data["total_expense"] += expense data["balance"] = data["total_income"] - data["total_expense"] save_data(data) return { "message": "Transaction recorded successfully", "total_income": data["total_income"], "total_expense": data["total_expense"], "balance": data["balance"] }# 资源:获取当前账户状态@mcp.resource("accounting://status")def get_account_status() -> Dict: """获取当前账户的收入、支出和余额""" data = load_data() return { "total_income": data["total_income"], "total_expense": data["total_expense"], "balance": data["balance"] }# 提示:格式化账户报告@mcp.prompt()def format_account_report(status: Dict) -> str: """格式化账户状态为易读的报告""" returnf""" === 账户报告 === 总收入: ${status["total_income"]:.2f} 总支出: ${status["total_expense"]:.2f} 当前余额: ${status["balance"]:.2f} ================ """def run_server(): """运行 MCP 服务器""" print("=== Money Track MCP 服务启动 ===") logging.info("Money Track MCP 服务启动") print(f"当前工作目录: {os.getcwd()}") mcp.run(transport=stdio)安装和运行
git clone https://github.com/mathinml/mcp_money_track.gitcd mcp_money_trackpip install mcppip install .打开你喜欢的 mcp 客户端,比如 Cline,Roo Code, Cursor 等等。mcp 配置文件中请参考如下设置,
"money-track-mcp": { "command": "/opt/anaconda3/bin/python", "args": [ "-m", "mcp_money_track" ], "env": { "ACCOUNTING_WORKING_DIR": "/Users/xyz/account" } },环境变量 "ACCOUNTING_WORKING_DIR" 是用于设置账本的保存目录。
1、Cline

点击 Approve 以后,

再次输入:我今天收入才 500 元,花掉了 1500 元。
没多说啥,它自动领会要记账啦,请看结果。

打开保存目录里的账本看一看,

2、Roo Code
然后在另一个客户端里试试,VS Code + 插件 Roo Code。
换套说辞,咱不提记账不记账,只跟它说:我想买个电脑,1 万元左右,看看我的余额还够吗?

点击 Approve,如果觉得每次要点太烦人,也可以在 Auto-approve 里设定总是允许。

余额不够啦,谁打赏一点让我凑个整呗。
3、Cherry Studio
在 Cherry Studio 里设置也是类似的,如图。

然后,在聊天界面一定要在 MCP 服务器里选中这个服务。

大模型这里我们选用 OpenRoute 提供的免费 Gemini 2.5 Pro,

也还行,速度上感觉比前面两个慢一丢丢。
好了,通过这个例子,应该已经明白如何使用 Python 来写一个简单但完整的 mcp 服务。
代码:https://github.com/mathinml/mcp_money_track
本文转载自机器学习与数学,作者:大师兄




