1. 从 Demo 到工程FastMCP 2.0 服务端到底卡在哪FastMCP 2.0 是一个用 Python 快速构建 MCPModel Context Protocol服务端的框架它把工具注册、资源暴露、提示模板这些能力封装成装饰器让你几十行代码就能跑起一个能被 LLM 客户端调用的服务。但很多人写完第一个mcp.tool之后就停住了工具之间怎么共享状态请求进来想加日志和缓存往哪塞OAuth 令牌、会话数据放内存里重启就没了怎么办这些问题不解决服务永远只能停在 Demo 阶段。这篇是 FastMCP 2.0 服务端教学的下篇聚焦三条主线Context 上下文传递、中间件拦截、存储后端选型。适合已经能跑通基础工具、准备把 MCP 服务推向可维护工程的开发者。我会给出可复制的config.toml骨架、中间件注册代码以及启动验证和请求链路排查的具体动作。上篇讲的是工具/资源/提示的基础注册这篇直接进入进阶部分假设你已经有一个能启动的 FastMCP 实例。读完之后你应该能做到在任意深度的调用栈里拿到 Context 并写日志、报进度用中间件给所有请求统一加缓存和认证根据部署形态在 Memory、Disk、Redis 之间选对存储后端并且知道生产环境为什么必须加密 OAuth 令牌。2. TaoToken 前置把模型能力接进你的 MCP 服务MCP 服务本身不产生智能它负责把工具和资源暴露给 LLM 客户端。当你的工具里需要调用 LLM 做摘要、分类、采样ctx.sample时就需要一个稳定的模型接入点。TaoToken 提供统一的 API 入口兼容主流模型调用方式适合作为 MCP 服务里sampling_handler的后端。官网地址https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentAPI 入口https://taotoken.net/api接入前你需要准备一个 API Key在控制台创建即可https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite如果你只是想先验证模型对话是否通可以直接用模型对话页面测试https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite对于长期做编码和 Agent 开发的场景Coding Plan 会更划算适合把 MCP 服务作为常驻工具链的一部分https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite接入文档在这里包含请求格式和参数说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite如果你用 Claude Code 这类客户端Anthropic 兼容接入方式参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite把 Key 配好之后回到 FastMCP 这边我们就可以在采样回退处理器里用上它。3. 可复制配置config.toml 骨架与中间件注册3.1 config.toml 骨架FastMCP 支持从配置文件读取服务定义下面是一个覆盖 Context、中间件、存储后端三块的最小骨架。你可以直接复制到项目根目录的config.toml[server] name FastMCPAdvancedServer version 0.2.0 mask_error_details true [server.storage] # 开发用 memory单机生产用 disk分布式用 redis backend disk directory /var/lib/fastmcp/storage [server.storage.encryption] # 生产环境必须开启密钥从环境变量注入 enabled true key_env STORAGE_ENCRYPTION_KEY [middleware.caching] enabled true backend disk directory /var/lib/fastmcp/cache ttl_seconds 300 [middleware.logging] enabled true level info [llm.sampling] # 客户端不支持采样时的回退处理器 handler openai_compatible base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY behavior fallbackmask_error_details true这一项建议生产环境打开它会把内部异常细节隐藏只返回安全的错误信息避免把堆栈或路径泄露给客户端。3.2 Context 依赖注入Context 是连接工具函数和 MCP 运行时的桥梁。推荐用依赖注入方式在函数签名里加一个类型为Context的参数FastMCP 会自动注入from fastmcp import FastMCP, Context mcp FastMCP(AdvancedServer) mcp.tool async def process_files(paths: list[str], ctx: Context) - str: await ctx.info(f开始处理 {len(paths)} 个文件) for i, p in enumerate(paths): await ctx.report_progress(i 1, len(paths)) # 实际处理逻辑 await ctx.info(处理完成) return f已处理 {len(paths)} 个文件参数名可以任意ctx、context、_c都行关键是类型提示必须是Context。如果你在深层调用栈里拿不到注入的参数可以用运行时依赖函数from fastmcp import get_context def inner_helper(): ctx get_context() ctx.info(从嵌套函数记录日志)注意get_context()只在活跃请求上下文中有效脱离请求调用会抛RuntimeError。我试过在后台任务里直接调它结果就是报错所以后台任务要么自己传 ctx要么别用。3.3 中间件注册中间件用来统一拦截请求做缓存、认证、日志。以响应缓存中间件为例from fastmcp.server.middleware.caching import ResponseCachingMiddleware from key_value.aio.stores.disk import DiskStore mcp.add_middleware( ResponseCachingMiddleware( cache_storageDiskStore(directory/var/lib/fastmcp/cache) ) )缓存基于请求内容哈希会自动跳过有副作用的工具非幂等工具所以不用担心把写操作缓存了。如果你要加自定义中间件继承基类并实现on_request或on_response钩子即可注册顺序决定执行顺序缓存类中间件建议放在认证之后。3.4 存储后端选型FastMCP 2.13.0 之后用py-key-value-aio提供统一存储接口后端可插拔。对照表如下后端适用场景特点MemoryStore开发、测试快重启丢失DiskStore单机生产持久化需文件系统RedisStore分布式生产高可用支持 TTLDynamoDB/MongoDB云原生与现有基础设施集成OAuth 令牌这类敏感数据生产环境必须加密存储from key_value.aio.stores.redis import RedisStore from key_value.aio.wrappers.encryption import FernetEncryptionWrapper from cryptography.fernet import Fernet import os auth_storage FernetEncryptionWrapper( key_valueRedisStore(hostredis.internal), fernetFernet(os.environ[STORAGE_ENCRYPTION_KEY]) )不加密的话令牌就是明文躺在存储里一旦存储被读到等于所有用户授权都泄露了。4. 验证请求启动、调用与成功结果4.1 启动服务配置和代码就位后启动服务export TAOTOKEN_API_KEY你的key export STORAGE_ENCRYPTION_KEY$(python -c from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())) fastmcp run server.py --config config.toml启动成功会看到类似输出INFO FastMCP server FastMCPAdvancedServer starting INFO Storage backend: disk (/var/lib/fastmcp/storage) INFO Middleware loaded: caching, logging INFO Listening on http://127.0.0.1:8000/mcp4.2 调用工具验证 Context用一个带进度的工具测试 Context 是否正常注入。客户端发起请求时带上progressToken否则进度调用会被静默忽略{ method: tools/call, params: { name: process_files, arguments: {paths: [a.txt, b.txt, c.txt]}, _meta: {progressToken: task-001} } }成功时你会依次收到进度通知和最终结果progress: 1/3 progress: 2/3 progress: 3/3 result: 已处理 3 个文件4.3 验证缓存中间件同一个幂等工具连续调用两次第二次应该命中缓存。观察日志INFO Cache miss for tool get_weather INFO Cache hit for tool get_weather如果第二次还是 miss检查工具是否被标记为有副作用或者缓存目录权限是否正确。4.4 验证存储持久化用 DiskStore 时重启服务后之前写入的状态应该还在。写一个ctx.set_state的工具调用后重启再读一次mcp.tool async def save_note(key: str, value: str, ctx: Context) - str: ctx.set_state(key, value) return saved mcp.tool async def read_note(key: str, ctx: Context) - str: return ctx.get_state(key) or not found重启后read_note仍能返回之前的值说明 DiskStore 生效。如果返回not found多半是存储目录被清空或配置没加载。5. 本篇常见错排查5.1 get_context() 抛 RuntimeError现象在后台任务或非请求线程里调用get_context()报RuntimeError: No active context。原因Context 绑定在请求生命周期上脱离请求就不存在。排查动作确认调用点是否在工具/资源函数内或者是否由请求链路触发。后台任务需要显式把 ctx 传进去而不是重新获取。5.2 进度不显示现象调用了report_progress但客户端没收到。原因客户端初始请求没带progressToken。排查动作检查请求的_meta字段补上progressToken。另外确认客户端实现了进度处理程序有些精简客户端会忽略进度通知。5.3 缓存命中率异常现象缓存中间件加载了但几乎不命中。原因工具被判定为有副作用或者请求参数里有每次都变的值如时间戳。排查动作检查工具是否标记了非幂等检查请求参数是否稳定。缓存基于内容哈希参数一变哈希就变。5.4 OAuth 令牌明文存储现象检查存储发现令牌是明文。原因没套FernetEncryptionWrapper。排查动作确认client_storage是否被加密包装器包裹STORAGE_ENCRYPTION_KEY是否从环境变量正确注入。密钥丢了令牌就解不开所以密钥要单独备份。5.5 中间件顺序导致认证失效现象缓存中间件放在认证前面未授权请求也被缓存了。原因中间件按注册顺序执行缓存先跑就会把未认证的响应也缓存。排查动作把认证中间件注册在缓存之前确保未授权请求在进入缓存层前就被拦截。5.6 采样回退不生效现象客户端不支持采样工具直接报错而不是走回退。原因sampling_handler_behavior没设成fallback或者 handler 没配。排查动作确认配置里behavior fallback并且base_url和api_key_env指向正确的接入点。用 TaoToken 的 API 入口时base_url填https://taotoken.net/api。6. 下一步把服务跑成常驻工程到这里Context、中间件、存储后端三条线都通了。接下来建议做两件事一是把服务按功能拆成多个子服务器用mount或import_server组合性能敏感用静态导入需要热插拔用动态挂载二是把 OAuth 令牌和会话状态迁到 Redis 加加密包装为多实例部署做准备。如果你在采样回退或模型调用上还需要一个稳定入口可以从 API Keys 页面拿 Key再对照接入文档把sampling_handler配好https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite长期跑编码和 Agent 任务的话Coding Plan 更适合作为常驻后端https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite配置过程中遇到请求链路问题先看接入文档里的请求格式说明再对照本篇第 5 节的排查清单逐项过一遍基本能定位到是 Context、中间件还是存储层的问题。
企业数字化 ERP 产品动态
相关推荐
沥青路面缺陷目标检测:LabelMe标注到YOLOv8训练全流程 简介:这套沥青路面缺陷目标检测数据集Part2分卷,面向需要训练道路缺陷检测模型的算法工程师与科研人员,旨在缓解道路养护领域标注数据稀缺、缺陷类别不均衡的突出问题。全量数据集包含6000张道路图像,本分卷含2000张图片对应的Lab… · 2026/9/26 11:49:56
【赵渝强老师】崖山数据库的控制文件 崖山数据库的物理存储结构就是指的YashanDB数据库在硬盘上存储的各种文件,包括:数据文件、联机日志文件、控制文件、归档日志文件、参数文件、告警日志文件、跟踪文件和备份文件等。下面重点讨论一下崖山数据库的控制文件,视频讲解如下&#… · 2026/9/26 11:49:56
Codex 为什么不能直接开 Full Access?Agent 权限越大,越要先划清任务边界 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 11:49:56
算符优先分析法C语言实现:优先关系表构建与移进归约核心算法详解 开头 说到编译原理这门课,算符优先分析算法应该是很多人在语法分析这一章第一次真正动手写代码的地方。当年我也是从“文法、推导、归约到底都是啥”的懵圈状态过来的,到现在还能记得调试优先关系表时的那种抓狂感——明明照着书上的算法写的,… · 2026/9/26 12:24:41
Spark SQL调优实战:从Catalyst到执行计划的深度解析 实践了三年多离线数仓,把团队主流程从RDD重写成Spark SQL之后,我才真正理解“SQL比代码更高效”这句话不是在开玩笑。前两篇写了Spark3.x的核心抽象和数据读写,这篇是Spark3.x指北的第三篇,专门把Spark SQL讲透:它解决… · 2026/9/26 12:24:41
算符优先分析算法详解:C语言完整实现与工程实践 从大二下学期第一次翻开《编译原理》教材开始,“语法分析”这四个字就压得人喘不过气。等学到算符优先分析这一节时,很多人直接在纸上画完FIRSTVT和LASTVT集合就算交差,一到上机实验要用C语言写一个能跑通的分析器,立刻卡壳。这篇… · 2026/9/26 12:24:41
开源硬件项目怎么找?别搜代码,要找完整生态 1. 开源硬件不是“找代码”而是“找生态”:为什么90%的人搜不到真正可用的智能家居项目你是不是也试过在GitHub上搜“smart home”“home automation”“esp32 home”,结果翻了二十页全是半年没更新的空仓库、只有README没代码的“计划中”项目ÿ… · 2026/9/26 12:24:22
Vibe Coding实战:从自然语言到可运行项目的AI编程工作流 最近编程圈要是还没聊过“Vibe Coding”,那多半是断网超过三天了。这个词从2025年年初火起来之后,几乎成了AI编程话题里的“房间里的大象”——有人把它夸成码农解放宣言,有人把它骂成代码事故源头。我自己写了十几年代码,一开始听… · 2026/9/26 12:24:22
STM32嵌入式AI实战:从Model Zoo到自研模型的演进路线 1. 先搞清楚 ST Model Zoo 到底给了我们什么ST 官方这几年在嵌入式 AI 这条线上动作挺密集的,从最早的 X-CUBE-AI 扩展包,到后来的 STM32Cube.AI,再到现在的 ST Edge AI Suite,整个工具链一直在迭代。Model Zoo 这个概念其实是从 … · 2026/9/26 12:24:22
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46