@ivotoby/openapi-mcp-server 1.6.0 → 1.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.
Files changed (3) hide show
  1. package/dist/bundle.js +28 -18
  2. package/dist/cli.js +28 -18
  3. package/package.json +4 -2
package/dist/bundle.js CHANGED
@@ -14286,7 +14286,7 @@ var js_yaml_default = jsYaml;
14286
14286
  // src/openapi-loader.ts
14287
14287
  import crypto from "crypto";
14288
14288
 
14289
- // src/abbreviations.ts
14289
+ // src/utils/abbreviations.ts
14290
14290
  var REVISED_COMMON_WORDS_TO_REMOVE = [
14291
14291
  "controller",
14292
14292
  "api",
@@ -14371,6 +14371,21 @@ var WORD_ABBREVIATIONS = {
14371
14371
  query: "Qry"
14372
14372
  };
14373
14373
 
14374
+ // src/utils/tool-id.ts
14375
+ function parseToolId(toolId) {
14376
+ const [method, pathPart] = toolId.split("::", 2);
14377
+ const path = pathPart ? "/" + pathPart.replace(/-/g, "/") : "";
14378
+ return { method, path };
14379
+ }
14380
+ function sanitizeForToolId(input) {
14381
+ return input.replace(/[^A-Za-z0-9_-]/g, "").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
14382
+ }
14383
+ function generateToolId(method, path) {
14384
+ const cleanPath = path.replace(/^\//, "").replace(/\{([^}]+)\}/g, "$1").replace(/\//g, "-");
14385
+ const sanitizedPath = sanitizeForToolId(cleanPath);
14386
+ return `${method.toUpperCase()}::${sanitizedPath}`;
14387
+ }
14388
+
14374
14389
  // src/openapi-loader.ts
14375
14390
  var OpenAPISpecLoader = class {
14376
14391
  /**
@@ -14562,9 +14577,8 @@ var OpenAPISpecLoader = class {
14562
14577
  continue;
14563
14578
  }
14564
14579
  const op = operation;
14565
- const cleanPath = path.replace(/^\//, "").replace(/\{([^}]+)\}/g, "$1");
14566
- const toolId = `${method.toUpperCase()}-${cleanPath}`.replace(/[^a-zA-Z0-9-]/g, "-");
14567
- let nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
14580
+ const toolId = generateToolId(method, path);
14581
+ const nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
14568
14582
  const name = this.abbreviateOperationId(nameSource);
14569
14583
  const tool = {
14570
14584
  name,
@@ -14574,6 +14588,7 @@ var OpenAPISpecLoader = class {
14574
14588
  properties: {}
14575
14589
  }
14576
14590
  };
14591
+ tool["x-original-path"] = path;
14577
14592
  const requiredParams = [];
14578
14593
  if (op.parameters) {
14579
14594
  for (const param of op.parameters) {
@@ -14940,11 +14955,12 @@ var ToolsManager = class {
14940
14955
  }
14941
14956
  /**
14942
14957
  * Get the path and method from a tool ID
14958
+ *
14959
+ * Note: This converts hyphens back to slashes to reconstruct the original API path.
14960
+ * This is consistent with ApiClient.parseToolId() which needs the actual path for HTTP requests.
14943
14961
  */
14944
14962
  parseToolId(toolId) {
14945
- const [method, ...pathParts] = toolId.split("-");
14946
- const path = "/" + pathParts.join("/").replace(/-/g, "/");
14947
- return { method, path };
14963
+ return parseToolId(toolId);
14948
14964
  }
14949
14965
  };
14950
14966
 
@@ -18394,13 +18410,9 @@ var ApiClient = class {
18394
18410
  if (axios_default.isAxiosError(error)) {
18395
18411
  const axiosError = error;
18396
18412
  if (!isRetry && isAuthError(axiosError)) {
18397
- try {
18398
- const shouldRetry = await this.authProvider.handleAuthError(axiosError);
18399
- if (shouldRetry) {
18400
- return this.executeApiCallWithRetry(toolId, params, true);
18401
- }
18402
- } catch (authHandlerError) {
18403
- throw authHandlerError;
18413
+ const shouldRetry = await this.authProvider.handleAuthError(axiosError);
18414
+ if (shouldRetry) {
18415
+ return this.executeApiCallWithRetry(toolId, params, true);
18404
18416
  }
18405
18417
  }
18406
18418
  throw new Error(
@@ -18413,13 +18425,11 @@ var ApiClient = class {
18413
18425
  /**
18414
18426
  * Parse a tool ID into HTTP method and path
18415
18427
  *
18416
- * @param toolId - Tool ID in format METHOD-path-parts
18428
+ * @param toolId - Tool ID in format METHOD::pathPart
18417
18429
  * @returns Object containing method and path
18418
18430
  */
18419
18431
  parseToolId(toolId) {
18420
- const [method, ...pathParts] = toolId.split("-");
18421
- const path = "/" + pathParts.join("/").replace(/-/g, "/");
18422
- return { method, path };
18432
+ return parseToolId(toolId);
18423
18433
  }
18424
18434
  /**
18425
18435
  * Process query parameters for GET requests
package/dist/cli.js CHANGED
@@ -14286,7 +14286,7 @@ var js_yaml_default = jsYaml;
14286
14286
  // src/openapi-loader.ts
14287
14287
  import crypto from "crypto";
14288
14288
 
14289
- // src/abbreviations.ts
14289
+ // src/utils/abbreviations.ts
14290
14290
  var REVISED_COMMON_WORDS_TO_REMOVE = [
14291
14291
  "controller",
14292
14292
  "api",
@@ -14371,6 +14371,21 @@ var WORD_ABBREVIATIONS = {
14371
14371
  query: "Qry"
14372
14372
  };
14373
14373
 
14374
+ // src/utils/tool-id.ts
14375
+ function parseToolId(toolId) {
14376
+ const [method, pathPart] = toolId.split("::", 2);
14377
+ const path = pathPart ? "/" + pathPart.replace(/-/g, "/") : "";
14378
+ return { method, path };
14379
+ }
14380
+ function sanitizeForToolId(input) {
14381
+ return input.replace(/[^A-Za-z0-9_-]/g, "").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
14382
+ }
14383
+ function generateToolId(method, path) {
14384
+ const cleanPath = path.replace(/^\//, "").replace(/\{([^}]+)\}/g, "$1").replace(/\//g, "-");
14385
+ const sanitizedPath = sanitizeForToolId(cleanPath);
14386
+ return `${method.toUpperCase()}::${sanitizedPath}`;
14387
+ }
14388
+
14374
14389
  // src/openapi-loader.ts
14375
14390
  var OpenAPISpecLoader = class {
14376
14391
  /**
@@ -14562,9 +14577,8 @@ var OpenAPISpecLoader = class {
14562
14577
  continue;
14563
14578
  }
14564
14579
  const op = operation;
14565
- const cleanPath = path.replace(/^\//, "").replace(/\{([^}]+)\}/g, "$1");
14566
- const toolId = `${method.toUpperCase()}-${cleanPath}`.replace(/[^a-zA-Z0-9-]/g, "-");
14567
- let nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
14580
+ const toolId = generateToolId(method, path);
14581
+ const nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
14568
14582
  const name = this.abbreviateOperationId(nameSource);
14569
14583
  const tool = {
14570
14584
  name,
@@ -14574,6 +14588,7 @@ var OpenAPISpecLoader = class {
14574
14588
  properties: {}
14575
14589
  }
14576
14590
  };
14591
+ tool["x-original-path"] = path;
14577
14592
  const requiredParams = [];
14578
14593
  if (op.parameters) {
14579
14594
  for (const param of op.parameters) {
@@ -14940,11 +14955,12 @@ var ToolsManager = class {
14940
14955
  }
14941
14956
  /**
14942
14957
  * Get the path and method from a tool ID
14958
+ *
14959
+ * Note: This converts hyphens back to slashes to reconstruct the original API path.
14960
+ * This is consistent with ApiClient.parseToolId() which needs the actual path for HTTP requests.
14943
14961
  */
14944
14962
  parseToolId(toolId) {
14945
- const [method, ...pathParts] = toolId.split("-");
14946
- const path = "/" + pathParts.join("/").replace(/-/g, "/");
14947
- return { method, path };
14963
+ return parseToolId(toolId);
14948
14964
  }
14949
14965
  };
14950
14966
 
@@ -18394,13 +18410,9 @@ var ApiClient = class {
18394
18410
  if (axios_default.isAxiosError(error)) {
18395
18411
  const axiosError = error;
18396
18412
  if (!isRetry && isAuthError(axiosError)) {
18397
- try {
18398
- const shouldRetry = await this.authProvider.handleAuthError(axiosError);
18399
- if (shouldRetry) {
18400
- return this.executeApiCallWithRetry(toolId, params, true);
18401
- }
18402
- } catch (authHandlerError) {
18403
- throw authHandlerError;
18413
+ const shouldRetry = await this.authProvider.handleAuthError(axiosError);
18414
+ if (shouldRetry) {
18415
+ return this.executeApiCallWithRetry(toolId, params, true);
18404
18416
  }
18405
18417
  }
18406
18418
  throw new Error(
@@ -18413,13 +18425,11 @@ var ApiClient = class {
18413
18425
  /**
18414
18426
  * Parse a tool ID into HTTP method and path
18415
18427
  *
18416
- * @param toolId - Tool ID in format METHOD-path-parts
18428
+ * @param toolId - Tool ID in format METHOD::pathPart
18417
18429
  * @returns Object containing method and path
18418
18430
  */
18419
18431
  parseToolId(toolId) {
18420
- const [method, ...pathParts] = toolId.split("-");
18421
- const path = "/" + pathParts.join("/").replace(/-/g, "/");
18422
- return { method, path };
18432
+ return parseToolId(toolId);
18423
18433
  }
18424
18434
  /**
18425
18435
  * Process query parameters for GET requests
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ivotoby/openapi-mcp-server",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "An MCP server that exposes OpenAPI endpoints as resources",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,7 +30,8 @@
30
30
  "inspect-watch": "node ./scripts/inspect-watch.js",
31
31
  "start": "node bin/mcp-server.js",
32
32
  "test": "vitest run --config vitest.config.ts",
33
- "test:watch": "vitest watch --config vitest.config.ts"
33
+ "test:watch": "vitest watch --config vitest.config.ts",
34
+ "test:coverage": "vitest run --coverage --config vitest.config.ts"
34
35
  },
35
36
  "dependencies": {
36
37
  "@modelcontextprotocol/sdk": "1.11.1",
@@ -49,6 +50,7 @@
49
50
  "@types/yargs": "^17.0.33",
50
51
  "@typescript-eslint/eslint-plugin": "^6.12.0",
51
52
  "@typescript-eslint/parser": "^6.12.0",
53
+ "@vitest/coverage-v8": "^3.1.3",
52
54
  "dotenv": "^16.4.7",
53
55
  "esbuild": "^0.25.1",
54
56
  "eslint": "^8.57.1",