@ivotoby/openapi-mcp-server 1.2.1 → 1.2.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 +82 -0
- package/dist/bundle.js +235 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,6 +125,7 @@ The server can be configured through environment variables or command line argum
|
|
|
125
125
|
- `HTTP_PORT` - Port for HTTP transport (default: 3000)
|
|
126
126
|
- `HTTP_HOST` - Host for HTTP transport (default: "127.0.0.1")
|
|
127
127
|
- `ENDPOINT_PATH` - Endpoint path for HTTP transport (default: "/mcp")
|
|
128
|
+
- `TOOLS_MODE` - Tools loading mode: "all" (load all endpoint-based tools) or "dynamic" (load only meta-tools) (default: "all")
|
|
128
129
|
|
|
129
130
|
### Command Line Arguments
|
|
130
131
|
|
|
@@ -141,6 +142,61 @@ npx @ivotoby/openapi-mcp-server \
|
|
|
141
142
|
--path /mcp
|
|
142
143
|
```
|
|
143
144
|
|
|
145
|
+
### OpenAPI Schema Processing
|
|
146
|
+
|
|
147
|
+
#### Reference Resolution
|
|
148
|
+
|
|
149
|
+
This MCP server implements robust OpenAPI reference (`$ref`) resolution to ensure accurate representation of API schemas:
|
|
150
|
+
|
|
151
|
+
- **Parameter References**: Fully resolves `$ref` pointers to parameter components in the OpenAPI spec
|
|
152
|
+
- **Schema References**: Handles nested schema references within parameters and request bodies
|
|
153
|
+
- **Recursive References**: Prevents infinite loops by detecting and handling circular references
|
|
154
|
+
- **Nested Properties**: Preserves complex nested object and array structures with all their attributes
|
|
155
|
+
|
|
156
|
+
### Input Schema Composition
|
|
157
|
+
|
|
158
|
+
The server intelligently merges parameters and request bodies into a unified input schema for each tool:
|
|
159
|
+
|
|
160
|
+
- **Parameters + Request Body Merging**: Combines path, query, and body parameters into a single schema
|
|
161
|
+
- **Collision Handling**: Resolves naming conflicts by prefixing body properties that conflict with parameter names
|
|
162
|
+
- **Type Preservation**: Maintains the original type information for all schema elements
|
|
163
|
+
- **Metadata Retention**: Preserves descriptions, formats, defaults, enums, and other schema attributes
|
|
164
|
+
|
|
165
|
+
### Complex Schema Support
|
|
166
|
+
|
|
167
|
+
The MCP server handles various OpenAPI schema complexities:
|
|
168
|
+
|
|
169
|
+
- **Primitive Type Bodies**: Wraps non-object request bodies in a "body" property
|
|
170
|
+
- **Object Bodies**: Flattens object properties into the tool's input schema
|
|
171
|
+
- **Array Bodies**: Properly handles array schemas with their nested item definitions
|
|
172
|
+
- **Required Properties**: Tracks and preserves which parameters and properties are required
|
|
173
|
+
|
|
174
|
+
## Tool Loading & Filtering Options
|
|
175
|
+
|
|
176
|
+
Based on the Stainless article "What We Learned Converting Complex OpenAPI Specs to MCP Servers" (https://www.stainless.com/blog/what-we-learned-converting-complex-openapi-specs-to-mcp-servers), the following flags were added to control which API endpoints (tools) are loaded:
|
|
177
|
+
|
|
178
|
+
- `--tools <all|dynamic>`: Choose to load all tools (default) or only dynamic meta-tools (`list-api-endpoints`, `get-api-endpoint-schema`, `invoke-api-endpoint`).
|
|
179
|
+
- `--tool <toolId>`: Import only specified tool IDs or names. Can be used multiple times.
|
|
180
|
+
- `--tag <tag>`: Import only tools with the specified OpenAPI tag. Can be used multiple times.
|
|
181
|
+
- `--resource <resource>`: Import only tools under the specified resource path prefixes. Can be used multiple times.
|
|
182
|
+
- `--operation <method>`: Import only tools for the specified HTTP methods (get, post, etc). Can be used multiple times.
|
|
183
|
+
|
|
184
|
+
**Examples:**
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Load only dynamic meta-tools
|
|
188
|
+
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools dynamic
|
|
189
|
+
|
|
190
|
+
# Load only the GET /users endpoint tool
|
|
191
|
+
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tool GET-users
|
|
192
|
+
|
|
193
|
+
# Load tools tagged with "user" under the "/users" resource
|
|
194
|
+
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tag user --resource users
|
|
195
|
+
|
|
196
|
+
# Load only POST operations
|
|
197
|
+
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --operation post
|
|
198
|
+
```
|
|
199
|
+
|
|
144
200
|
## Security Considerations
|
|
145
201
|
|
|
146
202
|
- The HTTP transport validates Origin headers to prevent DNS rebinding attacks
|
|
@@ -187,6 +243,32 @@ To see debug logs:
|
|
|
187
243
|
4. Run tests and linting: `npm run typecheck && npm run lint`
|
|
188
244
|
5. Submit a pull request
|
|
189
245
|
|
|
246
|
+
## FAQ
|
|
247
|
+
|
|
248
|
+
**Q: What is a "tool"?**
|
|
249
|
+
A: A tool corresponds to a single API endpoint derived from your OpenAPI specification, exposed as an MCP resource.
|
|
250
|
+
|
|
251
|
+
**Q: How do I filter which tools are loaded?**
|
|
252
|
+
A: Use the `--tool`, `--tag`, `--resource`, and `--operation` flags, or set `TOOLS_MODE=dynamic` for meta-tools only.
|
|
253
|
+
|
|
254
|
+
**Q: When should I use dynamic mode?**
|
|
255
|
+
A: Dynamic mode provides meta-tools (`list-api-endpoints`, `get-api-endpoint-schema`, `invoke-api-endpoint`) to inspect and interact with endpoints without preloading all operations, which is useful for large or changing APIs.
|
|
256
|
+
|
|
257
|
+
**Q: How do I specify custom headers for API requests?**
|
|
258
|
+
A: Use the `--headers` flag or `API_HEADERS` environment variable with `key:value` pairs separated by commas.
|
|
259
|
+
|
|
260
|
+
**Q: Which transport methods are supported?**
|
|
261
|
+
A: The server supports stdio transport (default) for integration with AI systems and HTTP transport (with streaming via SSE) for web clients.
|
|
262
|
+
|
|
263
|
+
**Q: How does the server handle complex OpenAPI schemas with references?**
|
|
264
|
+
A: The server fully resolves `$ref` references in parameters and schemas, preserving nested structures, default values, and other attributes. See the "OpenAPI Schema Processing" section for details on reference resolution and schema composition.
|
|
265
|
+
|
|
266
|
+
**Q: What happens when parameter names conflict with request body properties?**
|
|
267
|
+
A: The server detects naming conflicts and automatically prefixes body property names with `body_` to avoid collisions, ensuring all properties are accessible.
|
|
268
|
+
|
|
269
|
+
**Q: Where can I find development and contribution guidelines?**
|
|
270
|
+
A: See the "For Developers" section above for commands (`npm run build`, `npm run dev`, etc) and pull request workflow.
|
|
271
|
+
|
|
190
272
|
## License
|
|
191
273
|
|
|
192
274
|
MIT
|
package/dist/bundle.js
CHANGED
|
@@ -14399,6 +14399,50 @@ var OpenAPISpecLoader = class {
|
|
|
14399
14399
|
}
|
|
14400
14400
|
}
|
|
14401
14401
|
}
|
|
14402
|
+
/**
|
|
14403
|
+
* Inline `$ref` schemas from components and drop recursive cycles
|
|
14404
|
+
*/
|
|
14405
|
+
inlineSchema(schema2, components, visited) {
|
|
14406
|
+
if ("$ref" in schema2 && typeof schema2.$ref === "string") {
|
|
14407
|
+
const ref = schema2.$ref;
|
|
14408
|
+
const match = ref.match(/^#\/components\/schemas\/(.+)$/);
|
|
14409
|
+
if (match && components) {
|
|
14410
|
+
const name = match[1];
|
|
14411
|
+
if (visited.has(name)) {
|
|
14412
|
+
return {};
|
|
14413
|
+
}
|
|
14414
|
+
const comp = components[name];
|
|
14415
|
+
if (!comp) {
|
|
14416
|
+
return {};
|
|
14417
|
+
}
|
|
14418
|
+
visited.add(name);
|
|
14419
|
+
return this.inlineSchema(comp, components, visited);
|
|
14420
|
+
}
|
|
14421
|
+
}
|
|
14422
|
+
const schemaObj = schema2;
|
|
14423
|
+
if (schemaObj.type === "object" && schemaObj.properties) {
|
|
14424
|
+
const newProps = {};
|
|
14425
|
+
for (const [propName, propSchema] of Object.entries(schemaObj.properties)) {
|
|
14426
|
+
newProps[propName] = this.inlineSchema(
|
|
14427
|
+
propSchema,
|
|
14428
|
+
components,
|
|
14429
|
+
new Set(visited)
|
|
14430
|
+
);
|
|
14431
|
+
}
|
|
14432
|
+
return { ...schemaObj, properties: newProps };
|
|
14433
|
+
}
|
|
14434
|
+
if (schemaObj.type === "array" && schemaObj.items) {
|
|
14435
|
+
return {
|
|
14436
|
+
...schemaObj,
|
|
14437
|
+
items: this.inlineSchema(
|
|
14438
|
+
schemaObj.items,
|
|
14439
|
+
components,
|
|
14440
|
+
new Set(visited)
|
|
14441
|
+
)
|
|
14442
|
+
};
|
|
14443
|
+
}
|
|
14444
|
+
return schemaObj;
|
|
14445
|
+
}
|
|
14402
14446
|
/**
|
|
14403
14447
|
* Parse an OpenAPI specification into a map of tools
|
|
14404
14448
|
*/
|
|
@@ -14408,8 +14452,7 @@ var OpenAPISpecLoader = class {
|
|
|
14408
14452
|
if (!pathItem) continue;
|
|
14409
14453
|
for (const [method, operation] of Object.entries(pathItem)) {
|
|
14410
14454
|
if (method === "parameters" || !operation) continue;
|
|
14411
|
-
if (!["get", "post", "
|
|
14412
|
-
console.log(`Skipping non-HTTP method "${method}" for path ${path}`);
|
|
14455
|
+
if (!["get", "put", "post", "delete", "options", "head", "patch", "trace"].includes(method)) {
|
|
14413
14456
|
continue;
|
|
14414
14457
|
}
|
|
14415
14458
|
const op = operation;
|
|
@@ -14425,26 +14468,84 @@ var OpenAPISpecLoader = class {
|
|
|
14425
14468
|
properties: {}
|
|
14426
14469
|
}
|
|
14427
14470
|
};
|
|
14471
|
+
const requiredParams = [];
|
|
14428
14472
|
if (op.parameters) {
|
|
14429
|
-
const requiredParams = [];
|
|
14430
14473
|
for (const param of op.parameters) {
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
if (
|
|
14434
|
-
|
|
14435
|
-
|
|
14436
|
-
|
|
14437
|
-
|
|
14474
|
+
let paramObj;
|
|
14475
|
+
if (!("name" in param)) {
|
|
14476
|
+
if ("$ref" in param && typeof param.$ref === "string") {
|
|
14477
|
+
const refMatch = param.$ref.match(/^#\/components\/parameters\/(.+)$/);
|
|
14478
|
+
if (refMatch && spec.components?.parameters) {
|
|
14479
|
+
const paramName = refMatch[1];
|
|
14480
|
+
const resolvedParam = spec.components.parameters[paramName];
|
|
14481
|
+
if (!resolvedParam || !("name" in resolvedParam)) continue;
|
|
14482
|
+
paramObj = resolvedParam;
|
|
14483
|
+
} else {
|
|
14484
|
+
continue;
|
|
14485
|
+
}
|
|
14486
|
+
} else {
|
|
14487
|
+
continue;
|
|
14488
|
+
}
|
|
14489
|
+
} else {
|
|
14490
|
+
paramObj = param;
|
|
14491
|
+
}
|
|
14492
|
+
if (paramObj.schema) {
|
|
14493
|
+
const paramSchema = this.inlineSchema(
|
|
14494
|
+
paramObj.schema,
|
|
14495
|
+
spec.components?.schemas,
|
|
14496
|
+
/* @__PURE__ */ new Set()
|
|
14497
|
+
);
|
|
14498
|
+
const paramDef = {
|
|
14499
|
+
description: paramObj.description || `${paramObj.name} parameter`
|
|
14500
|
+
};
|
|
14501
|
+
if (paramSchema.type) {
|
|
14502
|
+
paramDef.type = paramSchema.type;
|
|
14503
|
+
} else {
|
|
14504
|
+
paramDef.type = "string";
|
|
14438
14505
|
}
|
|
14439
|
-
|
|
14440
|
-
|
|
14506
|
+
for (const [key, value] of Object.entries(paramSchema)) {
|
|
14507
|
+
if (key === "type" || key === "description") continue;
|
|
14508
|
+
paramDef[key] = value;
|
|
14509
|
+
}
|
|
14510
|
+
tool.inputSchema.properties[paramObj.name] = paramDef;
|
|
14511
|
+
if (paramObj.required === true) {
|
|
14512
|
+
requiredParams.push(paramObj.name);
|
|
14441
14513
|
}
|
|
14442
14514
|
}
|
|
14443
14515
|
}
|
|
14444
|
-
|
|
14445
|
-
|
|
14516
|
+
}
|
|
14517
|
+
if (op.requestBody && "content" in op.requestBody) {
|
|
14518
|
+
const requestBodyObj = op.requestBody;
|
|
14519
|
+
let mediaTypeObj;
|
|
14520
|
+
if (requestBodyObj.content["application/json"]) {
|
|
14521
|
+
mediaTypeObj = requestBodyObj.content["application/json"];
|
|
14522
|
+
} else if (Object.keys(requestBodyObj.content).length > 0) {
|
|
14523
|
+
const firstContentType = Object.keys(requestBodyObj.content)[0];
|
|
14524
|
+
mediaTypeObj = requestBodyObj.content[firstContentType];
|
|
14525
|
+
}
|
|
14526
|
+
if (mediaTypeObj?.schema) {
|
|
14527
|
+
const inlinedSchema = this.inlineSchema(
|
|
14528
|
+
mediaTypeObj.schema,
|
|
14529
|
+
spec.components?.schemas,
|
|
14530
|
+
/* @__PURE__ */ new Set()
|
|
14531
|
+
);
|
|
14532
|
+
if (inlinedSchema.type === "object" && inlinedSchema.properties) {
|
|
14533
|
+
for (const [propName, propSchema] of Object.entries(inlinedSchema.properties)) {
|
|
14534
|
+
const paramName = tool.inputSchema.properties[propName] ? `body_${propName}` : propName;
|
|
14535
|
+
tool.inputSchema.properties[paramName] = propSchema;
|
|
14536
|
+
if (inlinedSchema.required && inlinedSchema.required.includes(propName)) {
|
|
14537
|
+
requiredParams.push(paramName);
|
|
14538
|
+
}
|
|
14539
|
+
}
|
|
14540
|
+
} else {
|
|
14541
|
+
tool.inputSchema.properties["body"] = inlinedSchema;
|
|
14542
|
+
requiredParams.push("body");
|
|
14543
|
+
}
|
|
14446
14544
|
}
|
|
14447
14545
|
}
|
|
14546
|
+
if (requiredParams.length > 0) {
|
|
14547
|
+
tool.inputSchema.required = requiredParams;
|
|
14548
|
+
}
|
|
14448
14549
|
tools.set(toolId, tool);
|
|
14449
14550
|
}
|
|
14450
14551
|
}
|
|
@@ -14571,16 +14672,103 @@ var OpenAPISpecLoader = class {
|
|
|
14571
14672
|
var ToolsManager = class {
|
|
14572
14673
|
constructor(config) {
|
|
14573
14674
|
this.config = config;
|
|
14675
|
+
this.config.toolsMode = this.config.toolsMode || "all";
|
|
14574
14676
|
this.specLoader = new OpenAPISpecLoader();
|
|
14575
14677
|
}
|
|
14576
14678
|
tools = /* @__PURE__ */ new Map();
|
|
14577
14679
|
specLoader;
|
|
14680
|
+
/**
|
|
14681
|
+
* Create dynamic discovery meta-tools
|
|
14682
|
+
*/
|
|
14683
|
+
createDynamicTools() {
|
|
14684
|
+
const dynamicTools = /* @__PURE__ */ new Map();
|
|
14685
|
+
dynamicTools.set("LIST-API-ENDPOINTS", {
|
|
14686
|
+
name: "list-api-endpoints",
|
|
14687
|
+
description: "List all available API endpoints",
|
|
14688
|
+
inputSchema: { type: "object", properties: {} }
|
|
14689
|
+
});
|
|
14690
|
+
dynamicTools.set("GET-API-ENDPOINT-SCHEMA", {
|
|
14691
|
+
name: "get-api-endpoint-schema",
|
|
14692
|
+
description: "Get the JSON schema for a specified API endpoint",
|
|
14693
|
+
inputSchema: {
|
|
14694
|
+
type: "object",
|
|
14695
|
+
properties: {
|
|
14696
|
+
endpoint: { type: "string", description: "Endpoint path (e.g. /users/{id})" }
|
|
14697
|
+
},
|
|
14698
|
+
required: ["endpoint"]
|
|
14699
|
+
}
|
|
14700
|
+
});
|
|
14701
|
+
dynamicTools.set("INVOKE-API-ENDPOINT", {
|
|
14702
|
+
name: "invoke-api-endpoint",
|
|
14703
|
+
description: "Invoke an API endpoint with provided parameters",
|
|
14704
|
+
inputSchema: {
|
|
14705
|
+
type: "object",
|
|
14706
|
+
properties: {
|
|
14707
|
+
endpoint: { type: "string", description: "Endpoint path to invoke" },
|
|
14708
|
+
params: {
|
|
14709
|
+
type: "object",
|
|
14710
|
+
description: "Parameters for the API call",
|
|
14711
|
+
properties: {}
|
|
14712
|
+
}
|
|
14713
|
+
},
|
|
14714
|
+
required: ["endpoint"]
|
|
14715
|
+
}
|
|
14716
|
+
});
|
|
14717
|
+
return dynamicTools;
|
|
14718
|
+
}
|
|
14578
14719
|
/**
|
|
14579
14720
|
* Initialize tools from the OpenAPI specification
|
|
14580
14721
|
*/
|
|
14581
14722
|
async initialize() {
|
|
14582
14723
|
const spec = await this.specLoader.loadOpenAPISpec(this.config.openApiSpec);
|
|
14583
|
-
this.
|
|
14724
|
+
if (this.config.toolsMode === "dynamic") {
|
|
14725
|
+
this.tools = this.createDynamicTools();
|
|
14726
|
+
return;
|
|
14727
|
+
}
|
|
14728
|
+
const rawTools = this.specLoader.parseOpenAPISpec(spec);
|
|
14729
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
14730
|
+
const includeToolsLower = this.config.includeTools?.map((t) => t.toLowerCase()) || [];
|
|
14731
|
+
const includeOperationsLower = this.config.includeOperations?.map((op) => op.toLowerCase()) || [];
|
|
14732
|
+
const includeResourcesLower = this.config.includeResources || [];
|
|
14733
|
+
const includeTagsLower = this.config.includeTags?.map((tag) => tag.toLowerCase()) || [];
|
|
14734
|
+
const resourcePathsLower = includeResourcesLower.map((res) => ({
|
|
14735
|
+
exact: `/${res}`.toLowerCase(),
|
|
14736
|
+
prefix: `/${res}/`.toLowerCase()
|
|
14737
|
+
}));
|
|
14738
|
+
for (const [toolId, tool] of rawTools.entries()) {
|
|
14739
|
+
if (includeToolsLower.length > 0) {
|
|
14740
|
+
const toolIdLower = toolId.toLowerCase();
|
|
14741
|
+
const toolNameLower = tool.name.toLowerCase();
|
|
14742
|
+
if (!includeToolsLower.includes(toolIdLower) && !includeToolsLower.includes(toolNameLower)) {
|
|
14743
|
+
continue;
|
|
14744
|
+
}
|
|
14745
|
+
}
|
|
14746
|
+
if (includeOperationsLower.length > 0) {
|
|
14747
|
+
const { method } = this.parseToolId(toolId);
|
|
14748
|
+
if (!includeOperationsLower.includes(method.toLowerCase())) {
|
|
14749
|
+
continue;
|
|
14750
|
+
}
|
|
14751
|
+
}
|
|
14752
|
+
if (resourcePathsLower.length > 0) {
|
|
14753
|
+
const { path } = this.parseToolId(toolId);
|
|
14754
|
+
const pathLower = path.toLowerCase();
|
|
14755
|
+
const match = resourcePathsLower.some(
|
|
14756
|
+
(res) => pathLower === res.exact || pathLower.startsWith(res.prefix)
|
|
14757
|
+
);
|
|
14758
|
+
if (!match) continue;
|
|
14759
|
+
}
|
|
14760
|
+
if (includeTagsLower.length > 0) {
|
|
14761
|
+
const { method, path } = this.parseToolId(toolId);
|
|
14762
|
+
const methodLower = method.toLowerCase();
|
|
14763
|
+
const pathItem = spec.paths[path];
|
|
14764
|
+
if (!pathItem) continue;
|
|
14765
|
+
const opObj = pathItem[methodLower];
|
|
14766
|
+
const tags = Array.isArray(opObj?.tags) ? opObj.tags : [];
|
|
14767
|
+
if (!tags.some((tag) => includeTagsLower.includes(tag.toLowerCase()))) continue;
|
|
14768
|
+
}
|
|
14769
|
+
filtered.set(toolId, tool);
|
|
14770
|
+
}
|
|
14771
|
+
this.tools = filtered;
|
|
14584
14772
|
for (const [toolId, tool] of this.tools.entries()) {
|
|
14585
14773
|
console.error(`Registered tool: ${toolId} (${tool.name})`);
|
|
14586
14774
|
}
|
|
@@ -14595,11 +14783,14 @@ var ToolsManager = class {
|
|
|
14595
14783
|
* Find a tool by ID or name
|
|
14596
14784
|
*/
|
|
14597
14785
|
findTool(idOrName) {
|
|
14598
|
-
|
|
14599
|
-
|
|
14786
|
+
const lowerIdOrName = idOrName.toLowerCase();
|
|
14787
|
+
for (const [toolId, tool] of this.tools.entries()) {
|
|
14788
|
+
if (toolId.toLowerCase() === lowerIdOrName) {
|
|
14789
|
+
return { toolId, tool };
|
|
14790
|
+
}
|
|
14600
14791
|
}
|
|
14601
14792
|
for (const [toolId, tool] of this.tools.entries()) {
|
|
14602
|
-
if (tool.name ===
|
|
14793
|
+
if (tool.name.toLowerCase() === lowerIdOrName) {
|
|
14603
14794
|
return { toolId, tool };
|
|
14604
14795
|
}
|
|
14605
14796
|
}
|
|
@@ -22980,6 +23171,26 @@ function loadConfig() {
|
|
|
22980
23171
|
alias: "v",
|
|
22981
23172
|
type: "string",
|
|
22982
23173
|
description: "Server version"
|
|
23174
|
+
}).option("tools", {
|
|
23175
|
+
type: "string",
|
|
23176
|
+
choices: ["all", "dynamic"],
|
|
23177
|
+
description: "Which tools to load: all or dynamic meta-tools"
|
|
23178
|
+
}).option("tool", {
|
|
23179
|
+
type: "array",
|
|
23180
|
+
string: true,
|
|
23181
|
+
description: "Import only specified tool IDs or names"
|
|
23182
|
+
}).option("tag", {
|
|
23183
|
+
type: "array",
|
|
23184
|
+
string: true,
|
|
23185
|
+
description: "Import only tools with specified OpenAPI tags"
|
|
23186
|
+
}).option("resource", {
|
|
23187
|
+
type: "array",
|
|
23188
|
+
string: true,
|
|
23189
|
+
description: "Import only tools under specified resource path prefixes"
|
|
23190
|
+
}).option("operation", {
|
|
23191
|
+
type: "array",
|
|
23192
|
+
string: true,
|
|
23193
|
+
description: "Import only tools for specified HTTP methods (e.g., get, post)"
|
|
22983
23194
|
}).help().parseSync();
|
|
22984
23195
|
let transportType;
|
|
22985
23196
|
if (argv.transport === "http" || process.env.TRANSPORT_TYPE === "http") {
|
|
@@ -23008,7 +23219,12 @@ function loadConfig() {
|
|
|
23008
23219
|
transportType,
|
|
23009
23220
|
httpPort,
|
|
23010
23221
|
httpHost,
|
|
23011
|
-
endpointPath
|
|
23222
|
+
endpointPath,
|
|
23223
|
+
includeTools: argv.tool,
|
|
23224
|
+
includeTags: argv.tag,
|
|
23225
|
+
includeResources: argv.resource,
|
|
23226
|
+
includeOperations: argv.operation,
|
|
23227
|
+
toolsMode: argv.tools || process.env.TOOLS_MODE || "all"
|
|
23012
23228
|
};
|
|
23013
23229
|
}
|
|
23014
23230
|
|