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 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAA6B,MAAM,aAAa,CAAC;AAElE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAU;IAGzB,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,mBAAmB,CAAY;IAGvC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,sBAAsB,CAAU;IAGxC,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,iBAAiB,CAAU;IAGnC,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,eAAe,CAAY;IACnC,OAAO,CAAC,aAAa,CAAU;gBAEnB,MAAM,EAAE,sBAAsB;IAwF1C;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAmB9F;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAM5B;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAM9B;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAOxF;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAK1D;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAS/E;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAK9D;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAOnC;;OAEG;IACH,WAAW,IAAI,QAAQ;IAIvB;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;IAcrB;;;;OAIG;IACH,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Prometheus Metrics Collector
3
+ *
4
+ * Why: Observability for production deployments
5
+ *
6
+ * Tracks:
7
+ * - HTTP requests (status, method, path)
8
+ * - Session lifecycle (active, created, destroyed)
9
+ * - MCP operations (tool calls, duration, errors)
10
+ * - API calls to backend (operation, status, duration)
11
+ */
12
+ import { Registry, Counter, Gauge, Histogram } from 'prom-client';
13
+ export class MetricsCollector {
14
+ registry;
15
+ enabled;
16
+ // HTTP metrics
17
+ httpRequestsTotal;
18
+ httpRequestDuration;
19
+ // Session metrics
20
+ sessionsActive;
21
+ sessionsCreatedTotal;
22
+ sessionsDestroyedTotal;
23
+ // MCP operation metrics
24
+ mcpToolCallsTotal;
25
+ mcpToolCallDuration;
26
+ mcpToolCallErrors;
27
+ // API metrics (calls to backend API)
28
+ apiCallsTotal;
29
+ apiCallDuration;
30
+ apiCallErrors;
31
+ constructor(config) {
32
+ this.enabled = config.enabled;
33
+ this.registry = new Registry();
34
+ const prefix = config.prefix || 'mcp_';
35
+ // HTTP metrics
36
+ this.httpRequestsTotal = new Counter({
37
+ name: `${prefix}http_requests_total`,
38
+ help: 'Total number of HTTP requests',
39
+ labelNames: ['method', 'path', 'status'],
40
+ registers: [this.registry],
41
+ });
42
+ this.httpRequestDuration = new Histogram({
43
+ name: `${prefix}http_request_duration_seconds`,
44
+ help: 'HTTP request duration in seconds',
45
+ labelNames: ['method', 'path', 'status'],
46
+ buckets: [0.001, 0.01, 0.05, 0.1, 0.5, 1, 2, 5],
47
+ registers: [this.registry],
48
+ });
49
+ // Session metrics
50
+ this.sessionsActive = new Gauge({
51
+ name: `${prefix}sessions_active`,
52
+ help: 'Number of active sessions',
53
+ registers: [this.registry],
54
+ });
55
+ this.sessionsCreatedTotal = new Counter({
56
+ name: `${prefix}sessions_created_total`,
57
+ help: 'Total number of sessions created',
58
+ registers: [this.registry],
59
+ });
60
+ this.sessionsDestroyedTotal = new Counter({
61
+ name: `${prefix}sessions_destroyed_total`,
62
+ help: 'Total number of sessions destroyed',
63
+ registers: [this.registry],
64
+ });
65
+ // MCP operation metrics
66
+ this.mcpToolCallsTotal = new Counter({
67
+ name: `${prefix}tool_calls_total`,
68
+ help: 'Total number of MCP tool calls',
69
+ labelNames: ['tool', 'status'],
70
+ registers: [this.registry],
71
+ });
72
+ this.mcpToolCallDuration = new Histogram({
73
+ name: `${prefix}tool_call_duration_seconds`,
74
+ help: 'MCP tool call duration in seconds',
75
+ labelNames: ['tool', 'status'],
76
+ buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10, 30],
77
+ registers: [this.registry],
78
+ });
79
+ this.mcpToolCallErrors = new Counter({
80
+ name: `${prefix}tool_call_errors_total`,
81
+ help: 'Total number of MCP tool call errors',
82
+ labelNames: ['tool', 'error_type'],
83
+ registers: [this.registry],
84
+ });
85
+ // API metrics
86
+ this.apiCallsTotal = new Counter({
87
+ name: `${prefix}api_calls_total`,
88
+ help: 'Total number of API calls to backend',
89
+ labelNames: ['operation', 'status'],
90
+ registers: [this.registry],
91
+ });
92
+ this.apiCallDuration = new Histogram({
93
+ name: `${prefix}api_call_duration_seconds`,
94
+ help: 'API call duration in seconds',
95
+ labelNames: ['operation', 'status'],
96
+ buckets: [0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10],
97
+ registers: [this.registry],
98
+ });
99
+ this.apiCallErrors = new Counter({
100
+ name: `${prefix}api_call_errors_total`,
101
+ help: 'Total number of API call errors',
102
+ labelNames: ['operation', 'error_type'],
103
+ registers: [this.registry],
104
+ });
105
+ }
106
+ /**
107
+ * Record HTTP request
108
+ */
109
+ recordHttpRequest(method, path, status, durationSeconds) {
110
+ if (!this.enabled)
111
+ return;
112
+ this.httpRequestsTotal.inc({
113
+ method,
114
+ path: this.normalizePath(path),
115
+ status: status.toString(),
116
+ });
117
+ this.httpRequestDuration.observe({
118
+ method,
119
+ path: this.normalizePath(path),
120
+ status: status.toString(),
121
+ }, durationSeconds);
122
+ }
123
+ /**
124
+ * Record session created
125
+ */
126
+ recordSessionCreated() {
127
+ if (!this.enabled)
128
+ return;
129
+ this.sessionsCreatedTotal.inc();
130
+ this.sessionsActive.inc();
131
+ }
132
+ /**
133
+ * Record session destroyed
134
+ */
135
+ recordSessionDestroyed() {
136
+ if (!this.enabled)
137
+ return;
138
+ this.sessionsDestroyedTotal.inc();
139
+ this.sessionsActive.dec();
140
+ }
141
+ /**
142
+ * Record MCP tool call
143
+ */
144
+ recordToolCall(tool, status, durationSeconds) {
145
+ if (!this.enabled)
146
+ return;
147
+ this.mcpToolCallsTotal.inc({ tool, status });
148
+ this.mcpToolCallDuration.observe({ tool, status }, durationSeconds);
149
+ }
150
+ /**
151
+ * Record MCP tool call error
152
+ */
153
+ recordToolCallError(tool, errorType) {
154
+ if (!this.enabled)
155
+ return;
156
+ this.mcpToolCallErrors.inc({ tool, error_type: errorType });
157
+ }
158
+ /**
159
+ * Record API call to backend
160
+ */
161
+ recordApiCall(operation, status, durationSeconds) {
162
+ if (!this.enabled)
163
+ return;
164
+ const statusLabel = this.getStatusLabel(status);
165
+ this.apiCallsTotal.inc({ operation, status: statusLabel });
166
+ this.apiCallDuration.observe({ operation, status: statusLabel }, durationSeconds);
167
+ }
168
+ /**
169
+ * Record API call error
170
+ */
171
+ recordApiCallError(operation, errorType) {
172
+ if (!this.enabled)
173
+ return;
174
+ this.apiCallErrors.inc({ operation, error_type: errorType });
175
+ }
176
+ /**
177
+ * Get metrics in Prometheus format
178
+ */
179
+ async getMetrics() {
180
+ if (!this.enabled) {
181
+ return '# Metrics disabled\n';
182
+ }
183
+ return this.registry.metrics();
184
+ }
185
+ /**
186
+ * Get registry (for testing)
187
+ */
188
+ getRegistry() {
189
+ return this.registry;
190
+ }
191
+ /**
192
+ * Normalize path for metrics (remove dynamic segments)
193
+ *
194
+ * Why: Avoid high cardinality in metrics labels
195
+ *
196
+ * Examples:
197
+ * - /mcp?sessionId=abc123 -> /mcp
198
+ * - /metrics -> /metrics
199
+ * - /health -> /health
200
+ */
201
+ normalizePath(path) {
202
+ // Remove query string
203
+ const pathWithoutQuery = path.split('?')[0];
204
+ // Known paths
205
+ if (pathWithoutQuery === '/mcp' ||
206
+ pathWithoutQuery === '/metrics' ||
207
+ pathWithoutQuery === '/health') {
208
+ return pathWithoutQuery;
209
+ }
210
+ return pathWithoutQuery;
211
+ }
212
+ /**
213
+ * Get status label (2xx, 4xx, 5xx)
214
+ *
215
+ * Why: Group similar statuses to reduce cardinality
216
+ */
217
+ getStatusLabel(status) {
218
+ if (status >= 200 && status < 300)
219
+ return '2xx';
220
+ if (status >= 300 && status < 400)
221
+ return '3xx';
222
+ if (status >= 400 && status < 500)
223
+ return '4xx';
224
+ if (status >= 500 && status < 600)
225
+ return '5xx';
226
+ return 'unknown';
227
+ }
228
+ }
229
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * OpenAPI specification parser and indexer
3
+ *
4
+ * Why indexing: Large OpenAPI specs (GitLab has ~200 operations) need fast lookup.
5
+ * Pre-indexing by operationId and path avoids linear search on every tool call.
6
+ */
7
+ import type { OperationInfo, PathInfo } from './types/openapi.js';
8
+ export declare class OpenAPIParser {
9
+ private spec?;
10
+ private index?;
11
+ load(specPath: string): Promise<void>;
12
+ /**
13
+ * Build search index from OpenAPI spec
14
+ *
15
+ * Why upfront: Trading startup time for runtime performance. Index creation
16
+ * happens once; lookups happen on every tool call.
17
+ */
18
+ private buildIndex;
19
+ private extractOperationInfo;
20
+ private extractParameters;
21
+ /**
22
+ * Resolve $ref to parameter definition
23
+ *
24
+ * Why: GitLab spec uses shared parameter definitions (e.g., ProjectIdOrPath).
25
+ * Need to resolve these refs to get actual parameter details.
26
+ */
27
+ private resolveParameter;
28
+ private extractRequestBody;
29
+ private extractSchema;
30
+ getOperation(operationId: string): OperationInfo | undefined;
31
+ getPath(path: string): PathInfo | undefined;
32
+ getBaseUrl(): string;
33
+ getAllOperations(): OperationInfo[];
34
+ }
35
+ //# sourceMappingURL=openapi-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-parser.d.ts","sourceRoot":"","sources":["../src/openapi-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAgB,aAAa,EAAiB,QAAQ,EAA+B,MAAM,oBAAoB,CAAC;AAE5H,qBAAa,aAAa;IACxB,OAAO,CAAC,IAAI,CAAC,CAAqB;IAClC,OAAO,CAAC,KAAK,CAAC,CAAe;IAEvB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IAkClB,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,CAAC,iBAAiB;IAqBzB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,aAAa;IA0BrB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI5D,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI3C,UAAU,IAAI,MAAM;IAKpB,gBAAgB,IAAI,aAAa,EAAE;CAGpC"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * OpenAPI specification parser and indexer
3
+ *
4
+ * Why indexing: Large OpenAPI specs (GitLab has ~200 operations) need fast lookup.
5
+ * Pre-indexing by operationId and path avoids linear search on every tool call.
6
+ */
7
+ import fs from 'fs/promises';
8
+ import { parse as parseYaml } from 'yaml';
9
+ export class OpenAPIParser {
10
+ spec;
11
+ index;
12
+ async load(specPath) {
13
+ const content = await fs.readFile(specPath, 'utf-8');
14
+ // Parse YAML or JSON based on extension
15
+ if (specPath.endsWith('.yaml') || specPath.endsWith('.yml')) {
16
+ this.spec = parseYaml(content);
17
+ }
18
+ else {
19
+ this.spec = JSON.parse(content);
20
+ }
21
+ this.buildIndex();
22
+ }
23
+ /**
24
+ * Build search index from OpenAPI spec
25
+ *
26
+ * Why upfront: Trading startup time for runtime performance. Index creation
27
+ * happens once; lookups happen on every tool call.
28
+ */
29
+ buildIndex() {
30
+ if (!this.spec)
31
+ throw new Error('Spec not loaded');
32
+ const operations = new Map();
33
+ const paths = new Map();
34
+ for (const [path, pathItem] of Object.entries(this.spec.paths || {})) {
35
+ if (!pathItem)
36
+ continue;
37
+ const pathOperations = {};
38
+ for (const method of ['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) {
39
+ const operation = pathItem[method];
40
+ if (!operation)
41
+ continue;
42
+ const operationInfo = this.extractOperationInfo(path, method, operation);
43
+ if (operationInfo.operationId) {
44
+ operations.set(operationInfo.operationId, operationInfo);
45
+ }
46
+ pathOperations[method] = operationInfo;
47
+ }
48
+ paths.set(path, { path, operations: pathOperations });
49
+ }
50
+ this.index = {
51
+ spec: this.spec,
52
+ operations,
53
+ paths,
54
+ };
55
+ }
56
+ extractOperationInfo(path, method, operation) {
57
+ return {
58
+ operationId: operation.operationId || `${method}_${path}`,
59
+ method: method.toUpperCase(),
60
+ path,
61
+ summary: operation.summary,
62
+ description: operation.description,
63
+ parameters: this.extractParameters(operation),
64
+ requestBody: this.extractRequestBody(operation),
65
+ tags: operation.tags,
66
+ };
67
+ }
68
+ extractParameters(operation) {
69
+ if (!operation.parameters)
70
+ return [];
71
+ return operation.parameters
72
+ .map(p => {
73
+ // Resolve $ref to parameter definition
74
+ if ('$ref' in p) {
75
+ return this.resolveParameter(p.$ref);
76
+ }
77
+ return p;
78
+ })
79
+ .filter((p) => p !== null)
80
+ .map(param => ({
81
+ name: param.name,
82
+ in: param.in,
83
+ required: param.required ?? false,
84
+ schema: this.extractSchema(param.schema),
85
+ description: param.description,
86
+ }));
87
+ }
88
+ /**
89
+ * Resolve $ref to parameter definition
90
+ *
91
+ * Why: GitLab spec uses shared parameter definitions (e.g., ProjectIdOrPath).
92
+ * Need to resolve these refs to get actual parameter details.
93
+ */
94
+ resolveParameter(ref) {
95
+ if (!this.spec)
96
+ return null;
97
+ // Extract ref path: #/components/parameters/ProjectIdOrPath => ProjectIdOrPath
98
+ const refName = ref.split('/').pop();
99
+ if (!refName)
100
+ return null;
101
+ const param = this.spec.components?.parameters?.[refName];
102
+ if (!param || '$ref' in param)
103
+ return null;
104
+ return param;
105
+ }
106
+ extractRequestBody(operation) {
107
+ if (!operation.requestBody || '$ref' in operation.requestBody)
108
+ return undefined;
109
+ const body = operation.requestBody;
110
+ const content = {};
111
+ for (const [mediaType, mediaTypeObj] of Object.entries(body.content || {})) {
112
+ if (mediaTypeObj.schema) {
113
+ content[mediaType] = {
114
+ schema: this.extractSchema(mediaTypeObj.schema),
115
+ };
116
+ }
117
+ }
118
+ return {
119
+ required: body.required ?? false,
120
+ content,
121
+ };
122
+ }
123
+ extractSchema(schema) {
124
+ if (!schema)
125
+ return {};
126
+ if ('$ref' in schema)
127
+ return { type: 'object' }; // Simplified: don't resolve refs
128
+ const result = {
129
+ type: schema.type,
130
+ format: schema.format,
131
+ enum: schema.enum,
132
+ default: schema.default,
133
+ };
134
+ if (schema.type === 'array' && schema.items && !('$ref' in schema.items)) {
135
+ result.items = this.extractSchema(schema.items);
136
+ }
137
+ if (schema.type === 'object' && schema.properties) {
138
+ result.properties = {};
139
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
140
+ result.properties[key] = this.extractSchema(propSchema);
141
+ }
142
+ result.required = schema.required;
143
+ }
144
+ return result;
145
+ }
146
+ getOperation(operationId) {
147
+ return this.index?.operations.get(operationId);
148
+ }
149
+ getPath(path) {
150
+ return this.index?.paths.get(path);
151
+ }
152
+ getBaseUrl() {
153
+ const servers = this.spec?.servers;
154
+ return servers?.[0]?.url || '';
155
+ }
156
+ getAllOperations() {
157
+ return Array.from(this.index?.operations.values() || []);
158
+ }
159
+ }
160
+ //# sourceMappingURL=openapi-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi-parser.js","sourceRoot":"","sources":["../src/openapi-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
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
+ import type { Profile } from './types/profile.js';
8
+ export declare class ProfileLoader {
9
+ load(profilePath: string): Promise<Profile>;
10
+ /**
11
+ * Validate semantic rules beyond schema
12
+ *
13
+ * Why separate: Some rules can't be expressed in JSON Schema (e.g.,
14
+ * "if composite=true then steps must exist"). Fail fast with clear messages.
15
+ */
16
+ private validateLogic;
17
+ /**
18
+ * Create a minimal default profile from OpenAPI spec
19
+ *
20
+ * Why: Allows running server without profile for quick exploration.
21
+ * Generates simple pass-through tools for all operations.
22
+ */
23
+ static createDefaultProfile(profileName: string): Profile;
24
+ }
25
+ //# sourceMappingURL=profile-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-loader.d.ts","sourceRoot":"","sources":["../src/profile-loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAoFlD,qBAAa,aAAa;IAClB,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYjD;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAsCrB;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;CAQ1D"}
@@ -0,0 +1,134 @@
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
+ import fs from 'fs/promises';
8
+ import { z } from 'zod';
9
+ // Zod schemas for runtime validation
10
+ const ParameterDefSchema = z.object({
11
+ type: z.enum(['string', 'integer', 'number', 'boolean', 'array', 'object']),
12
+ description: z.string(),
13
+ required: z.boolean().optional(),
14
+ required_for: z.array(z.string()).optional(),
15
+ enum: z.array(z.string()).optional(),
16
+ items: z.object({ type: z.string() }).optional(),
17
+ default: z.unknown().optional(),
18
+ example: z.unknown().optional(),
19
+ });
20
+ const ArrayFormatSchema = z.enum(['brackets', 'indices', 'repeat', 'comma']);
21
+ const CompositeStepSchema = z.object({
22
+ call: z.string(),
23
+ store_as: z.string(),
24
+ });
25
+ const ToolDefSchema = z.object({
26
+ name: z.string(),
27
+ description: z.string(),
28
+ operations: z.record(z.string()).optional(),
29
+ composite: z.boolean().optional(),
30
+ steps: z.array(CompositeStepSchema).optional(),
31
+ partial_results: z.boolean().optional(),
32
+ parameters: z.record(ParameterDefSchema),
33
+ metadata_params: z.array(z.string()).optional(),
34
+ response_fields: z.record(z.array(z.string())).optional(),
35
+ });
36
+ const AuthInterceptorSchema = z.object({
37
+ type: z.enum(['bearer', 'query', 'custom-header']),
38
+ header_name: z.string().optional(),
39
+ query_param: z.string().optional(),
40
+ value_from_env: z.string(),
41
+ }).refine((data) => {
42
+ if (data.type === 'query' && !data.query_param) {
43
+ return false;
44
+ }
45
+ if (data.type === 'custom-header' && !data.header_name) {
46
+ return false;
47
+ }
48
+ return true;
49
+ }, {
50
+ message: 'query type requires query_param, custom-header requires header_name',
51
+ });
52
+ const BaseUrlConfigSchema = z.object({
53
+ value_from_env: z.string(),
54
+ default: z.string().optional(),
55
+ });
56
+ const RateLimitConfigSchema = z.object({
57
+ max_requests_per_minute: z.number().positive(),
58
+ });
59
+ const RetryConfigSchema = z.object({
60
+ max_attempts: z.number().int().positive(),
61
+ backoff_ms: z.array(z.number().positive()),
62
+ retry_on_status: z.array(z.number().int()),
63
+ });
64
+ const InterceptorConfigSchema = z.object({
65
+ auth: AuthInterceptorSchema.optional(),
66
+ base_url: BaseUrlConfigSchema.optional(),
67
+ rate_limit: RateLimitConfigSchema.optional(),
68
+ retry: RetryConfigSchema.optional(),
69
+ array_format: ArrayFormatSchema.optional(),
70
+ });
71
+ const ProfileSchema = z.object({
72
+ profile_name: z.string(),
73
+ description: z.string().optional(),
74
+ tools: z.array(ToolDefSchema),
75
+ interceptors: InterceptorConfigSchema.optional(),
76
+ parameter_aliases: z.record(z.array(z.string())).optional(),
77
+ });
78
+ export class ProfileLoader {
79
+ async load(profilePath) {
80
+ const content = await fs.readFile(profilePath, 'utf-8');
81
+ const json = JSON.parse(content);
82
+ // Validate with Zod - throws detailed error if invalid
83
+ const profile = ProfileSchema.parse(json);
84
+ this.validateLogic(profile);
85
+ return profile;
86
+ }
87
+ /**
88
+ * Validate semantic rules beyond schema
89
+ *
90
+ * Why separate: Some rules can't be expressed in JSON Schema (e.g.,
91
+ * "if composite=true then steps must exist"). Fail fast with clear messages.
92
+ */
93
+ validateLogic(profile) {
94
+ for (const tool of profile.tools) {
95
+ // Composite tools must have steps
96
+ if (tool.composite && (!tool.steps || tool.steps.length === 0)) {
97
+ throw new Error(`Tool '${tool.name}' is marked as composite but has no steps`);
98
+ }
99
+ // Non-composite tools must have operations
100
+ if (!tool.composite && !tool.operations) {
101
+ throw new Error(`Tool '${tool.name}' must have either 'operations' or be marked as 'composite' with 'steps'`);
102
+ }
103
+ // Validate required_for references existing enum values
104
+ for (const [paramName, paramDef] of Object.entries(tool.parameters)) {
105
+ if (paramDef.required_for) {
106
+ const actionParam = tool.parameters['action'];
107
+ if (!actionParam?.enum) {
108
+ throw new Error(`Parameter '${paramName}' in tool '${tool.name}' has 'required_for' but 'action' parameter has no enum`);
109
+ }
110
+ for (const action of paramDef.required_for) {
111
+ if (!actionParam.enum.includes(action)) {
112
+ throw new Error(`Parameter '${paramName}' requires action '${action}' but it's not in action enum: ${actionParam.enum.join(', ')}`);
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ /**
120
+ * Create a minimal default profile from OpenAPI spec
121
+ *
122
+ * Why: Allows running server without profile for quick exploration.
123
+ * Generates simple pass-through tools for all operations.
124
+ */
125
+ static createDefaultProfile(profileName) {
126
+ return {
127
+ profile_name: profileName,
128
+ description: 'Auto-generated default profile',
129
+ tools: [],
130
+ interceptors: {},
131
+ };
132
+ }
133
+ }
134
+ //# 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,32 @@
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
+ private isEmail;
30
+ private isUri;
31
+ }
32
+ //# 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;AAEpE,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;IA4G7B,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,KAAK;CAQd"}