@ttoss/http-server-mcp-openapi 0.1.3 → 0.2.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/dist/index.cjs CHANGED
@@ -45,6 +45,7 @@ var dereferenceValue = args => {
45
45
  const refName = obj.$ref.replace("#/components/schemas/", "");
46
46
  if (seenRefs.has(refName)) return {};
47
47
  const resolved = spec.components?.schemas?.[refName];
48
+ if (resolved === void 0) return {};
48
49
  return dereferenceValue({
49
50
  value: resolved,
50
51
  spec,
@@ -184,6 +185,34 @@ var getJsonSchemaType = schemaType => {
184
185
  var sanitizeDescription = description => {
185
186
  return (description || "").replace(/'/g, "\\'").replace(/\n/g, " ").trim();
186
187
  };
188
+ /**
189
+ * Builds a single body/query property's `JsonSchemaProperty`. Split out of
190
+ * {@link buildInputSchema} to keep that function's size and branching down.
191
+ */
192
+ var buildTypedProperty = param => {
193
+ const description = sanitizeDescription(param.description);
194
+ if (param.oneOf && param.oneOf.length > 0) return {
195
+ oneOf: param.oneOf,
196
+ description
197
+ };
198
+ if (param.anyOf && param.anyOf.length > 0) return {
199
+ anyOf: param.anyOf,
200
+ description
201
+ };
202
+ const jsonType = getJsonSchemaType(param.type);
203
+ const finalType = param.nullable === true ? [jsonType, "null"] : jsonType;
204
+ if (param.type === "array") return {
205
+ type: finalType,
206
+ items: param.items ? param.items : {
207
+ type: "string"
208
+ },
209
+ description
210
+ };
211
+ return {
212
+ type: finalType,
213
+ description
214
+ };
215
+ };
187
216
  var buildInputSchema = (pathParams, queryParams, bodyProps) => {
188
217
  const allParams = [...pathParams, ...queryParams, ...bodyProps];
189
218
  if (allParams.length === 0) return {
@@ -201,30 +230,16 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
201
230
  return p.camelName;
202
231
  })];
203
232
  const properties = {};
204
- for (const param of allParams) if ("type" in param) {
205
- const jsonType = getJsonSchemaType(param.type);
206
- const description = sanitizeDescription(param.description);
207
- if (param.type === "array") {
208
- const itemsSchema = "items" in param && param.items ? param.items : {
209
- type: "string"
210
- };
211
- properties[param.camelName] = {
212
- type: "array",
213
- items: itemsSchema,
214
- description
215
- };
216
- } else properties[param.camelName] = {
217
- type: jsonType,
218
- description
219
- };
220
- } else properties[param.camelName] = {
233
+ for (const param of allParams) properties[param.camelName] = "type" in param ? buildTypedProperty(param) : {
221
234
  type: "string",
222
235
  description: ""
223
236
  };
224
237
  return {
225
238
  type: "object",
226
239
  properties,
227
- required: requiredFields.length > 0 ? requiredFields : void 0
240
+ ...(requiredFields.length > 0 ? {
241
+ required: requiredFields
242
+ } : {})
228
243
  };
229
244
  };
230
245
  /**
@@ -289,7 +304,10 @@ var extractBodyProps = args => {
289
304
  description: typeof val.description === "string" ? val.description : "",
290
305
  required: (bodySchema.required || []).includes(key),
291
306
  type: typeof val.type === "string" ? val.type : "string",
292
- items: val.items
307
+ items: val.items,
308
+ nullable: val.nullable === true,
309
+ oneOf: Array.isArray(val.oneOf) ? val.oneOf : void 0,
310
+ anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0
293
311
  };
294
312
  });
295
313
  };
package/dist/index.d.cts CHANGED
@@ -2,16 +2,28 @@
2
2
  import { JsonObjectSchema, McpServer } from "@ttoss/http-server-mcp";
3
3
 
4
4
  //#region src/types.d.ts
5
+ /** The JSON Schema primitive types this generator can derive from an OpenAPI `type`. */
6
+ type JsonSchemaPrimitiveType = 'string' | 'number' | 'boolean' | 'array' | 'integer' | 'object' | 'null';
5
7
  /**
6
8
  * A single JSON Schema property descriptor as emitted for a tool's
7
9
  * `inputSchema`. Only the subset of JSON Schema the generator produces is
8
10
  * modelled here; the value is forwarded verbatim over the MCP wire protocol.
11
+ *
12
+ * A property with OpenAPI `oneOf`/`anyOf` is forwarded as-is (no `type`) so a
13
+ * client-side validator enforces the same alternatives the REST API does,
14
+ * rather than collapsing to a single guessed primitive. `type` may be an
15
+ * array of two entries (e.g. `['string', 'null']`) to represent an OpenAPI
16
+ * `nullable: true` property without losing its declared type.
9
17
  */
10
- interface JsonSchemaProperty {
11
- type: 'string' | 'number' | 'boolean' | 'array' | 'integer' | 'object' | 'null';
18
+ type JsonSchemaProperty = {
19
+ type: JsonSchemaPrimitiveType | JsonSchemaPrimitiveType[];
12
20
  description?: string;
13
21
  items?: unknown;
14
- }
22
+ } | {
23
+ oneOf?: unknown[];
24
+ anyOf?: unknown[];
25
+ description?: string;
26
+ };
15
27
  /**
16
28
  * A REST-backed MCP tool derived from a single OpenAPI operation.
17
29
  *
@@ -256,6 +268,9 @@ declare const buildInputSchema: (pathParams: Array<{
256
268
  required: boolean;
257
269
  type: string;
258
270
  items?: unknown;
271
+ nullable?: boolean;
272
+ oneOf?: unknown[];
273
+ anyOf?: unknown[];
259
274
  }>) => JsonObjectSchema;
260
275
  declare const extractPathParams: (args: {
261
276
  parameters?: Array<{
@@ -301,6 +316,9 @@ declare const extractBodyProps: (args: {
301
316
  required: boolean;
302
317
  type: string;
303
318
  items?: unknown;
319
+ nullable: boolean;
320
+ oneOf?: unknown[];
321
+ anyOf?: unknown[];
304
322
  }>;
305
323
  declare const processOperation: (args: {
306
324
  pathTemplate: string;
package/dist/index.d.mts CHANGED
@@ -2,16 +2,28 @@
2
2
  import { JsonObjectSchema, McpServer } from "@ttoss/http-server-mcp";
3
3
 
4
4
  //#region src/types.d.ts
5
+ /** The JSON Schema primitive types this generator can derive from an OpenAPI `type`. */
6
+ type JsonSchemaPrimitiveType = 'string' | 'number' | 'boolean' | 'array' | 'integer' | 'object' | 'null';
5
7
  /**
6
8
  * A single JSON Schema property descriptor as emitted for a tool's
7
9
  * `inputSchema`. Only the subset of JSON Schema the generator produces is
8
10
  * modelled here; the value is forwarded verbatim over the MCP wire protocol.
11
+ *
12
+ * A property with OpenAPI `oneOf`/`anyOf` is forwarded as-is (no `type`) so a
13
+ * client-side validator enforces the same alternatives the REST API does,
14
+ * rather than collapsing to a single guessed primitive. `type` may be an
15
+ * array of two entries (e.g. `['string', 'null']`) to represent an OpenAPI
16
+ * `nullable: true` property without losing its declared type.
9
17
  */
10
- interface JsonSchemaProperty {
11
- type: 'string' | 'number' | 'boolean' | 'array' | 'integer' | 'object' | 'null';
18
+ type JsonSchemaProperty = {
19
+ type: JsonSchemaPrimitiveType | JsonSchemaPrimitiveType[];
12
20
  description?: string;
13
21
  items?: unknown;
14
- }
22
+ } | {
23
+ oneOf?: unknown[];
24
+ anyOf?: unknown[];
25
+ description?: string;
26
+ };
15
27
  /**
16
28
  * A REST-backed MCP tool derived from a single OpenAPI operation.
17
29
  *
@@ -256,6 +268,9 @@ declare const buildInputSchema: (pathParams: Array<{
256
268
  required: boolean;
257
269
  type: string;
258
270
  items?: unknown;
271
+ nullable?: boolean;
272
+ oneOf?: unknown[];
273
+ anyOf?: unknown[];
259
274
  }>) => JsonObjectSchema;
260
275
  declare const extractPathParams: (args: {
261
276
  parameters?: Array<{
@@ -301,6 +316,9 @@ declare const extractBodyProps: (args: {
301
316
  required: boolean;
302
317
  type: string;
303
318
  items?: unknown;
319
+ nullable: boolean;
320
+ oneOf?: unknown[];
321
+ anyOf?: unknown[];
304
322
  }>;
305
323
  declare const processOperation: (args: {
306
324
  pathTemplate: string;
package/dist/index.mjs CHANGED
@@ -42,6 +42,7 @@ var dereferenceValue = args => {
42
42
  const refName = obj.$ref.replace("#/components/schemas/", "");
43
43
  if (seenRefs.has(refName)) return {};
44
44
  const resolved = spec.components?.schemas?.[refName];
45
+ if (resolved === void 0) return {};
45
46
  return dereferenceValue({
46
47
  value: resolved,
47
48
  spec,
@@ -181,6 +182,34 @@ var getJsonSchemaType = schemaType => {
181
182
  var sanitizeDescription = description => {
182
183
  return (description || "").replace(/'/g, "\\'").replace(/\n/g, " ").trim();
183
184
  };
185
+ /**
186
+ * Builds a single body/query property's `JsonSchemaProperty`. Split out of
187
+ * {@link buildInputSchema} to keep that function's size and branching down.
188
+ */
189
+ var buildTypedProperty = param => {
190
+ const description = sanitizeDescription(param.description);
191
+ if (param.oneOf && param.oneOf.length > 0) return {
192
+ oneOf: param.oneOf,
193
+ description
194
+ };
195
+ if (param.anyOf && param.anyOf.length > 0) return {
196
+ anyOf: param.anyOf,
197
+ description
198
+ };
199
+ const jsonType = getJsonSchemaType(param.type);
200
+ const finalType = param.nullable === true ? [jsonType, "null"] : jsonType;
201
+ if (param.type === "array") return {
202
+ type: finalType,
203
+ items: param.items ? param.items : {
204
+ type: "string"
205
+ },
206
+ description
207
+ };
208
+ return {
209
+ type: finalType,
210
+ description
211
+ };
212
+ };
184
213
  var buildInputSchema = (pathParams, queryParams, bodyProps) => {
185
214
  const allParams = [...pathParams, ...queryParams, ...bodyProps];
186
215
  if (allParams.length === 0) return {
@@ -198,30 +227,16 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
198
227
  return p.camelName;
199
228
  })];
200
229
  const properties = {};
201
- for (const param of allParams) if ("type" in param) {
202
- const jsonType = getJsonSchemaType(param.type);
203
- const description = sanitizeDescription(param.description);
204
- if (param.type === "array") {
205
- const itemsSchema = "items" in param && param.items ? param.items : {
206
- type: "string"
207
- };
208
- properties[param.camelName] = {
209
- type: "array",
210
- items: itemsSchema,
211
- description
212
- };
213
- } else properties[param.camelName] = {
214
- type: jsonType,
215
- description
216
- };
217
- } else properties[param.camelName] = {
230
+ for (const param of allParams) properties[param.camelName] = "type" in param ? buildTypedProperty(param) : {
218
231
  type: "string",
219
232
  description: ""
220
233
  };
221
234
  return {
222
235
  type: "object",
223
236
  properties,
224
- required: requiredFields.length > 0 ? requiredFields : void 0
237
+ ...(requiredFields.length > 0 ? {
238
+ required: requiredFields
239
+ } : {})
225
240
  };
226
241
  };
227
242
  /**
@@ -286,7 +301,10 @@ var extractBodyProps = args => {
286
301
  description: typeof val.description === "string" ? val.description : "",
287
302
  required: (bodySchema.required || []).includes(key),
288
303
  type: typeof val.type === "string" ? val.type : "string",
289
- items: val.items
304
+ items: val.items,
305
+ nullable: val.nullable === true,
306
+ oneOf: Array.isArray(val.oneOf) ? val.oneOf : void 0,
307
+ anyOf: Array.isArray(val.anyOf) ? val.anyOf : void 0
290
308
  };
291
309
  });
292
310
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/http-server-mcp-openapi",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "Generate Model Context Protocol (MCP) tools from an OpenAPI specification for @ttoss/http-server-mcp",
5
5
  "keywords": [
6
6
  "ai",
@@ -35,14 +35,15 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "@ttoss/http-server-mcp": "^0.23.1"
38
+ "@ttoss/http-server-mcp": "^0.24.0"
39
39
  },
40
40
  "devDependencies": {
41
+ "@modelcontextprotocol/server": "^2.0.0",
41
42
  "jest": "^30.4.2",
42
43
  "supertest": "^7.2.2",
43
44
  "tsdown": "^0.22.2",
44
- "@ttoss/http-server": "^0.7.1",
45
- "@ttoss/config": "^1.37.17"
45
+ "@ttoss/config": "^1.37.17",
46
+ "@ttoss/http-server": "^0.7.1"
46
47
  },
47
48
  "publishConfig": {
48
49
  "access": "public",