@ttoss/http-server-mcp-openapi 0.1.0 → 0.1.2
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 +3 -0
- package/dist/index.cjs +22 -7
- package/dist/index.d.cts +10 -0
- package/dist/index.d.mts +10 -0
- package/dist/index.mjs +22 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -62,6 +62,9 @@ Each OpenAPI operation with an `operationId` and a supported HTTP method
|
|
|
62
62
|
|
|
63
63
|
Path params are always required strings. Query and body params carry their
|
|
64
64
|
declared type and `required` flag. Array params keep their `items` schema.
|
|
65
|
+
Parameters declared at the **path-item level** (shared by every operation on a
|
|
66
|
+
path) are merged into each operation; an operation-level parameter overrides a
|
|
67
|
+
path-item one with the same `name`+`in`.
|
|
65
68
|
|
|
66
69
|
Tool arguments are **camelCase** (`agentId`, `projectId`); the generated
|
|
67
70
|
request path, query string, and body use the original **snake_case** names.
|
package/dist/index.cjs
CHANGED
|
@@ -227,8 +227,18 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
|
|
|
227
227
|
required: requiredFields.length > 0 ? requiredFields : void 0
|
|
228
228
|
};
|
|
229
229
|
};
|
|
230
|
+
/**
|
|
231
|
+
* Deduplicates parameter entries by `name`, keeping the last occurrence. When
|
|
232
|
+
* path-item-level and operation-level parameters are concatenated (operation
|
|
233
|
+
* last), this makes the operation-level entry win — as the OpenAPI spec requires.
|
|
234
|
+
*/
|
|
235
|
+
var dedupeByName = items => {
|
|
236
|
+
const byName = /* @__PURE__ */new Map();
|
|
237
|
+
for (const item of items) byName.set(item.name, item);
|
|
238
|
+
return [...byName.values()];
|
|
239
|
+
};
|
|
230
240
|
var extractPathParams = args => {
|
|
231
|
-
return (args.parameters || []).map(p => {
|
|
241
|
+
return dedupeByName((args.parameters || []).map(p => {
|
|
232
242
|
return resolveParameter(p, args.spec);
|
|
233
243
|
}).filter(p => {
|
|
234
244
|
return p.in === "path";
|
|
@@ -237,10 +247,10 @@ var extractPathParams = args => {
|
|
|
237
247
|
name: p.name || "",
|
|
238
248
|
camelName: snakeToCamel(p.name || "")
|
|
239
249
|
};
|
|
240
|
-
});
|
|
250
|
+
}));
|
|
241
251
|
};
|
|
242
252
|
var extractQueryParams = args => {
|
|
243
|
-
return (args.parameters || []).map(p => {
|
|
253
|
+
return dedupeByName((args.parameters || []).map(p => {
|
|
244
254
|
return resolveParameter(p, args.spec);
|
|
245
255
|
}).filter(p => {
|
|
246
256
|
return p.in === "query";
|
|
@@ -252,7 +262,7 @@ var extractQueryParams = args => {
|
|
|
252
262
|
required: p.required || false,
|
|
253
263
|
type: p.schema?.type || "string"
|
|
254
264
|
};
|
|
255
|
-
});
|
|
265
|
+
}));
|
|
256
266
|
};
|
|
257
267
|
var resolveBodySchema = args => {
|
|
258
268
|
const rawBodySchema = args.requestBody?.content?.["application/json"]?.schema;
|
|
@@ -295,12 +305,13 @@ var processOperation = args => {
|
|
|
295
305
|
if (!args.operation.operationId) return null;
|
|
296
306
|
if (args.operation[args.options.excludeExtension]) return null;
|
|
297
307
|
const toolName = operationIdToToolName(args.operation.operationId);
|
|
308
|
+
const parameters = [...(args.pathItemParameters ?? []), ...(args.operation.parameters ?? [])];
|
|
298
309
|
const pathParams = extractPathParams({
|
|
299
|
-
parameters
|
|
310
|
+
parameters,
|
|
300
311
|
spec: args.spec
|
|
301
312
|
});
|
|
302
313
|
const queryParams = extractQueryParams({
|
|
303
|
-
parameters
|
|
314
|
+
parameters,
|
|
304
315
|
spec: args.spec
|
|
305
316
|
});
|
|
306
317
|
const bodyProps = extractBodyProps({
|
|
@@ -328,14 +339,18 @@ var processOperation = args => {
|
|
|
328
339
|
};
|
|
329
340
|
};
|
|
330
341
|
var processPath = args => {
|
|
342
|
+
const rawPathItemParameters = args.pathItem.parameters;
|
|
343
|
+
const pathItemParameters = Array.isArray(rawPathItemParameters) ? rawPathItemParameters : [];
|
|
331
344
|
const tools = [];
|
|
332
345
|
for (const [method, operation] of Object.entries(args.pathItem)) {
|
|
346
|
+
if (method === "parameters") continue;
|
|
333
347
|
const tool = processOperation({
|
|
334
348
|
pathTemplate: args.pathTemplate,
|
|
335
349
|
method,
|
|
336
350
|
operation,
|
|
337
351
|
spec: args.spec,
|
|
338
|
-
options: args.options
|
|
352
|
+
options: args.options,
|
|
353
|
+
pathItemParameters
|
|
339
354
|
});
|
|
340
355
|
if (tool) tools.push(tool);
|
|
341
356
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -308,6 +308,16 @@ declare const processOperation: (args: {
|
|
|
308
308
|
operation: OperationSpec;
|
|
309
309
|
spec: OpenApiSpec;
|
|
310
310
|
options: Required<OpenApiToToolsOptions>;
|
|
311
|
+
/**
|
|
312
|
+
* Parameters declared at the path-item level (shared by every operation on
|
|
313
|
+
* the path). Merged ahead of the operation's own parameters so operation-level
|
|
314
|
+
* entries win on a `name`+`in` clash.
|
|
315
|
+
*/
|
|
316
|
+
pathItemParameters?: Array<{
|
|
317
|
+
name?: string;
|
|
318
|
+
in?: string;
|
|
319
|
+
[key: string]: unknown;
|
|
320
|
+
}>;
|
|
311
321
|
}) => ToolDefinition | null;
|
|
312
322
|
declare const processPath: (args: {
|
|
313
323
|
pathTemplate: string;
|
package/dist/index.d.mts
CHANGED
|
@@ -308,6 +308,16 @@ declare const processOperation: (args: {
|
|
|
308
308
|
operation: OperationSpec;
|
|
309
309
|
spec: OpenApiSpec;
|
|
310
310
|
options: Required<OpenApiToToolsOptions>;
|
|
311
|
+
/**
|
|
312
|
+
* Parameters declared at the path-item level (shared by every operation on
|
|
313
|
+
* the path). Merged ahead of the operation's own parameters so operation-level
|
|
314
|
+
* entries win on a `name`+`in` clash.
|
|
315
|
+
*/
|
|
316
|
+
pathItemParameters?: Array<{
|
|
317
|
+
name?: string;
|
|
318
|
+
in?: string;
|
|
319
|
+
[key: string]: unknown;
|
|
320
|
+
}>;
|
|
311
321
|
}) => ToolDefinition | null;
|
|
312
322
|
declare const processPath: (args: {
|
|
313
323
|
pathTemplate: string;
|
package/dist/index.mjs
CHANGED
|
@@ -224,8 +224,18 @@ var buildInputSchema = (pathParams, queryParams, bodyProps) => {
|
|
|
224
224
|
required: requiredFields.length > 0 ? requiredFields : void 0
|
|
225
225
|
};
|
|
226
226
|
};
|
|
227
|
+
/**
|
|
228
|
+
* Deduplicates parameter entries by `name`, keeping the last occurrence. When
|
|
229
|
+
* path-item-level and operation-level parameters are concatenated (operation
|
|
230
|
+
* last), this makes the operation-level entry win — as the OpenAPI spec requires.
|
|
231
|
+
*/
|
|
232
|
+
var dedupeByName = items => {
|
|
233
|
+
const byName = /* @__PURE__ */new Map();
|
|
234
|
+
for (const item of items) byName.set(item.name, item);
|
|
235
|
+
return [...byName.values()];
|
|
236
|
+
};
|
|
227
237
|
var extractPathParams = args => {
|
|
228
|
-
return (args.parameters || []).map(p => {
|
|
238
|
+
return dedupeByName((args.parameters || []).map(p => {
|
|
229
239
|
return resolveParameter(p, args.spec);
|
|
230
240
|
}).filter(p => {
|
|
231
241
|
return p.in === "path";
|
|
@@ -234,10 +244,10 @@ var extractPathParams = args => {
|
|
|
234
244
|
name: p.name || "",
|
|
235
245
|
camelName: snakeToCamel(p.name || "")
|
|
236
246
|
};
|
|
237
|
-
});
|
|
247
|
+
}));
|
|
238
248
|
};
|
|
239
249
|
var extractQueryParams = args => {
|
|
240
|
-
return (args.parameters || []).map(p => {
|
|
250
|
+
return dedupeByName((args.parameters || []).map(p => {
|
|
241
251
|
return resolveParameter(p, args.spec);
|
|
242
252
|
}).filter(p => {
|
|
243
253
|
return p.in === "query";
|
|
@@ -249,7 +259,7 @@ var extractQueryParams = args => {
|
|
|
249
259
|
required: p.required || false,
|
|
250
260
|
type: p.schema?.type || "string"
|
|
251
261
|
};
|
|
252
|
-
});
|
|
262
|
+
}));
|
|
253
263
|
};
|
|
254
264
|
var resolveBodySchema = args => {
|
|
255
265
|
const rawBodySchema = args.requestBody?.content?.["application/json"]?.schema;
|
|
@@ -292,12 +302,13 @@ var processOperation = args => {
|
|
|
292
302
|
if (!args.operation.operationId) return null;
|
|
293
303
|
if (args.operation[args.options.excludeExtension]) return null;
|
|
294
304
|
const toolName = operationIdToToolName(args.operation.operationId);
|
|
305
|
+
const parameters = [...(args.pathItemParameters ?? []), ...(args.operation.parameters ?? [])];
|
|
295
306
|
const pathParams = extractPathParams({
|
|
296
|
-
parameters
|
|
307
|
+
parameters,
|
|
297
308
|
spec: args.spec
|
|
298
309
|
});
|
|
299
310
|
const queryParams = extractQueryParams({
|
|
300
|
-
parameters
|
|
311
|
+
parameters,
|
|
301
312
|
spec: args.spec
|
|
302
313
|
});
|
|
303
314
|
const bodyProps = extractBodyProps({
|
|
@@ -325,14 +336,18 @@ var processOperation = args => {
|
|
|
325
336
|
};
|
|
326
337
|
};
|
|
327
338
|
var processPath = args => {
|
|
339
|
+
const rawPathItemParameters = args.pathItem.parameters;
|
|
340
|
+
const pathItemParameters = Array.isArray(rawPathItemParameters) ? rawPathItemParameters : [];
|
|
328
341
|
const tools = [];
|
|
329
342
|
for (const [method, operation] of Object.entries(args.pathItem)) {
|
|
343
|
+
if (method === "parameters") continue;
|
|
330
344
|
const tool = processOperation({
|
|
331
345
|
pathTemplate: args.pathTemplate,
|
|
332
346
|
method,
|
|
333
347
|
operation,
|
|
334
348
|
spec: args.spec,
|
|
335
|
-
options: args.options
|
|
349
|
+
options: args.options,
|
|
350
|
+
pathItemParameters
|
|
336
351
|
});
|
|
337
352
|
if (tool) tools.push(tool);
|
|
338
353
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/http-server-mcp-openapi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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,7 +35,7 @@
|
|
|
35
35
|
"dist"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ttoss/http-server-mcp": "^0.
|
|
38
|
+
"@ttoss/http-server-mcp": "^0.23.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"jest": "^30.4.2",
|