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/README.md +89 -68
- package/annotations.d.ts +57 -0
- package/client-targets.d.ts +55 -0
- package/errors.d.ts +14 -0
- package/esm/index.mjs +2891 -937
- package/esm/package.json +3 -3
- package/generator.d.ts +9 -1
- package/index.d.ts +16 -2
- package/index.js +2885 -912
- package/lint.d.ts +33 -0
- package/overlay.d.ts +43 -0
- package/package.json +3 -3
- package/parameter-resolver.d.ts +23 -2
- package/request-builder.d.ts +52 -0
- package/response-builder.d.ts +1 -0
- package/schema-builder.d.ts +34 -0
- package/sdk.d.ts +22 -0
- package/token-report.d.ts +65 -0
- package/types.d.ts +227 -19
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.
|
|
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.
|
|
52
|
+
"@apidevtools/json-schema-ref-parser": "^15.5.1",
|
|
53
53
|
"openapi-types": "^12.1.3",
|
|
54
|
-
"yaml": "^2.
|
|
54
|
+
"yaml": "^2.9.0"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"zod": "^4.0.0"
|
package/parameter-resolver.d.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/response-builder.d.ts
CHANGED
|
@@ -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
|
package/schema-builder.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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:
|
|
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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
466
|
-
*
|
|
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)
|