<p align="center">
  <h1 align="center">@vurb/openapi-gen</h1>
  <p align="center">
    <strong>MCP Server Generator from OpenAPI — Vurb.ts</strong> — A framework for creating MCP servers from any REST API<br/>
    OpenAPI 3.x / Swagger 2.0 → complete MCP server in one command · Presenters · PII redaction · Zod schemas
  </p>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@vurb/openapi-gen"><img src="https://img.shields.io/npm/v/@vurb/openapi-gen?color=blue" alt="npm" /></a>
  <a href="https://github.com/vinkius-labs/vurb.ts/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green" alt="License" /></a>
  <img src="https://img.shields.io/badge/node-%3E%3D18-brightgreen" alt="Node" />
  <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-compatible-purple" alt="MCP" /></a>
  <a href="https://vurb.vinkius.com/"><img src="https://img.shields.io/badge/Vurb.ts-framework-0ea5e9" alt="Vurb.ts" /></a>
</p>

---

> **MCP Server Generator from OpenAPI — Vurb.ts**, the Model Context Protocol framework for building production MCP servers. Parse any **OpenAPI 3.x** or **Swagger 2.0** spec and generate a **complete, ready-to-run MCP Server** — with Presenters, Tools, ToolRegistry, and server bootstrap. All features configurable via YAML.

## What It Generates

```
output/
├── models/                # M — Zod schemas (data boundary)
│   ├── pet.schema.ts
│   └── store.schema.ts
├── views/                 # V — createPresenter() (perception layer)
│   ├── pet.presenter.ts
│   └── store.presenter.ts
├── agents/                # A — Agent layer — defineTool()
│   ├── pet.tool.ts
│   └── store.tool.ts
├── server.ts              # MCP Server bootstrap
└── index.ts               # ToolRegistry + registerAll barrel
```

Every file follows the **MVA Convention** — the standard directory structure for Vurb.ts projects.

## Quick Start

```bash
# 1. Generate from OpenAPI spec
npx openapi-gen --input ./petstore.yaml --output ./generated

# 2. Run the generated server
API_BASE_URL=https://api.example.com npx tsx ./generated/server.ts
```

## Configuration

Create an `openapi-gen.yaml` file in your project root:

```yaml
input: ./specs/petstore.yaml
output: ./generated

features:
  tags: true              # Add tags to tools
  annotations: true       # Infer readOnly, destructive, idempotent from HTTP method
  presenters: true        # Generate Presenter files with response schemas
  descriptions: true      # Include summaries/descriptions on actions
  serverFile: true        # Generate server.ts bootstrap
  deprecated: comment     # 'include' | 'skip' | 'comment'

naming:
  style: snake_case       # 'snake_case' | 'camelCase'
  deduplication: true     # Auto-suffix duplicates

server:
  name: petstore-mcp
  version: 1.0.0
  transport: stdio        # 'stdio' | 'sse'
  toolExposition: flat    # 'flat' | 'grouped'
```

## CLI Options

| Flag | Description | Default |
|------|-------------|---------|
| `--input <path>` | Path to OpenAPI YAML/JSON spec | From config |
| `--output <dir>` | Output directory | `./generated` |
| `--config <path>` | Path to config file | Auto-detect |
| `--base-url <expr>` | Base URL expression for fetch calls | `ctx.baseUrl` |
| `--server-name <name>` | MCP Server name | `openapi-mcp-server` |
| `--context <import>` | Custom context type import | Default `ApiContext` |

## Programmatic API

```typescript
import { parseOpenAPI, mapEndpoints, emitFiles, mergeConfig } from '@vurb/openapi-gen';

const spec = parseOpenAPI(yamlString);
const mapped = mapEndpoints(spec);
const config = mergeConfig({ features: { tags: true }, includeTags: ['pet'] });
const files = emitFiles(mapped, config);

for (const file of files) {
    writeFileSync(`./out/${file.path}`, file.content);
}
```

## Swagger 2.0 Support

Swagger 2.0 specs are **automatically detected and converted** to OpenAPI 3.0 internally. No extra configuration needed — just point to your spec:

```bash
# Works with Swagger 2.0 specs out of the box
npx openapi-gen --input ./petstore-v2.json --output ./generated
```

The converter handles:

| Swagger 2.0 | → OpenAPI 3.0 |
|---|---|
| `host` + `basePath` + `schemes` | `servers` array |
| `definitions` | `components.schemas` |
| `parameters[in: body]` | `requestBody` |
| `parameters[in: formData]` | `requestBody` (multipart) |
| `#/definitions/Pet` | `#/components/schemas/Pet` |
| `produces` / `consumes` | Per-operation `content` types |

Runtime mode (`loadOpenAPI()`) also accepts Swagger 2.0:

```typescript
import { loadOpenAPI } from '@vurb/openapi-gen';

// Swagger 2.0 JSON — auto-converted internally
const tools = loadOpenAPI(swagger2Json, { baseUrl: 'https://petstore.swagger.io/v2' });
registry.registerAll(...tools);
```

## Pipeline

```
OpenAPI 3.x / Swagger 2.0 Spec (YAML/JSON)
        │
        ▼
  ┌──────────────────┐
  │ Swagger2Converter │  → Auto-detect & convert 2.0 → 3.0 (if needed)
  └──────────────────┘
        │
        ▼
  ┌─────────────┐
  │ OpenApiParser │  → ApiSpec IR (groups, actions, params, responses)
  └─────────────┘
        │
        ▼
  ┌───────────────┐
  │ EndpointMapper │  → Named actions (snake_case), dedup, annotations
  └───────────────┘
        │
        ▼
  ┌────────────┐
  │ CodeEmitter │  → TypeScript files (Presenters, Tools, Registry, Server)
  └────────────┘
```

## Installation

```bash
npm install @vurb/openapi-gen
```

### Peer Dependencies

| Package | Version |
|---------|---------|
| `vurb` | `^2.0.0` |
| `zod` | `^3.25.1 \|\| ^4.0.0` |

## Requirements

- **Node.js** ≥ 18.0.0
- **Vurb.ts** ≥ 2.0.0 (peer dependency)

## License

[Apache-2.0](https://github.com/vinkius-labs/vurb.ts/blob/main/LICENSE)
