fastmcp客户端传输方式代码实战

前言

FastMCP Client 通过处理底层连接机制的传输对象与 MCP 服务器通信。虽然客户端可以根据您传递给它的内容自动选择传输方式,但显式实例化传输可以让您完全控制配置——环境变量、身份验证、会话管理等等。
将传输视为您的客户端代码和 MCP 服务器之间的可配置适配器。每种传输类型处理不同的通信模式:带管道的子进程、HTTP 连接或直接内存调用。

本博客为了完整性,把官网的很多内容都写进来了,如果我们仅仅是想要直接运行几种不同传输方式的代码,请直接参考本文后记的部分。

统一测试的MCP Server

这里就简单的写一个MCP Server供下面不同的MCP Client使用

from fastmcp import FastMCP

# 初始化FastMCP Server
mcp = FastMCP("My MCP Server")


# 用@mcp.tool()装饰器定义一个工具
@mcp.tool()
def add(a: int, b: int) -> int:
    """

    :param a: 第一个整数
    :param b: 第二个整数
    :return: 返回两个数字之和
    """
    return a + b


# 启动MCP Server
if __name__ == "__main__":
    # sse
    mcp.run(transport="sse", host="127.0.0.1", port=8001)
    # streamable-http
    # mcp.run(transport="streamable-http", host="127.0.0.1", port=8001)
    # stdio
    # mcp.run(transport="stdio")

选择合适的传输方式

  • 使用 STDIO 传输 当您需要运行本地 MCP 服务器并完全控制其环境和生命周期时
  • 使用 远程传输 当连接到独立运行的生产服务或共享 MCP 服务器时
  • 使用 内存传输 当测试 FastMCP 服务器而不需要子进程或网络开销时
  • 使用 MCP JSON 配置 当您需要连接到配置文件中定义的多个服务器时

STDIO 传输

STDIO(标准输入/输出)传输通过子进程管道与 MCP 服务器通信。这是桌面客户端(如 Claude Desktop)使用的标准机制,也是运行本地 MCP 服务器的主要方式。

客户端运行服务器

关键概念:使用 STDIO 传输时,您的客户端实际上会启动并管理服务器进程。这与网络传输根本不同,网络传输是连接到已经运行的服务器。理解这种关系是有效使用 STDIO 的关键。

使用 STDIO 传输,您的客户端会:

  • 在连接时将服务器作为子进程启动
  • 管理服务器的生命周期(启动、停止、重启)
  • 控制服务器的环境和配置
  • 通过 stdin/stdout 管道进行通信

这种架构支持强大的本地集成,但需要理解环境隔离和进程管理。

环境隔离

STDIO 服务器默认在隔离环境中运行。这是 MCP 协议强制执行的安全功能,用于防止敏感数据的意外暴露。
当您的客户端启动 MCP 服务器时:

  • 服务器不会继承您 shell 的环境变量
  • API 密钥、路径和其他配置必须显式传递
  • 工作目录和系统路径可能与您的 shell 不同

要向服务器传递环境变量,请使用 env 参数:

from fastmcp import Client

# 如果您的服务器需要环境变量(如 API 密钥),
# 您必须显式传递它们:
client = Client(
    "my_server.py",
    env={"API_KEY": "secret", "DEBUG": "true"}
)

# 这样不会起作用 - 服务器在隔离环境中运行:
# export API_KEY="secret"  # 在您的 shell 中
# client = Client("my_server.py")  # 服务器看不到 API_KEY
基本用法

要使用 STDIO 传输,您需要创建一个传输实例,包含运行服务器所需的命令和参数:

from fastmcp import Client
from fastmcp.client.transports import StdioTransport

transport = StdioTransport(
    command="python",
    args=["my_server.py"]
)


async def main():
    async  with Client(transport=transport) as client:
        # 列出可用工具
        tools = await client.list_tools()
        print(f"可用的工具有:{tools}")
        # 调用add工具
        result = await client.call_tool("add", {"a": 1, "b": 3})
        print(f"结果为:{result}")

import asyncio
asyncio.run(main())

用stdio的方式启动MCP Server后,运行上面的MCP Client代码结果:

[12/20/25 13:55:45] INFO     Starting MCP server 'My MCP Server' server.py:2527
                             with transport 'stdio'                            
可用的工具有:[Tool(name='add', title=None, description=':param a: 第一个整数\n:param b: 第二个整数\n:return: 返回两个数字之和', inputSchema={'properties': {'a': {'type': 'integer'}, 'b': {'type': 'integer'}}, 'required': ['a', 'b'], 'type': 'object'}, outputSchema={'properties': {'result': {'type': 'integer'}}, 'required': ['result'], 'type': 'object', 'x-fastmcp-wrap-result': True}, icons=None, annotations=None, meta={'_fastmcp': {'tags': []}}, execution=None)]
结果为:CallToolResult(content=[TextContent(type='text', text='4', annotations=None, meta=None)], structured_content={'result': 4}, meta=None, data=4, is_error=False)

从日志中也可以看出这种方式MCP Server就是MCP Client的一个子进程。

您可以配置其他设置,如环境变量、工作目录或命令参数:

transport = StdioTransport(
    command="python",
    args=["my_server.py", "--verbose"],
    env={"LOG_LEVEL": "DEBUG"},
    cwd="/path/to/server"
)
client = Client(transport)

为了方便,客户端也可以从文件路径推断 STDIO 传输,但这不允许配置:

from fastmcp import Client

client = Client("my_server.py")  # 受限 - 无配置选项
环境变量

由于 STDIO 服务器不会继承您的环境,您需要传递配置的策略。以下是两种常见方法:
选择性转发 仅传递服务器实际需要的变量:

import os
from fastmcp.client.transports import StdioTransport

required_vars = ["API_KEY", "DATABASE_URL", "REDIS_HOST"]
env = {
    var: os.environ[var] 
    for var in required_vars 
    if var in os.environ
}

transport = StdioTransport(
    command="python",
    args=["server.py"],
    env=env
)
client = Client(transport)

从 .env 文件加载 将配置与代码分离:

from dotenv import dotenv_values
from fastmcp.client.transports import StdioTransport

env = dotenv_values(".env")
transport = StdioTransport(
    command="python",
    args=["server.py"],
    env=env
)
client = Client(transport)
会话持续

STDIO 传输默认在多个客户端上下文之间维护会话(keep_alive=True)。这通过为多个连接重用同一个子进程来提高性能,但在需要隔离时可以控制。
默认情况下,子进程在连接之间持续存在:

from fastmcp.client.transports import StdioTransport

transport = StdioTransport(
    command="python",
    args=["server.py"]
)
client = Client(transport)

async def efficient_multiple_operations():
    async with client:
        await client.ping()
    
    async with client:  # 重用同一个子进程
        await client.call_tool("process_data", {"file": "data.csv"})

要在连接之间实现完全隔离,请禁用会话持久性:

transport = StdioTransport(
    command="python",
    args=["server.py"],
    keep_alive=False
)
client = Client(transport)

当您需要完全隔离(例如,在测试套件中)或当服务器状态可能在连接之间引起问题时,请使用 keep_alive=False。

专用 STDIO 传输

FastMCP 提供便利的传输方式,它们是围绕 StdioTransport 的轻量包装器,具有预配置的命令:

  • PythonStdioTransport - 对 .py 文件使用 python 命令
  • NodeStdioTransport - 对 .js 文件使用 node 命令
  • UvStdioTransport - 对 Python 包使用 uv(使用 env_vars 参数)
  • UvxStdioTransport - 对 Python 包使用 uvx(使用 env_vars 参数)
  • NpxStdioTransport - 对 Node 包使用 npx(使用 env_vars 参数)

对于大多数用例,请直接使用您所需的命令实例化 StdioTransport。这些专用传输主要对客户端推断快捷方式有用。

远程传输

远程传输连接到作为 Web 服务运行的 MCP 服务器。这与 STDIO 传输是根本不同的模式——您的客户端不是启动和管理服务器进程,而是连接到已经运行的、管理自己环境和生命周期的服务。

流式 HTTP 传输

流式 HTTP 是生产部署的推荐传输方式,通过 HTTP 连接提供高效的双向流式传输。

  • 类: StreamableHttpTransport
  • 服务器兼容性: 使用 mcp run --transport http 运行的 FastMCP 服务器

该传输需要一个 URL,并可选择性地支持用于身份验证和配置的自定义头部:

from fastmcp.client.transports import StreamableHttpTransport

# 基本连接
transport = StreamableHttpTransport(url="https://api.example.com/mcp")
client = Client(transport)

# 使用自定义头部进行身份验证
transport = StreamableHttpTransport(
    url="https://api.example.com/mcp",
    headers={
        "Authorization": "Bearer your-token-here",
        "X-Custom-Header": "value"
    }
)
client = Client(transport)

为了方便,FastMCP 还提供身份验证助手:

from fastmcp.client.auth import BearerAuth

client = Client(
    "https://api.example.com/mcp",
    auth=BearerAuth("your-token-here")
)

我们这里就用streamable-http方式启动上面的MCP Server,然后运行下面的客户端代码:

from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport

transport = StreamableHttpTransport(url="http://127.0.0.1:8001/mcp")


async def main():
    async  with Client(transport=transport) as client:
        # 列出可用工具
        tools = await client.list_tools()
        print(f"可用的工具有:{tools}")
        # 调用add工具
        result = await client.call_tool("add", {"a": 1, "b": 3})
        print(f"结果为:{result}")

import asyncio
asyncio.run(main())

运行结果:

可用的工具有:[Tool(name='add', title=None, description=':param a: 第一个整数\n:param b: 第二个整数\n:return: 返回两个数字之和', inputSchema={'properties': {'a': {'type': 'integer'}, 'b': {'type': 'integer'}}, 'required': ['a', 'b'], 'type': 'object'}, outputSchema={'properties': {'result': {'type': 'integer'}}, 'required': ['result'], 'type': 'object', 'x-fastmcp-wrap-result': True}, icons=None, annotations=None, meta={'_fastmcp': {'tags': []}}, execution=None)]
结果为:CallToolResult(content=[TextContent(type='text', text='4', annotations=None, meta=None)], structured_content={'result': 4}, meta=None, data=4, is_error=False)

注意:streamable-http协议中客户端访问的端点为mcp,地址中必须以mcp结尾:http://127.0.0.1:8001/mcp。

SSE(遗留)

服务器发送事件传输为向后兼容性而维护,但在新部署中已被流式 HTTP 取代。

  • 类: SSETransport
  • 服务器兼容性: 使用 mcp run --transport sse 运行的 FastMCP 服务器

SSE 传输支持与流式 HTTP 相同的配置选项:

from fastmcp.client.transports import SSETransport

transport = SSETransport(
    url="https://api.example.com/sse",
    headers={"Authorization": "Bearer token"}
)
client = Client(transport)

除非您对 SSE 有特定的基础设施要求,否则请在新部署中使用流式 HTTP。
这类也可以用sse传输方式启动MCP Server,用下面的MCP Client进行测试:

from fastmcp import Client
from fastmcp.client.transports import SSETransport

transport = SSETransport(url="http://127.0.0.1:8001/sse")


async def main():
    async  with Client(transport=transport) as client:
        # 列出可用工具
        tools = await client.list_tools()
        print(f"可用的工具有:{tools}")
        # 调用add工具
        result = await client.call_tool("add", {"a": 1, "b": 3})
        print(f"结果为:{result}")

import asyncio
asyncio.run(main())

运行结果:

可用的工具有:[Tool(name='add', title=None, description=':param a: 第一个整数\n:param b: 第二个整数\n:return: 返回两个数字之和', inputSchema={'properties': {'a': {'type': 'integer'}, 'b': {'type': 'integer'}}, 'required': ['a', 'b'], 'type': 'object'}, outputSchema={'properties': {'result': {'type': 'integer'}}, 'required': ['result'], 'type': 'object', 'x-fastmcp-wrap-result': True}, icons=None, annotations=None, meta={'_fastmcp': {'tags': []}}, execution=None)]
结果为:CallToolResult(content=[TextContent(type='text', text='4', annotations=None, meta=None)], structured_content={'result': 4}, meta=None, data=4, is_error=False)

内存传输

内存传输直接连接到同一 Python 进程中的 FastMCP 服务器实例。这消除了子进程管理和网络开销,使其非常适合测试和开发。

  • 类: FastMCPTransport

与 STDIO 传输不同,内存服务器可以完全访问您 Python 进程的环境。它们与您的客户端代码共享相同的内存空间和环境变量——不需要隔离或显式环境传递。

from fastmcp import FastMCP, Client
import os

mcp = FastMCP("TestServer")

@mcp.tool
def greet(name: str) -> str:
    prefix = os.environ.get("GREETING_PREFIX", "Hello")
    return f"{prefix}, {name}!"

client = Client(mcp)

async with client:
    result = await client.call_tool("greet", {"name": "World"})

MCP JSON 配置传输

此传输支持新兴的 MCP JSON 配置标准,用于定义多个服务器:

  • 类: MCPConfigTransport
config = {
    "mcpServers": {
        "weather": {
            "url": "https://weather.example.com/mcp",
            "transport": "http"
        },
        "assistant": {
            "command": "python",
            "args": ["./assistant.py"],
            "env": {"LOG_LEVEL": "INFO"}
        }
    }
}

client = Client(config)

async with client:
    # 工具按服务器命名空间
    weather = await client.call_tool("weather_get_forecast", {"city": "NYC"})
    answer = await client.call_tool("assistant_ask", {"question": "What?"})
使用 FastMCP 和 MCPConfig 进行工具转换

FastMCP 支持在 MCPConfig 文件中与 MCP 服务器一起定义基本的工具转换。

config = {
    "mcpServers": {
        "weather": {
            "url": "https://weather.example.com/mcp",
            "transport": "http",
            "tools": { }   #  <--- 这是工具转换部分
        }
    }
}

通过这些转换,您可以转换(更改)工具的名称、标题、描述、标签、启用状态和参数。
对于工具采用的每个参数,您可以转换(更改)名称、描述、默认值、可见性、是否必需,并且可以提供示例值。
在以下示例中,我们将 weather_get_forecast 工具转换为仅检索 Miami 的天气,并从客户端隐藏 city 参数。

tool_transformations = {
    "weather_get_forecast": {
        "name": "miami_weather",
        "description": "获取迈阿密的天气",
        "arguments": {
            "city": {
                "name": "city",
                "default": "Miami",
                "hide": True,
            }
        }
    }
}

config = {
    "mcpServers": {
        "weather": {
            "url": "https://weather.example.com/mcp",
            "transport": "http",
            "tools": tool_transformations
        }
    }
}
工具白名单和黑名单

通过在服务器上为工具应用 tags,可以从客户端将工具列入白名单或黑名单。在以下示例中,我们仅将标记有 forecast 标签的工具列入白名单,所有其他工具对客户端不可用。

tool_transformations = {
    "weather_get_forecast": {
        "enabled": True,
        "tags": ["forecast"]
    }
}


config = {
    "mcpServers": {
        "weather": {
            "url": "https://weather.example.com/mcp",
            "transport": "http",
            "tools": tool_transformations,
            "include_tags": ["forecast"]
        }
    }
}

后记

对于初学者,可以直接关注stdio和streamable-http两种传输方式,可以直接运行的代码如下:

MCP Server
from fastmcp import FastMCP

# 初始化FastMCP Server
mcp = FastMCP("My MCP Server")


# 用@mcp.tool()装饰器定义一个工具
@mcp.tool()
def add(a: int, b: int) -> int:
    """

    :param a: 第一个整数
    :param b: 第二个整数
    :return: 返回两个数字之和
    """
    return a + b


# 启动MCP Server
if __name__ == "__main__":
    # sse
    mcp.run(transport="sse", host="127.0.0.1", port=8001)
    # streamable-http
    # mcp.run(transport="streamable-http", host="127.0.0.1", port=8001)
    # stdio
    # mcp.run(transport="stdio")
MCP Client
  1. stdio
from fastmcp import Client
from fastmcp.client.transports import StdioTransport

transport = StdioTransport(
    command="python",
    args=["my_server.py"]
)


async def main():
    async  with Client(transport=transport) as client:
        # 列出可用工具
        tools = await client.list_tools()
        print(f"可用的工具有:{tools}")
        # 调用add工具
        result = await client.call_tool("add", {"a": 1, "b": 3})
        print(f"结果为:{result}")

import asyncio
asyncio.run(main())
  1. streamable-http
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport

transport = StreamableHttpTransport(url="http://127.0.0.1:8001/mcp")


async def main():
    async  with Client(transport=transport) as client:
        # 列出可用工具
        tools = await client.list_tools()
        print(f"可用的工具有:{tools}")
        # 调用add工具
        result = await client.call_tool("add", {"a": 1, "b": 3})
        print(f"结果为:{result}")

import asyncio
asyncio.run(main())

参考文献

FastMCP客户端传输

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
内容概要:本文系统阐述了企业新闻发稿在生成式引擎优化(GEO)时代下的全渠道策略与效果评估体系,涵盖当前企业传播面临的预算、资源、内容与效果评估四大挑战,并深入分析2025年新闻发稿行业五大趋势,包括AI驱动的智能化转型、精准化传播、首发内容价值提升、内容资产化及数据可视化。文章重点解析央媒、地方官媒、综合门户和自媒体四类媒体资源的特性、传播优势与发稿策略,提出基于内容适配性、时间节奏、话题设计的策略制定方法,并构建涵盖品牌价值、销售转化与GEO优化的多维评估框架。此外,结合“传声港”工具实操指南,提供AI智能投放、效果监测、自媒体管理与舆情应对的全流程解决方案,并针对科技、消费、B2B、区域品牌四大行业推出定制化发稿方案。; 适合人群:企业市场/公关负责人、品牌传播管理者、数字营销从业者及中小企业决策者,具备一定媒体传播经验并希望提升发稿效率与ROI的专业人士。; 使用场景及目标:①制定科学的新闻发稿策略,实现从“流量思维”向“价值思维”转型;②构建央媒定调、门户扩散、自媒体互动的立体化传播矩阵;③利用AI工具实现精准投放与GEO优化,提升品牌在AI搜索中的权威性与可见性;④通过数据驱动评估体系量化品牌影响力与销售转化效果。; 阅读建议:建议结合文中提供的实操清单、案例分析与工具指南进行系统学习,重点关注媒体适配性策略与GEO评估指标,在实际发稿中分阶段试点“AI+全渠道”组合策略,并定期复盘优化,以实现品牌传播的长期复利效应。
<think>嗯,用户询问FastMCP客户端的信息,看来需要根据之前提供的引用内容来组织回答。用户可能是个开发者,正在评估这个工具是否适合项目需求。 先梳理引用中的关键点:引用1提到FastMCP的核心优势是简化通信实现,引用2展示具体代码示例,引用3强调日志功能。用户没明确具体需求方向,所以需要覆盖全面但保持结构化。 考虑分成三个逻辑块:首先是框架定位说明,重点突出"专注业务逻辑"这个核心卖点;接着是核心功能,要包含通信、认证和日志这三大支柱;最后是应用场景,准备用AI交互和分布式系统作为典型用例。这样既全面又有层次。 代码示例部分打算直接引用展示过的HttpTransport用法,但要注意简化掉async语法避免初学者困惑。认证示例保留自定义头部设置,因为这是实际开发常见需求。 突然想到用户可能是第一次接触FastMCP,补充说明安装方式很重要。需要提醒pip安装命令,但要注意标注"假设"字样,毕竟引用里没明确提供安装指引。 日志功能单独作为特性列出,引用3提到"客户端视角的调试监控",这个点对工程化开发很实用,要强调可配置日志级别这类细节。 最后的应用场景考虑加入IoT边缘计算用例,虽然引用里没提,但基于FastMCP轻量级特性应该适用,这样能帮用户打开思路。不过补充说明这是推测性内容,保持严谨。 相关问题设计侧重实操:优化方向和安全实践紧扣引用2的"最佳实践",调试技巧则呼应引用3的日志主题。这样能引导用户深入技术细节。 </think>以下是关于 FastMCP 客户端的详细介绍及使用指南,综合引用信息整理: --- ### **一、FastMCP 客户端核心定位** FastMCP 是基于 **Model Context Protocol (MCP)** 的 Python 框架,专为简化客户端-服务器通信设计: - **核心优势**:封装底层通信细节(如 HTTP 传输),提供简洁 API - **适用场景**:AI 模型交互、分布式系统协调、进程间通信 [^1] - **扩展能力**:支持自定义传输协议和认证方案 --- ### **二、核心功能与使用方法** #### 1. **基础通信示例** ```python from fastmcp import Client async def main(): async with Client("https://api.example.com/mcp") as client: response = await client.request("ping") # 发送请求 print(response.data) # 接收响应 ``` #### 2. **自定义认证方案** 当服务端使用非标准认证时(引用[2]示例): ```python from fastmcp.client.transports import StreamableHttpTransport transport = StreamableHttpTransport( base_url="https://fastmcp.cloud/mcp", headers={ "X-API-Key": "your-secret-key", # 自定义头部认证 "X-Auth-Scheme": "token-v2" } ) async with Client(transport=transport) as client: await client.call("model/predict", data={"input": "test"}) ``` #### 3. **日志与监控(引用[3])** - **日志层级**:支持 `DEBUG`/`INFO`/`WARNING` 分级输出 - **关键日志字段**: - 请求/响应元数据 - 传输层错误追踪 - 业务逻辑执行耗时 ```python import logging logging.basicConfig(level=logging.DEBUG) # 启用调试日志 ``` --- ### **三、典型应用场景** | 场景 | FastMCP 解决方案 | |---------------------|-------------------------------------| | **AI 模型部署** | 封装模型推理为 API 端点,客户端远程调用 | | **微服务协调** | 通过标准协议衔接 Python/非Python 服务 | | **边缘设备通信** | 轻量级 HTTP 传输节省资源 | --- ### **四、安装与配置** ```bash pip install fastmcp # 假设通过 PyPI 安装 ``` **安全实践建议**(引用[2]): - 使用环境变量管理密钥(如 `os.getenv("API_KEY")`) - 为不同环境(开发/生产)配置独立传输通道 --- ### **五、扩展能力** - **传输层定制**:支持替换 HTTP 为 WebSocket/GRPC - **协议扩展**:通过继承 `MCPMessage` 实现自定义数据包结构 - **中间件机制**:注入请求预处理逻辑(如数据加密) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRivers

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值