GUIDE · SPEC READINESS
What a generation-friendly OpenAPI document looks like.
Ajolla can work with imperfect specs — but the quality of the generated SDK, docs, and MCP server is bounded by the quality of the input. This guide is opinionated about the patterns that make Ajolla’s output materially better, and the patterns that quietly degrade it.
At a glance
- Affects SDK quality
- operationIds, request/response schemas, named components, deprecation flags.
- Affects docs quality
- Tag definitions, operation summaries and descriptions, example payloads, security schemes.
- Affects MCP quality
- operationIds (become tool names), descriptions (become tool prompts), method + path (drive safety classification), security.
- Blocks generation
- Unparseable YAML/JSON, external $refs we can’t resolve, missing paths object.
Structure and metadata
- Provide a stable info.title and a semver info.version. Both surface in generated package names and docs.
- List explicit servers entries with absolute URLs. The first server is used as the SDK’s default baseUrl.
- Use product-oriented tags. Generated docs and MCP groupings inherit them; cryptic acronyms become cryptic group names.
- Provide operation summary (one line) and description (a paragraph) on every operation. Both flow through to the docs and to the MCP tool prompt.
yamlopenapi: 3.1.0 info: title: Petstore version: 1.2.0 description: A small API for tracking pets and their owners. servers: - url: https://api.example.com/v1 description: Production
operationId is load-bearing
The operationId drives the SDK method name, the MCP tool name, and the docs anchor. Use predictable, action-led names. Without them, Ajolla synthesizes a name from the method + path, which works but produces brittle identifiers.
yamlpaths: /pets: get: operationId: petsList # → client.pets.list() summary: List pets post: operationId: petsCreate # → client.pets.create() summary: Create a pet /pets/{petId}: get: operationId: petsGet # → client.pets.get(petId) summary: Find pet by ID
Schemas and responses
- Prefer named components.schemas over large inline objects when a shape is reused. Named schemas become reusable types in the SDK.
- Document every status you return — including the error shape. Generated SDKs throw typed errors for any documented non-2xx response.
- Use $ref to share request, response, and error envelopes across operations.
- Avoid additionalProperties: true on payloads — it weakens both the SDK type and the MCP tool input schema.
yamlcomponents: schemas: Pet: type: object required: [id, name] properties: id: { type: string, format: uuid } name: { type: string } tag: { type: string } Error: type: object required: [code, message] properties: code: { type: string } message: { type: string } paths: /pets/{petId}: get: operationId: petsGet responses: "200": description: The pet content: application/json: schema: { $ref: "#/components/schemas/Pet" } "404": description: Not found content: application/json: schema: { $ref: "#/components/schemas/Error" }
Security schemes
- Declare authentication explicitly. Missing security metadata degrades both the SDK’s auth helpers and the MCP safety classification.
- Use one securityScheme per credential surface (bearer token, API key, OAuth flow) and reference it from operations that require auth.
- Mark public operations with security: [] so the SDK can avoid sending the credential for them.
- If your API has admin-only routes, scope them with a separate security requirement; the MCP generator uses that signal to bucket the tools as `admin`.
yamlcomponents: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT security: - bearerAuth: [] paths: /admin/users: delete: operationId: adminUsersDelete summary: Delete a user (admin) security: - bearerAuth: [] x-ajolla-safety: admin # optional hint for the MCP classifier
Operation safety hints
Ajolla’s MCP generator bins each operation into safe, destructive, admin, or disabled. The defaults are method-based (GET / HEAD are safe; DELETE is destructive). You can override with an extension field:
yamlpaths: /pets/{petId}: delete: operationId: petsDelete x-ajolla-safety: destructive /pets: post: operationId: petsCreate x-ajolla-safety: safe # idempotent in our system
Deprecation and breaking changes
- Mark legacy operations with deprecated: true. The endpoint inventory shows them with a warning state and the SDK adds a deprecation marker.
- When a breaking change is shipped, prefer a new operationId over silently changing the shape. Generated SDK consumers should see a renamed method, not a runtime surprise.
- Bump info.version with semver. The SDK’s package version reflects info.version.
Examples
- Add an example or examples block on requestBody and 2xx responses. The docs page renders them inline.
- Make examples illustrative and small. Avoid pasting real customer records.
- Strip secrets out of examples before upload — treat any spec that has ever included a credential as compromised.
Operational hygiene
- Host the spec over HTTPS and pin it by release tag or version, so a re-ingestion is reproducible.
- Validate the spec in CI (e.g. with @apidevtools/swagger-cli) before uploading; Ajolla will degrade gracefully but a CI gate catches drift earlier.
- Regenerate every output after a spec change. Never edit generated files by hand.
- Track the spec revision (commit SHA, release tag) in the consuming repo’s release notes.
Common anti-patterns and the cost
- Missing operationId
- Method names become method+path slugs. Refactors silently rename methods.
- additionalProperties: true
- SDK types become Record<string, unknown>. MCP tool inputs lose validation.
- Inline schemas everywhere
- Repeated shapes become anonymous types; refactoring an envelope means refactoring every operation.
- Undocumented errors
- SDK throws untyped errors; agents using the MCP server can’t reason about failure modes.
- External $refs
- Remote and file $refs are blocked at parse time (security). Inline before upload.
- Wildcard security
- No way to bucket admin tools in MCP. Either restrict the surface or use scope-specific security.
Related guides
- Getting started — From sign-in to downloaded SDK in one session.
- Shipping SDKs and MCP servers — The release checklist for each generated artifact.
- Using the CLI — Drive ingestion + generation from the terminal.