By ChengTan and Wang Chen
Convert existing OpenAPI into MCP Server in batches. This is the latest open-source capability from Higress, helping developers efficiently build MCP Server. [1]
- Relevant Concepts of OpenAPI
- Common Practices for Converting Existing OpenAPI into MCP Server
- Batch Conversion of OpenAPI to MCP Server
- Tuning Configuration for MCP Server
- Conclusion
OpenAPI is written in YAML or JSON and defines a language-agnostic HTTP API interface, providing a unified way to transmit information across all stages of the API life cycle. APIs allow developers to discover and use corresponding services without having to access the source code. For example, a social app wanting to obtain the geographical location information of both parties does not need to build its own Gaode Map or obtain its source code, but can instead receive geographical location information functionality through the Gaode Map API interface.
Classic internet applications such as Gaode Map and Alipay provide API services externally through an open platform. Public cloud services, such as Alibaba Cloud, offer API services to users through OpenAPI Explorer, allowing developers to manage cloud resources, data, and services through these APIs. Additionally, AI large models such as Tongyi, DeepSeek, and OpenAI offer access to large models via APIs. These APIs all comply with the OpenAPI specification; having standards enables efficient collaboration.
MCP allows LLM to access external resources, data, and services in a standardized way. Converting existing OpenAPI into MCP Server is a useful reuse strategy and an economically efficient path that aims to enable external AI applications to invoke your services, thereby enhancing the value of existing services. For instance, Gaode Map provides the capability to convert existing OpenAPI services such as IP positioning and geocoding into MCP Server, allowing external applications to utilize Gaode Map capabilities, thus increasing service activity.
Although MCP has significantly reduced the complexity of accessing and invoking external resources, data, and services for large model applications, if you adopt reuse of existing infrastructure as a development strategy for MCP, you will face a new challenge: converting existing OpenAPI into MCP Server is a "repetitive manual task" that requires daily maintenance, including interface updates and server stability assurances. MCP provides SDK toolkits such as TypeScript and Java for developing MCP Server, exposing existing OpenAPI as regular HTTP services through MCP protocol. This process includes: [1]
tool/list
results to the client.tool/call
, generates the backend HTTP call request using the mapped parameter configuration, Path, backend address, etc., and executes the call. After the call is completed, it wraps the backend call result to return the result for the standard tool/call
interface.go install github.com/higress-group/openapi-to-mcpserver/cmd/openapi-to-mcp@latest
openapi-to-mcp --input path/to/openapi.json --output path/to/mcp-config.yaml
Instructions
--input
: The path to the OpenAPI specification file (in JSON or YAML format), required.--output
: The path for the output MCP configuration file (in YAML format), required.--server-name
: The name of the MCP server, default value is "openapi-server".--tool-prefix
: The prefix for tool names, default value is empty.--format
: Output format (yaml or json), default value is "yaml".--validate
: Whether to validate the OpenAPI specification, default value is false.--template
: The path to the template file used for fixing the output, default value is empty.openapi-to-mcp --input petstore.json --output petstore-mcp.yaml --server-name petstore
This example converts petstore.json
into the petstore-mcp.yaml
file and sets the MCP server name to petstore.
Here is the complete example.
a) Start with an OpenAPI specification (petstore.json):
{
"requestBody": {
"description": "Pet to add to the store",
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "Name of the pet"
},
"tag": {
"type": "string",
"description": "Tag of the pet"
}
}
}
}
}
},
"responses": {
"201": {
"description": "Null response"
}
}
}
},
"/pets/{petId}": {
"get": {
"summary": "Info for a specific pet",
"operationId": "showPetById",
"parameters": [
{
"name": "petId",
"in": "path",
"required": true,
"description": "The id of the pet to retrieve",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Expected response to a valid request",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "Unique identifier for the pet"
},
"name": {
"type": "string",
"description": "Name of the pet"
},
"tag": {
"type": "string",
"description": "Tag of the pet"
}
}
}
}
}
}
}
}
}
}
}
b) Convert it into Higress REST-to-MCP configuration:
openapi-to-mcp --input petstore.json --output petstore-mcp.yaml --server-name petstore
c) Generate petstore-mcp.yaml file:
server:
name: petstore
tools:
- name: showPetById
description: Info for a specific pet
args:
- name: petId
description: The id of the pet to retrieve
type: string
required: true
position: path
requestTemplate:
url: /pets/{petId}
method: GET
responseTemplate:
prependBody: |
# API Response Information
Below is the response from an API call. To help you understand the data, I've provided:
1. A detailed description of all fields in the response structure
2. The complete API response
## Response Structure
> Content-Type: application/json
- **id**: Unique identifier for the pet (Type: integer)
- **name**: Name of the pet (Type: string)
- **tag**: Tag of the pet (Type: string)
## Original Response
- name: createPets
description: Create a pet
args:
- name: name
description: Name of the pet
type: string
required: true
position: body
- name: tag
description: Tag of the pet
type: string
position: body
requestTemplate:
url: /pets
method: POST
headers:
- key: Content-Type
value: application/json
responseTemplate: {}
- name: listPets
description: List all pets
args:
- name: limit
description: How many items to return at one time (max 100)
type: integer
position: query
requestTemplate:
url: /pets
method: GET
responseTemplate:
prependBody: |
# API Response Information
Below is the response from an API call. To help you understand the data, I've provided:
1. A detailed description of all fields in the response structure
2. The complete API response
## Response Structure
> Content-Type: application/json
- **pets**: (Type: array)
- **pets[].id**: Unique identifier for the pet (Type: integer)
- **pets[].name**: Name of the pet (Type: string)
- **pets[].tag**: Tag of the pet (Type: string)
- **nextPage**: URL to get the next page of pets (Type: string)
## Original Response
Note that the tool will automatically set the position field based on the location of each parameter in the OpenAPI specification:
petId
parameter is set to position: path
, as it is defined as in: path
in the OpenAPI specification.limit
parameter is set to position: query
, as it is defined as in: query
in the OpenAPI specification.name
and tag
) are set to position: body
.The MCP server will automatically handle these parameters in the correct position when initiating API requests. For more information on how to use this configuration with Higress REST-to-MCP, please refer to the Higress REST-to-MCP documentation. [2]
Next, we will import the generated file into the Higress console, add the MCP Server plugin, and configure it for use together with Higress.
Example of plugin configuration:
server:
name: "random-user-server"
tools:
- description: "Get random user information"
name: "get-user"
requestTemplate:
method: "GET"
url: "https://randomuser.me/api/"
responseTemplate:
body: |-
# User Information
{{- with (index .results 0) }}
- **Name**: {{.name.first}} {{.name.last}}
- **Email**: {{.email}}
- **Location**: {{.location.city}}, {{.location.country}}
- **Phone**: {{.phone}}
{{- end }}
Note: For the MCP streamable HTTP protocol dated 2025-03-26, this plugin can be used directly without global ConfigMap configuration.
Configure the SSE connection for MCP Server in the AI Agent, taking Cursor as an example:
Database-type MCP Server: Use path + sse_path_suffix configured in ConfigMap
REST API-type MCP Server: Use routing path + sse_path_suffix configured in the console
"mcpServers": {
"postgres": {
"url": "http://your-higress-address/postgres/sse"
},
"rest-api": {
"url": "http://your-higress-address/user/sse"
}
Configuration completed in Cursor:
Through the MCP Server, you can quickly add various data source support for AI agents, improving development efficiency. Any REST API can be transformed into MCP Server with simple configuration without writing additional code.
In the previous chapters, we have learned how the OpenAPI to MCP tool helps us quickly convert existing APIs into tools that can be invoked by AI assistants. This automated conversion greatly improves development efficiency, allowing us to accomplish what would originally take hours or even days in just a few minutes.
However, although the automatically generated configuration is functionally complete, it is often not precise enough. Particularly when APIs return complex data structures, if the configuration is not manually tuned, it may lead to large language models (LLMs) not accurately understanding the data, thus affecting user experience.
Automatically generated MCP configurations usually include all fields returned by APIs and present them in a flat manner. This may be sufficient for simple APIs, but for complex APIs that return a large amount of nested data, it brings several issues:
By manually tuning MCP configurations, we can significantly enhance LLM's understanding of the data returned by APIs, reducing misinterpretations and hallucinations, thereby providing users with more accurate and valuable responses.
Let’s illustrate the importance of MCP configuration tuning through a specific case. Suppose we have a product search API from an e-commerce platform, which returns complex product information laden with technical details.
The configuration automatically generated using the OpenAPI to MCP tool might look like this:
server:
name: ecommerce-api
tools:
- name: searchProducts
description: "Search for products in the e-commerce platform"
args:
- name: query
description: "Search query string"
type: string
required: true
- name: category
description: "Product category"
type: string
required: false
- name: limit
description: "Maximum number of results to return"
type: integer
default: 10
requestTemplate:
url: "https://api.example.com/products/search"
method: GET
argsToUrlParam: true
responseTemplate:
prependBody: |
# Search Results
Below is the API response with these fields:
- **success**: Boolean indicating if the request was successful
- **total**: Total number of matching products
- **page**: Current page number
- **pageSize**: Number of items per page
- **products**: Array of product objects with the following fields:
- **id**: Product unique identifier
- **name**: Product name
- **description**: Product description
- **price**: Product price
- **compareAtPrice**: Original price before discount
- **currency**: Currency code (e.g., USD, EUR)
- **availability**: Product availability status
- **metadata**: Technical metadata
- **attributes**: Product attributes
- **variants**: Product variations
- **images**: Product images
- **categories**: Categories the product belongs to
- **tags**: Product tags
- **brand**: Product brand information
- **shipping**: Shipping information
- **ratings**: Product ratings and reviews
Original response:
When LLM receives API responses under this configuration, it will face the following challenges:
These problems might lead LLM to misinterpret various aspects:
Higress supports fine-tuning request and response templates by combining go template and gjson expressions (for detailed capabilities, please refer to the documentation: https://higress.cn/en/ai/mcp-server ), through careful tuning, we can optimize the configuration as follows:
server:
name: ecommerce-api
tools:
- name: searchProducts
description: "Search for products on the e-commerce platform and return a list of products that match the search criteria, including basic product information, price, stock status, rating, etc."
args:
- name: query
description: "Search keyword, which can be a product name, brand, model, or keywords from the description."
type: string
required: true
- name: category
description: "Product category, for example, 'electronics', 'clothing', 'home', etc."
type: string
required: false
- name: limit
description: "Number of results to return, range from 1 to 50."
type: integer
minimum: 1
maximum: 50
default: 10
requestTemplate:
url: "https://api.example.com/products/search"
method: GET
argsToUrlParam: true
responseTemplate:
body: |
# Product Search Results
Found {{.total}} products matching "{{.query}}". Here are the {{len .products}} most relevant results:
{{range $index, $product := .products}}
## {{add $index 1}}. {{$product.name}}
**Price**: {{if $product.onSale}}~~{{$product.compareAtPrice}} {{$product.currency}}~~ **{{$product.price}} {{$product.currency}}** (Save {{percentage $product.compareAtPrice $product.price}}%){{else}}{{$product.price}} {{$product.currency}}{{end}}
**Brand**: {{$product.brand.name}}
**Stock Status**: {{if eq $product.availability "in_stock"}}In stock{{else if eq $product.availability "low_stock"}}Low stock{{else}}Out of stock{{end}}
{{if gt (len $product.ratings.reviews) 0}}**Rating**: {{$product.ratings.averageRating}}/5 ({{$product.ratings.reviewCount}} reviews){{end}}
{{$product.description | truncate 200 "..."}}
{{if gt (len $product.highlights) 0}}**Product Features**:
{{range $highlight := $product.highlights}}
- {{$highlight}}
{{end}}{{end}}
{{end}}
{{if gt .total (len .products)}}
There are more results not displayed. You can adjust the search criteria for more precise matches.
{{end}}
Here is a real response example for a smart watch product showcasing how the tuned template handles raw data:
# Product Search Results
Found 128 products matching "smartwatch." Here are the 10 most relevant results:
## 1. TechFit Pro Smartwatch
**Price**: ~~1299 CNY~~ **899 CNY** (Save 30.8%)
**Brand**: TechFit
**Stock Status**: In Stock
**Rating**: 4.7/5 (342 reviews)
The TechFit Pro smartwatch features a high-definition color touchscreen, supports heart rate monitoring, blood oxygen detection, multiple sports mode tracking, and sleep analysis. It has a waterproof design with a battery life of up to 7 days.
**Product Features**:
- High-definition AMOLED touchscreen
- Ultra-long battery life of 7 days
- Heart rate and blood oxygen monitoring
- 30 sports modes
- 5ATM waterproof
## 2. FitBit Versa 3
**Price**: 1499 CNY
**Brand**: FitBit
**Stock Status**: In Stock
**Rating**: 4.5/5 (287 reviews)
The FitBit Versa 3 smartwatch integrates GPS positioning and supports 24/7 heart rate monitoring. It has a built-in voice assistant that allows for phone calls, with a battery life of up to 6 days.
**Product Features**:
- Built-in GPS
- Voice assistant functionality
- Call answering capability
- 20+ sports modes
- 50-meter waterproof
## 3. Apple Watch Series 7
**Price**: 2999 CNY
**Brand**: Apple
**Stock Status**: Limited Stock
**Rating**: 4.9/5 (1243 reviews)
The Apple Watch Series 7 features a larger display, faster charging speed, IP6X dust resistance certification, swim-proof design, and provides all-day blood oxygen monitoring and ECG functionality.
**Product Features**:
- Retina-grade OLED display
- Fast charging
- ECG and blood oxygen monitoring
- Fall detection and emergency SOS
- Supports Apple Pay
There are more results not displayed. You can adjust the search criteria to obtain more precise matches.
With this structured response format, LLM can clearly identify each product's key information without being overwhelmed by excessive technical details and raw JSON structures.
Tuned configurations can significantly enhance LLM's data understanding:
Based on the above case, we can extract the following MCP configuration tuning strategies:
The OpenAPI to MCP tool provides us with the ability to quickly convert APIs into AI tools, while manual tuning is a crucial step in enhancing AI understanding and user experience. Through carefully designed response templates, we can guide LLM to more accurately understand the data returned by APIs, reducing misinterpretation and hallucinations, thereby offering users more valuable services.
In practical applications, it is recommended to first use the OpenAPI to MCP tool to generate the basic configuration and then tune it based on the complexity of the API and user needs. For simple APIs, the automatically generated configuration may already be sufficient; however, for complex APIs, particularly those that return large amounts of nested data, manual tuning will significantly enhance the experience.
It should be emphasized that high-quality MCP configuration tuning often relies on data feedback and iterative optimization. A single configuration is unlikely to meet all user scenarios at once, thus requiring a gray testing approach based on multiple configuration versions to create a feedback loop for evaluation and continuous improvement. Higress will combine with the powerful capabilities of the Nacos configuration center to provide more refined configuration management features for MCP server maintainers, including version control, gray publishing, configuration rollback, and effect analysis, making configuration tuning a continuous optimization process driven by data rather than a one-off task.
Through a complete chain of "automatic conversion + manual tuning + data feedback," we can enjoy the efficiency gains brought by automation while ensuring that AI assistants deliver a high-quality user experience, concurrently optimizing configurations based on actual usage data, so that the capabilities of AI assistants continually evolve with use.
Preview: Higress will launch the first MCP Marketplace based on API gateway in the country, including 50 meticulously tuned MCP services.
[1] https://github.com/higress-group/openapi-to-mcpserver
[2] https://mp.weixin.qq.com/s/bgDd82lj0jBUWifLMNByjw
[3] https://higress.cn/en/ai/mcp-quick-start/#configuring-rest-api-mcp-server
Frontline Practice of Implementing a New Paradigm of AI Application Architecture Based on MCP
Nacos-Controller 2.0: Efficiently Manage Your K8s Configuration with Nacos
557 posts | 53 followers
FollowAlibaba Cloud Native Community - May 20, 2025
Alibaba Cloud Native Community - May 21, 2025
Alibaba Cloud Native Community - April 18, 2025
Alibaba Cloud Native Community - May 15, 2025
Alibaba Cloud Native Community - May 23, 2025
Alibaba Cloud Native Community - May 22, 2025
557 posts | 53 followers
FollowAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreMulti-source metrics are aggregated to monitor the status of your business and services in real time.
Learn MoreAccelerate and secure the development, deployment, and management of containerized applications cost-effectively.
Learn MoreLindorm is an elastic cloud-native database service that supports multiple data models. It is capable of processing various types of data and is compatible with multiple database engine, such as Apache HBase®, Apache Cassandra®, and OpenTSDB.
Learn MoreMore Posts by Alibaba Cloud Native Community