第14章 由Gradio构建MCP服务器与客户端------ 项目十一:MCP客户端配置Gradio文档的MCP服务器
- [第14章 由Gradio构建MCP服务器与客户端](#第14章 由Gradio构建MCP服务器与客户端)
- [14.1 MCP协议概念与架构组件](#14.1 MCP协议概念与架构组件)
-
-
- [14.1.1 MCP协议的作用和组成部分](#14.1.1 MCP协议的作用和组成部分)
- [14.1.2 MCP架构与核心组件](#14.1.2 MCP架构与核心组件)
- [14.2 MCP功能协商与消息规范](#14.2 MCP功能协商与消息规范)
-
- [14.2.1 功能协商机制](#14.2.1 功能协商机制)
- [14.2.2 消息规范:请求、结果、错误及通知](#14.2.2 消息规范:请求、结果、错误及通知)
- [14.3 MCP传输层:Stdio与Streamable HTTP](#14.3 MCP传输层:Stdio与Streamable HTTP)
- [14.3.1 Stdio传输标准及示例](#14.3.1 Stdio传输标准及示例)
- [14.3.2 传输层:Streamable HTTP传输](#14.3.2 传输层:Streamable HTTP传输)
-
- [1. Streamable HTTP传输的通信原理](#1. Streamable HTTP传输的通信原理)
- [2. 向服务器发送和接受消息](#2. 向服务器发送和接受消息)
- [3. 如何选择与示例](#3. 如何选择与示例)
- [14.4 配置MCP服务器及其关键特性](#14.4 配置MCP服务器及其关键特性)
-
- [14.4.1 练习13:Gradio配置MCP服务器------字母计数器](#14.4.1 练习13:Gradio配置MCP服务器——字母计数器)
- [14.4.2 特性1:函数自动转换为MCP工具](#14.4.2 特性1:函数自动转换为MCP工具)
- [14.4.3 特性2:文件上传MCP服务器](#14.4.3 特性2:文件上传MCP服务器)
- [14.4.4 特性3:在Spaces上托管MCP服务器](#14.4.4 特性3:在Spaces上托管MCP服务器)
- [14.5 项目十一:MCP客户端配置Gradio文档的MCP服务器](#14.5 项目十一:MCP客户端配置Gradio文档的MCP服务器)
-
- [14.5.1 Gradio文档的MCP服务器](#14.5.1 Gradio文档的MCP服务器)
- [14.5.2 两种传输机制的配置方法](#14.5.2 两种传输机制的配置方法)
- [14.5.3 Cursor与Claude配置Gradio文档的MCP服务器](#14.5.3 Cursor与Claude配置Gradio文档的MCP服务器)
-
第14章 由Gradio构建MCP服务器与客户端
MCP在当前人工智能领域大热,它是LLM打通最后一公里的连接标准,是LLM使用各类工具的粘合剂。本章将使用Gradio构建配置形式的MCP服务器与客户端,首先介绍MCP协议细节,包括MCP协议概念与架构组件、MCP功能协商与消息规范、MCP的传输层标准Stdio与Streamable HTTP。然后讲述本章重点:由Gradio应用的配置构建MCP服务器示例及其关键特性,MCP客户端的配置方法及示例。
考虑到MCP官方以Claude for Desktop为例进行演示,且当前版本Version 0.14.4主要支持Windows和MacOS,暂不支持Linux,因此本章示例及命令均在Windows下运行,需要MacOS版的读者可移步官网(🖇️链接14-1)对照本章查看。
14.1 MCP协议概念与架构组件
本节将详细介绍MCP,内容包括MCP协议介绍、架构与核心组件。
14.1.1 MCP协议的作用和组成部分
MCP是AI的USB-C接口。MCP(Model Context Protocol,模型上下文协议)是一种开源协议,让AI应用无缝集成外部的数据源和工具。MCP可以被视为AI应用的USB-C接口,为AI应用连接数据源和工具建立了统一标准,因此自诞生之初就具备更强大的功能。无论用户是在构建基于AI的IDE、增强聊天接口,还是创建自定义AI工作流或可组合的集成应用,MCP都提供了一种标准化的方式将LLM与所需的资源连接起来,并向其展示可用的工具和功能。简单地说,MCP是AI应用(如Claude for Desktop、Goose或5ire)与各种数据源和工具(如数据文件系统、开发工具或产品工具)交换信息的桥梁,这三者间的数据流如图14-1所示:

图14-1
MCP帮助开发者在LLM之上构建智能体和复杂工作流,优势包括:预置不断增长的集成库供LLM调用;在不同LLM之间灵活切换以及实现在设备中最佳数据安全。
MCP的组成部分 。MCP借鉴了LSP(Language Server Protocol:语言服务协议🖇️链接14-2),LSP规范了整个开发工具生态系统对编程语言的支持,MCP则规范了AI应用的生态系统对数据源和工具的集成。MCP由以下协同工作的关键部分组成:
(1)基础协议:核心使用JSON-RPC消息类型。
(2)生命周期管理:连接初始化、功能协商和会话控制。
(3)授权:基于HTTP传输的认证与授权框架。
(4)服务器功能:服务器提供资源、提示词和工具。
(5)客户端功能:客户端提供采样、根目录列表和需求获取。
(6)工具组件:日志记录和参数补全等横切关注点。
所有实现必须支持基础协议和生命周期管理,其他部分可根据应用需求选择实现。MCP模块化设计可以精确支持所需功能,又能支持客户端与服务器之间的丰富交互。
14.1.2 MCP架构与核心组件
MCP采用灵活可扩展的客户端-宿主-服务器(client-host-server)架构,该架构使开发者可以跨应用集成AI功能的同时,维持清晰的安全边界并隔离关注点。MCP架构基于JSON-RPC构建,提供了一个有状态的会话协议,并专注于客户端与服务器间的上下文交换与采样协作,其架构如图14-2所示:

图14-2
与图14-1对照可知,架构中的宿主对应AI应用,MCP客户端和服务器对应MCP协议,本地及远程数据对应数据源和工具。MCP的单台宿主可运行多个客户端实例,客户端与服务端一一对应连接,详细说明如下:
- MCP宿主:需要通过MCP访问数据源或工具的AI应用,如Claude for Desktop、IDE(Integrated Development Environment,集成开发环境)等。
- MCP客户端:与MCP宿主应用绑定并由其运行,与MCP服务器保持一对一连接。
- MCP服务器:轻量级程序,AI应用通过MCP客户端连接MCP服务器,MCP服务器一般由厂商维护,向客户端提供上下文、工具和提示等信息。
- 本地数据源:MCP服务器可安全访问的本地计算机文件、数据库和功能函数等。
- 远程服务:MCP服务器通过因特网可连接的外部资源。
该模块化系统架构意味着新增功能时无需修改AI应用本体,如同为计算机添加新外设而无需升级整机。在MCP架构中,有三类核心组件:宿主、客户端和服务端:
(1)宿主(Host),是启动连接的LLM应用程序,充当容器与协调员角色,功能如下:①创建并管理多个客户端实例。②初始化客户端连接,控制客户端连接权限及生命周期。③强制执行安全策略与准入请求。④处理用户授权决策。⑤协调AI/LLM的集成与采样。⑥管理跨客户端的上下文聚合。
(2)客户端(Client)。每个客户端由宿主创建,是宿主应用的连接器,维持与服务器的独立连接,功能如下:①为每个服务器建立单条有状态会话。②处理协议的协商与功能交换。③双向路由协议消息。④管理订阅及通知。⑤维护服务器间安全边界。⑥一个宿主可以创建并管理多个客户端,每个客户端与特定服务器保持1:1关联。
(3)服务器(Server)。服务器提供专有上下文及功能,具体功能如下:①通过MCP原语暴露资源、工具及提示。②专注某职能独立运行。③通过客户端接口请求采样。④必须遵守安全约束。⑤可作为本地进程或远程服务。
当MCP宿主被用户或AI/LLM授予权限后,就能通过创建MCP客户端连接相应的MCP服务器,随后可由这些连接读取服务器本地或远程数据并执行操作。MCP客户端主要负责创建接口、建立连接、处理宿主与服务器之间的信息交互等。MCP服务器通过客户端为宿主提供服务,并暴露可用的资源、工具及提示等。
14.2 MCP功能协商与消息规范
MCP的各部分之间通过功能协商机制及消息规范建立连接。
14.2.1 功能协商机制
MCP在连接初始化时,客户端和服务器通过功能(Capability)协商机制明确各自能力范围,客户端与服务器在初始化时需显式声明各自支持的功能。功能声明决定会话期间可用的协议特性及原语操作,例如,服务器功能声明包括可订阅资源、支持工具、提示模板等;客户端功能声明有支持采样、通知处理等。双方必须全程遵循功能声明的范围,新增功能也可通过协商扩展协议实现。功能协商流程如图14-3所示:

图14-3
由图14-3可知,协商流程包括五个阶段:宿主初始化客户端、客户端工具或资源请求(仍由宿主的用户或大模型发起)、服务器采样请求、客户端与服务器之间的通知消息、宿主发起结束会话。会话期间,每项功能解锁对应协议特性,例如:
- 在宿主初始化客户端时,已实现的服务器特性必须在服务器功能声明中公示。
- 服务器发送消息通知资源更新时,要求客户端声明支持通知处理。
- 客户端请求工具调用时,要求服务器声明该工具的功能。
- 服务器采样操作时,要求客户端声明支持采样。
该功能协商机制确保双方对支持功能有明确认知,同时保持协议的可扩展性。
14.2.2 消息规范:请求、结果、错误及通知
消息规范规定了传输消息的格式,MCP客户端与服务器之间的所有消息必须遵循JSON-RPC 2.0规范(🖇️链接14-3)。MCP消息规范基于schema.ts(🖇️链接14-4)中的TypeScript模式定义了权威性的协议标准,并制定了JSON-RPC 2.0规范要求的消息格式,该消息格式同时也适用于Python版的MCP。本节将列出TypeScript语法的消息定义,并给出JSON格式的实例。
JSON-RPC 2.0规范制定了四种消息类型:请求、结果、错误及通知,分别讲述。
请求(Request)。可由客户端发往服务器,亦可由服务器发往客户端,用于发起操作,需要接收方返回响应。Request接口类的TypeScript定义如下所示:
json
interface Request {
method: string;
params?: { ... }; # ?:代表可选参数
}
实际传输中Request实例采用JSON格式,如下所示:
json
{
jsonrpc: "2.0";
id: string | number;
method: string;
params?: {
[key: string]: unknown;
};
}
Request实例中必须包含字符串或整型格式的ID,与基础JSON-RPC不同,ID不得为空。请求方在同一会话中不得重复使用已用过的Request ID。
结果(Result)。Result是对Request的成功响应,有时也写作Response。结果消息用于回复请求,包含操作结果或错误信息。Result接口类定义如下所示:
json
interface Result {
[key: string]: unknown;
}
实际传输中Result实例如下所示:
json{
jsonrpc: "2.0";
id: string | number;
result?: {
[key: string]: unknown;
}
error?: {
code: number;
message: string;
data?: unknown;
}
}
Result响应必须包含与对应Request相同的ID,可进一步细分为result和error类型,必须设置为两者之一,但不得同时设置。两种类型中,result类型可采用任意JSON对象结构,而error类型必须至少包含错误代码和消息,错误代码必须为整数。
错误(Error)。当出现Error时,表示请求处理失败,它包含于Result的error字段,其接口类定义如下:
jsoninterface
code: number;
message: string;
data?: unknown;
}
实例可参照Result的示例。MCP制定了错误处理规范,定义了以下标准错误码:
json
enum ErrorCode {
// Standard JSON-RPC error codes
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603,
}
MCP SDK和应用程序可在-32000以上范围自定义错误码。而error传播途径有:
- 请求错误响应,对请求返回的错误应答。
- 传输层错误事件,传输通道触发的错误事件。
- 协议级错误处理程序,协议层面的错误处理机制。
通知(Notification)。作为单向消息在客户端与服务器之间传输,接收方不得发送响应,其接口类定义如下所示:
jsoninterface
method: string;
params?: { ... };
}
Notification在传输中实例如下所示(通知中不得包含ID):
json
{
jsonrpc: "2.0";
method: string;
params?: {
[key: string]: unknown;
};
}
14.3 MCP传输层:Stdio与Streamable HTTP
MCP基于灵活可扩展的架构构建,能够实现LLM应用与集成间的无缝通信,帮助MCP连接客户端、服务器和大语言模型应用。传输层负责处理客户端与服务器之间的实际通信,MCP使用JSON-RPC 2.0格式进行消息交换,且JSON-RPC 2.0消息必须采用UTF-8编码。MCP协议目前为client-server间通信定义了两种标准传输机制:stdio和Streamable HTTP,本节分别讲述。
14.3.1 Stdio传输标准及示例
Stdio即标准输入和标准输出通信,在Stdio模式下:
- 客户端将MCP服务作为子进程启动。
- 服务器从自身的标准输入(stdin)读取JSON-RPC消息,并向自身的标准输出(stdout)发送消息。
- 消息应为独立JSON-RPC 2.0格式的请求、通知或响应。
- 消息以换行符分隔,且不得包含嵌入式换行符。
- 服务器为记录日志,可向标准错误端(stderr)写入UTF-8字符串,客户端可选择捕获、转发或忽略该日志。
- 服务器和客户端均不得向服务器的stdout写入任何非合规MCP消息的内容。
客户端应尽可能支持Stdio传输。客户端和服务进程之间信息交换如图14-4所示:

图14-4
Stdio传输示例。只需创建服务器,然后导入stdio_server的参数以启动服务器即可。或者在服务器启动时,设置transport参数为stdio。使用Stdio传输实现MCP服务器的基本示例如伪代码14-1所示:
伪代码14-1
py
# stdio_server.py
import asyncio
import mcp.types as types
from mcp.server import Server
from mcp.server.stdio import stdio_server
app = Server("example-server")
@app.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(uri="example://resource",
name="Example Resource")]
async def main():
async with stdio_server() as streams:
await app.run(streams[0], streams[1],
app.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())
这段代码实现了一个MCP服务器,用于向AI助手提供资源。解析如下:
- 导入依赖。asyncio是Python异步编程库,用于处理并发I/O操作;mcp.types是MCP协议的类型定义,包含Resource、Tool、Prompt等类型;Server是MCP服务器核心类,负责处理客户端请求;stdio_server是通过标准输入/输出流与客户端通信的服务器实现。
- 创建服务器实例。装饰器@app.list_resources(),注册一个处理"列出资源"请求的处理器,返回一个资源列表,每个资源包含uri和name。
- 处理流程。MCP服务器通过标准输入/输出与AI客户端通信,暴露一个示例资源供AI读取,使用异步编程模型处理并发请求。
- 主函数。由stdio_server()创建标准I/O服务器,返回一个包含读写流的元组,其中streams[0]是输入流(从客户端读取数据),streams[1]是输出流(向客户端写入数据),app.create_initialization_options()用于创建服务器初始化配置(通常包含服务器能力声明)。最后app.run()启动服务器,处理客户端连接和消息。
客户端连接服务器如伪代码14-2所示:
伪代码14-2
py
# stdio_client.py
import asyncio
from mcp.client.stdio import stdio_client, StdioServerParameters
from mcp.client.session import ClientSession
async def main():
params = StdioServerParameters(
command="./server", # 或 "python", args=["./server.py"]
args=["--option", "value"]
)
async with stdio_client(params) as streams:
async with ClientSession(streams[0], streams[1]) as session:
await session.initialize()
# 列出可用的资源
resources = await session.list_resources()
# 读取特定资源
content = await session.read_resource("example://resource")
# 列出可用的工具
tools = await session.list_tools()
if __name__ == "__main__":
asyncio.run(main()
代码实现MCP客户端,用于连接到MCP服务器并进行通信,详解如下:
- 服务器参数配置。StdioServerParameters定义如何启动和连接MCP服务器的参数,command是要执行的服务器程序路径(可以是可执行文件、Python脚本等),args是传递给服务器程序的命令行参数,这告诉客户端:请执行./server --option value命令来启动MCP服务器。
- stdio_client(params)创建一个通过标准I/O与服务器通信的客户端,自动启动./server --option value进程,并建立与该进程的stdin/stdout管道,返回一个包含两个流的元组:(read_stream, write_stream),async则确保连接正确关闭。
- 创建客户端会话。ClientSession管理客户端与服务器之间的会话,streams[0]是读取流(从服务器接收消息),streams[1],写入流(向服务器发送消息),会话负责消息的序列化、反序列化和分发。
- 初始化会话。session.initialize()执行MCP协议握手,包括向服务器发送初始化请求、协商协议版本、交换能力声明及验证服务器是否兼容等。
客户端启动服务器进程,建立通信管道,初始化请求和响应后便可执行后续请求。
14.3.2 传输层:Streamable HTTP传输
Streamable HTTP即可流式HTTP传输,现版本已取代版本2024-11-05中的HTTP+SSE传输方式。作为MCP主要的传输方式,本小节将详细介绍,内容包括其通信原理、向服务器发送消息并监听来自服务器的消息、可恢复性与消息重传、会话管理与会话时序图、如何选择与自定义传输协议、Streamable HTTP实战。
1. Streamable HTTP传输的通信原理
在Streamable HTTP传输架构中,服务器作为独立进程运行,可处理多个客户端连接。该传输协议采用HTTP的POST与GET请求实现通信,服务器还可以选择性地利用SSE(Server-Sent Events,服务器发送事件)技术实现多路流式传输服务器消息。这一设计既支持基础型MCP服务器,也适用于具备流式传输、server-to-client通知及请求等高级功能的增强型MCP服务器。
服务器必须提供支持POST和GET方法的HTTP端统一路径,一般称为MCP端点,类似URL形式为:https://xxx.com/mcp。实施Streamable HTTP传输时需注意:
- 服务器必须验证所有接入连接的Origin头部,以防范DNS重绑定攻击。
- 本地服务器应仅绑定本地回环地址(127.0.0.1),而非所有网络接口(0.0.0.0)。
- 服务器应对所有连接实施完善的身份验证机制。
若未采取这些防护,攻击者可能通过DNS重绑定技术远程访问本地MCP服务器。
2. 向服务器发送和接受消息
在Streamable HTTP传输模式下,支持有状态和无状态操作模式,支持从事件中恢复连接。另外,Streamable HTTP传输支持多节点部署,可扩展性更好。
客户端向服务器发送消息的要求如下所述:
- 客户端必须使用HTTP POST方式向MCP端点发送JSON-RPC消息。
- 客户端发送的消息必须包含Accept头部,并声明同时支持application/json和text/event-stream两种内容类型。
- POST请求的正文必须是单个JSON-RPC请求、通知或响应。
- 若输入为JSON-RPC通知或响应:
(1)若服务器接受输入,必须返回HTTP状态码:202 Accepted,且不包含正文。
(2)若服务器无法接受输入,必须返回HTTP错误状态码(如400 Bad Request),其响应正文可包含无id的JSON-RPC错误响应。 - 若输入为JSON-RPC请求,服务器必须返回Content-Type: text/event-stream以启动SSE流,或返回Content-Type: application/json以携带单个JSON对象。客户端必须同时支持处理这两种情况。
若服务器启动SSE流:
- SSE流最终应包含针对POST正文中JSON-RPC请求的JSON-RPC响应。
- 服务器在发送JSON-RPC响应之前可发送JSON-RPC请求和通知,这些消息应与原客户端的JSON-RPC请求相关。
- 除非会话过期,服务器在发送完所接收JSON-RPC请求的响应前不应关闭SSE流。发送完JSON-RPC响应后,服务器应关闭SSE流。
- 连接可能随时中断(如因网络状况),因此:
(1)连接中断不应被解读为客户端取消请求。
(2)若需取消,客户端应显式发送一个MCP CancelledNotification。
(3)为避免因连接中断导致消息丢失,服务器应实现可恢复的流传输。
客户端监听来自服务器的消息。客户端既可发送POST消息,也可只发起HTTP GET请求并开始监听来自服务器的消息,处理逻辑如下所述:
- 客户端可向MCP端点发起HTTP GET请求,此操作可用于开启SSE流,使服务器能够发现客户端并与之通信,而无需客户端先通过HTTP POST发送数据。
- 客户端必须包含Accept头部,并声明支持text/event-stream的内容类型。
- 服务器必须针对该HTTP GET请求返回Content-Type: text/event-stream响应以启动SSE流,或返回HTTP 405 Method Not Allowed状态码,表明服务器在此端点不提供SSE流服务。
若服务器启动SSE流:
- 服务器可通过该流发送JSON-RPC请求与通知。
- 这些消息应当与客户端当前正在执行的其它JSON-RPC请求无关。
- 除非正在恢复与先前客户端请求关联的流,否则服务器不得通过由GET请求启动的SSE流发送JSON-RPC响应。
- 服务器可随时关闭SSE流,客户端也可随时关闭SSE流。
关于多路连接,客户端可同时保持多个SSE流的连接状态。服务器中的各个JSON-RPC消息必须仅通过某个已连接流进行发送,即禁止在不同流之间广播相同消息。通过流恢复机制可降低消息丢失风险。
3. 如何选择与示例
Stdio与Streamable HTTP两种传输机制如何选择呢?方案如下:
- 本地通信:对本地进程使用stdio传输,在同机进程间可高效通信并简化进程管理。
- 远程通信:在需要HTTP兼容性的场景中使用Streamable HTTP,另外考虑安全影响,应包括身份验证和授权。
Streamable HTTP传输的示例。对于远程服务器,设置为Streamable HTTP传输,处理客户端请求和服务器到客户端通知,如代码14-3所示:
代码14-3
py
# strem_http_server.py
from mcp.server.fastmcp import FastMCP
# Stateless server (no session persistence)
mcp = FastMCP(name="EchoServer", stateless_http=True)
@mcp.tool(description="A simple echo tool")
def echo(message: str) -> str:
return f"Echo: {message}"
# Run server with streamable_http transport
mcp.run(transport="streamable-http")
对于客户端,同样可以使用Streamable HTTP传输,如代码14-4所示:
代码14-4
# stream_http_client.py
from mcp.client.streamable_http import streamablehttp_client
from mcp import ClientSession
import asyncio
async def main():
# Connect to a streamable HTTP server
async with streamablehttp_client("EchoServer/mcp") as (
read_stream,
write_stream,
_,
):
# Create a session using the client streams
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
tool_result = await session.call_tool("echo", {"message": "hello"})
print(tool_result)
if __name__ == "__main__":
asyncio.run(main())
服务器代码中,首先创建无状态的FastMCP类型的mcp服务器,然后将工具echo绑定到服务器,最后以Streamable HTTP传输机制启动。客户端代码中,首先创建streamablehttp_client类型的客户端并连接到刚创建的服务器EchoServer/mcp,然后根据客户端的读写流创建会话ClientSession,最后调用会话中的服务器工具echo并打印工具执行结果。异步启动主函数。
14.4 配置MCP服务器及其关键特性
本节介绍在启动Gradio应用时,如何构建内置MCP服务器,并介绍Gradio应用与MCP集成的四类关键特性。Gradio 6已支持最新版的MCP(2025-11-25),与Gradio 5有细微差别,本章以Gradio 6为准。
14.4.1 练习13:Gradio配置MCP服务器------字母计数器
使用Gradio应用构建MCP服务器的核心要点:只需在launch()中设置mcp_server=True或设置环境变量GRADIO_MCP_SERVER=True即可。
MCP服务器是一种公开工具的标准方式,以便LLM调用。而工具能为LLM提供其原生不具备的功能,例如生成图像或计算数字的质因数。众所周知,LLM并不擅长统计单词中的字母数量(例如"strawberry"中有多少个"r"),但如果为它们配备工具,就可以轻松实现,下面通过此示例演示Gradio应用如何自动集成MCP服务器。
示例代码及解读 。若尚未配置环境,请安装Gradio的MCP扩展:uv pip install "gradio[mcp]"。同时还需要一个通过MCP协议进行工具调用的LLM应用,即"MCP客户端",例如Claude for Desktop、Cursor或Cline。
下面编写一个简单的Gradio应用来统计单词或句子中的字母数量。创建服务器文件mcp_letter_server.py并录入代码,如代码14-5所示:
代码14-5
py
# mcp_letter_server.py
import gradio as gr
def letter_counter(word: str, letter: str) -> int:
"""Count the number of letters in a word or phrase.
Parameters:
word (str): The word or phrase to count the letters of.
letter (str): The letter to count the occurrences of.
Returns:
str: A message indicating how many times the letter appears"""
return word.count(letter)
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
word = gr.Textbox(label="Word")
letter = gr.Textbox(label="Letter")
btn = gr.Button("Count Letters")
with gr.Column():
count = gr.Number(label="Count")
btn.click(letter_counter, inputs=[word, letter], outputs=count)
demo.launch(mcp_server=True)
请注意这里完成了两个关键步骤:①为函数添加了详细的文档字符注释;设置launch(mcp_server=True)。仅需这些配置,Gradio应用就能作为MCP服务器运行!
运行Gradio并获取MCP端点。当启动该应用时,它将:①启动常规Gradio网页;②启动MCP服务器;③在控制台打印Gradio网页的URL和MCP服务器的URL。通过CLI命令:gradio mcp_letter_server.py启动服务器,控制台输出如下所示:
bash
* Running on local URL: http://127.0.0.1:7860
🔨 Launching MCP server:
* Streamable HTTP URL: http://127.0.0.1:7860/gradio_api/mcp/
MCP服务器的URL即MCP端点。访问MCP端点的URL/sse,则会在浏览器显示session_id和ping信息:
event: endpoint
data: /gradio_api/mcp/messages/?session_id=e1a11e1887144c038374d5c8131174ad
: ping - 2025-10-17 13:07:04.470980+00:00
在Gradio应用集成MCP服务器时,包括四类关键特性:环境变量支持、工具自动转换、文件处理和在Spaces上托管MCP服务器。环境变量支持比较简单,即除了通过启动参数mcp_server=True,还可以通过:set GRADIO_MCP_SERVER=True设置环境变量来集成MCP服务器。下面详细讲述其它三类关键特性。
14.4.2 特性1:函数自动转换为MCP工具
Gradio应用中的每个API端点都会自动转换为MCP服务器工具,并包含对应的名称、描述和输入模式。例如在字母计数示例中,Gradio可自动将letter_counter函数转换为可供LLM使用的MCP工具。该函数名称将作为工具名称,函数的文档字符串与参数类型将分别用于生成工具描述与参数定义。若LLM未对特定输入参数指定数值,输入组件中设置的初始值将作为默认值使用。要查看可用工具及其数据结构,请访问:http://your-server:port/gradio_api/mcp/schema,或点击Gradio页脚的"通过API或MCP使用"→"MCP"。比如字母计数示例中,再选择STDIO传输机制,即可看到被自动转化的函数letter_counter,如图14-5所示:

图14-5
除了作为工具,Gradio应用还会作为MCP服务器提供可用资源和提示,客户端可通过任意传输机制连接到MCP服务器后使用它们。
14.4.3 特性2:文件上传MCP服务器
文件上传MCP服务器的原理 。如果读者曾尝试使用需要文件输入(图像、视频、音频)的远程Gradio MCP服务器,可能会遇到以下错误:
Invalid file data format, provide a url ('http://...' or 'https://...'). Received: /User/shao/Pictures/profile.jpeg
错误原因在于,由于集成MCP的Gradio应用托管在不同机器上,所有输入文件必须通过公共URL才能在远程机器下载。虽然有多种网络托管文件的方法,但它们都需要在工作流程中增加手动操作步骤。而由Gradio构建的MCP服务器可以自动处理文件的数据转换,包括:①处理图像文件并以正确格式返回;②管理临时文件存储。
默认情况下,由Gradio构建的MCP服务器接受输入图像和文件的完整URL。但为方便起见,还额外生成了一个基于STDIO的MCP服务器,可将本地文件上传到任何远程Gradio应用,并返回一个可用于后续工具调用的URL。
使用文件上传MCP服务器 。自5.26.0版本起,Gradio实现了内置MCP服务器,它可将文件上传至正在运行的Gradio应用。若任何工具需要文件输入,在UI页脚的"通过API或MCP使用"可看到MCP客户端的配置代码。以图像滤镜Sepia为例,其MCP客户端的配置代码如图14-6所示:

图14-6
由图14-6可见,启动文件上传MCP服务器的命令需要两个参数:
- 上传文件的目标Gradio应用的URL(或Hugging Face的Space ID),本例中为:http://127.0.0.1:7860/gradio_api/mcp/。
- 允许向服务器上传文件的本地目录路径(<UPLOAD_DIRECTORY>)。出于安全考虑,请将该目录范围设置得尽可能小,以防意外文件上传。
如图中提示,在通过MCP客户端连接服务器前,用户需要先安装UV。连接至上传服务器后,MCP客户端的智能体自行判断何时需要向MCP服务器上传文件。
14.4.4 特性3:在Spaces上托管MCP服务器
将Gradio应用免费部署在Spaces上,从而获得免费的MCP托管服务器。本节讲述如何转换现有Spaces项目以及相应的MCP客户端配置。
转换现有Spaces项目为MCP服务器。需完成以下三个步骤:
- 首先,若非自有Spaces项目请先复制,复制后即可配置MCP服务。若原Spaces项目需GPU加速,请将复制Spaces项目的硬件配置与原Spaces项目保持一致。可选择设为公开或私有Spaces项目,二者均可作为MCP服务器使用。
- 其次,为需要被LLM作为工具调用的函数添加文档字符串。文档字符串格式须与示例代码14-5保持一致。
- 最后,在launch()中添加mcp_server=True参数或设置环境变量set GRADIO_MCP_SERVER=True。
客户端配置公共及私有Spaces应用 。MCP客户端的配置方法,以Spaces项目:abidlabs/mcp-tools🖇️链接14-5为例,只需将该公共Space项目的配置信息添加到MCP客户端,即可立即使用此Spaces项目中的工具集。若使用私有Spaces项目(或ZeroGPU配额的自有Spaces项目),需在请求时提供Hugging Face凭证。具体操作是在配置中添加以下请求头,如下所示:
json
{
"mcpServers": {
"gradio": {
"url": "https://abidlabs-mcp-tools.hf.space/gradio_api/mcp/",
"headers": {
"Authorization": "Bearer <YOUR-HUGGING-FACE-TOKEN>"
}
}
}
}
14.5 项目十一:MCP客户端配置Gradio文档的MCP服务器
有了MCP服务器的URL(即MCP端点),就可以配置客户端参数:使用时将该MCP端点添加到MCP客户端配置中,即可使用服务器的工具集。本节讲述客户端两种传输机制的配置方法,并配置一个Gradio文档功能的MCP服务器。
14.5.1 Gradio文档的MCP服务器
如果在工作流中使用LLM,该服务器将为模型提供精准的Gradio上下文信息,从而显著提升使用效率和流畅度。他运行在Spaces上,完全使用Gradio部署,完整代码参见:gradio/docs-mcp🖇️链接14-6,如代码14-6所示:
代码14-6
py
import gradio as gr
import requests
def load_gradio_docs():
"""Get Gradio's full documentation, example demos, and useful context before answering questions or generating code. Should be used for general questions about core concepts and features of Gradio.
Returns:
str: Gradio's full documentation, example demos, and useful context."""
try:
response = requests.get("https://www.gradio.app/llms.txt")
text = response.text
return text
except Exception as error:
print(f"Error fetching document: {error}")
return f"Error fetching document: {str(error)}"
def search_gradio_docs(query):
"""Run embedding search on Gradio's documentation, guides and demos and return the most relevant useful context before answering questions or generating code. This tool should be used when the user's question is specific to a Gradio demo, docs, or guide. The query should be concise and straightforward, ie: 'how to use the image component' or 'audio component demo', and should not include the word 'Gradio'.
Args:
query (str): The query to search for
Returns:
str: The search results"""
response = requests.post(
"https://playground-worker.pages.dev/api/prompt",
headers={
"Content-Type": "application/json",
"Origin": "https://gradio.app"
},
json={
"prompt_to_embed": query,
"SYSTEM_PROMPT": "$INSERT_GUIDES_DOCS_DEMOS",
"FALLBACK_PROMPT": "No results found"
},
verify=False
)
res = response.json()
return res["SYS_PROMPT"]
css = """#search_results {
background-color: #ffebc3;
padding: 10px;
border-radius: 5px;
}"""
with gr.Blocks(css=css) as demo:
gr.HTML("<center><h1>Gradio Documentation Search</h1></center>")
with gr.Row():
with gr.Column():
load_button = gr.Button("Load Gradio Docs llms.txt")
gr.HTML("<center><h2>OR</h2></center>")
query = gr.Textbox(label="Enter your search query")
search_button = gr.Button("Search by Query")
with gr.Column():
gr.Markdown("### Search results:")
output = gr.Markdown(elem_id="search_results")
load_button.click(load_gradio_docs, outputs=output, queue=False, concurrency_limit=40)
search_button.click(search_gradio_docs, inputs=query, outputs=output)
if __name__ == "__main__":
demo.launch(mcp_server=True, strict_cors=False, max_threads=200)
代码基于Gradio框架构建的文档搜索工具,专门用于查询和检索Gradio框架的官方文档。详细解析如下:
- load_gradio_docs() 。获取完整的 Gradio 文档,请求URL是Gradio官方提供的文档文件,返回完整的文档文本(包含API参考、示例、指南等),回答关于Gradio核心概念和通用功能的问题。
- search_gradio_docs()。基于嵌入向量搜索文档,关键参数包括:①API端点;②请求头,包括内容类型和来源验证;③请求体:用户查询内容、系统提示和无结果时的默认返回。查询时,将输入转换为向量嵌入,在文档库中进行语义相似度搜索,返回最相关的文档片段。适用于具体问题,如"audio component demo"。
- UI界面构建。分两列分别展示操作和结果,设置输出框为Markdown格式并设置CSS样式,加载时最大并发40个请求。
- 启动配置。启用MCP服务器模式,允许其他AI应用通过标准协议调用此服务,支持工具调用和上下文提供。strict_cors=False作用是禁用严格的跨域资源共享限制,允许不同域的应用访问此服务。设置最大线程数为200,支持高并发请求。
当前服务器仅提供两个工具,具体说明如下:
(1)gload_gradio_docs:无需调用参数,将加载最新版Gradio完整文档/llms.txt的格式摘要,为大语言模型在回答问题或生成代码前,提供有价值的上下文解析素材。
(2)search_gradio_docs:需传入查询类参数,通过对Gradio文档、指南和示例进行嵌入式搜索,返回最相关的上下文内容供大语言模型解析。
启动应用,加载页面后输入查询问题,运行界面如图14-7所示:

图14-7
14.5.2 两种传输机制的配置方法
Gradio的MCP服务器支持两种传输机制:Streamable HTTP及Stdio。单击支持MCP服务的Gradio应用页脚的"通过API或MCP使用",可查看MCP服务器支持的传输机制。不同传输机制,MCP客户端配置文件中的配置信息也不同。MCP客户端的配置文件通常为Json格式,以Claude for Desktop为例,其MCP客户端配置文件路径为:%APPDATA%\Claude\claude_desktop_config.json。传输机制对应MCP客户端配置方法如下所述:
(1)Streamable HTTP客户端,将下面配置信息添加到客户端的MCP服务器配置:
json
{
"mcpServers": {
"gradio": {
"url": "http://your-server:port/gradio_api/mcp/"
}
}
}
(2) 对于只支持Stdio的客户端(例如Claude for Desktop),请先安装Node.js,然后将以下信息添加到配置文件中:
json
{
"mcpServers": {
"gradio": {
"command": "npx",
"args": [
"mcp-remote",
"http://your-server:port/gradio_api/mcp/",
"--transport",
"streamable-http"
]
}
}
}
14.5.3 Cursor与Claude配置Gradio文档的MCP服务器
本节将介绍如何通过MCP客户端配置使用官方的Gradio Docs MCP服务器。
Streamable HTTP客户端配置:Cursor 。Cursor是一款由AI驱动的代码编辑器,能够理解开发者的代码库,并通过自然语言帮助开发语言更高效地编写代码,更多信息请参考Cursor官方文档(🖇️链接14-7)。Cursor支持全部传输机制(包括旧版MCP的SSE),下面将分步说明Cursor配置步骤,用户也可以参考Windsurf官方文档(🖇️链接14-8)和Cline官方文档(🖇️链接14-9),它们的设置方式类似。确保使用最新版Cursor,然后如下操作:
(1)前往 Cursor > Cursor Settings> Tools & MCP。
(2)单击 "+ Add Custom MCP"。
(3)对于支持Streamable HTTP传输的MCP服务器,将以下JSON配置粘贴到上一步打开的文件中并保存:
json
{
"mcpServers": {
"server-name": { # Gradio文档MCP服务器,此处改为gradio-docs
"url": "https://gradio-docs-mcp.hf.space/gradio_api/mcp/",
"headers": {
"API_KEY": "value"
}
}
}
}
对于支持Stdio的命令行式的MCP服务器,配置如下:
json
{
"mcpServers": {
"server-name": {
"command": "npx",
"args": ["-y", "mcp-server"],
"env": {
"API_KEY": "value"
}
}
}
}
完成!可能需要单击刷新图标或等待几秒钟,然后用户将在设置页面上看到工具加载完成且状态变为绿色。如图14-8所示:

图14-8
Stdio客户端配置:Claude for Desktop 。对于某些客户端仅支持Stdio通信,如Claude for Desktop,用户需要安装Node.js才能正常使用。确保使用最新版Claude for Desktop🖇️链接14-10,配置步骤如下所示:
(1)前往Claude,左上角单击设置,选择File > Settings > Developer > Edit Config。
(2)用文本编辑器打开配置文件claude_desktop_config.json,保存JSON:
json
{
"mcpServers": {
"gradio-docs": {
"command": "npx",
"args": [
"mcp-remote",
"https://gradio-docs-mcp.hf.space/gradio_api/mcp/",
"--transport",
"streamable-http"
]
}
}
}
完全退出后重新启动Claude for Desktop,或者单击Menu -> Developer -> Reload MCP Configuration。配置正确时,应该在"搜索和工具"栏或"开发人员设置"页面上看到它已加载,如图14-9所示:

图14-9