Python 玩转 MCP:在工具函数中获取请求 Headers 的正确姿势

一、问题出现:工具函数里怎么拿请求信息?

假设你用 FastMCP 写了一个最简单的工具函数:

python 复制代码
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("My Server")

@mcp.tool(name="打招呼",description="简单的打招呼")
async def hello() -> str:
    return "hello world"

这个函数很简单,运行也没问题。

但是一旦你想要在函数里获取请求头、用户信息、IP、Token 等信息(一般用于一些权限校验,数据打点等操作),就会发现:

函数没有直接的 Request 对象!

这时就要用到关键角色 ------ ctx: Context

二、Context 到底是什么?

在 FastMCP 框架中,每个工具函数都会自动注入一个 ctx: Context 参数。

你可以把它理解成一次 调用上下文(context),它内部封装了这次请求的关键信息,包括但不限于:

  • 当前请求的上下文信息

  • request 对象(如果是通过 HTTP 请求触发)

简单来说:ctx 是 MCP 工具函数与外部世界沟通的桥梁。

三、实战:获取请求 Headers

有了这个认识,我们就可以轻松拿到 headers:

python 复制代码
from mcp.server.fastmcp import FastMCP, Context  
from starlette.requests import Request  
  
mcp = FastMCP("My Server")  
  
@mcp.tool(name="显示 headers 信息", description="显示请求的 headers信息")  
async def echo_headers(ctx: Context) -> str:  
    """获取请求的 header 信息"""  
    # 访问请求对象  
    if ctx.request_context.request and isinstance(ctx.request_context.request, Request):  
        headers = dict(ctx.request_context.request.headers)  
        return str(headers)  
    return "No headers available"

如果工具函数中有参数应该如何传递?

Context 注入机制会自动检测函数参数中的 Context 类型注解,当工具被调用时,FastMCP 会自动将 Context 对象注入到该参数中。 Context 参数的名称可以是任意的(如 ctxcontextmy_ctx),只要它带有 Context 类型注解即可。

python 复制代码
from mcp.server.fastmcp import FastMCP, Context  
from starlette.requests import Request  
  
mcp = FastMCP("My Server")  
  
@mcp.tool(name="打招呼", description="打招呼")  
async def say_hello(   
        name: str = Field(description="你的名字", examples=["小王"]),
        ctx: Context=Context(),  
        ):
    # 访问请求对象  
    if ctx.request_context.request and isinstance(ctx.request_context.request, Request):  
        headers = dict(ctx.request_context.request.headers)  
        print( headers)  
    return f"hello {name}"

ctx 在工具函数中的位置无所谓,但必须是使用 Context 注解的,你也可以写成

python 复制代码
@mcp.tool(name="打招呼", description="打招呼")  
async def say_hello(  
            ctx: Context=Context(),  
        name: str = Field(description="你的名字", examples=["小王"])
        ):
        ...

但是推荐放到最后或者第一个参数,不要和混合在正常的工具参数中。

四、总结一下

通过这次小例子,我们了解了:

  • ctx: Context 是工具函数的上下文入口

  • 通过 ctx.request_context.request 可以拿到 Starlette 的 Request 对象,这个对象包含了请求的上下文信息,header, cookies 等

  • MCP SDK 使用 Context 来统一不同通信模式下的请求访问方式

在实际开发中,你可以基于这个思路进一步扩展,比如:

  • 从 headers 里提取 Authorization,实现鉴权;

  • ctx 里获取调用链信息;

相关推荐
Victor35611 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor35611 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术12 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
Gogo81613 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang13 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐14 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦16 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德16 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
MX_935917 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
程序员泠零澪回家种桔子18 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构