Swagger MCP Server
by nksmkj7
README.md
# Swagger MCP Server
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that brings OpenAPI/Swagger documentation directly into your AI assistant. Point it at any Swagger/OpenAPI JSON URL and instantly get endpoint discovery, deep inspection, cURL generation, and TypeScript type generation — all inside Cursor or Claude.
---
## Table of Contents
- [Overview](#overview)
- [Features](#features)
- [How It Works](#how-it-works)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Setup in Cursor](#setup-in-cursor)
- [Setup in Claude Desktop](#setup-in-claude-desktop)
- [MCP Inspector (Debug)](#mcp-inspector-debug)
- [Available Tools](#available-tools)
- [Available Prompts](#available-prompts)
- [Typical Workflow](#typical-workflow)
- [Project Structure](#project-structure)
- [Environment Variables](#environment-variables)
- [Troubleshooting](#troubleshooting)
---
## Overview
The Swagger MCP Server acts as a bridge between your AI assistant and any REST API documented with OpenAPI 3.x or Swagger 2.x. Once registered as an MCP server in Cursor or Claude Desktop, it exposes a set of **tools** and **prompts** that let your AI:
- Fetch and cache an OpenAPI spec from a URL
- Browse all available API endpoints grouped by tag
- Inspect full endpoint contracts (parameters, request body, responses) with `$ref` resolution
- Generate ready-to-run `curl` commands with schema-derived sample bodies
- Generate copy-paste TypeScript interfaces and types from response/request schemas
The server runs over **stdio transport** (standard input/output), which is the native transport for MCP in Cursor and Claude Desktop.
---
## Features
| Feature | Description |
|---------|-------------|
| **Spec fetching & caching** | Downloads OpenAPI JSON and caches it locally under `doc/` |
| **Endpoint discovery** | Lists all endpoints grouped by OpenAPI tags |
| **Deep inspection** | Full parameter, request body, and response details with recursive `$ref` resolution |
| **cURL generation** | Executable `curl` commands with placeholder values derived from the schema |
| **TypeScript types** | Generates `interface` or `type` aliases for request/response shapes |
| **Guided prompts** | Step-by-step AI workflow prompts for setup, exploration, implementation, and testing |
| **Multi-project support** | Register multiple API projects and switch between them instantly |
| **Persistent state** | Remembers all registered projects and the active one across server restarts |
---
## How It Works
```
AI Client (Cursor / Claude Desktop)
│
│ stdio (MCP protocol)
▼
swagger-mcp-server (src/server.ts)
│
├── Tools ──► utility + helpers
│ │
│ ▼
│ doc/*.json ← cached OpenAPI spec
│ doc/.project-config.json ← active project state
│
└── Prompts ──► guided AI instructions
```
### First-use flow
1. Call `generate-swagger-json` with a `projectName` and `swaggerUrl`
2. Server fetches the JSON spec, validates it, and saves it under `doc/`
3. A grouped summary (`-grouped.json`) is also saved for fast browsing
4. The project is added to `doc/.project-config.json` and set as active
### Subsequent calls
- All other tools read from the cached spec for the active project — no network calls needed
- State is restored automatically from `doc/.project-config.json` on server start
### Multi-project flow
- Register as many projects as you need — each call to `generate-swagger-json` adds a new entry
- Use `list-projects` to see all registered projects and which is active
- Use `switch-project` to change the active project — all tools immediately use the new project's spec
---
## Prerequisites
- **Node.js** v18 or later
- **npm** v9 or later
- An OpenAPI/Swagger spec accessible at a **direct JSON URL** (not the Swagger UI HTML page)
---
## Installation
```bash
# 1. Clone the repository
git clone https://github.com/your-org/swagger-mcp.git
cd swagger-mcp
# 2. Install dependencies
npm install
# 3. (Optional) copy the env sample
cp .env.sample .env
```
No build step is required for local use — the server runs directly via `tsx`.
To verify the server starts correctly:
```bash
npm start
```
You should see the server start with no errors. Press `Ctrl+C` to stop it.
---
## Setup in Cursor
Cursor supports MCP servers through its **MCP configuration file**. You can configure the Swagger MCP server at either the global level (available in all projects) or the project level.
### Global configuration (recommended)
Open or create the Cursor MCP config file at:
```
~/.cursor/mcp.json
```
Add the following entry under `mcpServers`:
```json
{
"mcpServers": {
"swagger-mcp": {
"command": "node",
"args": [
"/absolute/path/to/swagger/node_modules/tsx/dist/cli.mjs",
"/absolute/path/to/swagger/src/server.ts"
],
"cwd": "/absolute/path/to/swagger"
}
}
}
```
Replace `/absolute/path/to/swagger` with the actual path to this repository. For example:
```json
{
"mcpServers": {
"swagger-mcp": {
"command": "node",
"args": [
"/Users/yourname/projects/swagger/node_modules/tsx/dist/cli.mjs",
"/Users/yourname/projects/swagger/src/server.ts"
],
"cwd": "/Users/yourname/projects/swagger"
}
}
}
```
### Project-level configuration
Create a `.cursor/mcp.json` file in the root of your project with the same structure as above.
### Enabling the server in Cursor
1. Open **Cursor Settings** (`Cmd+,`)
2. Navigate to **Features → MCP**
3. You should see `swagger-mcp` listed — toggle it on
4. Restart Cursor or reload the window (`Cmd+Shift+P` → `Developer: Reload Window`)
### Verifying it works
Open a Cursor chat and type:
```
Use the setup-project prompt to get started
```
Or invoke a tool directly:
```
Call the available-api-endpoints tool
```
If the server is running correctly, the AI will respond with results from your cached API spec.
---
## Setup in Claude Desktop
Claude Desktop uses the same MCP configuration format.
### Locate the config file
| Platform | Path |
|----------|------|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
### Add the server
Open (or create) the config file and add:
```json
{
"mcpServers": {
"swagger-mcp": {
"command": "node",
"args": [
"/absolute/path/to/swagger/node_modules/tsx/dist/cli.mjs",
"/absolute/path/to/swagger/src/server.ts"
],
"cwd": "/absolute/path/to/swagger"
}
}
}
```
### Restart Claude Desktop
Fully quit and reopen Claude Desktop. The MCP server will start alongside it.
### Verifying it works
In a Claude conversation, you can ask:
```
List all available API endpoints
```
Or use a prompt:
```
Use the explore-api prompt
```
Claude will use the `swagger-mcp` tools to answer from your cached spec.
---
## MCP Inspector (Debug)
The MCP Inspector is a browser-based tool for testing MCP servers interactively. It lets you call tools and prompts manually, inspect inputs/outputs, and debug issues.
```bash
npm run inspector
```
This launches the Inspector against the running server. Open the URL shown in the terminal (usually `http://localhost:5173`) and you can:
- Browse all registered tools and prompts
- Fill in arguments and execute tool calls
- See raw JSON responses
---
## Available Tools
Tools are callable functions exposed to the AI. All tools read from the locally cached OpenAPI spec (except `generate-swagger-json` which fetches from the network).
### `generate-swagger-json`
**Must be called first.** Fetches the OpenAPI spec from a URL and caches it locally.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `projectName` | string | Yes | A short name for this API project (e.g. `medex`, `stripe`) |
| `swaggerUrl` | string | Yes | Direct URL to the OpenAPI JSON spec (not the Swagger UI page) |
**Returns:** Saved file paths, API title, version, and total endpoint count.
**Example:**
```
Generate swagger JSON for projectName "myapi" and swaggerUrl "https://api.example.com/api-docs-json"
```
---
### `list-projects`
Lists all API projects that have been registered via `generate-swagger-json`.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| *(none)* | — | — | — |
**Returns:** All projects with their name, JSON URL, saved spec path, registration date, and which is currently active.
---
### `switch-project`
Switches the active API project. All subsequent tool calls will use the newly activated project's spec.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `projectName` | string | Yes | The name of the project to activate (must already be registered) |
**Returns:** Confirmation with the new active project's details.
**Example:**
```
Switch to project "medex"
```
---
### `available-api-endpoints`
Lists all API endpoints grouped by OpenAPI tag.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| *(none)* | — | — | — |
**Returns:** Endpoints grouped by tag with method and path, plus total count.
---
### `endpoint-detail`
Returns the full contract for a specific endpoint: path/query/header parameters, request body schema (with `$ref` resolved), and all response schemas.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path, e.g. `/users/{id}` |
| `method` | string | No | HTTP method (`GET`, `POST`, etc.). If omitted, returns all methods for the path. |
---
### `generate-curl`
Generates a ready-to-run `curl` command for an endpoint. The sample request body is auto-generated from the schema (with placeholder values like `"example@email.com"`, `"uuid-here"`, etc.).
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path |
| `method` | string | Yes | HTTP method |
| `baseUrl` | string | No | Override the base URL (defaults to the spec's server URL) |
| `pathParams` | object | No | Values for path parameters |
| `queryParams` | object | No | Values for query parameters |
| `headers` | object | No | Additional headers |
| `body` | object | No | Override the auto-generated request body |
---
### `generate-typescript-types`
Generates TypeScript `interface` or `type` definitions from an endpoint's schemas.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path |
| `method` | string | Yes | HTTP method |
| `generate` | array | Yes | Which parts to generate: `"requestBody"`, `"queryParams"`, `"pathParams"`, `"response"` |
| `outputStyle` | string | Yes | `"interface"` or `"type"` |
| `responseCodes` | array | No | Specific response codes to include (e.g. `["200", "404"]`). Defaults to all. |
---
## Available Prompts
Prompts are pre-built guided workflows that chain multiple tools together and provide context-aware instructions to the AI.
### `setup-project`
Onboards a new API project. Guides you through calling `generate-swagger-json` and confirms the spec was loaded successfully.
**Arguments:** None
---
### `explore-api`
Browse and summarize available API endpoints. Optionally filter by a specific tag.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `tag` | string | No | Filter endpoints to a specific OpenAPI tag |
---
### `implement-endpoint`
Full implementation workflow for a single endpoint. Chains `endpoint-detail` → `generate-curl` → `generate-typescript-types` and presents everything needed to implement an API call.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path |
| `method` | string | Yes | HTTP method |
---
### `generate-types`
Generates TypeScript types with configurable options.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path |
| `method` | string | Yes | HTTP method |
| `parts` | array | No | Which parts to include (defaults to all) |
| `style` | string | No | `"interface"` or `"type"` (defaults to `"interface"`) |
---
### `test-endpoint`
Generates a `curl` command and a Jest/Vitest test scaffold for an endpoint.
| Argument | Type | Required | Description |
|----------|------|----------|-------------|
| `path` | string | Yes | API path |
| `method` | string | Yes | HTTP method |
---
## Typical Workflow
### 1. Initialize a project
```
Use the setup-project prompt
```
The AI will ask for your project name and Swagger JSON URL, then load and cache the spec.
### 1b. Register additional projects (optional)
```
Generate swagger JSON for projectName "payments-api" and swaggerUrl "https://pay.example.com/api-docs-json"
```
Each call to `generate-swagger-json` adds a new project without removing existing ones.
### 1c. Switch between projects
```
List all my registered projects
```
```
Switch to project "payments-api"
```
### 2. Explore the API
```
Use the explore-api prompt
```
Or filter by tag:
```
Use the explore-api prompt with tag "users"
```
### 3. Deep-dive into an endpoint
```
Use the implement-endpoint prompt with path "/auth/login" and method "POST"
```
This returns the full parameter/body/response contract, a sample curl command, and TypeScript types.
### 4. Generate types only
```
Use the generate-types prompt with path "/users/{id}" method "GET" style "interface"
```
### 5. Scaffold a test
```
Use the test-endpoint prompt with path "/auth/register" method "POST"
```
---
## Project Structure
```
swagger/
├── src/
│ ├── server.ts # MCP server entry point (stdio transport)
│ ├── state/
│ │ └── project.state.ts # In-memory + persisted project config
│ ├── types/
│ │ ├── index.ts # Tool / Prompt characteristic types
│ │ ├── endpoint.types.ts # HTTP / endpoint domain types
│ │ └── openapi.types.ts # OpenAPI spec types + type guard
│ ├── tools/
│ │ ├── generate-swagger-json.tool.ts
│ │ ├── list-projects.tool.ts
│ │ ├── switch-project.tool.ts
│ │ ├── available-endpoints.tool.ts
│ │ ├── endpoint-detail.tool.ts
│ │ ├── generate-curl.tool.ts
│ │ └── generate-typescript-types.tool.ts
│ ├── prompts/
│ │ ├── setup-project.prompt.ts
│ │ ├── explore-api.prompt.ts
│ │ ├── implement-endpoint.prompt.ts
│ │ ├── generate-types.prompt.ts
│ │ └── test-endpoint.prompt.ts
│ ├── helpers/
│ │ ├── endpoint-detail.helper.ts # $ref resolution + endpoint parsing
│ │ ├── curl-builder.helper.ts # curl command generation
│ │ └── typescript-type-builder.helper.ts # JSON Schema → TypeScript
│ └── utility/
│ ├── add-tool-registry.utility.ts
│ ├── add-prompt-registry.utility.ts
│ └── swagger.utility.ts # Fetch, save, load, parse OpenAPI specs
├── doc/
│ ├── .project-config.json # Multi-project registry + active project pointer
│ └── *.json # Cached OpenAPI specs + grouped summaries (gitignored)
├── .env.sample # Environment variable template
├── package.json
└── tsconfig.json
```
---
## Environment Variables
Copy `.env.sample` to `.env`. The variables are optional placeholders for future use — none are required for the server to run.
| Variable | Description |
|----------|-------------|
| `CURSOR_API_KEY` | Reserved for future Cursor integration |
| `DEVELOPMENT_BASE_URL` | Your API's development base URL |
| `STAGING_BASE_URL` | Your API's staging base URL |
| `PRODUCTION_BASE_URL` | Your API's production base URL |
| `SWAGGER_TITLE` | Default API title label |
| `SWAGGER_VERSION` | Default API version label |
| `SWAGGER_DESCRIPTION` | Default API description |
---
## Troubleshooting
### The server doesn't appear in Cursor / Claude
- Verify the **absolute paths** in your MCP config are correct
- Confirm `node_modules` is installed (`npm install`)
- Check that Node.js is accessible at the `command` path — run `which node` to confirm
- Reload Cursor (`Cmd+Shift+P` → `Developer: Reload Window`) or restart Claude Desktop
### `generate-swagger-json` returns an error about HTML
The `swaggerUrl` must point to the **raw JSON spec**, not the Swagger UI page. In Swagger UI, look for a link like `/api-docs-json`, `/openapi.json`, or `/swagger.json` — use that URL, not the browser page URL.
### Tools return "No project configured"
Run `generate-swagger-json` first to initialize a project. Once registered, use `list-projects` to confirm it appears, and `switch-project` to activate it if needed.
### Tools are querying the wrong API
You may have multiple projects registered. Call `list-projects` to check which project is currently active, then call `switch-project` with the correct name.
### State is lost after restart
The server auto-restores state from `doc/.project-config.json` on startup. If this file is missing or corrupted, re-run `generate-swagger-json`.
### MCP Inspector won't connect
Make sure you are not already running `npm start` in another terminal — only one process can hold stdio. Stop any running instance before launching the Inspector.
### TypeScript types are missing fields
Deeply nested `$ref` schemas are resolved up to **10 levels deep** to prevent circular reference loops. If a schema is cut off, it means the nesting exceeds this limit.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues