@ttoss/http-server-mcp-openapi 0.2.14 → 0.2.15

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 CHANGED
@@ -61,7 +61,11 @@ Each OpenAPI operation with an `operationId` and a supported HTTP method
61
61
  | operation `description` | tool description (quotes/newlines sanitised) |
62
62
 
63
63
  Path params are always required strings. Query and body params carry their
64
- declared type and `required` flag. Array params keep their `items` schema.
64
+ declared type and `required` flag. Array params keep their `items` schema. A
65
+ body property declared as a single-entry `allOf` (usually `allOf: [{ $ref }]`
66
+ beside its own `description`) takes `type`, `nullable` and `items` from the
67
+ referenced schema; a multi-entry `allOf` is forwarded verbatim, and a property
68
+ with no declared type is advertised untyped so it accepts any value.
65
69
  Parameters declared at the **path-item level** (shared by every operation on a
66
70
  path) are merged into each operation; an operation-level parameter overrides a
67
71
  path-item one with the same `name`+`in`.
package/dist/index.cjs CHANGED
@@ -272,11 +272,13 @@ var sanitizeDescription = description => {
272
272
  return (description || "").replace(/'/g, "\\'").replace(/\n/g, " ").trim();
273
273
  };
274
274
  /**
275
- * Builds a single body/query property's `JsonSchemaProperty`. Split out of
276
- * {@link buildInputSchema} to keep that function's size and branching down.
275
+ * Forwards a property's `oneOf` / `anyOf` / multi-entry `allOf` verbatim, or
276
+ * returns `undefined` when it declares none.
277
277
  */
278
- var buildTypedProperty = param => {
279
- const description = sanitizeDescription(param.description);
278
+ var buildComposedProperty = param => {
279
+ const {
280
+ description
281
+ } = param;
280
282
  if (param.oneOf && param.oneOf.length > 0) return {
281
283
  oneOf: param.oneOf,
282
284
  description
@@ -285,6 +287,25 @@ var buildTypedProperty = param => {
285
287
  anyOf: param.anyOf,
286
288
  description
287
289
  };
290
+ if (param.allOf && param.allOf.length > 0) return {
291
+ allOf: param.allOf,
292
+ description
293
+ };
294
+ };
295
+ /**
296
+ * Builds a single body/query property's `JsonSchemaProperty`. Split out of
297
+ * {@link buildInputSchema} to keep that function's size and branching down.
298
+ */
299
+ var buildTypedProperty = param => {
300
+ const description = sanitizeDescription(param.description);
301
+ const composed = buildComposedProperty({
302
+ ...param,
303
+ description
304
+ });
305
+ if (composed) return composed;
306
+ if (param.type === void 0) return {
307
+ description
308
+ };
288
309
  const jsonType = getJsonSchemaType(param.type);
289
310
  const finalType = param.nullable === true ? [jsonType, "null"] : jsonType;
290
311
  if (param.type === "array") return {
@@ -316,7 +337,7 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
316
337
  return p.camelName;
317
338
  })];
318
339
  const properties = {};
319
- for (const param of allParams) properties[param.camelName] = "type" in param ? buildTypedProperty(param) : {
340
+ for (const param of allParams) properties[param.camelName] = "description" in param ? buildTypedProperty(param) : {
320
341
  type: "string",
321
342
  description: ""
322
343
  };
@@ -379,23 +400,47 @@ var extractAcceptedBodyFields = args => {
379
400
  const bodySchema = resolveBodySchema(args);
380
401
  return Object.keys(bodySchema?.properties ?? {});
381
402
  };
403
+ var isPlainObject = value => {
404
+ return typeof value === "object" && value !== null && !Array.isArray(value);
405
+ };
406
+ /**
407
+ * Folds a single-entry `allOf` into the property that wraps it. OpenAPI
408
+ * declares `allOf: [{ $ref }]` so a property can carry its own `description`
409
+ * next to a referenced schema; without folding, the referenced `type`,
410
+ * `nullable` and `items` would be lost. Keys on the wrapper win over the
411
+ * referenced schema's. Multi-entry `allOf` is left intact.
412
+ */
413
+ var flattenSingleAllOf = schema => {
414
+ const {
415
+ allOf,
416
+ ...rest
417
+ } = schema;
418
+ if (!Array.isArray(allOf) || allOf.length !== 1) return schema;
419
+ const [entry] = allOf;
420
+ if (!isPlainObject(entry)) return rest;
421
+ return {
422
+ ...flattenSingleAllOf(entry),
423
+ ...rest
424
+ };
425
+ };
382
426
  var extractBodyProps = args => {
383
427
  const bodySchema = resolveBodySchema(args);
384
428
  if (!bodySchema?.properties) return [];
385
429
  return Object.entries(bodySchema.properties).filter(([, value]) => {
386
430
  return !value[args.serverManagedExtension];
387
431
  }).map(([key, value]) => {
388
- const val = value;
432
+ const val = flattenSingleAllOf(value);
389
433
  return {
390
434
  snakeName: key,
391
435
  camelName: snakeToCamel(key),
392
436
  description: typeof val.description === "string" ? val.description : "",
393
437
  required: (bodySchema.required || []).includes(key),
394
- type: typeof val.type === "string" ? val.type : "string",
438
+ type: typeof val.type === "string" ? val.type : void 0,
395
439
  items: val.items,
396
440
  nullable: val.nullable === true,
397
441
  oneOf: Array.isArray(val.oneOf) ? val.oneOf : void 0,
398
- anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0
442
+ anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0,
443
+ allOf: Array.isArray(val.allOf) ? val.allOf : void 0
399
444
  };
400
445
  });
401
446
  };
package/dist/index.d.cts CHANGED
@@ -13,7 +13,9 @@ type JsonSchemaPrimitiveType = 'string' | 'number' | 'boolean' | 'array' | 'inte
13
13
  * client-side validator enforces the same alternatives the REST API does,
14
14
  * rather than collapsing to a single guessed primitive. `type` may be an
15
15
  * array of two entries (e.g. `['string', 'null']`) to represent an OpenAPI
16
- * `nullable: true` property without losing its declared type.
16
+ * `nullable: true` property without losing its declared type. A property with
17
+ * no declared type is emitted untyped (only `description`), so it accepts any
18
+ * value instead of a guessed `string`.
17
19
  */
18
20
  type JsonSchemaProperty = {
19
21
  type: JsonSchemaPrimitiveType | JsonSchemaPrimitiveType[];
@@ -22,6 +24,7 @@ type JsonSchemaProperty = {
22
24
  } | {
23
25
  oneOf?: unknown[];
24
26
  anyOf?: unknown[];
27
+ allOf?: unknown[];
25
28
  description?: string;
26
29
  };
27
30
  /**
@@ -274,11 +277,12 @@ declare const buildInputSchema: (pathParams: Array<{
274
277
  camelName: string;
275
278
  description: string;
276
279
  required: boolean;
277
- type: string;
280
+ type?: string;
278
281
  items?: unknown;
279
282
  nullable?: boolean;
280
283
  oneOf?: unknown[];
281
284
  anyOf?: unknown[];
285
+ allOf?: unknown[];
282
286
  }>) => JsonObjectSchema;
283
287
  declare const extractPathParams: (args: {
284
288
  parameters?: Array<{
@@ -324,11 +328,12 @@ declare const extractBodyProps: (args: {
324
328
  camelName: string;
325
329
  description: string;
326
330
  required: boolean;
327
- type: string;
331
+ type?: string;
328
332
  items?: unknown;
329
333
  nullable: boolean;
330
334
  oneOf?: unknown[];
331
335
  anyOf?: unknown[];
336
+ allOf?: unknown[];
332
337
  }>;
333
338
  declare const processOperation: (args: {
334
339
  pathTemplate: string;
package/dist/index.d.mts CHANGED
@@ -13,7 +13,9 @@ type JsonSchemaPrimitiveType = 'string' | 'number' | 'boolean' | 'array' | 'inte
13
13
  * client-side validator enforces the same alternatives the REST API does,
14
14
  * rather than collapsing to a single guessed primitive. `type` may be an
15
15
  * array of two entries (e.g. `['string', 'null']`) to represent an OpenAPI
16
- * `nullable: true` property without losing its declared type.
16
+ * `nullable: true` property without losing its declared type. A property with
17
+ * no declared type is emitted untyped (only `description`), so it accepts any
18
+ * value instead of a guessed `string`.
17
19
  */
18
20
  type JsonSchemaProperty = {
19
21
  type: JsonSchemaPrimitiveType | JsonSchemaPrimitiveType[];
@@ -22,6 +24,7 @@ type JsonSchemaProperty = {
22
24
  } | {
23
25
  oneOf?: unknown[];
24
26
  anyOf?: unknown[];
27
+ allOf?: unknown[];
25
28
  description?: string;
26
29
  };
27
30
  /**
@@ -274,11 +277,12 @@ declare const buildInputSchema: (pathParams: Array<{
274
277
  camelName: string;
275
278
  description: string;
276
279
  required: boolean;
277
- type: string;
280
+ type?: string;
278
281
  items?: unknown;
279
282
  nullable?: boolean;
280
283
  oneOf?: unknown[];
281
284
  anyOf?: unknown[];
285
+ allOf?: unknown[];
282
286
  }>) => JsonObjectSchema;
283
287
  declare const extractPathParams: (args: {
284
288
  parameters?: Array<{
@@ -324,11 +328,12 @@ declare const extractBodyProps: (args: {
324
328
  camelName: string;
325
329
  description: string;
326
330
  required: boolean;
327
- type: string;
331
+ type?: string;
328
332
  items?: unknown;
329
333
  nullable: boolean;
330
334
  oneOf?: unknown[];
331
335
  anyOf?: unknown[];
336
+ allOf?: unknown[];
332
337
  }>;
333
338
  declare const processOperation: (args: {
334
339
  pathTemplate: string;
package/dist/index.mjs CHANGED
@@ -269,11 +269,13 @@ var sanitizeDescription = description => {
269
269
  return (description || "").replace(/'/g, "\\'").replace(/\n/g, " ").trim();
270
270
  };
271
271
  /**
272
- * Builds a single body/query property's `JsonSchemaProperty`. Split out of
273
- * {@link buildInputSchema} to keep that function's size and branching down.
272
+ * Forwards a property's `oneOf` / `anyOf` / multi-entry `allOf` verbatim, or
273
+ * returns `undefined` when it declares none.
274
274
  */
275
- var buildTypedProperty = param => {
276
- const description = sanitizeDescription(param.description);
275
+ var buildComposedProperty = param => {
276
+ const {
277
+ description
278
+ } = param;
277
279
  if (param.oneOf && param.oneOf.length > 0) return {
278
280
  oneOf: param.oneOf,
279
281
  description
@@ -282,6 +284,25 @@ var buildTypedProperty = param => {
282
284
  anyOf: param.anyOf,
283
285
  description
284
286
  };
287
+ if (param.allOf && param.allOf.length > 0) return {
288
+ allOf: param.allOf,
289
+ description
290
+ };
291
+ };
292
+ /**
293
+ * Builds a single body/query property's `JsonSchemaProperty`. Split out of
294
+ * {@link buildInputSchema} to keep that function's size and branching down.
295
+ */
296
+ var buildTypedProperty = param => {
297
+ const description = sanitizeDescription(param.description);
298
+ const composed = buildComposedProperty({
299
+ ...param,
300
+ description
301
+ });
302
+ if (composed) return composed;
303
+ if (param.type === void 0) return {
304
+ description
305
+ };
285
306
  const jsonType = getJsonSchemaType(param.type);
286
307
  const finalType = param.nullable === true ? [jsonType, "null"] : jsonType;
287
308
  if (param.type === "array") return {
@@ -313,7 +334,7 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
313
334
  return p.camelName;
314
335
  })];
315
336
  const properties = {};
316
- for (const param of allParams) properties[param.camelName] = "type" in param ? buildTypedProperty(param) : {
337
+ for (const param of allParams) properties[param.camelName] = "description" in param ? buildTypedProperty(param) : {
317
338
  type: "string",
318
339
  description: ""
319
340
  };
@@ -376,23 +397,47 @@ var extractAcceptedBodyFields = args => {
376
397
  const bodySchema = resolveBodySchema(args);
377
398
  return Object.keys(bodySchema?.properties ?? {});
378
399
  };
400
+ var isPlainObject = value => {
401
+ return typeof value === "object" && value !== null && !Array.isArray(value);
402
+ };
403
+ /**
404
+ * Folds a single-entry `allOf` into the property that wraps it. OpenAPI
405
+ * declares `allOf: [{ $ref }]` so a property can carry its own `description`
406
+ * next to a referenced schema; without folding, the referenced `type`,
407
+ * `nullable` and `items` would be lost. Keys on the wrapper win over the
408
+ * referenced schema's. Multi-entry `allOf` is left intact.
409
+ */
410
+ var flattenSingleAllOf = schema => {
411
+ const {
412
+ allOf,
413
+ ...rest
414
+ } = schema;
415
+ if (!Array.isArray(allOf) || allOf.length !== 1) return schema;
416
+ const [entry] = allOf;
417
+ if (!isPlainObject(entry)) return rest;
418
+ return {
419
+ ...flattenSingleAllOf(entry),
420
+ ...rest
421
+ };
422
+ };
379
423
  var extractBodyProps = args => {
380
424
  const bodySchema = resolveBodySchema(args);
381
425
  if (!bodySchema?.properties) return [];
382
426
  return Object.entries(bodySchema.properties).filter(([, value]) => {
383
427
  return !value[args.serverManagedExtension];
384
428
  }).map(([key, value]) => {
385
- const val = value;
429
+ const val = flattenSingleAllOf(value);
386
430
  return {
387
431
  snakeName: key,
388
432
  camelName: snakeToCamel(key),
389
433
  description: typeof val.description === "string" ? val.description : "",
390
434
  required: (bodySchema.required || []).includes(key),
391
- type: typeof val.type === "string" ? val.type : "string",
435
+ type: typeof val.type === "string" ? val.type : void 0,
392
436
  items: val.items,
393
437
  nullable: val.nullable === true,
394
438
  oneOf: Array.isArray(val.oneOf) ? val.oneOf : void 0,
395
- anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0
439
+ anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0,
440
+ allOf: Array.isArray(val.allOf) ? val.allOf : void 0
396
441
  };
397
442
  });
398
443
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/http-server-mcp-openapi",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "description": "Generate Model Context Protocol (MCP) tools from an OpenAPI specification for @ttoss/http-server-mcp",
5
5
  "keywords": [
6
6
  "ai",