OpenAPI Generator
Code generator for creating Tooly packages from OpenAPI specifications
The @tooly/openapi package is a powerful code generator that creates Tooly-compatible packages from OpenAPI specifications. It automatically generates TypeScript tools that integrate with AI SDKs and follow Tooly conventions.
Installation
npm install -g @tooly/openapiQuick Start
Generate a new Tooly package from an OpenAPI specification:
npx @tooly/openapi generate openapi.jsonThis will generate a complete Tooly package with:
- TypeScript types from your OpenAPI schema
- Individual tool files for each API operation
- AI SDK integration
- Proper error handling and validation
Usage
Basic Generation
npx @tooly/openapi generate openapi.jsonWith Options
npx @tooly/openapi generate twitter-api.json \
--package-name twitter \
--auth-type bearer \
--base-url https://api.twitter.com/2 \
--output src \
--verboseOptions
--output, -o
Output directory for generated code (default: src)
--package-name
Package name used for class names and exports. If not provided, it will be inferred from the OpenAPI specification.
--base-url
Base URL for the API. This overrides the URL specified in the OpenAPI spec.
--auth-type
Authentication type for the API:
apikey- API key in Authorization headerbearer- Bearer token in Authorization headerbasic- Basic authenticationoauth2- OAuth2 (requires additional setup)
--verbose, -v
Enable verbose output for debugging
Generated Package Structure
The generator creates a complete package structure following Tooly conventions:
src/
├── tools/
│ ├── index.ts # Tool exports
│ ├── create-user.ts # Individual tool files
│ ├── get-user.ts # (one per API operation)
│ └── update-user.ts
├── handlers.ts # API handler class
├── index.ts # Main exports and AI SDK integration
└── types.ts # Zod schemas and TypeScript typesGenerated Files
types.ts
Contains Zod schemas and TypeScript interfaces generated from your OpenAPI schema definitions:
import { z } from 'zod'
export const UserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
})
export type User = z.infer<typeof UserSchema>handlers.ts
Contains the main handler class with methods for each API operation:
export class TwitterHandler extends BaseToolManager {
async createUser(params: CreateUserParams): Promise<User> {
// Generated API call logic
}
}index.ts
Main entry point with AI SDK integration:
import { TwitterHandler } from './handlers.js'
import { tools } from './tools/index.js'
export function createAITools(apiKey: string) {
return tools(new TwitterHandler(apiKey))
}tools/[operation].ts
Individual tool files for each API operation:
import { tool } from 'ai'
import { z } from 'zod'
export const createUser = (handler: TwitterHandler) =>
tool({
description: 'Create a new user',
parameters: z.object({
name: z.string(),
email: z.string().email(),
}),
execute: async (params) => {
return await handler.createUser(params)
},
})Authentication Support
API Key Authentication
For APIs that use API keys:
npx @tooly/openapi generate api.json --auth-type apikeyGenerated code will include:
export class APIHandler extends BaseToolManager {
constructor(private apiKey: string) {
super()
}
protected getHeaders(): Record<string, string> {
return {
Authorization: `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
}
}
}Bearer Token Authentication
For APIs that use bearer tokens:
npx @tooly/openapi generate api.json --auth-type bearerBasic Authentication
For APIs that use basic authentication:
npx @tooly/openapi generate api.json --auth-type basicOAuth2
For APIs that use OAuth2 (requires additional setup):
npx @tooly/openapi generate api.json --auth-type oauth2Example: Twitter API
Let's create a Twitter API integration:
-
Download the OpenAPI spec:
curl -o twitter-api.json https://api.twitter.com/2/openapi.json -
Generate the package:
npx @tooly/openapi generate twitter-api.json \ --package-name twitter \ --auth-type bearer \ --base-url https://api.twitter.com/2 -
Use in your AI application:
import { createAITools } from './src/index.js' import { generateText } from 'ai' import { openai } from '@ai-sdk/openai' const tools = createAITools(process.env.TWITTER_BEARER_TOKEN!) const result = await generateText({ model: openai('gpt-4.1-nano'), messages: [{ role: 'user', content: 'Post a tweet about AI' }], tools, })
Best Practices
OpenAPI Specification Quality
- Ensure your OpenAPI spec has detailed descriptions for operations and parameters
- Use proper HTTP status codes
- Include examples in your schema definitions
- Validate your OpenAPI spec before generating code
Package Organization
- Keep your OpenAPI spec file in the root of your package
- Use descriptive operation IDs in your OpenAPI spec
- Group related operations with consistent naming
Error Handling
The generated code includes proper error handling:
// Generated error handling
try {
const response = await fetch(url, options)
if (!response.ok) {
throw new Error(`API Error: ${response.status} ${response.statusText}`)
}
return await response.json()
} catch (error) {
throw new Error(`Failed to ${operationId}: ${error.message}`)
}Contributing to Tooly
If you've generated a useful integration, consider contributing it back to the Tooly ecosystem:
- Create a new package in the
packages/directory - Generate the code using
@tooly/openapi - Add proper documentation
- Submit a pull request
Troubleshooting
Generation Errors
Invalid OpenAPI Spec:
Error: Invalid OpenAPI specificationValidate your OpenAPI spec using online validators or swagger-parser.
Missing Operation IDs:
Warning: Operation missing operationId, using generated nameAdd explicit operationId fields to your OpenAPI operations.
Runtime Errors
Authentication Errors:
Error: Unauthorized (401)Verify your API key is correct and has proper permissions.
Network Errors:
Error: Failed to fetchCheck your base URL and ensure the API is accessible.
Advanced Usage
Custom Templates
You can customize the generated code by modifying the Handlebars templates in the templates/ directory:
npx @tooly/openapi generate api.json --templates ./custom-templatesProgrammatic Usage
import { generateFromOpenAPI } from '@tooly/openapi'
await generateFromOpenAPI({
specPath: './openapi.json',
outputDir: './src',
packageName: 'myapi',
authType: 'bearer',
baseUrl: 'https://api.example.com',
})