本文详细介绍如何使用FastMCP框架构建MCP服务端与客户端。MCP是Anthropic推出的开放标准,用于统一AI应用与外部系统的交互。FastMCP通过装饰器、类型安全和异步支持等特性,简化了原本复杂的MCP开发流程。文章以计算器服务为例,展示了如何创建工具、资源和提示词,并提供了完整的客户端代码实现,让开发者能够快速搭建生产级Agentic生态系统。


Model Context Protocol(MCP,模型上下文协议)彻底改变了大语言模型(LLM)与外部工具、数据源和服务的交互方式。但传统上,从零搭建 MCP 服务端需要处理大量复杂的样板代码,还要吃透协议规范。FastMCP 扫清了这一障碍,它提供基于装饰器、符合 Python 习惯的框架,让开发者用极少代码就能构建生产级 MCP 服务端与客户端。

接下来,我们将使用 FastMCP 构建 MCP 服务端与客户端。FastMCP 内容完整、自带错误处理,对新手和中级开发者都非常友好。


环境准备

开始本教程前,请确保你已准备好:

  • • Python 3.10 或更高版本(推荐 3.11+,异步性能更好)
  • • pip 或 uv(推荐使用 uv 部署 FastMCP,CLI 工具也依赖它)
  • • 代码编辑器(本文使用 VS Code,你可任选)
  • • 熟悉终端/命令行,用于运行 Python 脚本

有以下基础会更有帮助:

  • • 扎实的 Python 编程知识(函数、装饰器、类型注解)
  • • 了解 async/await 语法(非必需,但对高级示例有帮助)
  • • 熟悉 JSON 与 REST API 概念
  • • 基本的命令行操作能力

在 FastMCP 出现之前,开发 MCP 服务端需要你深入理解 MCP JSON-RPC 规范、编写大量协议处理样板代码、手动管理连接与传输、实现复杂的错误处理与校验逻辑。 FastMCP 用直观的装饰器和简洁的 Pythonic API 解决了这些问题,让你专注业务逻辑,而非协议实现。


什么是 Model Context Protocol(MCP)?

MCP 是由 Anthropic 推出的开放标准,它为 AI 应用提供了一套通用接口,用于安全连接外部工具、数据源与服务。 MCP 统一了 LLM 与外部系统的交互方式,就像 Web API 统一了网络服务通信一样。

MCP 核心特性

  • 标准化通信:基于 JSON-RPC 2.0,实现可靠、结构化的消息传输
  • 双向交互:支持客户端→服务端请求与服务端→客户端响应
  • 安全性:内置认证与授权模式支持
  • 灵活传输:兼容任意传输方式(stdio、HTTP、WebSocket、SSE)

MCP 架构:服务端与客户端

MCP 采用清晰的客户端–服务端架构:

  • MCP 服务端:对外暴露能力(工具、资源、提示词),可理解为专为 LLM 集成设计的后端 API。
  • MCP 客户端:嵌入在 AI 应用(如 Claude Desktop、Cursor IDE 或自定义应用)中,连接 MCP 服务端并使用其资源。

MCP 核心组件

MCP 服务端主要暴露三类能力:

  • Tools(工具):LLM 可调用的可执行函数,用于查询数据库、调用 API、计算或触发工作流。
  • Resources(资源):只读数据,客户端可获取并作为上下文使用,如文件内容、配置数据、动态内容。
  • Prompts(提示词):可复用的消息模板,用于引导 LLM 行为,为多步骤操作或专业推理提供统一指令。

什么是 FastMCP?

FastMCP 是一个高层 Python 框架,用于简化 MCP 服务端与客户端的开发。它的设计目标是降低开发成本,主要特点:

  • 基于装饰器的 API:使用 @mcp.tool@mcp.resource@mcp.prompt 消除样板代码
  • 类型安全:完整的类型注解与校验,基于 Python 类型系统
  • 异步支持:现代化 async Python,支持高性能操作
  • 多传输协议:支持 stdio、HTTP、WebSocket、SSE
  • 内置测试:无需子进程即可轻松测试客户端–服务端交互
  • 生产就绪:自带错误处理、日志、配置等生产级功能

FastMCP 设计理念

FastMCP 遵循三大核心原则:

    1. 高层抽象:更少代码,更快开发
    1. 简洁易用:极少样板代码,专注功能而非协议
    1. Pythonic:符合 Python 习惯,对 Python 开发者友好

安装依赖

推荐使用 uv 安装 FastMCP 及依赖。

uv pip install fastmcp

如果没有安装 uv,先安装:

pip install uv

也可以直接用 pip 安装:

pip install fastmcp

验证安装:

python -c "from fastmcp import FastMCP; print('FastMCP installed successfully')"

构建 MCP 服务端

我们将创建一个实用的 MCP 服务端,演示工具、资源、提示词三大能力。以计算器服务端为例,提供数学运算、配置资源与指令提示。

步骤 1:项目结构初始化

创建项目目录并进入:

mkdir fastmcp-calculatorcd fastmcp-calculator

使用 uv 初始化项目(指定 Python 3.11):

uv init --python 3.11

步骤 2:编写 MCP 服务端

在项目中创建 calculator_server.py,代码如下:

import loggingimport sysfrom typing import Dictfrom fastmcp import FastMCP# 日志输出到 stderr(对 MCP 协议完整性至关重要)logging.basicConfig(    level=logging.DEBUG,    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',    stream=sys.stderr)logger = logging.getLogger(__name__)# 创建 FastMCP 服务端实例mcp = FastMCP(name="CalculatorServer")

服务端导入 FastMCP 并将日志定向到 stderr。MCP 协议要求:除协议消息外,所有输出必须走 stderr,避免破坏通信。 FastMCP(name="CalculatorServer") 会自动处理所有协议管理。

接下来定义工具:

@mcp.tooldefadd(a: float, b: float) -> float:    """两数相加    Args:        a: 第一个数        b: 第二个数    Returns:        a 与 b 的和    """    try:        result = a + b        logger.info(f"Addition performed: {a} + {b} = {result}")        return result    except TypeError as e:        logger.error(f"Type error in add: {e}")        raise ValueError(f"Invalid input types: {e}")@mcp.tooldefsubtract(a: float, b: float) -> float:    """a 减 b    Args:        a: 被减数        b: 减数    Returns:        a 与 b 的差    """    try:        result = a - b        logger.info(f"Subtraction performed: {a} - {b} = {result}")        return result    except TypeError as e:        logger.error(f"Type error in subtract: {e}")        raise ValueError(f"Invalid input types: {e}")@mcp.tooldefmultiply(a: float, b: float) -> float:    """两数相乘    Args:        a: 第一个数        b: 第二个数    Returns:        a 与 b 的积    """    try:        result = a * b        logger.info(f"Multiplication performed: {a} * {b} = {result}")        return result    except TypeError as e:        logger.error(f"Type error in multiply: {e}")        raise ValueError(f"Invalid input types: {e}")@mcp.tooldefdivide(a: float, b: float) -> float:    """a 除以 b    Args:        a: 被除数        b: 除数    Returns:        商    Raises:        ValueError: 除零时抛出    """    try:        if b == 0:            logger.warning(f"Division by zero attempted: {a} / {b}")            raise ValueError("Cannot divide by zero")        result = a / b        logger.info(f"Division performed: {a} / {b} = {result}")        return result    except (TypeError, ZeroDivisionError) as e:        logger.error(f"Error in divide: {e}")        raise ValueError(f"Division error: {e}")

四个被 @mcp.tool 装饰的函数对外暴露数学运算。每个工具都包含:

  • • 参数与返回值类型注解
  • • 完整文档字符串(MCP 会将其作为工具描述)
  • • try-except 错误处理
  • • 日志记录
  • • 输入校验

接下来定义资源

@mcp.resource("config://calculator/settings")defget_settings() -> Dict:    """提供计算器配置与可用操作"""    logger.debug("Fetching calculator settings")    return {        "version": "1.0.0",        "operations": ["add", "subtract", "multiply", "divide"],        "precision": "IEEE 754 double precision",        "max_value": 1.7976931348623157e+308,        "min_value": -1.7976931348623157e+308,        "supports_negative": True,        "supports_decimals": True    }@mcp.resource("docs://calculator/guide")defget_guide() -> str:    """计算器使用指南"""    logger.debug("Retrieving calculator guide")    guide = """1. **add(a, b)**: 返回 a + b   示例:add(5, 3) = 82. **subtract(a, b)**: 返回 a - b   示例:subtract(10, 4) = 63. **multiply(a, b)**: 返回 a * b   示例:multiply(7, 6) = 424. **divide(a, b)**: 返回 a / b   示例:divide(20, 4) = 5.0## 错误处理- 除零会抛出 ValueError- 非数值输入会抛出 ValueError- 所有输入必须是合法数字(int / float)## 精度说明计算器使用 IEEE 754 双精度浮点数运算,部分运算可能存在微小舍入误差。"""    return guide

两个被 @mcp.resource 装饰的函数提供静态/动态数据:

  • config://calculator/settings:返回计算器元信息
  • docs://calculator/guide:返回格式化使用指南

资源 URI 遵循约定:类型://分类/资源名

接下来定义提示词

@mcp.promptdef calculate_expression(expression: str) -> str:    """生成数学表达式计算指令    Args:        expression: 待计算的数学表达式    Returns:        指导 LLM 分步计算的提示词    """    logger.debug(f"Generating calculation prompt for: {expression}")    prompt = f"""请分步计算以下数学表达式:表达式:{expression}计算步骤:1. 将表达式拆分为单个运算2. 使用对应计算器工具完成每一步3. 遵循运算优先级:括号 → 乘除 → 加减4. 展示所有中间步骤5. 给出最终结果可用工具:add、subtract、multiply、divide""".strip()    return prompt

最后添加服务启动代码:

if __name__ == "__main__":    logger.info("Starting Calculator MCP Server...")    try:        # 使用 stdio 传输(Claude Desktop 默认)        mcp.run(transport="stdio")    except KeyboardInterrupt:        logger.info("Server interrupted by user")        sys.exit(0)    except Exception as e:        logger.error(f"Fatal error: {e}", exc_info=True)        sys.exit(1)

@mcp.prompt 用于创建指令模板,引导 LLM 完成复杂任务。 本文包含的错误处理最佳实践:

  • • 精准捕获异常(TypeError、ZeroDivisionError)
  • • 对用户友好的错误信息
  • • 详细日志便于调试
  • • 优雅的异常传播

步骤 3:编写 MCP 客户端

创建 calculator_client.py,演示如何与上面的计算器服务端交互:

import asyncioimport loggingimport sysfrom typing importAnyfrom fastmcp import Client, FastMCPlogging.basicConfig(    level=logging.INFO,    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',    stream=sys.stderr)logger = logging.getLogger(__name__)asyncdefmain():    from calculator_server import mcp as server    logger.info("Initializing Calculator Client...")    try:        asyncwith Client(server) as client:            logger.info("✓ 已连接到计算器服务端")            # 1. 发现服务端能力            print("\n" + "="*60)            print("1. 发现服务端能力")            print("="*60)            tools = await client.list_tools()            print(f"\n可用工具({len(tools)}):")            for t in tools:                print(f"  • {t.name}: {t.description}")            resources = await client.list_resources()            print(f"\n可用资源({len(resources)}):")            for r in resources:                print(f"  • {r.uri}: {r.name or r.uri}")            prompts = await client.list_prompts()            print(f"\n可用提示词({len(prompts)}):")            for p in prompts:                print(f"  • {p.name}: {p.description}")            # 2. 调用工具            print("\n" + "="*60)            print("2. 调用工具")            print("="*60)            print("\n测试 1:15 + 27")            res = await client.call_tool("add", {"a": 15, "b": 27})            val = extract_tool_result(res)            print(f"  结果:15 + 27 = {val}")            print("\n测试 2:100 / 5")            res = await client.call_tool("divide", {"a": 100, "b": 5})            val = extract_tool_result(res)            print(f"  结果:100 / 5 = {val}")            print("\n测试 3:除零错误(异常处理)")            try:                res = await client.call_tool("divide", {"a": 10, "b": 0})                print(f"  意外成功:{res}")            except Exception as e:                print(f"  ✓ 正确捕获错误:{str(e)}")            # 3. 读取资源            print("\n" + "="*60)            print("3. 读取资源")            print("="*60)            print("\n获取计算器配置...")            settings = await client.read_resource("config://calculator/settings")            print(f"  配置信息:{settings[0].text}")            print("\n获取计算器指南...")            guide = await client.read_resource("docs://calculator/guide")            print(f"  指南预览:{guide[0].text[:200]}...")            # 4. 链式调用            print("\n" + "="*60)            print("4. 多步运算链式调用")            print("="*60)            print("\n计算:(10 + 5) * 3 - 7")            print("  步骤 1:10 + 5")            step1 = extract_tool_result(await client.call_tool("add", {"a": 10, "b": 5}))            print(f"    结果:{step1}")            print("  步骤 2:15 * 3")            step2 = extract_tool_result(await client.call_tool("multiply", {"a": step1, "b": 3}))            print(f"    结果:{step2}")            print("  步骤 3:45 - 7")            final = extract_tool_result(await client.call_tool("subtract", {"a": step2, "b": 7}))            print(f"    最终结果:{final}")            # 5. 使用提示词模板            print("\n" + "="*60)            print("5. 使用提示词模板")            print("="*60)            expr = "25 * 4 + 10 / 2"            print(f"\n表达式:{expr}")            prompt_res = await client.get_prompt(                "calculate_expression",                {"expression": expr}            )            print(f"  提示词模板:\n{prompt_res.messages[0].content.text}")            logger.info("✓ 客户端运行完成")    except Exception as e:        logger.error(f"客户端错误:{e}", exc_info=True)        sys.exit(1)

添加结果提取工具函数:

def extract_tool_result(response: Any) -> Any:    """从工具响应中解析真实结果"""    try:        ifhasattr(response, 'content') and response.content:            content = response.content[0]            ifhasattr(content, 'text') and content.text isnotNone:                import json                txt = content.text                try:                    parsed = json.loads(txt)                    ifisinstance(parsed, dict) and'result'in parsed:                        return parsed['result']                    return parsed                except json.JSONDecodeError:                    try:                        returnfloat(txt) if'.'in txt elseint(txt)                    except:                        return txt            ifhasattr(content, 'json'):                import json                try:                    j = content.json() ifcallable(content.json) else content.json                    parsed = json.loads(j) ifisinstance(j, str) else j                    ifisinstance(parsed, dict):                        res = parsed.get('result') or parsed.get('text') or parsed                        ifisinstance(res, str):                            try:                                returnfloat(res) if'.'in res elseint(res)                            except:                                return res                        return res                    return parsed                except:                    pass        return response    except Exception as e:        logger.warning(f"无法解析结果:{e}")        return responseif __name__ == "__main__":    logger.info("Calculator Client Starting...")    asyncio.run(main())

客户端使用 async with Client(server) 安全管理连接,自动处理建立与清理。

核心方法说明:

  • await client.list_tools():获取所有工具元信息
  • await client.list_resources():发现可用资源
  • await client.list_prompts():发现可用提示词模板
  • await client.call_tool():调用工具,传入工具名与参数字典
  • extract_tool_result():解开 MCP 响应包装,拿到真实值

链式调用演示了如何将一个工具的输出作为下一个工具的输入,实现复杂计算。 错误处理会捕获工具异常(如除零)并优雅记录,不会崩溃。


步骤 4:运行服务端与客户端

打开两个终端

终端 1 启动服务端:

python calculator_server.py

终端 2 运行客户端:

python calculator_client.py

你将看到完整的运行日志与输出。


FastMCP 高级模式

计算器示例只用到基础逻辑,FastMCP 可支撑复杂生产场景。扩展时可使用:

  • 异步操作:对数据库、API 等 I/O 密集型工具使用 async def
  • 动态资源:资源支持参数(如 resource://users/{user_id}),动态获取指定数据
  • 复杂类型校验:使用 Pydantic 或复杂类型注解,确保 LLM 传入格式严格匹配
  • 自定义传输:除 stdio 外,还支持 SSE 等用于 Web 集成与自定义 UI

写在最后

FastMCP 在复杂的 MCP 协议与 Python 开发者期望的简洁装饰器开发体验之间架起了桥梁。它去掉了 JSON-RPC 2.0 与手动传输管理的样板代码,让你专注真正重要的事情:构建让 LLM 更强大的工具。

无论你是开发简单工具,还是复杂的数据编排层,FastMCP 都提供最“Pythonic”的路径,帮你快速搭建生产级 Agentic 生态系统。

AI时代,未来的就业机会在哪里?

答案就藏在大模型的浪潮里。从ChatGPT、DeepSeek等日常工具,到自然语言处理、计算机视觉、多模态等核心领域,技术普惠化、应用垂直化与生态开源化正催生Prompt工程师、自然语言处理、计算机视觉工程师、大模型算法工程师、AI应用产品经理等AI岗位。

在这里插入图片描述

掌握大模型技能,就是把握高薪未来。

那么,普通人如何抓住大模型风口?

AI技术的普及对个人能力提出了新的要求,在AI时代,持续学习和适应新技术变得尤为重要。无论是企业还是个人,都需要不断更新知识体系,提升与AI协作的能力,以适应不断变化的工作环境。

因此,这里给大家整理了一份《2026最新大模型全套学习资源》,包括2026最新大模型学习路线、大模型书籍、视频教程、项目实战、最新行业报告、面试题、AI产品经理入门到精通等,带你从零基础入门到精通,快速掌握大模型技术!

由于篇幅有限,有需要的小伙伴可以扫码获取!
在这里插入图片描述

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。

在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

在这里插入图片描述

4. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

5. 大模型行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

为什么大家都在学AI大模型?

随着AI技术的发展,企业对人才的需求从“单一技术”转向 “AI+行业”双背景。企业对人才的需求从“单一技术”转向 “AI+行业”双背景。金融+AI、制造+AI、医疗+AI等跨界岗位薪资涨幅达30%-50%。

同时很多人面临优化裁员,近期科技巨头英特尔裁员2万人,传统岗位不断缩减,因此转行AI势在必行!

在这里插入图片描述

这些资料有用吗?

这份资料由我们和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

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

大模型全套学习资料已整理打包,有需要的小伙伴可以微信扫描下方CSDN官方认证二维码,免费领取【保证100%免费】

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐