How to Quickly Transform a Regular HTTP API into an MCP Server

The MCP protocol, short for “Model Context Protocol,” has shown remarkable momentum since the release of its first version in November 2024. Although it has been around for a short time, it has already demonstrated a “peak from the start” trend. The problems it aims to solve are not complex, but its core concepts and architectural design can be unfamiliar to many beginners. This article will explore “how to quickly convert a regular HTTP API into an MCP Server,” sharing practical insights into this emerging protocol. Any shortcomings are welcome for critique.

1. To Understand MCP Server, One Must First Understand Three Types of Scenarios

Simply put, the MCP Server acts as a “standard bridge” connecting large language models with external systems. It defines a unified protocol that allows models to call databases, system interfaces, or various tools in a standardized manner. The most critical point is that it is a widely recognized standard— just like the familiar Type-C interface, which can be used seamlessly across devices from Huawei, Lenovo, or Apple as long as they comply with the interface specifications. The MCP serves as a “unified interface” for interaction between models and the external world. Below, we will further understand this through specific manifestations.

(1) Understanding the Three Forms of MCP Server

Currently, the MCP Server provides three types of forms: Standard Input/Output (stdio), Server-Sent Events (SSE), and Streamable HTTP. The existence of these three different types contributes to its complexity. I will highlight their scenarios and differences in a concise manner; detailed technical implementations are widely available online for further reference.

1. Standard Input/Output (stdio)

This is similar to the pipe technology in Linux, connecting the client and the MCP Server through standard input and output, as shown in the diagram below:

How to Quickly Transform a Regular HTTP API into an MCP Server

A major characteristic of this method is its resemblance to the C/S architecture, where the code runs locally on the client, such as on your own computer, which will start the corresponding process.

  • Developers. They can use Python, NodeJS, etc., to develop code according to the MCP protocol specifications, ultimately providing executable programs or script files for client-side execution, including Cline, Cursor, Cherry Studio, and custom-developed agents.
  • Users. Their computers act as clients that submit requests (in natural language) through a proxy, providing the tools description (including parameter descriptions) and prompts (optional) from the MCP Server along with the user’s request to the large model, which decides whether there are suitable tools to solve the user’s problem. If so, it returns the response to the client, which then calls the specific tools (databases, service interfaces, etc.).
  • External Services. The MCP Server’s code already includes functionality for calling external services and returning the results of those calls.Thus, the standard input and output refer to the data exchange between the MCP Server and the client using StdIO.

This method is currently the most mature, with many open-source MCP Servers providing integration in this manner.However, this method, like traditional C/S architecture software, can be cumbersome to update and maintain..

2. Server-Sent Events (SSE)

This method is a typical B/S architecture, where the code runs independently on the server, and the client exchanges data via the SSE (Server-Sent Events) protocol (which is still fundamentally HTTP, just less emphasized). The client and server maintain a long connection (similar to a full-time four-wheel drive in a car). The differences can be compared in the diagram below:

How to Quickly Transform a Regular HTTP API into an MCP Server

When using SSE (Server-Sent Events) as the underlying communication method for MCP (Model Context Protocol), while the implementation is relatively simple, it has some obvious issues, mainly reflected in the following aspects:

1. Unidirectional Communication Limitations. SSE only supports server-to-client data pushing, and the client cannot actively send events, limiting interaction flexibility and real-time capabilities, especially in scenarios requiring bidirectional interaction between models and services.

2. Limited Concurrent Connections. SSE is based on HTTP long connections and does not support multiplexing. Browsers typically limit the number of concurrent connections to the same origin (e.g., Chrome defaults to a maximum of 6), which can easily reach a bottleneck in multi-model and multi-request concurrent scenarios.

3. No Support for Binary Data. SSE can only transmit UTF-8 encoded text and cannot directly support binary data transmission, making it unsuitable for contexts involving images, audio, or other unstructured data, limiting the protocol’s extensibility in multimodal agents.

4. Weak Reconnection and Disconnection Recovery Mechanisms. Although SSE provides a simple automatic reconnection mechanism (retry), its ability to handle connection interruptions, message loss, and other exceptions is weak, failing to ensure message integrity and order.

5. Lack of Extensibility and Standard Authentication Mechanisms. SSE itself does not include an authentication mechanism and typically requires additional implementation, such as carrying tokens via HTTP headers, which is less flexible than WebSocket or gRPC in terms of security and extensibility.

Due to these issues, it has not yet been widely adopted and is expected to be replaced by StreamableHttp. Therefore, it is sufficient to be aware of this method without needing to focus on it.

3. Streamable HTTP

This method is also a B/S architecture, and it is an upgraded version of the SSE method, which will replace SSE. The differences are illustrated in the diagram below:

How to Quickly Transform a Regular HTTP API into an MCP Server

The main difference is that it can interact using standard HTTP, and optionally use SSE for interaction (similar to a car’s on-demand four-wheel drive). The Streamable HTTP transmission method has significant advantages over traditional SSE, mainly reflected in the following core aspects:

1. High Reliability and Session Recovery. It supports optional session IDs and Last-Event-IDs, enabling reconnection and resuming from breakpoints, avoiding the context loss issues that occur with SSE reconnections. After connection recovery, the server can resend messages that the client may have missed, ensuring message integrity.

2. More Efficient Resource Utilization. There is no need to maintain a long connection continuously; connections are established only when needed, reducing resource consumption. It supports connection pooling and request batching mechanisms, further improving throughput and concurrency performance.

3. Strong Infrastructure Compatibility. It uses standard HTTP, requiring no special configuration for SSE endpoints, allowing seamless integration into mainstream CDNs, load balancers, reverse proxies, and other standard architectures. It has good REST-style compatibility, making it easy to integrate with existing microservices and API gateways.

4. Simple Implementation and Easy Maintenance. It centralizes client requests and server responses to a unified /message endpoint, making development practices more intuitive. It simplifies connection management logic, reducing development and debugging complexity.

5. Flexibly Supports Various Deployments and Extensions. It can support stateless service deployments, such as scenarios that do not require session persistence. It also supports stateful deployments, suitable for complex systems requiring session persistence and load balancing. It can optionally use SSE streaming responses to implement real-time progress notifications and other advanced features.

Although it appears to have many advantages, it can only be said that it looks impressive in design, but this method is still new and lacks extensive practical implementation; everything still needs time to be tested.

(2) The MCP Server Effectively Addresses the Question of Who Develops

The above analysis from a technical perspective covers the three methods, with the mainstream approach still being the standard input/output (stdio) form. Streamable HTTP is still new, while server-sent events (SSE) have already been abandoned. Beyond the technical implementation, I believe the MCP Server addresses the question of who develops, as illustrated in the diagram below:

How to Quickly Transform a Regular HTTP API into an MCP Server

Before MCP, if an agent needed to call external services, typically the agent developer would need to write code to connect the large model and service interface based on the service interface documentation. This code is generally developed within the client, as different clients (agents) need to develop specifically for these service interfaces.

With MCP, service interfaces can be developed by service providers, as they all adhere to the MCP standard, allowing agent developers to directly develop generic MCP client code to utilize the capabilities provided by the MCP Server.

This is actually why MCP is so popular.

2. What is the Relationship Between MCP Server and Function Calling?

In simple terms, there is no competitive relationship between them. Function Calling is an internal implementation of large models, while the tools provided by the MCP Server are used during Function Calling inference. The following further explains their relationship:

The Working Principle of Large Models Calling Tools

To clarify, current large models do not actually call tools; they only return whether they can call tools, which tools to call, and what parameters to pass to those tools based on prompts. There are typically two methods:

1. Large Models Without Function Calling Support, Using Pure Prompt-Driven

How to Quickly Transform a Regular HTTP API into an MCP Server

The key point is to specify the output format for calling tools through prompts, such as outputting in JSON format or others, and then parsing it in the code. This leads to significant variability in the prompts written by different individuals, resulting in unstable outputs that may not meet format requirements, necessitating prompt design based on model differences, lacking a cross-model consistent standard.

For example, a prompt example:

你是一个智能助手,具备调用天气查询工具的能力。 如果用户提出与天气相关的问题,你需要按照以下格式输出函数调用信息: 函数格式: get_weather(location="城市名", unit="单位") 说明: - location 是城市名称,例如 "Beijing"、"London" - unit 是温度单位,支持 "celsius" 或 "fahrenheit" 请只输出函数调用语句,不要输出任何额外的解释说明或自然语言。 示例: 用户输入:伦敦今天的天气如何? 输出:get_weather(location="London", unit="celsius")

2. Large Models with Function Calling Capability, Outputting Structured Function Calls

How to Quickly Transform a Regular HTTP API into an MCP Server

The key point is that the model itself can output a standardized format for calling tools without needing to emphasize it in the prompts. The format is stable (schema constraints), and the model’s parsing accuracy is high. Defining the schema allows the model to choose which tools to call without requiring detailed prompt design, and all mainstream models and platforms support this. The model can automatically select the appropriate tool and support multi-round calls, commonly used in chain agents and complex scenarios.

In summary, the MCP Server provides the definition and calling method for tools as prompt inputs to the large model, and the large model outputs the format for calling tools, which is parsed and executed by the application.

3. Quickly Transforming a Regular HTTP API into an MCP Server

The following discussion focuses on providing the MCP Server in the Streamable HTTP form.

(1) Providing an MCP Server Gateway Based on OpenAPI SpecificationsHow to Quickly Transform a Regular HTTP API into an MCP ServerBy using the OpenAPI specification, a regular HTTP API can be quickly converted into an MCP Server, allowing it to be directly recognized and called by the MCP Server gateway. First, simply provide a standardized OpenAPI description (such as paths, parameters, and return structures) for the existing API, and the MCP Gateway can automatically generate MCP-compatible interfaces, achieving automatic tool exposure. This means there is no need to manually write adaptation code or define JSON-RPC schemas, achieving almost “one-step” integration.At the same time, the structured contract brought by the MCP Server based on OpenAPI ensures that parameters are accurate, data formats are clear, and operations are safe during tool calls. This method bypasses common parsing errors and format confusion found in traditional prompt-driven approaches, significantly improving interaction stability and development efficiency. Finally, with the combination of MCP and OpenAPI, we achieve the unified principle of “standard as interface”: any REST API that follows OpenAPI can immediately become part of the MCP Server, achieving seamless integration with models.In short, the process from HTTP API → OpenAPI description → MCP Server gateway → model call requires no redundant code and is an efficient tool for integrating large language model applications.

Therefore, finding a mature open-source MCP Server gateway can provide a quick solution.

(2) Self-Developing a Gateway That Meets Business Requirements

For legacy interfaces without OpenAPI specifications, use FastMCP to self-develop an MCP Server that better meets business requirements and allows for more flexible control.

Currently, FastMCP is one of the efficient frameworks for quickly converting traditional HTTP APIs into MCP Servers, encapsulating protocol handling and tool exposure capabilities.

Here is a simple code example:

from fastmcp import FastMCP import httpx 
mcp = FastMCP(name="My Business MCP") 
@mcp.tool async def create_order(item_id: str, quantity: int) -> dict: """Call the legacy system to create an order""" 
       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")

This framework provides annotations like @mcp.tool and @mcp.resource, and running it directly creates a service compliant with the MCP protocol.

If you want to switch to stdio or SSE forms, simply use mcp.run(transport=”stdio”) or mcp.run(transport=”sse”) for a very concise and straightforward implementation.

Run:

uvicorn mcp_gateway:app --port 9000

(3) Testing Tools for MCP Server

You can use the official MCP Inspector tool for testing; specific tutorials can be found independently.

How to Quickly Transform a Regular HTTP API into an MCP Server

However, it is worth mentioning that the current version of this testing tool does not support setting some custom request header parameters for StreamableHttp, indicating that this tool is still very new and in development.

(4) Integrating MCP Server with Agent Client Tools

Using Cherry Studio as an example, other client tools are similar but may have some differences.

1. Cherry Studio

Example JSON (stdio): {     "mcpServers": {        "stdio-server-example": {              "command": "npx",              "args": ["-y", "mcp-server-example"]              }      } } 
Example JSON (sse): {      "mcpServers": {           "sse-server-example": {               "type": "sse",               "url": "http://localhost:3000"               }     } } 
Example JSON (streamableHttp): {       "mcpServers": {            "streamable-http-example": {                 "type": "streamableHttp",                 "url": "http://localhost:3001",                 "headers": {                     "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIU"                  }               }        }  }

4. Further Issues to Explore

How to Better Control Permissions for Non-Local Agent Client Services

The previous discussions focused on local agent clients. If accessing public agent clients through a browser, permission control needs further exploration.

Currently, the standard input/output (stdio) form only supports obtaining credentials from environment variables, which are essentially fixed at startup. Here, we mainly discuss the Streamable HTTP form.

As illustrated in the diagram below:

How to Quickly Transform a Regular HTTP API into an MCP ServerIn the same agent, users A and B use independent sessions through the browser. Currently, the MCP specification recommends using OAuth 2.1 for authentication, suggesting that the authentication between the MCP Server and the client should be independent from that between the MCP Server and the business system. Assuming that calling the business system’s interface requires user identity information for access, how to pass user identity through the MCP Server is a relatively complicated issue. Additionally, many legacy business systems may not support OAuth 2.1. The following diagram illustrates a standard authentication process:How to Quickly Transform a Regular HTTP API into an MCP Server

5. Conclusion

The MCP protocol, as a key bridge connecting large models with the external world, is in a phase of rapid evolution. From structural design to communication mechanisms, especially the interaction model based on Streamable HTTP, it has taken shape but still requires further refinement in supporting tools and standards, particularly in terms of reliability and extensibility. In engineering practice, the promotion of MCP Streamable HTTP faces many real challenges, especially regarding the determinism, security, and stability of multi-tool collaboration processes in model calls. More fundamentally, the creativity brought by the “hallucinations” of large models is both a highlight of intelligent experiences and presents a natural conflict with the controllability and precision required in engineering. Finding a balance between “determinism and creativity” will be an unavoidable topic for the future development of MCP.

Leave a Comment