docs: update README and CLAUDE.md with new features

- 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>
This commit is contained in:
rimskij 2026-01-12 15:15:34 +01:00
parent 64f7e40ee2
commit 7791adc288
2 changed files with 84 additions and 4 deletions

View file

@ -48,6 +48,28 @@ Restart Claude Code after configuration.
"What does the User schema look like?" "What does the User schema look like?"
``` ```
## Key Features
### Broken $ref Fallback
When specs have broken `$ref` pointers, parser falls back to non-dereferenced mode:
```typescript
// In lib/parser.ts
try {
spec = await SwaggerParser.dereference(specPath); // Try first
} catch {
spec = await SwaggerParser.parse(specPath); // Fallback
}
```
### .NET Name Sanitization
Converts .NET-style schema names to valid TypeScript:
```typescript
// In tools/generate.ts - sanitizeName()
"Namespace.Type" → "Type"
"Generic`1[Inner]" → "Generic_Inner"
"Company.Api.V5.ViewModel" → "ViewModel"
```
## Project Structure ## Project Structure
``` ```
@ -58,9 +80,9 @@ src/
│ ├── validate.ts # validateSpec() → error collection │ ├── validate.ts # validateSpec() → error collection
│ ├── query.ts # queryEndpoints() → filtering logic │ ├── query.ts # queryEndpoints() → filtering logic
│ ├── schema.ts # getSchema() → schema lookup │ ├── schema.ts # getSchema() → schema lookup
│ └── generate.ts # generateTypes() → TS code generation │ └── generate.ts # generateTypes() → TS code generation + sanitizeName()
├── lib/ # Shared utilities ├── lib/ # Shared utilities
│ ├── parser.ts # SwaggerParser.dereference() wrapper │ ├── parser.ts # SwaggerParser wrapper (dereference with fallback)
│ ├── validator.ts # SwaggerParser.validate() wrapper │ ├── validator.ts # SwaggerParser.validate() wrapper
│ └── types.ts # TypeScript interfaces │ └── types.ts # TypeScript interfaces
└── utils/ └── utils/
@ -115,8 +137,14 @@ npm run dev # Run with tsx (hot reload)
# List tools # List tools
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js
# Call a tool # Local spec
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"parse-spec","arguments":{"path":"test/fixtures/petstore.yaml"}}}' | node dist/index.js echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"parse-spec","arguments":{"path":"test/fixtures/petstore.yaml"}}}' | node dist/index.js
# 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
# Enterprise API with broken refs
echo '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"parse-spec","arguments":{"path":"https://projects.moravia.com/api/swagger/v5/swagger.json"}}}' | node dist/index.js
``` ```
## Adding New Tools ## Adding New Tools

View file

@ -10,6 +10,8 @@ MCP (Model Context Protocol) server for parsing, validating, and querying OpenAP
- **Inspect** component schemas with resolved references - **Inspect** component schemas with resolved references
- **Generate** TypeScript interfaces from schemas - **Generate** TypeScript interfaces from schemas
- **Support** both local files and remote URLs - **Support** both local files and remote URLs
- **Handle** broken `$ref` pointers gracefully (fallback mode)
- **Sanitize** .NET-style schema names for valid TypeScript
## Installation ## Installation
@ -66,6 +68,7 @@ Parse an OpenAPI/Swagger spec and return metadata.
- Server URLs - Server URLs
- Path count, operation count, schema count - Path count, operation count, schema count
- Tags - Tags
- Warning if spec has broken `$refs` (parsed without dereferencing)
**Example:** **Example:**
``` ```
@ -167,6 +170,14 @@ Generate TypeScript interfaces from schemas.
- Arrays and nested objects - Arrays and nested objects
- allOf (intersection), oneOf/anyOf (union) - allOf (intersection), oneOf/anyOf (union)
- additionalProperties as Record<string, T> - 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:** **Examples:**
``` ```
@ -191,6 +202,24 @@ Generate only User and Order types from api.yaml
| Remote URL (HTTPS) | `https://example.com/openapi.json` | | Remote URL (HTTPS) | `https://example.com/openapi.json` |
| Remote URL (HTTP) | `http://localhost:3000/api-docs` | | 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 ## Architecture
``` ```
@ -203,7 +232,7 @@ src/
│ ├── schema.ts # get-schema implementation │ ├── schema.ts # get-schema implementation
│ └── generate.ts # generate-types implementation │ └── generate.ts # generate-types implementation
├── lib/ ├── lib/
│ ├── parser.ts # SwaggerParser wrapper │ ├── parser.ts # SwaggerParser wrapper (with fallback)
│ ├── validator.ts # Validation logic │ ├── validator.ts # Validation logic
│ └── types.ts # TypeScript type definitions │ └── types.ts # TypeScript type definitions
└── utils/ └── utils/
@ -244,6 +273,9 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js
# Parse a spec # 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 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 ## Example Output
@ -286,6 +318,26 @@ export interface Pet {
export type PetStatus = 'available' | 'pending' | 'sold'; 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 ## License
MIT MIT