mcpField
O
openapi-codegen

openapi-codegen

github.com/claude-dev-suiteDevelopment4659 installsUpdated 2d ago
Repository

About openapi-codegen

A coding skill that guides TypeScript developers through generating types and API clients from OpenAPI documents, and exporting tRPC routers as OpenAPI. It also covers validation, automation, and common generation pitfalls.

Key features

  1. 01Generate TypeScript types from OpenAPI
  2. 02Generate fetch or axios API clients
  3. 03Customize output with templates
  4. 04Export tRPC routers as OpenAPI
  5. 05Validate and automate generation

Use cases

  1. 01Add typed API contracts to a TypeScript project
  2. 02Generate clients from local or remote specifications
  3. 03Expose tRPC endpoints through an OpenAPI document

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill openapi-codegen

After installing, type/openapi-codegenin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

quick-ref/
openapi-generator.md
openapi-typescript.md
swagger-typescript-api.md
trpc-openapi.md

Details

From the project README

OpenAPI Code Generation Core Knowledge

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: openapi-codegen for comprehensive documentation.

openapi-typescript (Types Only)

Generates TypeScript types from OpenAPI schemas. Lightweight, no runtime.

# Installation
npm install -D openapi-typescript

# Generate types
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts
npx openapi-typescript https://api.example.com/openapi.json -o ./src/types/api.ts
Generated Types Usage
import type { paths, components } from './types/api';

// Schema types
type User = components['schemas']['User'];
type CreateUserDto = components['schemas']['CreateUserDto'];

// Request/Response types
type CreateUserRequest = paths['/users']['post']['requestBody']['content']['application/json'];
type UserResponse = paths['/users/{id}']['get']['responses']['200']['content']['application/json'];
type UsersListResponse = paths['/users']['get']['responses']['200']['content']['application/json'];

// Path parameters
type UserPathParams = paths['/users/{id}']['get']['parameters']['path'];
With openapi-fetch
import createClient from 'openapi-fetch';
import type { paths } from './types/api';

const client = createClient<paths>({
  baseUrl: 'https://api.example.com',
});

// Fully typed requests
const { data, error } = await client.GET('/users/{id}', {
  params: { path: { id: '123' } },
});

const { data } = await client.POST('/users', {
  body: { name: 'John', email: '[email protected]' },
});

// Query parameters
const { data } = await client.GET('/users', {
  params: { query: { status: 'active', page: 1 } },
});

openapi-generator-cli (Full Client)

Generates complete API clients with fetch/axios implementations.

# Installation
npm install -D @openapitools/openapi-generator-cli

# Generate TypeScript Fetch client
npx @openapitools/openapi-generator-cli generate \
  -i openapi.yaml \
  -g typescript-fetch \
  -o ./src/api-client

# Generate TypeScript Axios client
npx @openapitools/openapi-generator-cli generate \
  -i openapi.yaml \
  -g typescript-axios \
  -o ./src/api-client
Configuration File
# openapitools.json
{
  "$schema": "https://raw.githubusercontent.com/OpenAPITools/openapi-generator-cli/master/apps/generator-cli/src/config.schema.json",
  "spaces": 2,
  "generator-cli": {
    "version": "7.0.0",
    "generators": {
      "typescript-client": {
        "generatorName": "typescript-fetch",
        "output": "#{cwd}/src/api-client",
        "inputSpec": "#{cwd}/openapi.yaml",
        "additionalProperties": {
          "supportsES6": true,
          "npmName": "@myorg/api-client",
          "typescriptThreePlus": true,
          "withInterfaces": true
        }
      }
    }
  }
}
Generated Client Usage
import { Configuration, UsersApi } from './api-client';

const config = new Configuration({
  basePath: 'https://api.example.com',
  accessToken: () => localStorage.getItem('token') || '',
});

const usersApi = new UsersApi(config);

// Typed API calls
const users = await usersApi.listUsers({ status: 'active' });
const user = await usersApi.getUserById({ id: '123' });
const newUser = await usersApi.createUser({
  createUserDto: { name: 'John', email: '[email protected]' },
});

swagger-typescript-api

Fast, customizable generator with template support.

# Installation
npm install -D swagger-typescript-api

# Generate
npx swagger-typescript-api -p ./openapi.yaml -o ./src/api -n api.ts
Configuration
npx swagger-typescript-api \
  -p ./openapi.yaml \
  -o ./src/api \
  -n api.ts \
  --axios \                    # Use axios instead of fetch
  --modular \                  # Separate files per tag
  --route-types \              # Generate route types
  --extract-request-body \     # Extract request body types
  --extract-response-body      # Extract response body types
Generated Client Usage
import { Api } from './api/api';

const api = new Api({
  baseUrl: 'https://api.example.com',
  securityWorker: () => ({
    headers: { Authorization: `Bearer ${getToken()}` },
  }),
});

// Typed API calls
const users = await api.users.usersList({ status: 'active' });
const user = await api.users.usersDetail('123');
const newUser = await api.users.usersCreate({
  name: 'John',
  email: '[email protected]',
});

trpc-openapi (Export tRPC as OpenAPI)

Generate OpenAPI spec from tRPC router. Useful for external API consumers.

npm install trpc-openapi
Define OpenAPI Endpoints
import { initTRPC } from '@trpc/server';
import { OpenApiMeta } from 'trpc-openapi';
import { z } from 'zod';

const t = initTRPC.meta<OpenApiMeta>().create();

export const appRouter = t.router({
  getUser: t.procedure
    .meta({
      openapi: {
        method: 'GET',
        path: '/users/{id}',
        tags: ['users'],
        summary: 'Get user by ID',
      },
    })
    .input(z.object({ id: z.string() }))
    .output(z.object({
      id: z.string(),
      name: z.string(),
      email: z.string(),
    }))
    .query(({ input }) => getUserById(input.id)),

  createUser: t.procedure
    .meta({
      openapi: {
        method: 'POST',
        path: '/users',
        tags: ['users'],
        summary: 'Create a new user',
      },
    })
    .input(z.object({
      name: z.string(),
      email: z.string().email(),
    }))
    .output(z.object({
      id: z.string(),
      name: z.string(),
      email: z.string(),
    }))
    .mutation(({ input }) => createUser(input)),
});
Generate OpenAPI Document
import { generateOpenApiDocument } from 'trpc-openapi';
import { appRouter } from './router';

const openApiDocument = generateOpenApiDocument(appRouter, {
  title: 'My API',
  version: '1.0.0',
  baseUrl: 'https://api.example.com',
});

// Save to file
import fs from 'fs';
fs.writeFileSync('./openapi.json', JSON.stringify(openApiDocument, null, 2));
REST Handler
import { createOpenApiNextHandler } from 'trpc-openapi';
import { appRouter } from './router';

// Next.js API route: pages/api/[...trpc].ts
export default createOpenApiNextHandler({
  router: appRouter,
  createContext: () => ({}),
});

Production Readiness

CI/CD Integration
# .github/workflows/generate-client.yml
name: Generate API Client

on:
  push:
    paths:
      - 'openapi.yaml'

jobs:
  generate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Generate types
        run: npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts

      - name: Check for changes
        id: check
        run: |
          if git diff --quiet src/types/api.ts; then
            echo "changed=false" >> $GITHUB_OUTPUT
          else
            echo "changed=true" >> $GITHUB_OUTPUT
          fi

      - name: Commit and push
        if: steps.check.outputs.changed == 'true'
        run: |
          git config --local user.email "[email protected]"
          git config --local user.name "API Generator Bot"
          git add src/types/api.ts
          git commit -m "chore: regenerate API types"
          git push
Package Scripts
{
  "scripts": {
    "generate:types": "openapi-typescript ./openapi.yaml -o ./src/types/api.ts",
    "generate:client": "openapi-generator-cli generate -c openapitools.json",
    "generate:all": "npm run generate:types && npm run generate:client",
    "precommit": "npm run generate:types && git add src/types/api.ts"
  }
}
Watch Mode Development
# openapi-typescript with watch
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts --watch

# Or use nodemon
npx nodemon --watch openapi.yaml --exec "npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts"
Validation Before Generation
# Validate spec first
npx @redocly/cli lint openapi.yaml

# Then generate
npx openapi-typescript ./openapi.yaml -o ./src/types/api.ts
Monitoring Metrics
MetricTarget
Generated type coverage100% of endpoints
Build time with generation< 30s
Type errors after generation0
Spec validation errors0
Checklist
  • OpenAPI spec validation in CI
  • Automated type generation on spec changes
  • Generated code committed or gitignored
  • Version pinned for generator CLI
  • Custom templates documented
  • API client initialization documented
  • Error handling patterns documented
  • Authentication setup in client
  • Breaking change detection
  • Generated code tested

When NOT to Use This Skill

  • Writing OpenAPI specifications (use openapi skill)
  • GraphQL type generation (use graphql-codegen skill)
  • tRPC type-safe APIs (use trpc skill)
  • Manual API client implementation
  • Simple APIs where manual types suffice

Anti-Patterns

Anti-PatternWhy It's BadSolution
Committing generated code to gitMerge conflicts, stale codeAdd to .gitignore, generate in CI/build
Not versioning generator CLIInconsistent outputPin generator versions in package.json
Editing generated files manuallyChanges lost on regenerationExtend or wrap generated code
No validation before generationInvalid types generatedValidate spec with @redocly/cli first
Using different generators across teamType inconsistenciesStandardize on one generator
Generating from remote spec without cachingSlow builds, network dependencyCache spec locally or use schema registry
Not updating on spec changesType/runtime mismatchRun generation in CI on spec updates
Missing error handling in generated codePoor error UXWrap generated client with error handling

Quick Troubleshooting

IssuePossible CauseSolution
Generation failsInvalid OpenAPI specValidate with @redocly/cli lint
Type errors after generationSpec doesn't match APIVerify spec matches actual responses
Missing typesSpec incomplete or refs brokenCheck all $refs resolve, add missing schemas
Wrong HTTP client generatedGenerator config mismatchCheck -g flag or generator setting
Circular reference errorsSelf-referencing schemasUse discriminators or flatten schema
Slow generationLarge spec fileUse spec splitting or partial generation
Auth not workingSecurity scheme not configuredAdd securityWorker or token config
"Cannot find module" errorsGeneration didn't completeCheck for generation errors, rerun
Type conflictsMultiple generators runningUse single generator, remove others

Reference Documentation

Comments

Markdown supported