- Document broken $ref fallback handling - Document .NET-style name sanitization for TypeScript - Add "Tested With" section showing enterprise API support - Add example output from .NET API - Update CLAUDE.md with key features section Co-Authored-By: Claude <noreply@anthropic.com>
343 lines
8 KiB
Markdown
343 lines
8 KiB
Markdown
# swagger-tools
|
|
|
|
MCP (Model Context Protocol) server for parsing, validating, and querying OpenAPI/Swagger specifications.
|
|
|
|
## Features
|
|
|
|
- **Parse** OpenAPI 3.x and Swagger 2.0 specifications
|
|
- **Validate** specs against official schemas with detailed error reporting
|
|
- **Query** endpoints by method, path pattern, tag, or operation ID
|
|
- **Inspect** component schemas with resolved references
|
|
- **Generate** TypeScript interfaces from schemas
|
|
- **Support** both local files and remote URLs
|
|
- **Handle** broken `$ref` pointers gracefully (fallback mode)
|
|
- **Sanitize** .NET-style schema names for valid TypeScript
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
git clone https://git.hyperlocalplatform.com/rimskij/swagger-tools.git
|
|
cd swagger-tools
|
|
npm install
|
|
npm run build
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Claude Code
|
|
|
|
Add to `~/.claude.json`:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"swagger-tools": {
|
|
"command": "node",
|
|
"args": ["/path/to/swagger-tools/dist/index.js"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
Restart Claude Code after configuration.
|
|
|
|
### Other MCP Clients
|
|
|
|
The server uses stdio transport. Run with:
|
|
|
|
```bash
|
|
node /path/to/swagger-tools/dist/index.js
|
|
```
|
|
|
|
Communicate via JSON-RPC 2.0 over stdin/stdout.
|
|
|
|
## Tools
|
|
|
|
### parse-spec
|
|
|
|
Parse an OpenAPI/Swagger spec and return metadata.
|
|
|
|
**Input:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `path` | string | Yes | Path to spec file or URL |
|
|
|
|
**Output:**
|
|
- Version (OpenAPI 3.x or Swagger 2.0)
|
|
- Title and description
|
|
- Server URLs
|
|
- Path count, operation count, schema count
|
|
- Tags
|
|
- Warning if spec has broken `$refs` (parsed without dereferencing)
|
|
|
|
**Example:**
|
|
```
|
|
Parse the OpenAPI spec at ./api.yaml
|
|
```
|
|
|
|
---
|
|
|
|
### validate-spec
|
|
|
|
Validate a spec against the OpenAPI schema.
|
|
|
|
**Input:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `path` | string | Yes | Path to spec file or URL |
|
|
|
|
**Output:**
|
|
- Validation status (pass/fail)
|
|
- Errors with JSON path locations
|
|
- Warnings (missing operationId, missing descriptions)
|
|
|
|
**Example:**
|
|
```
|
|
Validate https://petstore.swagger.io/v2/swagger.json
|
|
```
|
|
|
|
---
|
|
|
|
### query-endpoints
|
|
|
|
Search and filter API endpoints.
|
|
|
|
**Input:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `path` | string | Yes | Path to spec file or URL |
|
|
| `method` | string | No | Filter by HTTP method (GET, POST, etc.) |
|
|
| `pathPattern` | string | No | Regex pattern to match paths |
|
|
| `tag` | string | No | Filter by tag name |
|
|
| `operationId` | string | No | Filter by exact operation ID |
|
|
|
|
**Output:**
|
|
- Matching endpoints with:
|
|
- Method and path
|
|
- Operation ID and summary
|
|
- Tags
|
|
- Parameters (name, location, required, schema)
|
|
- Request body info
|
|
- Response status codes and content types
|
|
|
|
**Examples:**
|
|
```
|
|
Show all GET endpoints in api.yaml
|
|
List endpoints with path matching /users in api.yaml
|
|
Find endpoints tagged "authentication" in api.yaml
|
|
```
|
|
|
|
---
|
|
|
|
### get-schema
|
|
|
|
Get details of a component schema.
|
|
|
|
**Input:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `path` | string | Yes | Path to spec file or URL |
|
|
| `schemaName` | string | Yes | Schema name in components/schemas |
|
|
|
|
**Output:**
|
|
- Schema name and type
|
|
- Description
|
|
- Full JSON schema with resolved $refs
|
|
|
|
**Example:**
|
|
```
|
|
Show the User schema from api.yaml
|
|
```
|
|
|
|
---
|
|
|
|
### generate-types
|
|
|
|
Generate TypeScript interfaces from schemas.
|
|
|
|
**Input:**
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `path` | string | Yes | Path to spec file or URL |
|
|
| `schemas` | string[] | No | Specific schemas (all if omitted) |
|
|
|
|
**Output:**
|
|
- TypeScript interface/type definitions
|
|
- JSDoc comments from descriptions
|
|
- Proper handling of:
|
|
- Required vs optional properties
|
|
- Enums as union types
|
|
- Arrays and nested objects
|
|
- allOf (intersection), oneOf/anyOf (union)
|
|
- additionalProperties as Record<string, T>
|
|
- .NET-style names sanitized to valid TypeScript identifiers
|
|
|
|
**Name Sanitization:**
|
|
| Original | Sanitized |
|
|
|----------|-----------|
|
|
| `Namespace.SubNs.TypeName` | `TypeName` |
|
|
| `GenericType\`1[InnerType]` | `GenericType_InnerType` |
|
|
| `Company.Api.V5.UserViewModel` | `UserViewModel` |
|
|
|
|
**Examples:**
|
|
```
|
|
Generate TypeScript types from api.yaml
|
|
Generate only User and Order types from api.yaml
|
|
```
|
|
|
|
## Supported Formats
|
|
|
|
| Format | Version | File Types |
|
|
|--------|---------|------------|
|
|
| OpenAPI | 3.0.x | .yaml, .yml, .json |
|
|
| OpenAPI | 3.1.x | .yaml, .yml, .json |
|
|
| Swagger | 2.0 | .yaml, .yml, .json |
|
|
|
|
## Input Sources
|
|
|
|
| Source | Example |
|
|
|--------|---------|
|
|
| Local file (relative) | `./api.yaml` |
|
|
| Local file (absolute) | `/path/to/api.yaml` |
|
|
| Remote URL (HTTPS) | `https://example.com/openapi.json` |
|
|
| Remote URL (HTTP) | `http://localhost:3000/api-docs` |
|
|
|
|
## Broken $ref Handling
|
|
|
|
When a spec contains broken `$ref` pointers (e.g., typos in schema names), the parser:
|
|
|
|
1. **Attempts** full dereferencing first
|
|
2. **Falls back** to parsing without dereferencing if refs are broken
|
|
3. **Warns** in output: "Spec has broken $refs. Parsed without dereferencing."
|
|
|
|
This allows you to still extract metadata, query endpoints, and generate types from imperfect specs.
|
|
|
|
## Tested With
|
|
|
|
| API | Stats | Notes |
|
|
|-----|-------|-------|
|
|
| Petstore (Swagger) | 14 paths, 20 ops | Standard test spec |
|
|
| Petstore (OpenAPI 3) | 3 paths, 5 ops | Local fixture |
|
|
| Moravia Symfonie | 293 paths, 381 ops, 185 schemas | Enterprise .NET API with broken $refs |
|
|
|
|
## Architecture
|
|
|
|
```
|
|
src/
|
|
├── index.ts # MCP server entry (stdio transport)
|
|
├── tools/
|
|
│ ├── parse.ts # parse-spec implementation
|
|
│ ├── validate.ts # validate-spec implementation
|
|
│ ├── query.ts # query-endpoints implementation
|
|
│ ├── schema.ts # get-schema implementation
|
|
│ └── generate.ts # generate-types implementation
|
|
├── lib/
|
|
│ ├── parser.ts # SwaggerParser wrapper (with fallback)
|
|
│ ├── validator.ts # Validation logic
|
|
│ └── types.ts # TypeScript type definitions
|
|
└── utils/
|
|
└── format.ts # Output formatting
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
| Package | Purpose |
|
|
|---------|---------|
|
|
| `@modelcontextprotocol/sdk` | MCP server framework |
|
|
| `@apidevtools/swagger-parser` | Parse, validate, dereference specs |
|
|
| `zod` | Input schema validation |
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Build TypeScript
|
|
npm run build
|
|
|
|
# Type check without emit
|
|
npm run typecheck
|
|
|
|
# Run in development (with tsx)
|
|
npm run dev
|
|
```
|
|
|
|
## Testing
|
|
|
|
Manual test with JSON-RPC:
|
|
|
|
```bash
|
|
# List available tools
|
|
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js
|
|
|
|
# Parse a spec
|
|
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"parse-spec","arguments":{"path":"test/fixtures/petstore.yaml"}}}' | node dist/index.js
|
|
|
|
# Test with remote URL
|
|
echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"parse-spec","arguments":{"path":"https://petstore.swagger.io/v2/swagger.json"}}}' | node dist/index.js
|
|
```
|
|
|
|
## Example Output
|
|
|
|
### parse-spec
|
|
|
|
```
|
|
# Pet Store API
|
|
Version: OpenAPI 3.0.3
|
|
Description: A sample Pet Store API
|
|
|
|
## Statistics
|
|
- Paths: 3
|
|
- Operations: 5
|
|
- Schemas: 5
|
|
|
|
## Servers
|
|
- https://api.petstore.example.com/v1
|
|
|
|
## Tags
|
|
- pets
|
|
- store
|
|
```
|
|
|
|
### generate-types
|
|
|
|
```typescript
|
|
/** A pet in the store */
|
|
export interface Pet {
|
|
/** Unique identifier */
|
|
id: number;
|
|
/** Pet name */
|
|
name: string;
|
|
/** Pet availability status */
|
|
status?: 'available' | 'pending' | 'sold';
|
|
tags?: Tag[];
|
|
}
|
|
|
|
/** Pet availability status */
|
|
export type PetStatus = 'available' | 'pending' | 'sold';
|
|
```
|
|
|
|
### generate-types (from .NET API)
|
|
|
|
```typescript
|
|
/** Original: Microsoft.AspNetCore.OData.Results.SingleResult`1[...] */
|
|
export interface SingleResult_JobCommentViewModel {
|
|
queryable?: JobCommentViewModel[];
|
|
}
|
|
|
|
/** Job view model */
|
|
export interface JobViewModel {
|
|
/** The identifier. */
|
|
id?: number;
|
|
/** The name. MaxLength(255) */
|
|
name: string;
|
|
/** The project identifier. */
|
|
projectId: number;
|
|
// ...
|
|
}
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|