mcp4openapi 0.1.0

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 (209) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +489 -0
  3. package/dist/composite-executor.d.ts +65 -0
  4. package/dist/composite-executor.d.ts.map +1 -0
  5. package/dist/composite-executor.js +147 -0
  6. package/dist/composite-executor.js.map +1 -0
  7. package/dist/constants.d.ts +36 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +36 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/http-transport.d.ts +195 -0
  12. package/dist/http-transport.d.ts.map +1 -0
  13. package/dist/http-transport.js +760 -0
  14. package/dist/http-transport.js.map +1 -0
  15. package/dist/interceptors.d.ts +74 -0
  16. package/dist/interceptors.d.ts.map +1 -0
  17. package/dist/interceptors.js +220 -0
  18. package/dist/interceptors.js.map +1 -0
  19. package/dist/logger.d.ts +81 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +264 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/mcp-server.d.ts +110 -0
  24. package/dist/mcp-server.d.ts.map +1 -0
  25. package/dist/mcp-server.js +568 -0
  26. package/dist/mcp-server.js.map +1 -0
  27. package/dist/metrics.d.ts +86 -0
  28. package/dist/metrics.d.ts.map +1 -0
  29. package/dist/metrics.js +229 -0
  30. package/dist/metrics.js.map +1 -0
  31. package/dist/openapi-parser.d.ts +35 -0
  32. package/dist/openapi-parser.d.ts.map +1 -0
  33. package/dist/openapi-parser.js +160 -0
  34. package/dist/openapi-parser.js.map +1 -0
  35. package/dist/profile-loader.d.ts +25 -0
  36. package/dist/profile-loader.d.ts.map +1 -0
  37. package/dist/profile-loader.js +134 -0
  38. package/dist/profile-loader.js.map +1 -0
  39. package/dist/schema-validator.d.ts +32 -0
  40. package/dist/schema-validator.d.ts.map +1 -0
  41. package/dist/schema-validator.js +126 -0
  42. package/dist/schema-validator.js.map +1 -0
  43. package/dist/scripts/validate-profile.d.ts +9 -0
  44. package/dist/scripts/validate-profile.d.ts.map +1 -0
  45. package/dist/scripts/validate-profile.js +289 -0
  46. package/dist/scripts/validate-profile.js.map +1 -0
  47. package/dist/scripts/validate-schema.d.ts +9 -0
  48. package/dist/scripts/validate-schema.d.ts.map +1 -0
  49. package/dist/scripts/validate-schema.js +84 -0
  50. package/dist/scripts/validate-schema.js.map +1 -0
  51. package/dist/src/composite-executor.d.ts +75 -0
  52. package/dist/src/composite-executor.d.ts.map +1 -0
  53. package/dist/src/composite-executor.js +175 -0
  54. package/dist/src/composite-executor.js.map +1 -0
  55. package/dist/src/constants.d.ts +36 -0
  56. package/dist/src/constants.d.ts.map +1 -0
  57. package/dist/src/constants.js +36 -0
  58. package/dist/src/constants.js.map +1 -0
  59. package/dist/src/dag-executor.d.ts +49 -0
  60. package/dist/src/dag-executor.d.ts.map +1 -0
  61. package/dist/src/dag-executor.js +138 -0
  62. package/dist/src/dag-executor.js.map +1 -0
  63. package/dist/src/errors.d.ts +47 -0
  64. package/dist/src/errors.d.ts.map +1 -0
  65. package/dist/src/errors.js +99 -0
  66. package/dist/src/errors.js.map +1 -0
  67. package/dist/src/generated-schemas.d.ts +661 -0
  68. package/dist/src/generated-schemas.d.ts.map +1 -0
  69. package/dist/src/generated-schemas.js +66 -0
  70. package/dist/src/generated-schemas.js.map +1 -0
  71. package/dist/src/http-client-factory.d.ts +62 -0
  72. package/dist/src/http-client-factory.d.ts.map +1 -0
  73. package/dist/src/http-client-factory.js +121 -0
  74. package/dist/src/http-client-factory.js.map +1 -0
  75. package/dist/src/http-transport.d.ts +194 -0
  76. package/dist/src/http-transport.d.ts.map +1 -0
  77. package/dist/src/http-transport.js +851 -0
  78. package/dist/src/http-transport.js.map +1 -0
  79. package/dist/src/index.d.ts +8 -0
  80. package/dist/src/index.d.ts.map +1 -0
  81. package/dist/src/index.js +59 -0
  82. package/dist/src/index.js.map +1 -0
  83. package/dist/src/interceptors.d.ts +78 -0
  84. package/dist/src/interceptors.d.ts.map +1 -0
  85. package/dist/src/interceptors.js +252 -0
  86. package/dist/src/interceptors.js.map +1 -0
  87. package/dist/src/jsonrpc-validator.d.ts +27 -0
  88. package/dist/src/jsonrpc-validator.d.ts.map +1 -0
  89. package/dist/src/jsonrpc-validator.js +58 -0
  90. package/dist/src/jsonrpc-validator.js.map +1 -0
  91. package/dist/src/lib.d.ts +8 -0
  92. package/dist/src/lib.d.ts.map +1 -0
  93. package/dist/src/lib.js +7 -0
  94. package/dist/src/lib.js.map +1 -0
  95. package/dist/src/logger.d.ts +81 -0
  96. package/dist/src/logger.d.ts.map +1 -0
  97. package/dist/src/logger.js +264 -0
  98. package/dist/src/logger.js.map +1 -0
  99. package/dist/src/mcp-server.d.ts +117 -0
  100. package/dist/src/mcp-server.d.ts.map +1 -0
  101. package/dist/src/mcp-server.js +621 -0
  102. package/dist/src/mcp-server.js.map +1 -0
  103. package/dist/src/metrics.d.ts +86 -0
  104. package/dist/src/metrics.d.ts.map +1 -0
  105. package/dist/src/metrics.js +229 -0
  106. package/dist/src/metrics.js.map +1 -0
  107. package/dist/src/naming-warnings.d.ts +23 -0
  108. package/dist/src/naming-warnings.d.ts.map +1 -0
  109. package/dist/src/naming-warnings.js +83 -0
  110. package/dist/src/naming-warnings.js.map +1 -0
  111. package/dist/src/naming.d.ts +58 -0
  112. package/dist/src/naming.d.ts.map +1 -0
  113. package/dist/src/naming.js +510 -0
  114. package/dist/src/naming.js.map +1 -0
  115. package/dist/src/openapi-parser.d.ts +49 -0
  116. package/dist/src/openapi-parser.d.ts.map +1 -0
  117. package/dist/src/openapi-parser.js +216 -0
  118. package/dist/src/openapi-parser.js.map +1 -0
  119. package/dist/src/profile-loader.d.ts +77 -0
  120. package/dist/src/profile-loader.d.ts.map +1 -0
  121. package/dist/src/profile-loader.js +443 -0
  122. package/dist/src/profile-loader.js.map +1 -0
  123. package/dist/src/schema-validator.d.ts +30 -0
  124. package/dist/src/schema-validator.d.ts.map +1 -0
  125. package/dist/src/schema-validator.js +115 -0
  126. package/dist/src/schema-validator.js.map +1 -0
  127. package/dist/src/testing/fixtures.d.ts +268 -0
  128. package/dist/src/testing/fixtures.d.ts.map +1 -0
  129. package/dist/src/testing/fixtures.js +210 -0
  130. package/dist/src/testing/fixtures.js.map +1 -0
  131. package/dist/src/testing/mock-gitlab-server.d.ts +34 -0
  132. package/dist/src/testing/mock-gitlab-server.d.ts.map +1 -0
  133. package/dist/src/testing/mock-gitlab-server.js +351 -0
  134. package/dist/src/testing/mock-gitlab-server.js.map +1 -0
  135. package/dist/src/testing/mock-utils.d.ts +41 -0
  136. package/dist/src/testing/mock-utils.d.ts.map +1 -0
  137. package/dist/src/testing/mock-utils.js +59 -0
  138. package/dist/src/testing/mock-utils.js.map +1 -0
  139. package/dist/src/testing/test-http-utils.d.ts +52 -0
  140. package/dist/src/testing/test-http-utils.d.ts.map +1 -0
  141. package/dist/src/testing/test-http-utils.js +109 -0
  142. package/dist/src/testing/test-http-utils.js.map +1 -0
  143. package/dist/src/testing/test-types.d.ts +76 -0
  144. package/dist/src/testing/test-types.d.ts.map +1 -0
  145. package/dist/src/testing/test-types.js +7 -0
  146. package/dist/src/testing/test-types.js.map +1 -0
  147. package/dist/src/tool-generator.d.ts +43 -0
  148. package/dist/src/tool-generator.d.ts.map +1 -0
  149. package/dist/src/tool-generator.js +123 -0
  150. package/dist/src/tool-generator.js.map +1 -0
  151. package/dist/src/types/http-transport.d.ts +45 -0
  152. package/dist/src/types/http-transport.d.ts.map +1 -0
  153. package/dist/src/types/http-transport.js +8 -0
  154. package/dist/src/types/http-transport.js.map +1 -0
  155. package/dist/src/types/openapi.d.ts +50 -0
  156. package/dist/src/types/openapi.d.ts.map +1 -0
  157. package/dist/src/types/openapi.js +9 -0
  158. package/dist/src/types/openapi.js.map +1 -0
  159. package/dist/src/types/profile.d.ts +80 -0
  160. package/dist/src/types/profile.d.ts.map +1 -0
  161. package/dist/src/types/profile.js +9 -0
  162. package/dist/src/types/profile.js.map +1 -0
  163. package/dist/src/validation-utils.d.ts +15 -0
  164. package/dist/src/validation-utils.d.ts.map +1 -0
  165. package/dist/src/validation-utils.js +25 -0
  166. package/dist/src/validation-utils.js.map +1 -0
  167. package/dist/testing/fixtures.d.ts +186 -0
  168. package/dist/testing/fixtures.d.ts.map +1 -0
  169. package/dist/testing/fixtures.js +135 -0
  170. package/dist/testing/fixtures.js.map +1 -0
  171. package/dist/testing/http-integration.test.d.ts +7 -0
  172. package/dist/testing/http-integration.test.d.ts.map +1 -0
  173. package/dist/testing/http-integration.test.js +383 -0
  174. package/dist/testing/http-integration.test.js.map +1 -0
  175. package/dist/testing/http-multiuser.test.d.ts +10 -0
  176. package/dist/testing/http-multiuser.test.d.ts.map +1 -0
  177. package/dist/testing/http-multiuser.test.js +255 -0
  178. package/dist/testing/http-multiuser.test.js.map +1 -0
  179. package/dist/testing/integration.test.d.ts +8 -0
  180. package/dist/testing/integration.test.d.ts.map +1 -0
  181. package/dist/testing/integration.test.js +247 -0
  182. package/dist/testing/integration.test.js.map +1 -0
  183. package/dist/testing/mock-gitlab-server.d.ts +34 -0
  184. package/dist/testing/mock-gitlab-server.d.ts.map +1 -0
  185. package/dist/testing/mock-gitlab-server.js +224 -0
  186. package/dist/testing/mock-gitlab-server.js.map +1 -0
  187. package/dist/testing/test-types.d.ts +59 -0
  188. package/dist/testing/test-types.d.ts.map +1 -0
  189. package/dist/testing/test-types.js +7 -0
  190. package/dist/testing/test-types.js.map +1 -0
  191. package/dist/tool-generator.d.ts +43 -0
  192. package/dist/tool-generator.d.ts.map +1 -0
  193. package/dist/tool-generator.js +123 -0
  194. package/dist/tool-generator.js.map +1 -0
  195. package/dist/tsconfig.tsbuildinfo +1 -0
  196. package/dist/types/http-transport.d.ts +39 -0
  197. package/dist/types/http-transport.d.ts.map +1 -0
  198. package/dist/types/http-transport.js +8 -0
  199. package/dist/types/http-transport.js.map +1 -0
  200. package/dist/types/openapi.d.ts +50 -0
  201. package/dist/types/openapi.d.ts.map +1 -0
  202. package/dist/types/openapi.js +9 -0
  203. package/dist/types/openapi.js.map +1 -0
  204. package/dist/types/profile.d.ts +76 -0
  205. package/dist/types/profile.d.ts.map +1 -0
  206. package/dist/types/profile.js +9 -0
  207. package/dist/types/profile.js.map +1 -0
  208. package/package.json +84 -0
  209. package/profile-schema.json +369 -0
@@ -0,0 +1,443 @@
1
+ /**
2
+ * Profile configuration loader and validator
3
+ *
4
+ * Why validation: Profile config comes from user files. Invalid config would
5
+ * cause runtime errors. Validate upfront with clear error messages.
6
+ *
7
+ * ✅ Schemas are now auto-generated from TypeScript types!
8
+ * When adding fields to src/types/profile.ts:
9
+ * 1. Update TypeScript interface (compile-time checking)
10
+ * 2. Run `npm run generate-schemas` (auto-generates JSON + Zod schemas)
11
+ * 3. That's it! No manual sync needed.
12
+ *
13
+ * See IMPLEMENTATION.md for details.
14
+ */
15
+ import fs from 'fs/promises';
16
+ import { ValidationError, ConfigurationError } from './errors.js';
17
+ import { profileSchema, authInterceptorSchema } from './generated-schemas.js';
18
+ import { shortenToolName, NamingStrategy, levenshteinDistance } from './naming.js';
19
+ // Schemas are now auto-generated from TypeScript types!
20
+ // See scripts/generate-schemas.js for details.
21
+ // Custom validations that can't be auto-generated
22
+ const enhancedAuthInterceptorSchema = authInterceptorSchema.refine((data) => {
23
+ if (data.type === 'query' && !data.query_param) {
24
+ return false;
25
+ }
26
+ if (data.type === 'custom-header' && !data.header_name) {
27
+ return false;
28
+ }
29
+ return true;
30
+ }, {
31
+ message: 'query type requires query_param, custom-header requires header_name',
32
+ });
33
+ // Override the auth schema in the profile schema tree
34
+ // Note: This is a workaround since we can't easily modify the generated schema
35
+ const enhancedProfileSchema = profileSchema.transform((data) => {
36
+ // Custom validation for auth interceptor if present
37
+ if (data.interceptors?.auth) {
38
+ enhancedAuthInterceptorSchema.parse(data.interceptors.auth);
39
+ }
40
+ return data;
41
+ });
42
+ export class ProfileLoader {
43
+ async load(profilePath) {
44
+ const content = await fs.readFile(profilePath, 'utf-8');
45
+ const json = JSON.parse(content);
46
+ // Validate with Zod - throws detailed error if invalid
47
+ const profile = enhancedProfileSchema.parse(json);
48
+ this.validateLogic(profile);
49
+ return profile;
50
+ }
51
+ /**
52
+ * Validate semantic rules beyond schema
53
+ *
54
+ * Why separate: Some rules can't be expressed in JSON Schema (e.g.,
55
+ * "if composite=true then steps must exist"). Fail fast with clear messages.
56
+ */
57
+ validateLogic(profile) {
58
+ for (const tool of profile.tools) {
59
+ // Composite tools must have steps
60
+ if (tool.composite && (!tool.steps || tool.steps.length === 0)) {
61
+ throw new ValidationError(`Tool '${tool.name}' is marked as composite but has no steps`, { toolName: tool.name, composite: tool.composite });
62
+ }
63
+ // Non-composite tools must have operations
64
+ if (!tool.composite && !tool.operations) {
65
+ throw new ValidationError(`Tool '${tool.name}' must have either 'operations' or be marked as 'composite' with 'steps'`, { toolName: tool.name, composite: tool.composite });
66
+ }
67
+ // Validate required_for references existing enum values
68
+ for (const [paramName, paramDef] of Object.entries(tool.parameters)) {
69
+ if (paramDef.required_for) {
70
+ const actionParam = tool.parameters['action'];
71
+ if (!actionParam?.enum) {
72
+ throw new ValidationError(`Parameter '${paramName}' in tool '${tool.name}' has 'required_for' but 'action' parameter has no enum`, { toolName: tool.name, paramName, hasActionParam: !!actionParam });
73
+ }
74
+ for (const action of paramDef.required_for) {
75
+ if (!actionParam.enum.includes(action)) {
76
+ throw new ValidationError(`Parameter '${paramName}' requires action '${action}' but it's not in action enum: ${actionParam.enum.join(', ')}`, { toolName: tool.name, paramName, requiredAction: action, availableActions: actionParam.enum });
77
+ }
78
+ }
79
+ }
80
+ }
81
+ // Validate operation keys match action enum or follow {action}_{resourceType} pattern
82
+ if (tool.operations && tool.parameters['action']?.enum) {
83
+ const actionEnum = tool.parameters['action'].enum;
84
+ const resourceTypeParam = tool.parameters['resource_type'];
85
+ const resourceTypeEnum = resourceTypeParam?.enum;
86
+ for (const operationKey of Object.keys(tool.operations)) {
87
+ // Check if operation key is directly in action enum
88
+ if (actionEnum.includes(operationKey)) {
89
+ continue;
90
+ }
91
+ // Check if operation key follows {action}_{resourceType} pattern
92
+ const parts = operationKey.split('_');
93
+ if (parts.length === 2) {
94
+ const [actionPart, resourceTypePart] = parts;
95
+ // Both parts must be valid
96
+ const actionValid = actionEnum.includes(actionPart);
97
+ const resourceTypeValid = resourceTypeEnum ? resourceTypeEnum.includes(resourceTypePart) : true;
98
+ if (actionValid && resourceTypeValid) {
99
+ continue;
100
+ }
101
+ }
102
+ // Generate helpful error message with suggestions
103
+ const suggestions = this.generateOperationKeySuggestions(operationKey, actionEnum, resourceTypeEnum);
104
+ const suggestionText = suggestions.length > 0
105
+ ? ` Did you mean one of: ${suggestions.join(', ')}?`
106
+ : '';
107
+ throw new ValidationError(`Invalid operation key '${operationKey}' in tool '${tool.name}'. ` +
108
+ `Must be an action from enum [${actionEnum.join(', ')}] or follow pattern {action}_{resourceType}.${suggestionText}`, {
109
+ toolName: tool.name,
110
+ operationKey,
111
+ availableActions: actionEnum,
112
+ availableResourceTypes: resourceTypeEnum,
113
+ suggestions
114
+ });
115
+ }
116
+ }
117
+ // Validate composite steps DAG (no circular dependencies)
118
+ if (tool.composite && tool.steps) {
119
+ this.validateCompositeStepsDAG(tool.name, tool.steps);
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Generate helpful suggestions for invalid operation keys
125
+ */
126
+ generateOperationKeySuggestions(invalidKey, actionEnum, resourceTypeEnum) {
127
+ const suggestions = [];
128
+ // Direct action matches (case-insensitive)
129
+ for (const action of actionEnum) {
130
+ if (action.toLowerCase() === invalidKey.toLowerCase()) {
131
+ suggestions.push(action);
132
+ }
133
+ }
134
+ // Levenshtein distance suggestions for actions
135
+ const maxDistance = Math.min(2, invalidKey.length - 1);
136
+ for (const action of actionEnum) {
137
+ if (levenshteinDistance(invalidKey, action) <= maxDistance) {
138
+ suggestions.push(action);
139
+ }
140
+ }
141
+ // Check for {action}_{resourceType} patterns
142
+ if (resourceTypeEnum) {
143
+ for (const action of actionEnum) {
144
+ for (const resourceType of resourceTypeEnum) {
145
+ const compositeKey = `${action}_${resourceType}`;
146
+ if (levenshteinDistance(invalidKey, compositeKey) <= maxDistance) {
147
+ suggestions.push(compositeKey);
148
+ }
149
+ }
150
+ }
151
+ }
152
+ // Remove duplicates and return unique suggestions
153
+ return [...new Set(suggestions)];
154
+ }
155
+ /**
156
+ * Validate composite steps form a DAG (no circular dependencies)
157
+ *
158
+ * Why: Circular dependencies would cause infinite loops or deadlocks.
159
+ * We use DFS with color-coding to detect cycles.
160
+ */
161
+ validateCompositeStepsDAG(toolName, steps) {
162
+ // Build adjacency list: store_as -> list of steps that depend on it
163
+ const graph = new Map();
164
+ const allStoreAs = new Set();
165
+ // Initialize all nodes
166
+ for (const step of steps) {
167
+ allStoreAs.add(step.store_as);
168
+ if (!graph.has(step.store_as)) {
169
+ graph.set(step.store_as, []);
170
+ }
171
+ }
172
+ // Build dependency edges
173
+ for (const step of steps) {
174
+ if (step.depends_on) {
175
+ for (const dep of step.depends_on) {
176
+ // Validate dependency exists
177
+ if (!allStoreAs.has(dep)) {
178
+ throw new ValidationError(`Composite step '${step.store_as}' in tool '${toolName}' depends on '${dep}' but no step produces '${dep}'`, { toolName, stepStoreAs: step.store_as, dependency: dep, availableStoreAs: Array.from(allStoreAs) });
179
+ }
180
+ // Add edge: dep -> step.store_as (dep must complete before step)
181
+ if (!graph.has(dep)) {
182
+ graph.set(dep, []);
183
+ }
184
+ graph.get(dep).push(step.store_as);
185
+ }
186
+ }
187
+ }
188
+ // DFS cycle detection with color-coding
189
+ const visited = new Set(); // Fully processed nodes
190
+ const visiting = new Set(); // Currently being processed (in recursion stack)
191
+ const dfs = (node) => {
192
+ if (visiting.has(node)) {
193
+ throw new ValidationError(`Circular dependency detected in composite steps of tool '${toolName}': ${node} depends on itself`, { toolName, circularNode: node, visitingNodes: Array.from(visiting) });
194
+ }
195
+ if (visited.has(node)) {
196
+ return; // Already fully processed
197
+ }
198
+ visiting.add(node);
199
+ // Visit all neighbors
200
+ const neighbors = graph.get(node) || [];
201
+ for (const neighbor of neighbors) {
202
+ dfs(neighbor);
203
+ }
204
+ visiting.delete(node);
205
+ visited.add(node);
206
+ };
207
+ // Check all nodes for cycles
208
+ for (const node of allStoreAs) {
209
+ if (!visited.has(node)) {
210
+ dfs(node);
211
+ }
212
+ }
213
+ }
214
+ /**
215
+ * Create a default profile with auto-generated tools from OpenAPI spec
216
+ *
217
+ * Why: Allows running server without profile for quick exploration.
218
+ * Generates simple pass-through tools for all operations.
219
+ *
220
+ * Auth Strategy:
221
+ * 1. Parse security scheme from OpenAPI spec
222
+ * 2. If found, generate auth interceptor
223
+ * 3. Fallback to bearer token from API_TOKEN env var
224
+ */
225
+ static createDefaultProfile(profileName, parser) {
226
+ const operations = parser.getAllOperations();
227
+ // Get configuration for name shortening
228
+ const maxLength = parseInt(process.env.MCP_TOOLNAME_MAX || '45', 10);
229
+ const strategyStr = (process.env.MCP_TOOLNAME_STRATEGY || 'none').toLowerCase();
230
+ const warnOnly = (process.env.MCP_TOOLNAME_WARN_ONLY || 'true').toLowerCase() === 'true';
231
+ const minParts = parseInt(process.env.MCP_TOOLNAME_MIN_PARTS || '3', 10);
232
+ const minLength = parseInt(process.env.MCP_TOOLNAME_MIN_LENGTH || '20', 10);
233
+ const strategy = Object.values(NamingStrategy).includes(strategyStr)
234
+ ? strategyStr
235
+ : NamingStrategy.None;
236
+ const shouldShorten = strategy !== NamingStrategy.None && !warnOnly;
237
+ // Convert to OperationForNaming for shortening
238
+ const opsForNaming = operations.map(op => ({
239
+ operationId: op.operationId,
240
+ method: op.method,
241
+ path: op.path,
242
+ tags: op.tags,
243
+ }));
244
+ const tools = operations.map(op => this.generateToolFromOperation(op, shouldShorten ? strategy : NamingStrategy.None, maxLength, opsForNaming, { minParts, minLength }));
245
+ // Generate auth interceptor from OpenAPI security scheme
246
+ const interceptors = this.generateAuthInterceptor(parser);
247
+ return {
248
+ profile_name: profileName,
249
+ description: `Auto-generated default profile with ${tools.length} tools from OpenAPI spec`,
250
+ tools,
251
+ interceptors,
252
+ };
253
+ }
254
+ /**
255
+ * Generate auth interceptor from OpenAPI security scheme
256
+ *
257
+ * Strategy:
258
+ * 1. Parse security scheme from OpenAPI spec
259
+ * 2. If not found, check for force auth override via env vars
260
+ * 3. Map to profile auth interceptor format
261
+ * 4. Use env var name from AUTH_ENV_VAR or default to API_TOKEN
262
+ *
263
+ * Returns empty object if no security scheme found (public API) and no force override
264
+ */
265
+ static generateAuthInterceptor(parser) {
266
+ const securityScheme = parser.getSecurityScheme();
267
+ // Check for force auth override (for APIs with incomplete OpenAPI spec)
268
+ const forceAuth = process.env.AUTH_FORCE === 'true';
269
+ if (!securityScheme && !forceAuth) {
270
+ return {}; // Public API, no auth required
271
+ }
272
+ // Get env var name from environment or use default
273
+ const envVarName = process.env.AUTH_ENV_VAR || 'API_TOKEN';
274
+ const interceptors = {};
275
+ // If force auth is enabled, use env config instead of OpenAPI spec
276
+ if (forceAuth && !securityScheme) {
277
+ const authType = (process.env.AUTH_TYPE || 'bearer').toLowerCase();
278
+ switch (authType) {
279
+ case 'bearer':
280
+ interceptors.auth = {
281
+ type: 'bearer',
282
+ value_from_env: envVarName,
283
+ };
284
+ break;
285
+ case 'query':
286
+ const queryParam = process.env.AUTH_QUERY_PARAM;
287
+ if (!queryParam) {
288
+ throw new ConfigurationError('AUTH_QUERY_PARAM is required when AUTH_TYPE=query', { authType });
289
+ }
290
+ interceptors.auth = {
291
+ type: 'query',
292
+ query_param: queryParam,
293
+ value_from_env: envVarName,
294
+ };
295
+ break;
296
+ case 'custom-header':
297
+ const headerName = process.env.AUTH_HEADER_NAME;
298
+ if (!headerName) {
299
+ throw new ConfigurationError('AUTH_HEADER_NAME is required when AUTH_TYPE=custom-header', { authType });
300
+ }
301
+ interceptors.auth = {
302
+ type: 'custom-header',
303
+ header_name: headerName,
304
+ value_from_env: envVarName,
305
+ };
306
+ break;
307
+ default:
308
+ throw new ConfigurationError(`Invalid AUTH_TYPE: ${authType}. Must be one of: bearer, query, custom-header`, { authType });
309
+ }
310
+ return interceptors;
311
+ }
312
+ // Use OpenAPI security scheme
313
+ if (!securityScheme) {
314
+ return {}; // Shouldn't happen, but TypeScript needs this
315
+ }
316
+ switch (securityScheme.type) {
317
+ case 'bearer':
318
+ // Bearer token in Authorization header
319
+ interceptors.auth = {
320
+ type: 'bearer',
321
+ value_from_env: envVarName,
322
+ };
323
+ break;
324
+ case 'apiKey':
325
+ // API key in header or query
326
+ if (securityScheme.in === 'query' && securityScheme.name) {
327
+ interceptors.auth = {
328
+ type: 'query',
329
+ query_param: securityScheme.name,
330
+ value_from_env: envVarName,
331
+ };
332
+ }
333
+ else if (securityScheme.in === 'header' && securityScheme.name) {
334
+ // Check if it's a standard Authorization header
335
+ if (securityScheme.name.toLowerCase() === 'authorization') {
336
+ interceptors.auth = {
337
+ type: 'bearer',
338
+ value_from_env: envVarName,
339
+ };
340
+ }
341
+ else {
342
+ interceptors.auth = {
343
+ type: 'custom-header',
344
+ header_name: securityScheme.name,
345
+ value_from_env: envVarName,
346
+ };
347
+ }
348
+ }
349
+ break;
350
+ default:
351
+ // Unknown security type, default to bearer
352
+ interceptors.auth = {
353
+ type: 'bearer',
354
+ value_from_env: envVarName,
355
+ };
356
+ }
357
+ return interceptors;
358
+ }
359
+ /**
360
+ * Generate a simple tool from an OpenAPI operation
361
+ *
362
+ * Creates a tool with parameters based on the operation's path/query/header parameters
363
+ * and request body. Uses operationId as tool name and summary/description for tool description.
364
+ */
365
+ static generateToolFromOperation(operation, strategy = NamingStrategy.None, maxLength = 45, allOperations = [], options) {
366
+ const parameters = {};
367
+ // Add path parameters
368
+ for (const param of operation.parameters) {
369
+ parameters[param.name] = {
370
+ type: this.mapOpenAPISchemaToParameterType(param.schema),
371
+ description: param.description || `Parameter ${param.name}`,
372
+ required: param.required,
373
+ };
374
+ }
375
+ // Add request body parameters if present
376
+ if (operation.requestBody?.content) {
377
+ // For simplicity, assume JSON content and flatten the schema
378
+ const jsonContent = operation.requestBody.content['application/json'];
379
+ if (jsonContent?.schema) {
380
+ this.flattenSchemaToParameters(jsonContent.schema, parameters, operation.requestBody.required);
381
+ }
382
+ }
383
+ // Warn if parameter inflation exceeds threshold
384
+ const paramCount = Object.keys(parameters).length;
385
+ if (paramCount > 60) {
386
+ // Using console.warn to avoid adding logger dependency here
387
+ console.warn(`[ProfileLoader] Generated tool has ${paramCount} parameters (>60). Operation: ${operation.operationId} ${operation.method.toUpperCase()} ${operation.path}`);
388
+ }
389
+ // Apply name shortening if strategy is specified
390
+ const opForNaming = {
391
+ operationId: operation.operationId,
392
+ method: operation.method,
393
+ path: operation.path,
394
+ tags: operation.tags,
395
+ };
396
+ const nameResult = shortenToolName(opForNaming, strategy, maxLength, allOperations.length > 0 ? allOperations : [opForNaming], options);
397
+ return {
398
+ name: nameResult.name,
399
+ description: operation.summary || operation.description || `Execute ${operation.method.toUpperCase()} ${operation.path}`,
400
+ operations: {
401
+ 'execute': operation.operationId,
402
+ },
403
+ parameters,
404
+ };
405
+ }
406
+ /**
407
+ * Map OpenAPI schema to parameter type
408
+ */
409
+ static mapOpenAPISchemaToParameterType(schema) {
410
+ switch (schema.type) {
411
+ case 'string':
412
+ return 'string';
413
+ case 'integer':
414
+ return 'integer';
415
+ case 'number':
416
+ return 'number';
417
+ case 'boolean':
418
+ return 'boolean';
419
+ case 'array':
420
+ return 'array';
421
+ case 'object':
422
+ return 'object';
423
+ default:
424
+ return 'string'; // fallback
425
+ }
426
+ }
427
+ /**
428
+ * Recursively flatten schema properties to parameters
429
+ */
430
+ static flattenSchemaToParameters(schema, parameters, required = false) {
431
+ if (schema.type === 'object' && schema.properties) {
432
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
433
+ const isRequired = schema.required?.includes(propName) || required;
434
+ parameters[propName] = {
435
+ type: this.mapOpenAPISchemaToParameterType(propSchema),
436
+ description: `Property ${propName}`,
437
+ required: isRequired,
438
+ };
439
+ }
440
+ }
441
+ }
442
+ }
443
+ //# sourceMappingURL=profile-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-loader.js","sourceRoot":"","sources":["../../src/profile-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Request body schema validator
3
+ *
4
+ * Why: Catch invalid requests before sending to API. Better error messages for users.
5
+ * Validates against OpenAPI schema definitions.
6
+ */
7
+ import type { SchemaInfo, OperationInfo } from './types/openapi.js';
8
+ export interface ValidationResult {
9
+ valid: boolean;
10
+ errors?: ValidationError[];
11
+ }
12
+ export interface ValidationError {
13
+ path: string;
14
+ message: string;
15
+ schema: SchemaInfo;
16
+ value: unknown;
17
+ }
18
+ export declare class SchemaValidator {
19
+ /**
20
+ * Validate request body against OpenAPI schema
21
+ *
22
+ * Why: Prevents sending malformed requests. OpenAPI schema is the source of truth.
23
+ */
24
+ validateRequestBody(operation: OperationInfo, body: Record<string, unknown>): ValidationResult;
25
+ /**
26
+ * Recursively validate data against schema
27
+ */
28
+ private validateAgainstSchema;
29
+ }
30
+ //# sourceMappingURL=schema-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-validator.d.ts","sourceRoot":"","sources":["../../src/schema-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGpE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,eAAe;IAC1B;;;;OAIG;IACH,mBAAmB,CACjB,SAAS,EAAE,aAAa,EACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,gBAAgB;IAgBnB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CA4G9B"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Request body schema validator
3
+ *
4
+ * Why: Catch invalid requests before sending to API. Better error messages for users.
5
+ * Validates against OpenAPI schema definitions.
6
+ */
7
+ import { isEmail, isUri } from './validation-utils.js';
8
+ export class SchemaValidator {
9
+ /**
10
+ * Validate request body against OpenAPI schema
11
+ *
12
+ * Why: Prevents sending malformed requests. OpenAPI schema is the source of truth.
13
+ */
14
+ validateRequestBody(operation, body) {
15
+ if (!operation.requestBody?.content['application/json']?.schema) {
16
+ return { valid: true };
17
+ }
18
+ const schema = operation.requestBody.content['application/json'].schema;
19
+ const errors = [];
20
+ this.validateAgainstSchema(body, schema, '', errors);
21
+ return {
22
+ valid: errors.length === 0,
23
+ errors: errors.length > 0 ? errors : undefined,
24
+ };
25
+ }
26
+ /**
27
+ * Recursively validate data against schema
28
+ */
29
+ validateAgainstSchema(data, schema, path, errors) {
30
+ // Null/undefined handling
31
+ if (data === null || data === undefined) {
32
+ if (schema.type && schema.type !== 'null') {
33
+ errors.push({
34
+ path: path || '(root)',
35
+ message: `Expected ${schema.type}, got ${data}`,
36
+ schema,
37
+ value: data,
38
+ });
39
+ }
40
+ return;
41
+ }
42
+ // Type validation
43
+ if (schema.type) {
44
+ const actualType = Array.isArray(data) ? 'array' : typeof data;
45
+ if (actualType !== schema.type) {
46
+ errors.push({
47
+ path: path || '(root)',
48
+ message: `Expected ${schema.type}, got ${actualType}`,
49
+ schema,
50
+ value: data,
51
+ });
52
+ return; // Stop validation if type is wrong
53
+ }
54
+ }
55
+ // Enum validation
56
+ // Note: Using 'as any' here is safe - we're checking if value exists in enum array
57
+ // TypeScript doesn't know the enum values at compile time
58
+ if (schema.enum && !schema.enum.includes(data)) {
59
+ errors.push({
60
+ path: path || '(root)',
61
+ message: `Value must be one of: ${schema.enum.join(', ')}`,
62
+ schema,
63
+ value: data,
64
+ });
65
+ }
66
+ // Object properties validation
67
+ if (schema.type === 'object' && schema.properties) {
68
+ const obj = data;
69
+ // Check required properties
70
+ for (const required of schema.required || []) {
71
+ if (obj[required] === undefined) {
72
+ errors.push({
73
+ path: path ? `${path}.${required}` : required,
74
+ message: 'Required property is missing',
75
+ schema,
76
+ value: undefined,
77
+ });
78
+ }
79
+ }
80
+ // Validate each property
81
+ for (const [key, value] of Object.entries(obj)) {
82
+ if (schema.properties[key]) {
83
+ this.validateAgainstSchema(value, schema.properties[key], path ? `${path}.${key}` : key, errors);
84
+ }
85
+ // Note: Not validating additionalProperties (too strict for most APIs)
86
+ }
87
+ }
88
+ // Array items validation
89
+ if (schema.type === 'array' && schema.items && Array.isArray(data)) {
90
+ data.forEach((item, index) => {
91
+ this.validateAgainstSchema(item, schema.items, `${path}[${index}]`, errors);
92
+ });
93
+ }
94
+ // String format validation (basic)
95
+ if (schema.type === 'string' && schema.format && typeof data === 'string') {
96
+ if (schema.format === 'email' && !isEmail(data)) {
97
+ errors.push({
98
+ path: path || '(root)',
99
+ message: 'Invalid email format',
100
+ schema,
101
+ value: data,
102
+ });
103
+ }
104
+ if (schema.format === 'uri' && !isUri(data)) {
105
+ errors.push({
106
+ path: path || '(root)',
107
+ message: 'Invalid URI format',
108
+ schema,
109
+ value: data,
110
+ });
111
+ }
112
+ }
113
+ }
114
+ }
115
+ //# sourceMappingURL=schema-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-validator.js","sourceRoot":"","sources":["../../src/schema-validator.ts"],"names":[],"mappings":"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"}