Spec compatibility
What Typeship accepts: Swagger 2.0, OpenAPI 3.0 and 3.1, and GraphQL, and how each construct maps to the generated packages.
Typeship accepts Swagger 2.0, OpenAPI 3.0.x, and OpenAPI 3.1.x as JSON or YAML. OpenAPI 3.2 is not supported yet; export 3.1 instead. Typeship also accepts GraphQL SDL, introspection JSON, and introspectable endpoint URLs. A Spec may be up to 10MB across all of its documents, and its expanded form has further limits listed in Hard limits.
Generation warns about most skipped or approximated details. The exceptions are listed in Dropped without a warning. Resolution fails when:
- the entrypoint is not an API description;
- a referenced document is missing or outside the source boundary;
- the graph exceeds a safety limit; or
- a GraphQL import requires named composition semantics.
Swagger 2.0
2.0 documents are normalized to OpenAPI 3.0 before generation:
host,basePath, andschemesbecome the server URL. https is used when listed or whenschemesis absent.definitionsbecomecomponents.schemas, and sharedparametersandresponsesmove tocomponents.$refpointers are rewritten to their 3.0 locations.bodyparameters become request bodies.formDataparameters become a form-encoded body, or multipart when there are file uploads.- The first
consumesandproducesentry becomes the request and response content type. Putapplication/jsonfirst when an operation offers it. securityDefinitionsbecome security schemes. Basic, apiKey, and oauth2 are mapped, including each OAuth flow's endpoints and scopes.collectionFormatsets how array query parameters are sent.csv, the default, sendsids=1,2;ssvandpipesjoin with spaces or pipes;multirepeats the key (ids=1&ids=2).tsvhas no equivalent and is sent as repeated keys with a warning.
Known limitation: shared body or formData parameters in the top-level parameters section are skipped with a warning, and operations that reference them lose their request body. Inline them in each operation.
References
Local references and multi-document Specs use the same graph loader as Diagnostics, previews, and Generations.
- Repository sources resolve
$refpaths relative to the referring file. A path that leaves the repository is rejected, and an absolutehttps://reference is treated as a missing repository file. - URL sources may reference documents on the same origin as the entrypoint. They reuse the source request headers unless fetching the entrypoint redirected across origins.
- Every cross-origin reference is rejected, including public ones, so Typeship never sends your source credentials to another host. Copy the external document into your repository or onto the same origin.
- A Spec pasted into a request cannot reference other documents. Use a URL or a Project instead.
Cross-document reference cycles are rejected; recursive $refs within one document are allowed. Typeship also limits redirects, document count, reference depth, fetch time, and total bytes. See Hard limits. A change to a referenced file alone creates a Spec Revision and preview.
GraphQL SDL composes whole documents with one #import "./file.graphql" directive per line. See Combine API specs. Named imports such as # import User from "./user.graphql" are rejected, because loading the entire file would produce a different schema than the author requested. Any comment line beginning with # import is read as an import, so reword prose comments that start that way.
GET and HEAD request bodies
Request bodies declared on GET or HEAD operations are dropped, with a warning naming the affected operations. Intermediaries do not reliably transmit GET bodies, so the SDK refuses to expose them.
Server URLs
- The first entry in
serversbecomes the client's default base URL. Server variables are substituted with their declared defaults. - When two or more servers resolve to a URL, the package exports named environments. Each name comes from the server's description, or
server1,server2, and so on when it has none. - A relative server URL (
/v1) or a variable without a default cannot produce a usable base URL. The client is still generated with a warning, and callers must supply the base URL. The TypeScript SDK requiresbaseUrlat construction. The Python and Go SDKs also read an environment variable and return an error when the client is created without either. The CLI takes--base-url, an environment variable, or saved config.
Authentication
Only security schemes referenced by a root or operation security requirement produce client options. A spec with no security requirement anywhere, and no explicit root security: [], gets one generic bearer credential: bearerToken in the SDKs and <PREFIX>_TOKEN in the CLI and MCP server. It is sent as Authorization: Bearer <token> when set and is never required. Declare the real scheme, or add it with a spec patch, to change it.
| Scheme in the spec | TypeScript | Python | Go |
|---|---|---|---|
| HTTP bearer | bearerToken | bearer_token | WithBearerToken |
| HTTP basic | basicAuth | username, password | WithBasicAuth |
| One API key in a header | apiKey | api_key | WithAPIKey |
| API key in a query parameter, or several keys | One option per key, named after its header or parameter | One argument per key, in snake_case | One With<Name> option per key |
| OAuth2 and OpenID Connect | bearerToken, plus refreshToken and clientCredentials for the grants the Spec declares | bearer_token, plus refresh_token and client_credentials | WithBearerToken, plus WithRefreshToken and WithClientCredentials |
| API key in a cookie | Treated as a key in the Cookie header | Same | Same |
Another HTTP scheme, such as Authorization: Token <key> | Treated as a key in the Authorization header | Same | Same |
| Mutual TLS, HTTP Digest, and other challenge-response schemes | Warning, no option | Warning, no option | Warning, no option |
For a cookie key or another HTTP scheme, pass only the credential: the client sends <cookie name>=<value> or <Scheme> <value>. Operations whose every alternative needs mutual TLS, Digest, or an undefined scheme get the openapi.operation.security.scheme_unsupported Diagnostic. Generated CLIs and MCP servers refuse them with NO_AUTH; SDK callers can add the credential through a custom fetch, transport, or WithHTTPClient.
bearerToken takes a token you obtained elsewhere. It serves every HTTP bearer scheme in the spec, since they share one wire format; use named credentials to send a different token to a particular scheme.
A parameter that repeats an operation's credential is left out of generated signatures, CLI flags, and MCP tool input, because the configured credential already reaches the API through the security scheme. Typeship drops a header or query parameter with the same name as the operation's API key scheme, an Authorization header parameter, and a parameter named token, access_token, api_key, or similar whose description says it carries the authentication token. Generation lists the dropped parameters in a warning. Put x-typeship-credential: false on a parameter to keep it, or x-typeship-credential: true to drop one Typeship does not recognize. The config alternative is auth.credential_parameters, and it wins when both are set.
The CLI and MCP server name credential variables after your package. Set x-typeship-env on a security scheme to choose the name instead: a string such as ACME_API_KEY, or { username: ACME_ACCOUNT_SID, password: ACME_AUTH_TOKEN } for Basic. One name on a Basic scheme means its credential is a single API key: the clients take apiKey (api_key, WithAPIKey, --api-key) and send it as the Basic-auth username with an empty password. An invalid value is ignored with a generation warning. The config alternative is auth.credential_variables, and it wins when both are set.
The SDKs offer only the grants the Spec declares; OpenID Connect schemes leave grants to the provider and offer both. clientCredentials runs the client credentials grant against the clientCredentials flow's token URL. refreshToken fits a user-delegated flow such as authorizationCode: pass a refresh token from your own login, and the client exchanges it at the flow's token URL, refreshes before expiry and once after a 401, and reports rotated refresh tokens to onRotate. A token callback passed as bearerToken receives { rejected: true } on the call after a 401 (Python: a rejected keyword argument; Go: CredentialRejected(ctx)). OpenID Connect schemes have no default token URL; pass one explicitly. Each generated method's documentation, the CLI's --help, MCP read_docs and api.md name the OAuth scopes an operation requires, and the CLI and MCP server report a 403 on such an operation as INSUFFICIENT_SCOPE naming them.
Generated CLIs add login when OAuth2 is declared. Customers supply a client ID with --client-id unless one is configured. Each grant reads its endpoints from the flow that uses it, in any order:
- Browser login uses the
authorizationCodeflow's URLs with PKCE, with or without an issuer. Device login is available only when adeviceAuthorizationflow (the OpenAPI 3.2 flow type, also read from 3.0 and 3.1 Specs) or the issuer's metadata supplies a device endpoint. - An OpenID Connect URL ending in
/.well-known/openid-configurationsupplies the issuer, so login opens a browser by default. - Login requests the scopes your operations require from the scheme unless you configure scopes.
Only the first OAuth scheme your operations reference configures login. See login, logout, whoami for the browser and device flows and the settings each needs.
Webhooks
The webhooks section (3.1) and the x-webhooks extension generate typed events and a verifying parser in every SDK. When both are present, webhooks is used. Each webhook needs a request body schema; one without is skipped with a warning. See Webhooks.
Query parameters
Array query parameters follow style and explode. The default, exploded form, repeats the key (ids=1&ids=2). explode: false joins values with commas (ids=1,2), and spaceDelimited and pipeDelimited join them with spaces or pipes. Object values use deep bracket encoding (created[gte]=5).
Bodies and responses
When an operation offers several request content types, Typeship generates the JSON one, or the first when none is JSON.
| Content type | Generated as |
|---|---|
application/json and other JSON types | Typed body, sent as application/json |
application/x-www-form-urlencoded | Typed body, deep bracket encoded |
multipart/form-data | File-path flags in the CLI; local-file paths on the package's local MCP server; typed upload in every SDK. Remote MCP omits it because it cannot read the caller's disk. |
text/* request bodies | A string, sent as text/plain |
| Other request bodies, including XML and binary | Raw bytes: --file in the CLI; a local-file path on the package's local MCP server; a byte upload in every SDK. Remote MCP omits it. |
text/event-stream responses | NDJSON events in the CLI. MCP omits it because one tool call returns one result. Every SDK streams events with an event name, id, and raw data string for you to parse. |
Other text/* responses | A string |
| Other responses | Raw bytes |
Pagination
Next-URL fields, the Link header, cursors, page numbers, and offsets are detected from parameter, response, and header names, including through allOf envelopes. When detection guesses wrong, pin the rule per operation. See Pagination and Pagination rules.
Typeship MCP extensions
Typeship does not require vendor extensions: every setting below also has a project-config path. OpenAPI authors who prefer to keep MCP behavior beside the operation can use two small extensions:
- Put
x-typeship-resolve: { via: listUsers, match: [name, email], id: id }on an ID parameter to accept exact human references.vianames one read collection by operationId,"METHOD /path", generated tool name, or dottedresource.method;matchcontains one to four item fields;iddefaults toid. Setx-typeship-resolve: falseto opt the parameter out. A malformed value is ignored with a generation warning. The equivalent setting ismcp.reference_resolversin Configuration reference, and it wins when both set the same parameter. - Put
x-typeship-me: trueon one GET operation with no arguments to declare the authenticated caller. User-shaped references then accept"me". Any value other thantrue, or a second declaration, is ignored without a warning. The config alternative isauth.identity_verification.operation, which also requires field mappings and makes the CLI verify the signed-in account. See Confirm the signed-in account.
GraphQL
GraphQL supports the same five Targets as OpenAPI: CLI, MCP server, and TypeScript, Python, and Go SDKs.
| Schema construct | Generated behavior |
|---|---|
| Query | Method on client.query (client.Query in Go) |
| Mutation | Method on client.mutation (client.Mutation in Go) |
| Object | Typed result with an optional __typename literal |
| Union or interface | Union of concrete types, discriminated by __typename |
| Subscription | Skipped with a warning |
| Custom scalar | Uses its configured JSON mapping, else a default for well-known names such as DateTime, UUID, and JSON, or remains untyped with a warning |
Operation documents are not an input. Protected endpoints may use write-only source request headers for introspection.
Configure the endpoint and client authentication under GraphQL settings. They default to the introspected URL and bearer authentication. See Generate from GraphQL for selections, pagination, and examples.
Dropped without a warning
These inputs produce no generated code and no warning:
traceoperations.- Operation parameters in a cookie, and parameters missing
nameorin. - Request content types beyond the one generated.
x-webhookswhenwebhooksis also present.
When generation fails
Generation fails when the input cannot describe an API. Examples include empty or unparseable input, an unsupported version, a missing paths object, no GraphQL Query or Mutation fields, or a Spec larger than 10MB. A 3.1 Spec that only describes webhooks still needs paths: {}.
Errors and warnings quotes the common messages and what to do about each.