mcp-from-openapi 2.5.1 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lint.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import type { OpenAPIDocument } from './types';
2
+ export type LintSeverity = 'error' | 'warning' | 'info';
3
+ /**
4
+ * One agent-readiness finding. `path` names the operation (`GET /users`);
5
+ * `hint` says how to fix it — in the spec or via generate options/overlays.
6
+ */
7
+ export interface LintFinding {
8
+ severity: LintSeverity;
9
+ /** Stable kebab-case finding code */
10
+ code: string;
11
+ message: string;
12
+ path: string;
13
+ hint?: string;
14
+ }
15
+ export interface LintResult {
16
+ /** Sorted: errors first, then warnings, then infos; by path within each */
17
+ findings: LintFinding[];
18
+ counts: {
19
+ error: number;
20
+ warning: number;
21
+ info: number;
22
+ };
23
+ }
24
+ /** Query-parameter names that read as pagination controls (shared with response hints) */
25
+ export declare const PAGINATION_PARAM: RegExp;
26
+ /**
27
+ * Lint an OpenAPI document for agent-readiness: the spec-quality gaps that
28
+ * measurably degrade tool-calling accuracy (missing operationIds, absent or
29
+ * vague descriptions, unpaginated list endpoints, oversized schemas, missing
30
+ * examples). Small spec fixes routinely take tool-call success rates from
31
+ * mediocre to near-perfect — each finding carries a concrete hint.
32
+ */
33
+ export declare function lintDocument(document: OpenAPIDocument): LintResult;
package/overlay.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * A single Overlay action (OpenAPI Overlay Specification 1.0.0).
3
+ */
4
+ export interface OverlayAction {
5
+ /** JSONPath expression selecting the nodes to act on (see supported subset below) */
6
+ target: string;
7
+ /** Human note; ignored by the processor */
8
+ description?: string;
9
+ /**
10
+ * Value merged into each matched node: objects deep-merge, arrays append
11
+ * the value, primitives are replaced.
12
+ */
13
+ update?: unknown;
14
+ /** Remove each matched node from its parent instead of updating */
15
+ remove?: boolean;
16
+ }
17
+ /**
18
+ * An OpenAPI Overlay document. Applied to specs at load time (before
19
+ * dereferencing and validation), overlays keep spec curation — agent-tuned
20
+ * descriptions, `x-mcp` flags — in a small separate file that survives every
21
+ * regeneration of the source spec.
22
+ */
23
+ export interface OverlayDocument {
24
+ /** Overlay Specification version (1.x) */
25
+ overlay: string;
26
+ info?: {
27
+ title?: string;
28
+ version?: string;
29
+ };
30
+ /** URL of the spec this overlay targets; informational here */
31
+ extends?: string;
32
+ actions: OverlayAction[];
33
+ }
34
+ /**
35
+ * Apply an OpenAPI Overlay 1.0 document to a spec, returning a NEW document
36
+ * (the input is never mutated). Actions run in order; targets that match
37
+ * nothing are skipped silently, per the Overlay specification.
38
+ *
39
+ * Update semantics: object targets deep-merge the update, array targets
40
+ * append it, primitive targets are replaced. `remove: true` deletes matched
41
+ * nodes (array elements are spliced, preserving order).
42
+ */
43
+ export declare function applyOverlay<T extends object>(document: T, overlay: OverlayDocument): T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-from-openapi",
3
- "version": "2.5.1",
3
+ "version": "2.6.1",
4
4
  "description": "Production-ready library for converting OpenAPI specifications into MCP tool definitions",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -49,9 +49,9 @@
49
49
  }
50
50
  },
51
51
  "dependencies": {
52
- "@apidevtools/json-schema-ref-parser": "^15.3.5",
52
+ "@apidevtools/json-schema-ref-parser": "^15.5.1",
53
53
  "openapi-types": "^12.1.3",
54
- "yaml": "^2.8.3"
54
+ "yaml": "^2.9.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "zod": "^4.0.0"
@@ -2,12 +2,23 @@ import type { JSONSchema } from 'zod/v4/core';
2
2
  /** JSON Schema type from Zod v4 */
3
3
  type JsonSchema = JSONSchema.JSONSchema;
4
4
  import type { ParameterMapper, ParameterObject, NamingStrategy, SecurityRequirement } from './types';
5
+ /**
6
+ * Options controlling parameter resolution behavior
7
+ */
8
+ export interface ParameterResolverOptions {
9
+ /**
10
+ * Include parameter-level and media-type-level example(s) in the
11
+ * generated input schema (as JSON Schema `examples` arrays).
12
+ */
13
+ includeExamples?: boolean;
14
+ }
5
15
  /**
6
16
  * Resolves parameters and handles naming conflicts
7
17
  */
8
18
  export declare class ParameterResolver {
9
19
  private namingStrategy;
10
- constructor(namingStrategy?: NamingStrategy);
20
+ private includeExamples;
21
+ constructor(namingStrategy?: NamingStrategy, options?: ParameterResolverOptions);
11
22
  /**
12
23
  * Default conflict resolver: prefix with location
13
24
  */
@@ -15,7 +26,7 @@ export declare class ParameterResolver {
15
26
  /**
16
27
  * Resolve all parameters for an operation
17
28
  */
18
- resolve(operation: any, pathParameters?: ParameterObject[], securityRequirements?: SecurityRequirement[], includeSecurityInInput?: boolean): {
29
+ resolve(operation: any, pathParameters?: ParameterObject[], securityRequirements?: SecurityRequirement[], includeSecurityInInput?: boolean | string[]): {
19
30
  inputSchema: JsonSchema;
20
31
  mapper: ParameterMapper[];
21
32
  };
@@ -36,4 +47,14 @@ export declare class ParameterResolver {
36
47
  */
37
48
  private processSecurityRequirements;
38
49
  }
50
+ /**
51
+ * Collect concrete example values from OpenAPI `example` / `examples` fields
52
+ * (parameter or media-type level). The `examples` map wins over the singular
53
+ * `example` (they are mutually exclusive per OpenAPI); `$ref` entries are
54
+ * skipped because example refs are not dereferenced into values here.
55
+ * Returns undefined when nothing usable is present.
56
+ *
57
+ * Internal helper shared with ResponseBuilder (not part of the public barrel).
58
+ */
59
+ export declare function collectExampleValues(example: unknown, examples?: Record<string, unknown> | unknown[]): unknown[] | undefined;
39
60
  export {};
@@ -0,0 +1,52 @@
1
+ import type { McpOpenAPITool } from './types';
2
+ /**
3
+ * Options for {@link buildHttpRequest}.
4
+ */
5
+ export interface BuildHttpRequestOptions {
6
+ /**
7
+ * Base URL for the request. Overrides the tool's `metadata.servers[0].url`.
8
+ * Must be empty (relative request) or an http/https URL.
9
+ */
10
+ baseUrl?: string;
11
+ }
12
+ /**
13
+ * The composed HTTP request. Pure data — nothing has been sent.
14
+ */
15
+ export interface BuiltHttpRequest {
16
+ /** Fully composed URL: base + expanded path + encoded query string */
17
+ url: string;
18
+ /** Uppercase HTTP method */
19
+ method: string;
20
+ /**
21
+ * Request headers, including a composed `Cookie` header (when cookie
22
+ * parameters exist) and `content-type` (when the body is not multipart —
23
+ * multipart bodies must let the HTTP client set the boundary itself).
24
+ */
25
+ headers: Record<string, string>;
26
+ /** Query parameters as sent (unencoded values, one array per key) */
27
+ query: Record<string, string[]>;
28
+ /** Cookie parameters (also folded into the `Cookie` header) */
29
+ cookies: Record<string, string>;
30
+ /** Selected request body content type (also in headers, except multipart) */
31
+ contentType?: string;
32
+ /**
33
+ * Serialized body ready for fetch: a JSON/form-urlencoded/text string, a
34
+ * `FormData` for multipart, the raw value for binary bodies, or undefined.
35
+ */
36
+ body?: unknown;
37
+ /** Structured body value before serialization (object/array/primitive) */
38
+ rawBody?: unknown;
39
+ }
40
+ /**
41
+ * Build an HTTP request from a generated tool and its input values — the
42
+ * mapper applied in full: style/explode serialization (form, spaceDelimited,
43
+ * pipeDelimited, deepObject, simple, label, matrix), `allowReserved`,
44
+ * whole-body and binary bodies, JSON / form-urlencoded / multipart / text
45
+ * serialization, cookies, and header-injection guards.
46
+ *
47
+ * Pure function: nothing is sent, no runtime context is consulted. Security
48
+ * mapper entries are applied only when their value is present in `input`
49
+ * (with scheme-aware formatting); missing security values never throw —
50
+ * frameworks resolve credentials separately (see SecurityResolver).
51
+ */
52
+ export declare function buildHttpRequest(tool: McpOpenAPITool, input: Record<string, unknown>, options?: BuildHttpRequestOptions): BuiltHttpRequest;
@@ -8,6 +8,7 @@ import type { GenerateOptions, ResponsesObject } from './types';
8
8
  export declare class ResponseBuilder {
9
9
  private preferredStatusCodes;
10
10
  private includeAllResponses;
11
+ private includeExamples;
11
12
  constructor(options?: GenerateOptions);
12
13
  /**
13
14
  * Build output schema from responses
@@ -110,6 +110,40 @@ export declare class SchemaBuilder {
110
110
  * Flatten nested oneOf/anyOf/allOf schemas
111
111
  */
112
112
  static flatten(schema: JsonSchema, maxDepth?: number): JsonSchema;
113
+ /**
114
+ * Truncate a schema tree to a maximum nesting depth.
115
+ *
116
+ * The root sits at depth 0; descending into `properties` values, `items`,
117
+ * `additionalProperties`, composition members (`allOf`/`anyOf`/`oneOf`), or
118
+ * `not` increments the depth. Nodes at `maxDepth` keep their scalar keywords
119
+ * (type, description, format, ...) but have their child schemas stripped and
120
+ * a truncation note appended to the description.
121
+ */
122
+ static truncateDepth(schema: JsonSchema, maxDepth: number): JsonSchema;
123
+ /** Keys whose value is a map of schemas (JSON Schema 2020-12) */
124
+ private static readonly TRUNCATE_MAP_KEYS;
125
+ /** Keys whose value is a single schema (or, for `items`, a tuple array) */
126
+ private static readonly TRUNCATE_SCHEMA_KEYS;
127
+ /** Keys whose value is an array of schemas */
128
+ private static readonly TRUNCATE_LIST_KEYS;
129
+ private static truncateDepthRecursive;
130
+ private static walkCopy;
131
+ /**
132
+ * Limit every object node to its first `max` properties (declaration
133
+ * order). Dropped properties are pruned from `required` and counted in a
134
+ * note appended to the node's description.
135
+ */
136
+ static limitProperties(schema: JsonSchema, max: number): JsonSchema;
137
+ /**
138
+ * Cap every description in the schema tree to `maxLength` characters,
139
+ * truncating with an ellipsis.
140
+ */
141
+ static capDescriptions(schema: JsonSchema, maxLength: number): JsonSchema;
142
+ /**
143
+ * Remove every `examples` array from the schema tree (a token-budget
144
+ * trimming step — validation keywords are untouched).
145
+ */
146
+ static stripExamples(schema: JsonSchema): JsonSchema;
113
147
  /**
114
148
  * Simplify schema by removing unnecessary fields
115
149
  */
package/sdk.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { JsonSchema, McpOpenAPITool, ToolAnnotations } from './types';
2
+ /**
3
+ * A `registerTool`-shaped config for the official MCP TypeScript SDK.
4
+ * `TSchema` is whatever the schema wrapper returns — the raw `JsonSchema`
5
+ * when no wrapper is used, or the SDK's wrapped schema type.
6
+ */
7
+ export interface SdkToolConfig<TSchema = JsonSchema> {
8
+ title?: string;
9
+ description: string;
10
+ inputSchema: TSchema;
11
+ outputSchema?: TSchema;
12
+ annotations?: ToolAnnotations;
13
+ }
14
+ /**
15
+ * Schema wrapper — pass the SDK v2 `fromJsonSchema` here so schemas are
16
+ * advertised verbatim and validated by the SDK's JSON Schema validator.
17
+ */
18
+ export interface SdkSchemaWrapper<TSchema> {
19
+ fromJsonSchema: (schema: JsonSchema) => TSchema;
20
+ }
21
+ export declare function toSdkTool(tool: McpOpenAPITool): [name: string, config: SdkToolConfig];
22
+ export declare function toSdkTool<TSchema>(tool: McpOpenAPITool, wrapper: SdkSchemaWrapper<TSchema>): [name: string, config: SdkToolConfig<TSchema>];
@@ -0,0 +1,65 @@
1
+ import type { McpOpenAPITool } from './types';
2
+ /**
3
+ * Per-tool token estimate for the definition a client ships to the model.
4
+ */
5
+ export interface ToolTokenEstimate {
6
+ name: string;
7
+ /** Estimated tokens for the full advertised definition */
8
+ tokens: number;
9
+ }
10
+ /**
11
+ * Context-budget report for a generated tool set.
12
+ */
13
+ export interface ToolSetReport {
14
+ toolCount: number;
15
+ /** Sum of all per-tool estimates */
16
+ estimatedTokens: number;
17
+ /** Every tool, heaviest first */
18
+ perTool: ToolTokenEstimate[];
19
+ /** Human-readable budget warnings (empty when the set is comfortably sized) */
20
+ warnings: string[];
21
+ }
22
+ /**
23
+ * Thresholds for {@link analyzeToolSet} warnings.
24
+ */
25
+ export interface AnalyzeToolSetOptions {
26
+ /**
27
+ * Estimated-token budget for the whole tool set before a warning fires.
28
+ * ~1,000 tokens per tool is typical; ecosystem guidance flags pain beyond
29
+ * ~10K tokens of definitions.
30
+ * @default 10000
31
+ */
32
+ tokenBudget?: number;
33
+ /**
34
+ * Tool count beyond which model selection accuracy measurably degrades
35
+ * (public evaluations put the cliff at ~30-40 tools).
36
+ * @default 40
37
+ */
38
+ maxRecommendedTools?: number;
39
+ /**
40
+ * Per-tool estimate that marks a single tool as disproportionately heavy.
41
+ * @default 2000
42
+ */
43
+ perToolWarning?: number;
44
+ }
45
+ /**
46
+ * Estimate the context-window cost of ONE tool definition — the fields a
47
+ * client advertises to the model (name, title, description, annotations,
48
+ * input/output schemas), serialized as JSON.
49
+ *
50
+ * The estimate is `ceil(chars / 4)` — the common BPE average for JSON-heavy
51
+ * English text. It is a sizing signal for curation decisions, not a
52
+ * tokenizer: real counts vary by model within roughly ±20%.
53
+ */
54
+ export declare function estimateToolTokens(tool: McpOpenAPITool): number;
55
+ /**
56
+ * Analyze a generated tool set's context-window bill: per-tool estimates
57
+ * (heaviest first), the total, and curation warnings when the set crosses
58
+ * the thresholds where agent accuracy is known to degrade.
59
+ *
60
+ * ```ts
61
+ * const report = analyzeToolSet(await generator.generateTools());
62
+ * report.warnings.forEach((w) => console.warn(w));
63
+ * ```
64
+ */
65
+ export declare function analyzeToolSet(tools: McpOpenAPITool[], options?: AnalyzeToolSetOptions): ToolSetReport;
package/types.d.ts CHANGED
@@ -49,20 +49,68 @@ export declare function isReferenceObject(obj: any): obj is ReferenceObject;
49
49
  * Convert OpenAPI schema to JsonSchema
50
50
  * Note: OpenAPI 3.0 uses a subset of JSON Schema Draft 4
51
51
  * OpenAPI 3.1 uses JSON Schema Draft 2020-12
52
+ *
53
+ * Normalizations applied for clean JSON Schema 2020-12 output (MCP's default
54
+ * dialect since spec revision 2025-11-25):
55
+ * - OpenAPI 3.0 `nullable: true` -> `type: [..., 'null']` union
56
+ * - OpenAPI 3.0 boolean `exclusiveMinimum`/`exclusiveMaximum` -> numeric form
57
+ * - OpenAPI `example` (singular) -> `examples` array (2020-12 keyword)
58
+ * - OpenAPI-only `xml` metadata is dropped
52
59
  */
53
60
  export declare function toJsonSchema(schema: SchemaObject | ReferenceObject): JsonSchema;
54
61
  /**
55
- * Main MCP Tool definition generated from OpenAPI
62
+ * MCP tool annotations — behavior hints for clients (MCP spec 2025-03-26).
63
+ * Hints are advisory: clients must not treat them as security guarantees.
64
+ */
65
+ export interface ToolAnnotations {
66
+ /**
67
+ * Legacy display-name slot inside annotations. Prefer the tool-level `title`.
68
+ */
69
+ title?: string;
70
+ /**
71
+ * Tool only reads data, never modifies state.
72
+ */
73
+ readOnlyHint?: boolean;
74
+ /**
75
+ * Tool may perform destructive updates (delete, overwrite).
76
+ */
77
+ destructiveHint?: boolean;
78
+ /**
79
+ * Calling repeatedly with the same arguments has no additional effect.
80
+ */
81
+ idempotentHint?: boolean;
82
+ /**
83
+ * Tool interacts with an open world of external entities.
84
+ */
85
+ openWorldHint?: boolean;
86
+ }
87
+ /**
88
+ * Main MCP Tool definition generated from OpenAPI.
89
+ *
90
+ * `TMeta` lets embedding frameworks extend the metadata contract without
91
+ * casting — e.g. `McpOpenAPITool<ToolMetadata & { adapter: AdapterState }>`.
56
92
  */
57
- export interface McpOpenAPITool {
93
+ export interface McpOpenAPITool<TMeta extends ToolMetadata = ToolMetadata> {
58
94
  /**
59
95
  * Unique tool name (from operationId or generated)
60
96
  */
61
97
  name: string;
98
+ /**
99
+ * Human-readable display name (MCP `Tool.title`, spec 2025-06-18).
100
+ * From extension overrides or the operation summary.
101
+ */
102
+ title?: string;
62
103
  /**
63
104
  * Tool description (from operation summary/description)
64
105
  */
65
106
  description: string;
107
+ /**
108
+ * MCP tool annotations. Inferred from HTTP method semantics by default
109
+ * (see `GenerateOptions.inferAnnotations`) and overridable via the
110
+ * `x-speakeasy-mcp` / `x-mcp` / `x-frontmcp` extensions (in ascending
111
+ * precedence).
112
+ */
113
+ annotations?: ToolAnnotations;
66
114
  /**
67
115
  * Combined input schema including all parameters
68
116
  * (path, query, header, cookie, body)
@@ -80,7 +128,7 @@ export interface McpOpenAPITool {
80
128
  /**
81
129
  * Additional metadata about the tool
82
130
  */
83
- metadata: ToolMetadata;
131
+ metadata: TMeta;
84
132
  }
85
133
  /**
86
134
  * Maps input schema properties to their actual request locations
@@ -110,10 +158,23 @@ export interface ParameterMapper {
110
158
  * Whether to explode arrays/objects
111
159
  */
112
160
  explode?: boolean;
161
+ /**
162
+ * Whether RFC 3986 reserved characters may appear unencoded in the value
163
+ * (query parameters only, OpenAPI `allowReserved`)
164
+ */
165
+ allowReserved?: boolean;
113
166
  /**
114
167
  * Custom serialization info
115
168
  */
116
169
  serialization?: SerializationInfo;
170
+ /**
171
+ * When true, this input value IS the entire request body — set for
172
+ * non-object bodies (arrays, primitives, binary) and for `oneOf`/`anyOf`
173
+ * union bodies that cannot be flattened into named properties. Consumers
174
+ * building requests must send the value directly as the body instead of
175
+ * wrapping it in an object keyed by `key`.
176
+ */
177
+ wholeBody?: boolean;
117
178
  /**
118
179
  * Security scheme information (if this is an auth parameter)
119
180
  * This allows frameworks to resolve auth from context, env vars, etc.
@@ -129,9 +190,16 @@ export interface SerializationInfo {
129
190
  */
130
191
  contentType?: string;
131
192
  /**
132
- * Encoding rules
193
+ * Encoding rules from the request body's media type (OpenAPI `encoding`).
194
+ * For a flattened body-property parameter this contains only that
195
+ * property's entry; for a whole-body parameter it is the full map.
133
196
  */
134
197
  encoding?: Record<string, EncodingObject>;
198
+ /**
199
+ * File-upload marker: the parameter schema declares binary content
200
+ * (`format: binary`), e.g. a multipart file part or a raw binary body.
201
+ */
202
+ binary?: boolean;
135
203
  }
136
204
  /**
137
205
  * Security parameter information for framework-agnostic auth resolution
@@ -224,6 +292,24 @@ export interface ToolMetadata {
224
292
  * Contains annotations, cache config, codecall config, tags, etc.
225
293
  */
226
294
  frontmcp?: FrontMcpExtensionData;
295
+ /**
296
+ * Response-shaping signals for consumers that paginate, truncate, or cache:
297
+ * present only when there is something to know.
298
+ */
299
+ responseHints?: ResponseHints;
300
+ }
301
+ /**
302
+ * Detected response-shaping signals. Clients cap tool results hard (Claude
303
+ * Code: 25K tokens) — these hints tell a consumer WHICH tools need paging or
304
+ * truncation before the first oversized response happens.
305
+ */
306
+ export interface ResponseHints {
307
+ /** The success response contains an array without `maxItems` */
308
+ unboundedArray?: boolean;
309
+ /** Query parameters that look like pagination controls (limit, cursor, ...) */
310
+ paginationParams?: string[];
311
+ /** Unbounded array AND no pagination controls: truncate or shape server-side */
312
+ largeResponseRisk?: boolean;
227
313
  }
228
314
  /**
229
315
  * FrontMCP extension data extracted from x-frontmcp in OpenAPI operations.
@@ -231,15 +317,10 @@ export interface ToolMetadata {
231
317
  */
232
318
  export interface FrontMcpExtensionData {
233
319
  /**
234
- * Tool annotations for AI behavior hints.
320
+ * Tool annotations for AI behavior hints (same contract as the tool-level
321
+ * `annotations` field).
235
322
  */
236
- annotations?: {
237
- title?: string;
238
- readOnlyHint?: boolean;
239
- destructiveHint?: boolean;
240
- idempotentHint?: boolean;
241
- openWorldHint?: boolean;
242
- };
323
+ annotations?: ToolAnnotations;
243
324
  /**
244
325
  * Cache configuration for response caching.
245
326
  */
@@ -395,9 +476,26 @@ export interface LoadOptions {
395
476
  * Whether to follow HTTP redirects when fetching the spec URL. Each redirect
396
477
  * hop is re-validated against the SSRF guard before being followed (a 3xx to
397
478
  * an internal target is refused), so following is safe by default.
398
- * @default true
479
+ * @default true (false when `secureDefaults` is set)
399
480
  */
400
481
  followRedirects?: boolean;
482
+ /**
483
+ * OpenAPI Overlay 1.0 document(s) applied to the spec at load time, BEFORE
484
+ * dereferencing and validation, in order. Overlays keep curation
485
+ * (agent-tuned descriptions, `x-mcp` flags) in a separate file that
486
+ * survives spec regeneration. See `applyOverlay` for the supported
487
+ * JSONPath subset.
488
+ */
489
+ overlays?: import('./overlay').OverlayDocument | import('./overlay').OverlayDocument[];
490
+ /**
491
+ * Opt into the strictest loading posture in one flag: redirects are not
492
+ * followed and external `$ref` resolution is disabled entirely
493
+ * (`refResolution.allowedProtocols: []`) — the right default when loading
494
+ * untrusted specs. Explicitly-set `followRedirects`/`refResolution` values
495
+ * still win over the preset.
496
+ * @default false
497
+ */
498
+ secureDefaults?: boolean;
401
499
  /**
402
500
  * Controls spec-loading security: external `$ref` resolution AND the host
403
501
  * policy for the initial spec-URL fetch. By default `file://` is blocked,
@@ -430,6 +528,38 @@ export interface GenerateOptions {
430
528
  * Custom filter function
431
529
  */
432
530
  filterFn?: (operation: OperationWithContext) => boolean;
531
+ /**
532
+ * Include only operations carrying at least one of these OpenAPI tags
533
+ */
534
+ includeTags?: string[];
535
+ /**
536
+ * Exclude operations carrying any of these OpenAPI tags
537
+ */
538
+ excludeTags?: string[];
539
+ /**
540
+ * Include only these HTTP methods
541
+ */
542
+ includeMethods?: HTTPMethod[];
543
+ /**
544
+ * Exclude these HTTP methods
545
+ */
546
+ excludeMethods?: HTTPMethod[];
547
+ /**
548
+ * Include only paths matching at least one of these globs.
549
+ * `*` matches within a path segment, `**` across segments, `?` one character
550
+ * (e.g. `/users/*`, `/admin/**`).
551
+ */
552
+ includePaths?: string[];
553
+ /**
554
+ * Exclude paths matching any of these globs
555
+ */
556
+ excludePaths?: string[];
557
+ /**
558
+ * Safety switch: include only operations whose effective annotations say
559
+ * `readOnlyHint: true` (HTTP-method inference merged with extension
560
+ * overrides, regardless of `inferAnnotations`).
561
+ */
562
+ readOnlyOnly?: boolean;
433
563
  /**
434
564
  * Naming strategy for resolving conflicts
435
565
  */
@@ -451,22 +581,100 @@ export interface GenerateOptions {
451
581
  */
452
582
  includeAllResponses?: boolean;
453
583
  /**
454
- * Maximum depth for dereferencing schemas
584
+ * Maximum schema nesting depth retained in generated input/output schemas.
585
+ * Structures nested deeper than this are truncated: child schemas are
586
+ * stripped and a truncation note is appended to the node's description.
587
+ * Clamped to a minimum of 1 so the root schema always keeps its properties.
455
588
  * @default 10
456
589
  */
457
590
  maxSchemaDepth?: number;
458
591
  /**
459
- * Whether to include examples in schemas
592
+ * How the tool description is assembled from the operation:
593
+ * - `summaryOnly` (default): summary, else description, else `METHOD path`
594
+ * - `descriptionOnly`: description, else summary, else `METHOD path`
595
+ * - `combined`: summary + blank line + description (whichever exist)
596
+ * - `full`: summary, description, `Operation: <id>`, and `METHOD path`
597
+ * An `x-mcp`-family description override always wins over the strategy.
598
+ * @default 'summaryOnly'
599
+ */
600
+ descriptionStrategy?: 'summaryOnly' | 'descriptionOnly' | 'combined' | 'full';
601
+ /**
602
+ * Append a compact `Returns: ...` line to each tool description,
603
+ * summarizing the output schema (top-level shape and field names) — cheap
604
+ * context that measurably improves result-handling without shipping the
605
+ * whole response schema in prose.
606
+ * @default false
607
+ */
608
+ appendResponseSummary?: boolean;
609
+ /**
610
+ * Limit object nodes in generated schemas to their first N properties
611
+ * (declaration order). Dropped properties are pruned from `required` and
612
+ * counted in a description note. The ROOT of `inputSchema` is exempt: its
613
+ * properties are mapper-backed parameters, so the cap applies inside each
614
+ * parameter subtree (and throughout output schemas). Unset = no limit.
615
+ */
616
+ maxProperties?: number;
617
+ /**
618
+ * Cap every description in generated schemas to N characters (ellipsis
619
+ * truncation). Unset = no cap.
620
+ */
621
+ maxDescriptionLength?: number;
622
+ /**
623
+ * Remove all `examples` arrays from generated schemas — a token-budget
624
+ * trimming step that leaves validation keywords untouched.
625
+ * @default false
626
+ */
627
+ stripExamples?: boolean;
628
+ /**
629
+ * Include OpenAPI parameter-level and media-type-level `example`/`examples`
630
+ * values in generated schemas (as JSON Schema `examples` arrays). These
631
+ * override schema-level examples where present. Schema-level `example`
632
+ * keywords are always normalized to `examples` regardless of this option.
460
633
  * @default false
461
634
  */
462
635
  includeExamples?: boolean;
463
636
  /**
464
- * Whether to include security requirements as input parameters
465
- * If false, security is only in mapper (frameworks resolve from context/env/etc.)
466
- * If true, security is added to inputSchema as explicit parameters
637
+ * Whether to include security requirements as input parameters.
638
+ * - `false` (default): security lives only in the mapper (frameworks
639
+ * resolve credentials from context/env/vaults)
640
+ * - `true`: every security scheme is added to inputSchema as a required
641
+ * string property
642
+ * - `string[]`: only the named schemes appear in inputSchema; the rest stay
643
+ * mapper-only (all schemes are always present in the mapper)
467
644
  * @default false
468
645
  */
469
- includeSecurityInInput?: boolean;
646
+ includeSecurityInInput?: boolean | string[];
647
+ /**
648
+ * Target client schema dialect. Every MCP client accepts a different JSON
649
+ * Schema subset; setting a target applies the transforms that make the
650
+ * generated input/output schemas valid for it: `strict` (safe baseline —
651
+ * local $refs inlined, arrays get `items`, root compositions collapsed),
652
+ * `claude` (= strict), `openai` (strict + closed objects), `gemini`
653
+ * (strict + all unions collapsed + unsupported formats demoted).
654
+ * See `applyClientTarget` for standalone use.
655
+ */
656
+ target?: import('./client-targets').ClientTarget;
657
+ /**
658
+ * Infer MCP tool annotations from HTTP method semantics:
659
+ * GET/HEAD/OPTIONS/TRACE -> read-only + idempotent; PUT/DELETE ->
660
+ * destructive + idempotent; POST/PATCH -> destructive, not idempotent.
661
+ * `openWorldHint` defaults to false (a known API backend is a closed world).
662
+ * Extension overrides (`x-speakeasy-mcp`, `x-mcp`, `x-frontmcp`) are applied
663
+ * on top of the inferred values regardless of this flag.
664
+ * @default true
665
+ */
666
+ inferAnnotations?: boolean;
667
+ /**
668
+ * Maximum length for generated tool names. Names longer than this are
669
+ * truncated and given a short hash suffix derived from the full name, so
670
+ * truncated names stay unique and stable across regenerations.
671
+ *
672
+ * MCP tool names may be 1-128 characters of `[A-Za-z0-9_.-]` (values above
673
+ * 128 are clamped to 128). The default of 64 matches the strictest common
674
+ * client limits (Claude / Bedrock cap tool names at 64 characters).
675
+ * @default 64
676
+ */
677
+ maxToolNameLength?: number;
470
678
  /**
471
679
  * Enable built-in format-to-schema resolution.
472
680
  * Enriches schemas with concrete constraints (patterns, descriptions, min/max)