如何将普通的HTTP API接口快速变成MCP Server(JTFPM22C17000362)
MCP 协议,全称 「模型上下文协议(Model Context Protocol)」,自 2024 年 11 月发布首个版本以来,虽然问世时间尚短,却已展现出 「出道即巅峰」 的势头。它试图解决的问题并不复杂,但其核心概念和架构设计却让不少初学者感到陌生。本文将以 「如何将普通的 HTTP API 快速转换为 MCP Server」 为切入点,结合实践分享对这一新兴协议的理解。如有不足之处,欢迎批评指正。
如何将普通的 HTTP API 接口快速变成 MCP Server
1. 要理解 MCP Server,就要先理解三种形态的场景
通俗地说,MCP Server 就像是连接大语言模型与外部系统的一座 「标准桥梁」。它定义了一套统一的协议,使得模型能够以标准方式调用数据库、系统接口或各种工具。最关键的一点,它是一种被广泛认可的标准——就像我们熟悉的 Type-C 接口,无论是华为、联想还是苹果的电脑,只要符合这个接口规范,都能即插即用、畅通无阻。MCP 也是如此,为模型和外部世界之间的互动提供了一个 「统一接口」。下面通过具体的表现形态来进一步理解。
1.1 MCP Server 三种形态的理解
现在 MCP Server 提供了三种形态类型,分别是标准输入/输出(stdio)、服务器发送事件(SSE)、可流式传输的 HTTP(StreamableHttp),也正是因为有三种的不同类型,导致其比较难理解的原因。我以比较简洁的方式凸显它们的场景和区别,详细的技术实现网上已经有很多,可以自行查看。
1.1.1 标准输入/输出(stdio)
与 Linux 的管道技术是一样的,它就是以标准输入和输出,连接客户端和 MCP Server,如下图所示:
这种方式的一大特点就是像C/S 架构,代码是运行在客户端本地的,比如就是运行在你自己的电脑,会启动相应的进程。
- 开发者。可以使用 python、NodeJS 等开发运行,按 MCP 协议的规范开发代码,最后以可执行程序或脚本文件,提供给客户端运行,包括 Cline、Cursor、Cherry studio 以及自己开发的智能体等。
- 用户。自己的电脑通过客户端代理用户提交的请求(自然语言),把 MCP Server 提供的工具 tools 说明(包括参数说明)、提示词(可选),加上用户的请求,一同提供给大模型,由大模型决定是否有合适的工具解决用户的问题,如果有就返回给客户端,由客户端调用具体的工具(数据库、服务接口等等)。
- 外部服务。MCP Server 的代码已经包含了如何调用外部服务的功能,以及返回调用结果。所以,这里说的标准输入和输出,指的是 MCP Server 与客户端之间的数据交换用的是 stdio。
这种方式是当前最成熟的方式,很多开源的 MCP Server 都是以这种方式提供对接。这种方式与传统的 C/S 架构的软件一样,更新维护很麻烦。
1.1.2 服务器发送事件(SSE)
这种方式是典型的 B/S 架构,代码是独立运行在服务端,客户端通过 SSE(Server Send Event)协议进行交换数据(最底层还是 HTTP,这里只是弱化了),客户端和服务端一直保持长连接(类似汽车的全时四驱)。可以通过下图对比其中的区别:
使用 SSE(Server-Sent Events)作为 MCP(模型上下文协议,Model Context Protocol)底层通信方式时,虽然实现相对简单,但也存在一些明显问题,主要体现在以下几个方面:
1. 单向通信限制。SSE 仅支持服务器向客户端推送数据,客户端无法主动发送事件,限制了交互的灵活性和实时性,尤其在模型和服务之间需要双向交互的场景中显得力不从心。
2. 并发连接数受限。SSE 基于 HTTP 长连接,不支持复用,浏览器通常对同一源的并发连接数量有限(例如 Chrome 默认最多 6 个),在多模型、多请求并发场景下容易达到瓶颈。
3. 不支持二进制数据。SSE 只能传输 UTF-8 编码的文本,无法直接支持二进制数据传输,不适用于图像、音频或其他非结构化数据的上下文场景,限制了协议在多模态智能体中的扩展能力。
4. 重连和断线恢复机制不够健壮。虽然 SSE 提供了简单的自动重连机制(retry),但对连接中断、消息丢失等异常情况的处理能力较弱,无法确保消息的完整性和顺序性。
5. 缺乏扩展性和标准的认证机制。SSE 本身不包含认证机制,通常需要额外实现,如通过 HTTP Header 携带 token,不如 WebSocket 或 gRPC 在安全和扩展控制方面灵活。
因为其存在比较多的问题,所以还没真正落地使用起来,就要被StreamableHttp取代。所以,大家可以不用管这种方式了,只是知道一下就好了。
1.1.3 可流式传输的 HTTP(StreamableHttp)
这种方式也是B/S 架构,它是 SSE 方式的升级版,将会取代 SSE 的方式。它们的区别如下图所示:
其实最大的区别就是它可以只使用普通的 HTTP 方式进行交互,按需可以使用 SSE 的方式交互(类似汽车的适时四驱)。采用 Streamable HTTP 传输方式相比传统 SSE 有显著优势,主要体现在以下几个核心方面:
1.高可靠性与会话恢复。支持可选 session ID 与 Last-Event-ID,可实现断线重连和断点续传,避免了 SSE 重连后上下文丢失的问题。连接恢复后,服务器可重发客户端可能错过的消息,确保消息完整性。
2.资源利用更高效。无需持续保持长连接,连接仅在需要时建立,降低资源占用。支持连接池和请求批处理机制,可进一步提高吞吐量与并发性能。
3.基础设施兼容性强。采用标准 HTTP,无需特殊配置 SSE 端点,在主流 CDN、负载均衡器、反向代理等标准架构中可无缝集成。REST 风格兼容性好,易于与现有微服务、API 网关集成。
4.实现简单、易维护。将客户端请求和服务器响应集中到一个统一的 /message 端点,开发实践更直观。精简了连接管理逻辑,减少开发和调试复杂度。
5.灵活支持各种部署与扩展。可支持无状态服务部署,如无需会话保存的场景。同时支持有状态部署,适用于需要会话持久化、负载均衡的复杂系统。可按需选用 SSE 流式响应,实现实时进度通知等高级功能。
虽然看上去有很多的优点,但是只能说是设计上很屌的样子,但是这种方式很新,还没很多的落地实践,一切还需要时间来考验。
1.2 MCP Server 有效解决谁来开发的问题
以上是从技术的角度分析了三种方式,主流的做法还是标准输入/输出(stdio)形态,Streamable HTTP 还很新,服务器发送事件(SSE)已经被遗弃。抛开技术的实现,我觉得 MCP Server 解决了谁来开发的问题,如下图所示:
在没有 MCP 的时候,如果智能体要调用外部的服务,通常情况下需要智能体开发者根据服务接口文档,开发连通大模型和服务接口的代码,这个代码一般是在开发在客户端里面,因为不同的客户端(智能体)使用这些服务接口的时候都要针对开发。
有 MCP 的时候,服务接口就可以由服务提供者开发,反正都是 MCP 的标准,智能体开发者直接开发通用的 MCP 客户端代码,就可以直接使用 MCP Server 提供的能力了。
这其实也是为什么 MCP 这么受欢迎的原因。
2. MCP Server 与 Function Calling 的关系是什么
简单来说它们之间没有竞争的关系,Function Calling 是大模型的一种内部实现,MCP Server 提供的 tools,就是提供给 Function Calling 推理时使用的。以下进一步说明它们的关系:
2.1 大模型调用工具的工作原理
明确说一下,当前阶段的大模型并不会真正去调用工具,大模型只是根据提示词,返回能不能调用工具,调用什么工具,以及调用工具传入什么参数。通常有两种方式:
2.1.1 不支持 Function Calling 的大模型,使用纯提示词驱动
关键点是通过提示词来约定输出调用工具的格式,比如输出 JSON 格式或其他,然后在代码进行解析。这样的话每个人写的提示词都很不一样,导致输出很不稳定,容易输出不符合格式要求的内容,需根据模型差异设计提示词,不具备跨模型一致标准。
例如提示词示例:
你是一个智能助手,具备调用天气查询工具的能力。如果用户提出与天气相关
的问题,你需要按照以下格式输出函数调用信息:
函数格式:
get_weather(location="城市名", unit="单位")
说明:
- location 是城市名称,例如 "Beijing"、"London"
- unit 是温度单位,支持 "celsius" 或 "fahrenheit"
请只输出函数调用语句,不要输出任何额外的解释说明或自然语言。
示例:
用户输入:伦敦今天的天气如何?
输出:get_weather(location="London", unit="celsius")
2.1.2 具备 Function Calling 能力的大模型,输出结构化函数调用
关键点是模型本身具备输出标准统一的调用工具的格式,不需要在提示词强调。并且格式稳定(schema 约束),模型解析准确性高。定义 schema 即可,由模型选择调用,无需精细提示设计,各主流模型和平台均支持。模型可自动选择合适工具,支持多轮调用,常用于链式 Agent 和复杂场景。
总之,MCP Server 是提供工具的定义和调用方式作为提示词输入到大模型,大模型输出如何调用工具的格式,由应用解析和实际调用。
3. 普通的 HTTP API 接口快速变成 MCP Server
以下讨论的都是可流式传输的 HTTP(StreamableHttp)形态的方式提供 MCP Server。
3.1 基于 OpenAPI 的规范,提供给 MCP Server 网关
通过 OpenAPI 规范,可以将普通的 HTTP API 快速转换为 MCP Server,使其可以被 MCP Server 网关直接识别和调用。首先,只需为已有的 API 提供标准化的 OpenAPI 描述(如路径、参数、返回结构),MCP Gateway 就能自动生成 MCP-compatible 接口,实现工具自动曝光。这意味着,无需手写适配代码,也不必额外定义 JSON‑RPC schema,几乎 「一步到位」。与此同时,MCP Server 基于 OpenAPI 带来的结构化契约,确保工具调用过程中参数准确、数据格式清晰、运行安全。这种方式绕过了传统提示词驱动中常见的解析失误和格式混乱问题,大大提高了交互的稳定性和开发效率。最后,借助 MCP 与 OpenAPI 的结合,我们实现了 「标准即接口」 的统一原则:任何遵循 OpenAPI 的 REST API,都能立刻成为 MCP Server 的一部分,实现与模型的无缝对接。简而言之,从 HTTP API → OpenAPI 描述 → MCP Server 网关 → 模型调用,整个流程无需冗余代码,是对接大语言模型应用的高效利器。
所以,找一个开源成熟的 MCP Server 网关,就可以快速提供了。
3.2 自行开发一个符合自身业务要求的网关
针对没有 OpenAPI 规范的旧接口,使用 FastMCP 自行开发 MCP Server,让它更符合自身的业务要求,更灵活控制。
目前,FastMCP 是将传统 HTTP API 快速转为 MCP Server 的高效框架之一,封装了协议处理与工具暴露能力。
以下是简单的代码示例:
from fastmcp import FastMCP
import httpx
mcp = FastMCP(name="My Business MCP")
@mcp.tool
async def create_order(item_id: str, quantity: int) -> dict:
"""调用旧系统创建订单"""
async with httpx.AsyncClient() as client:
resp = await client.post(
"https://legacy.api/createOrder",
json={"item": item_id, "qty": quantity},
timeout=5.0,
)
return resp.json()
if __name__ == "__main__":
mcp.run(transport="streamable-http")
这个框架提供了@mcp.tool、@mcp.resource 等注解,直接运行就是一个符合 MCP 协议的服务了。
如果要切换为 stdio、sse 形态的方式,直接 mcp.run(transport=“stdio”) 或 mcp.run(transport=“sse”) 就可以了,非常简洁、简单。
运行:
python mcp_server.py
3.3 MCP Server 的测试工具
可以使用官方提供的 MCP Inspector 工具进行测试,具体教程自行查找。
但是值得一说的是,这个测试工具当前的版本,StreamableHttp 还不支持设置一些自定义的请求头参数,所以说这个东西还非常新,还在发展阶段。
3.4 智能体客户端工具整合 MCP Server
以 Cherry studio 为示例,其他的客户端工具也大同小异,但还真的有点差别。
3.4.1 Cherry studio
示例 JSON(stdio):
{
"mcpServers": {
"stdio-server-example": {
"command": "npx",
"args": ["-y", "mcp-server-example"]
}
}
}
示例 JSON(sse):
{
"mcpServers": {
"sse-server-example": {
"type": "sse",
"url": "http://localhost:3000"
}
}
}
示例 JSON(streamableHttp):
{
"mcpServers": {
"streamable-http-example": {
"type": "streamableHttp",
"url": "http://localhost:3001",
"headers": {
"Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIU"
}
}
}
}
4. 还需要进一步探讨的问题
非本地智能体客户端的服务,如何更好地控制权限
前面讨论的都是本地智能体客户端,如果是通过浏览器访问公共的智能体客户端,权限控制还需要探讨一下。
目前标准输入/输出(stdio)形态,只支持从环境变量获取凭证,基本上在启动运行的时候就固定了。这里主要探讨一下可流式传输的 HTTP(StreamableHttp)的形态。
如下图所示的一个场景:
同一个智能体,用户 A、B 通过浏览器使用独立的会话进行使用,目前 MCP 规范是使用 OAuth 2.1 版本做认证,其推荐 MCP Server 与客户端的认证是独立的,就是跟 MCP Server 与业务系统的认证不是同一套。假设调用业务系统的接口是要使用用户的身份信息来访问,才有对应的权限,怎么通过 MCP Server 传递用户的身份是一个比较麻烦的事情。另外,很多旧的业务系统可能都不支持 OAuth 2.1 版本。下图是一个标准的认证流程:
5. 总结
MCP 协议作为连接大模型与外部世界的关键桥梁,正处于快速演进阶段。从结构设计到通信机制,尤其是基于 Streamable HTTP 的交互模型,虽已具备雏形,但配套工具和标准尚未完全成熟,仍需在可靠性、扩展性等方面持续打磨。在工程实践层面,MCP Streamable HTTP 的推广还面临许多现实挑战,尤其是在模型调用的确定性、安全性与多工具协作流程的稳定性上。更深层次地,大模型 「幻觉」 带来的创造力,既是智能化体验的亮点,也与工程所需的可控性和精确性存在天然冲突。如何在 「确定性与创新性」 之间找到平衡,将是 MCP 未来发展不可回避的课题。