diff --git a/docs/my-website/docs/mcp_openapi.md b/docs/my-website/docs/mcp_openapi.md
index 0ac90dc12e9..0f18ecc127a 100644
--- a/docs/my-website/docs/mcp_openapi.md
+++ b/docs/my-website/docs/mcp_openapi.md
@@ -1,30 +1,28 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
+import Image from '@theme/IdealImage';
# MCP from OpenAPI Specs
-LiteLLM can automatically convert OpenAPI specifications into MCP servers, exposing any REST API as MCP tools without writing custom MCP server code.
+LiteLLM can convert any OpenAPI/Swagger spec into an MCP server — no custom MCP server code required.
-## Adding an OpenAPI MCP Server
+## Step 1 — Add the MCP Server
-Add your OpenAPI-based MCP server in `config.yaml`:
+Add your OpenAPI-based server in `config.yaml`:
```yaml title="config.yaml" showLineNumbers
mcp_servers:
- # OpenAPI Spec Example - Petstore API
petstore_mcp:
url: "https://petstore.swagger.io/v2"
spec_path: "/path/to/openapi.json"
auth_type: "none"
- # OpenAPI Spec with API Key Authentication
my_api_mcp:
url: "http://0.0.0.0:8090"
spec_path: "/path/to/openapi.json"
auth_type: "api_key"
auth_value: "your-api-key-here"
- # OpenAPI Spec with Bearer Token
secured_api_mcp:
url: "https://api.example.com"
spec_path: "/path/to/openapi.json"
@@ -32,21 +30,117 @@ mcp_servers:
auth_value: "your-bearer-token"
```
+Or from the UI: go to **MCP Servers → Add New MCP Server**, fill in the URL and spec path, and LiteLLM will fetch the spec and load all endpoints as tools.
+
**Configuration parameters:**
| Parameter | Required | Description |
|-----------|----------|-------------|
-| `url` | Yes | Base URL of your API endpoint |
-| `spec_path` | Yes | Path or URL to your OpenAPI spec file (JSON or YAML) |
+| `url` | Yes | Base URL of your API |
+| `spec_path` | Yes | Path or URL to your OpenAPI spec (JSON or YAML) |
| `auth_type` | No | `none`, `api_key`, `bearer_token`, `basic`, `authorization`, `oauth2` |
| `auth_value` | No | Auth value (required if `auth_type` is set) |
-| `description` | No | Optional description for the MCP server |
-| `allowed_tools` | No | List of specific tools to allow |
-| `disallowed_tools` | No | List of specific tools to block |
+| `description` | No | Optional description |
+| `allowed_tools` | No | Allowlist of specific tools |
+| `disallowed_tools` | No | Blocklist of specific tools |
-**Supported OpenAPI versions:** 3.0.x, 3.1.x, Swagger 2.0
+**Supported spec versions:** OpenAPI 3.0.x, 3.1.x, Swagger 2.0. Each operation's `operationId` becomes the tool name — make sure they're unique.
-Each operation's `operationId` becomes the MCP tool name, so make sure your spec has unique `operationId` values.
+Once tools are loaded, you'll see them in the Tool Configuration section:
+
+
+
+
+
+## Step 2 — Optionally Override Tool Names and Descriptions
+
+By default, tool names and descriptions come from the `operationId` and description fields in your spec. You can rename or rewrite them so MCP clients see something cleaner — without touching the upstream spec.
+
+### From the UI
+
+Each tool card has a pencil icon. Click it to open the inline editor:
+
+
+
+
+
+- **Display Name** — overrides the name MCP clients see
+- **Description** — overrides the description MCP clients see
+- Leave a field blank to keep the original from the spec
+
+After setting overrides, a purple **Custom name** badge appears on the tool card:
+
+
+
+
+
+### From the API
+
+Pass `tool_name_to_display_name` and `tool_name_to_description` in the create or update request:
+
+```bash title="Create server with tool name overrides" showLineNumbers
+curl -X POST http://localhost:4000/v1/mcp/server \
+ -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "name": "petstore_mcp",
+ "url": "https://petstore.swagger.io/v2",
+ "spec_path": "/path/to/openapi.json",
+ "tool_name_to_display_name": {
+ "getPetById": "Get Pet",
+ "findPetsByStatus": "List Available Pets"
+ },
+ "tool_name_to_description": {
+ "getPetById": "Look up a pet by its ID",
+ "findPetsByStatus": "Returns all pets matching a given status (available, pending, sold)"
+ }
+ }'
+```
+
+```bash title="Update overrides on an existing server" showLineNumbers
+curl -X PUT http://localhost:4000/v1/mcp/server/{server_id} \
+ -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "tool_name_to_display_name": {
+ "getPetById": "Get Pet"
+ },
+ "tool_name_to_description": {
+ "getPetById": "Look up a pet by its ID"
+ }
+ }'
+```
+
+The map key is the **original `operationId`** from the spec — not the prefixed tool name. LiteLLM strips the server prefix before doing the lookup.
+
+For example, if your server is `petstore_mcp`, the tool is exposed as `petstore_mcp-getPetById`. The map key is still `getPetById`.
+
+**Before and after:**
+
+```
+# Without overrides
+Tool: "petstore_mcp-getPetById"
+Description: "Returns a single pet"
+
+Tool: "petstore_mcp-findPetsByStatus"
+Description: "Finds Pets by status"
+
+# After overrides
+Tool: "Get Pet"
+Description: "Look up a pet by its ID"
+
+Tool: "List Available Pets"
+Description: "Returns all pets matching a given status (available, pending, sold)"
+```
## Using the Server
@@ -76,7 +170,7 @@ async def main():
print(f"Available tools: {[tool.name for tool in tools]}")
response = await client.call_tool(
- name="getpetbyid",
+ name="Get Pet", # overridden name
arguments={"petId": "1"}
)
print(f"Response: {response}")
@@ -123,110 +217,10 @@ curl --location 'https://api.openai.com/v1/responses' \
}
}
],
- "input": "Find all available pets in the petstore",
+ "input": "Find all available pets",
"tool_choice": "required"
}'
```
-
-## Overriding Tool Names and Descriptions
-
-By default, tool names and descriptions come directly from the `operationId` and description fields in your OpenAPI spec. You can override these per-server so MCP clients see friendlier names and clearer descriptions — without touching the upstream spec.
-
-This is useful when:
-- The spec uses machine-generated `operationId` values like `getPetById_v2_deprecated`
-- You want to simplify descriptions for your team
-- You're exposing the same API to multiple audiences with different naming conventions
-
-### Via the UI
-
-When adding or editing an MCP server in the LiteLLM UI, each tool card in the **Tool Configuration** section has a pencil icon. Click it to open an inline edit panel:
-
-- **Display Name** — overrides the tool name shown to MCP clients
-- **Description** — overrides the tool description shown to MCP clients
-
-A purple **Custom name** badge appears on any tool with an active override. Leave a field blank to keep the original value from the spec.
-
-### Via the API
-
-Pass `tool_name_to_display_name` and `tool_name_to_description` when creating or updating an MCP server:
-
-```bash title="Create server with tool overrides" showLineNumbers
-curl -X POST http://localhost:4000/v1/mcp/server \
- -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
- -H "Content-Type: application/json" \
- -d '{
- "name": "petstore_mcp",
- "url": "https://petstore.swagger.io/v2",
- "spec_path": "/path/to/openapi.json",
- "tool_name_to_display_name": {
- "getPetById": "Get Pet",
- "findPetsByStatus": "List Available Pets"
- },
- "tool_name_to_description": {
- "getPetById": "Look up a pet by its ID",
- "findPetsByStatus": "Returns all pets that match the given status (available, pending, sold)"
- }
- }'
-```
-
-```bash title="Update overrides on an existing server" showLineNumbers
-curl -X PUT http://localhost:4000/v1/mcp/server/{server_id} \
- -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
- -H "Content-Type: application/json" \
- -d '{
- "tool_name_to_display_name": {
- "getPetById": "Get Pet"
- },
- "tool_name_to_description": {
- "getPetById": "Look up a pet by its ID"
- }
- }'
-```
-
-### How It Works
-
-The key used in both maps is the **original tool name** from the spec (the `operationId`), not the prefixed name. LiteLLM strips the server prefix before looking up overrides.
-
-For example, if your server is named `petstore_mcp`, the tool is exposed as `petstore_mcp-getPetById`. The map key is still `getPetById`:
-
-```json
-{
- "tool_name_to_display_name": {
- "getPetById": "Get Pet"
- }
-}
-```
-
-After the override, MCP clients will see `"Get Pet"` instead of `"petstore_mcp-getPetById"`.
-
-### Example: Before and After
-
-Admin configures on the `petstore_mcp` server:
-```json
-{
- "tool_name_to_display_name": {
- "getPetById": "Get Pet",
- "findPetsByStatus": "List Available Pets"
- },
- "tool_name_to_description": {
- "getPetById": "Look up a pet by its ID",
- "findPetsByStatus": "Returns all pets matching the given status"
- }
-}
-```
-
-MCP client calls `tools/list` and sees:
-
-```
-Tool: "Get Pet"
-Description: "Look up a pet by its ID"
-
-Tool: "List Available Pets"
-Description: "Returns all pets matching the given status"
-
-Tool: "petstore_mcp-addPet" ← no override, original name shown
-Description: "Add a new pet to the store"
-```
diff --git a/docs/my-website/img/mcp_openapi_custom_name_badge.png b/docs/my-website/img/mcp_openapi_custom_name_badge.png
new file mode 100644
index 00000000000..11f94c1e68c
Binary files /dev/null and b/docs/my-website/img/mcp_openapi_custom_name_badge.png differ
diff --git a/docs/my-website/img/mcp_openapi_tool_edit_panel.png b/docs/my-website/img/mcp_openapi_tool_edit_panel.png
new file mode 100644
index 00000000000..f826fb1f176
Binary files /dev/null and b/docs/my-website/img/mcp_openapi_tool_edit_panel.png differ
diff --git a/docs/my-website/img/mcp_openapi_tools_loaded.png b/docs/my-website/img/mcp_openapi_tools_loaded.png
new file mode 100644
index 00000000000..bb9f6be2719
Binary files /dev/null and b/docs/my-website/img/mcp_openapi_tools_loaded.png differ