@ampeco/public-api-mcp 0.3.0 → 3.98.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 (42) hide show
  1. package/README.md +61 -0
  2. package/dist/build/index.js +52 -7
  3. package/dist/build/index.js.map +1 -1
  4. package/dist/build/types.d.ts +24 -2
  5. package/dist/build/types.d.ts.map +1 -1
  6. package/dist/generated/build-stats.json +11 -5
  7. package/dist/generated/endpoints.json +398 -29
  8. package/dist/generated/response-schemas.json +85111 -0
  9. package/dist/generated/schemas.d.ts +326 -141
  10. package/dist/generated/schemas.d.ts.map +1 -1
  11. package/dist/generated/schemas.js +77 -18
  12. package/dist/generated/schemas.js.map +1 -1
  13. package/dist/generated/schemas.ts +79 -18
  14. package/dist/server/factory.d.ts +2 -2
  15. package/dist/server/factory.d.ts.map +1 -1
  16. package/dist/server/factory.js +129 -27
  17. package/dist/server/factory.js.map +1 -1
  18. package/dist/server/factory.test.js +5 -5
  19. package/dist/server/factory.test.js.map +1 -1
  20. package/dist/server/http.d.ts.map +1 -1
  21. package/dist/server/http.js +4 -2
  22. package/dist/server/http.js.map +1 -1
  23. package/dist/server/index.js +5 -2
  24. package/dist/server/index.js.map +1 -1
  25. package/dist/server/loader.d.ts +6 -1
  26. package/dist/server/loader.d.ts.map +1 -1
  27. package/dist/server/loader.js +9 -0
  28. package/dist/server/loader.js.map +1 -1
  29. package/dist/server/resources/handlers.js +2 -2
  30. package/dist/server/resources/handlers.js.map +1 -1
  31. package/dist/server/stdio.d.ts.map +1 -1
  32. package/dist/server/stdio.js +4 -2
  33. package/dist/server/stdio.js.map +1 -1
  34. package/dist/server/utils/response-transformer.d.ts +78 -0
  35. package/dist/server/utils/response-transformer.d.ts.map +1 -0
  36. package/dist/server/utils/response-transformer.js +423 -0
  37. package/dist/server/utils/response-transformer.js.map +1 -0
  38. package/dist/server/utils/response-transformer.test.d.ts +2 -0
  39. package/dist/server/utils/response-transformer.test.d.ts.map +1 -0
  40. package/dist/server/utils/response-transformer.test.js +103 -0
  41. package/dist/server/utils/response-transformer.test.js.map +1 -0
  42. package/package.json +2 -1
@@ -0,0 +1,423 @@
1
+ /**
2
+ * Response transformation utilities for handling large API responses
3
+ *
4
+ * This module implements schema-driven smart response transformation to:
5
+ * - Preserve critical pagination metadata
6
+ * - Provide statistical summaries (min/max/sum/avg/median/percentiles)
7
+ * - Include categorical distributions
8
+ * - Sample representative items
9
+ * - Dramatically reduce token usage (80-95% for large responses)
10
+ */
11
+ /**
12
+ * Detect if response needs transformation
13
+ */
14
+ export function shouldTransform(response, options) {
15
+ const maxSize = options.maxResponseSize || 20000;
16
+ const responseText = JSON.stringify(response);
17
+ if (responseText.length < maxSize) {
18
+ return false;
19
+ }
20
+ // Check if response contains arrays that could be summarized
21
+ return hasLargeArrays(response);
22
+ }
23
+ /**
24
+ * Check if response contains large arrays
25
+ */
26
+ function hasLargeArrays(obj) {
27
+ if (Array.isArray(obj) && obj.length > 10) {
28
+ return true;
29
+ }
30
+ if (typeof obj === "object" && obj !== null) {
31
+ for (const value of Object.values(obj)) {
32
+ if (Array.isArray(value) && value.length > 10) {
33
+ return true;
34
+ }
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ /**
40
+ * Extract pagination metadata from response
41
+ */
42
+ function extractPaginationMetadata(response) {
43
+ const metadata = {};
44
+ // Common pagination patterns
45
+ const paginationKeys = [
46
+ "pagination",
47
+ "paging",
48
+ "page",
49
+ "cursor",
50
+ "nextCursor",
51
+ "next",
52
+ "nextPage",
53
+ "hasMore",
54
+ "hasNext",
55
+ "total",
56
+ "totalCount",
57
+ "count",
58
+ "limit",
59
+ "offset",
60
+ "size",
61
+ "totalPages",
62
+ "currentPage",
63
+ ];
64
+ // Extract pagination from top level
65
+ for (const key of paginationKeys) {
66
+ if (key in response) {
67
+ metadata[key] = response[key];
68
+ }
69
+ }
70
+ // Check for nested pagination object
71
+ if (response.pagination && typeof response.pagination === "object") {
72
+ metadata.pagination = response.pagination;
73
+ }
74
+ if (response.meta && typeof response.meta === "object") {
75
+ metadata.meta = response.meta;
76
+ }
77
+ return metadata;
78
+ }
79
+ /**
80
+ * Compute statistics for numeric field
81
+ */
82
+ function computeNumericStats(values) {
83
+ if (values.length === 0) {
84
+ return { min: 0, max: 0, avg: 0, sum: 0, median: 0 };
85
+ }
86
+ const sorted = [...values].sort((a, b) => a - b);
87
+ const sum = values.reduce((acc, val) => acc + val, 0);
88
+ const percentile = (p) => {
89
+ const index = Math.ceil((p / 100) * sorted.length) - 1;
90
+ return sorted[Math.max(0, index)];
91
+ };
92
+ return {
93
+ min: sorted[0],
94
+ max: sorted[sorted.length - 1],
95
+ avg: sum / values.length,
96
+ sum: sum,
97
+ median: percentile(50),
98
+ p25: percentile(25),
99
+ p75: percentile(75),
100
+ p95: percentile(95),
101
+ };
102
+ }
103
+ /**
104
+ * Compute distribution for categorical field
105
+ */
106
+ function computeDistribution(values) {
107
+ const distribution = {};
108
+ for (const value of values) {
109
+ const key = String(value);
110
+ distribution[key] = (distribution[key] || 0) + 1;
111
+ }
112
+ return distribution;
113
+ }
114
+ /**
115
+ * Extract field types from OpenAPI schema (SCHEMA-DRIVEN APPROACH)
116
+ * Uses improved ID field detection and categorical field filtering
117
+ */
118
+ function extractFieldTypesFromSchema(schema) {
119
+ try {
120
+ const numeric = [];
121
+ const categorical = [];
122
+ if (!schema || typeof schema !== "object") {
123
+ return { numeric, categorical };
124
+ }
125
+ // Handle case where schema is array schema directly
126
+ if (schema.type === "array" && schema.items) {
127
+ return extractFieldTypesFromSchema(schema.items);
128
+ }
129
+ if (schema.type !== "object" || !schema.properties) {
130
+ return { numeric, categorical };
131
+ }
132
+ for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {
133
+ // IMPROVED: More precise ID field detection
134
+ // Only skip fields that are clearly IDs (exact match or suffix pattern)
135
+ const isIdField = /^id$|^.*[_-]id$/i.test(fieldName) || // Matches: id, user_id, session-id
136
+ /^.*Id$/i.test(fieldName); // Matches: userId, sessionId
137
+ if (isIdField) {
138
+ continue; // Skip ID fields for statistics
139
+ }
140
+ // Numeric fields: number or integer type
141
+ if (fieldSchema.type === "number" || fieldSchema.type === "integer") {
142
+ numeric.push(fieldName);
143
+ }
144
+ // Categorical fields: enums or strings (excluding dates)
145
+ else if (fieldSchema.enum && fieldSchema.enum.length > 0) {
146
+ // Only include enums with reasonable cardinality
147
+ if (fieldSchema.enum.length <= 50) {
148
+ // Max 50 distinct values
149
+ categorical.push(fieldName);
150
+ }
151
+ }
152
+ else if (fieldSchema.type === "string" &&
153
+ !fieldSchema.format?.includes("date") &&
154
+ !fieldSchema.format?.includes("time") &&
155
+ !fieldSchema.format?.includes("uuid") // Exclude UUIDs
156
+ ) {
157
+ // Add heuristics to avoid free-text fields
158
+ const likelyFreeText = [
159
+ "description",
160
+ "comment",
161
+ "note",
162
+ "text",
163
+ "message",
164
+ "body",
165
+ "content",
166
+ ].some((keyword) => fieldName.toLowerCase().includes(keyword));
167
+ // Check for max length constraint (long strings unlikely to be categorical)
168
+ const hasLongMaxLength = fieldSchema.maxLength && fieldSchema.maxLength > 100;
169
+ if (!likelyFreeText && !hasLongMaxLength) {
170
+ // Mark as categorical but will be validated at runtime
171
+ categorical.push(fieldName);
172
+ }
173
+ }
174
+ }
175
+ return { numeric, categorical };
176
+ }
177
+ catch (error) {
178
+ // Log error and return empty (will fallback to runtime detection)
179
+ console.error("[Transformer] Error extracting field types from schema:", error);
180
+ return { numeric: [], categorical: [] };
181
+ }
182
+ }
183
+ /**
184
+ * Auto-detect numeric and categorical fields (FALLBACK: runtime detection)
185
+ * This is used when schema is not available or as validation
186
+ */
187
+ function detectFieldTypes(items) {
188
+ if (items.length === 0) {
189
+ return { numeric: [], categorical: [] };
190
+ }
191
+ const numeric = [];
192
+ const categorical = [];
193
+ const sampleItem = items[0];
194
+ for (const [key, value] of Object.entries(sampleItem)) {
195
+ // IMPROVED: Use same precise ID detection
196
+ const isIdField = /^id$|^.*[_-]id$/i.test(key) || /^.*Id$/i.test(key);
197
+ if (isIdField) {
198
+ continue;
199
+ }
200
+ if (typeof value === "number") {
201
+ numeric.push(key);
202
+ }
203
+ else if (typeof value === "string" || typeof value === "boolean") {
204
+ // Only track categorical if field has reasonable cardinality
205
+ const uniqueValues = new Set(items.slice(0, 100).map((item) => item[key]));
206
+ if (uniqueValues.size <= 20) {
207
+ categorical.push(key);
208
+ }
209
+ }
210
+ }
211
+ return { numeric, categorical };
212
+ }
213
+ /**
214
+ * Transform array data with statistics and sampling
215
+ */
216
+ function transformArray(items, arrayName, options, responseSchema // Optional OpenAPI response schema
217
+ ) {
218
+ const sampleSize = options.sampleSize || 5;
219
+ let numericFields = [];
220
+ let categoricalFields = [];
221
+ // Try schema-driven detection first (with error handling)
222
+ if (responseSchema) {
223
+ try {
224
+ console.error("[Transformer] Using schema-driven field detection");
225
+ // Find the array schema in the response schema
226
+ let arrayItemSchema = null;
227
+ if (responseSchema.properties?.[arrayName]?.items) {
228
+ arrayItemSchema = responseSchema.properties[arrayName].items;
229
+ }
230
+ else if (responseSchema.type === "array") {
231
+ arrayItemSchema = responseSchema.items;
232
+ }
233
+ if (arrayItemSchema) {
234
+ const schemaFields = extractFieldTypesFromSchema(arrayItemSchema);
235
+ numericFields = schemaFields.numeric;
236
+ categoricalFields = schemaFields.categorical;
237
+ console.error(`[Transformer] Schema detected ${numericFields.length} numeric fields, ` +
238
+ `${categoricalFields.length} categorical fields`);
239
+ }
240
+ }
241
+ catch (error) {
242
+ console.error("[Transformer] Error in schema-driven detection, falling back to runtime:", error);
243
+ }
244
+ }
245
+ // Fallback to runtime detection if schema detection didn't work
246
+ if (numericFields.length === 0 && categoricalFields.length === 0) {
247
+ console.error("[Transformer] Falling back to runtime field detection");
248
+ try {
249
+ const detected = detectFieldTypes(items);
250
+ numericFields = detected.numeric;
251
+ categoricalFields = detected.categorical;
252
+ }
253
+ catch (error) {
254
+ console.error("[Transformer] Runtime detection failed:", error);
255
+ // Continue with empty field lists (will still return sample and count)
256
+ }
257
+ }
258
+ const result = {
259
+ arrayName,
260
+ count: items.length,
261
+ sample: items.slice(0, Math.min(sampleSize, items.length)),
262
+ };
263
+ // Compute statistics if enabled
264
+ if (options.computeStats !== false) {
265
+ const statistics = {
266
+ count: items.length,
267
+ };
268
+ // Numeric statistics
269
+ if (numericFields.length > 0) {
270
+ statistics.numericFields = {};
271
+ for (const field of numericFields) {
272
+ const values = items
273
+ .map((item) => item[field])
274
+ .filter((val) => typeof val === "number" && !isNaN(val));
275
+ if (values.length > 0) {
276
+ statistics.numericFields[field] = computeNumericStats(values);
277
+ }
278
+ }
279
+ }
280
+ // Categorical distributions (with runtime cardinality validation)
281
+ if (options.includeDistribution !== false && categoricalFields.length > 0) {
282
+ statistics.categoricalFields = {};
283
+ for (const field of categoricalFields) {
284
+ const values = items.map((item) => item[field]).filter((val) => val != null);
285
+ if (values.length === 0)
286
+ continue;
287
+ // Runtime cardinality check - only compute distribution if reasonable
288
+ const uniqueValues = new Set(values);
289
+ const cardinality = uniqueValues.size;
290
+ // Only include if cardinality is reasonable relative to dataset size
291
+ const cardinalityRatio = cardinality / values.length;
292
+ if (cardinality <= 50 || cardinalityRatio <= 0.3) {
293
+ // Max 50 values OR <30% unique
294
+ statistics.categoricalFields[field] = computeDistribution(values);
295
+ }
296
+ // Else: skip field (too many unique values, not truly categorical)
297
+ }
298
+ }
299
+ result.statistics = statistics;
300
+ }
301
+ return result;
302
+ }
303
+ /**
304
+ * Main transformation function
305
+ */
306
+ export function transformResponse(response, options = {}, responseSchema // Optional OpenAPI response schema for the endpoint
307
+ ) {
308
+ const startTime = Date.now();
309
+ if (!options.enabled) {
310
+ // Transformation disabled - return original
311
+ return {
312
+ status: response.status || 200,
313
+ metadata: {},
314
+ data: {
315
+ _transformation: {
316
+ applied: false,
317
+ reason: "Transformation disabled",
318
+ originalSize: JSON.stringify(response).length,
319
+ transformedSize: JSON.stringify(response).length,
320
+ timestamp: new Date().toISOString(),
321
+ },
322
+ full: response,
323
+ },
324
+ };
325
+ }
326
+ if (!shouldTransform(response, options)) {
327
+ // Response is small enough - no transformation needed
328
+ return {
329
+ status: response.status || 200,
330
+ metadata: {},
331
+ data: {
332
+ _transformation: {
333
+ applied: false,
334
+ reason: "Response size below threshold",
335
+ originalSize: JSON.stringify(response).length,
336
+ transformedSize: JSON.stringify(response).length,
337
+ timestamp: new Date().toISOString(),
338
+ },
339
+ full: response,
340
+ },
341
+ };
342
+ }
343
+ // Extract pagination metadata
344
+ const metadata = extractPaginationMetadata(response);
345
+ // Find the main data array
346
+ let arrayData = null;
347
+ let arrayName = "data";
348
+ if (Array.isArray(response)) {
349
+ arrayData = response;
350
+ arrayName = "items";
351
+ }
352
+ else if (typeof response === "object") {
353
+ // Common array field names
354
+ const arrayFieldNames = ["data", "items", "results", "records", "list"];
355
+ for (const fieldName of arrayFieldNames) {
356
+ if (Array.isArray(response[fieldName])) {
357
+ arrayData = response[fieldName];
358
+ arrayName = fieldName;
359
+ break;
360
+ }
361
+ }
362
+ // If no common field found, find first large array
363
+ if (!arrayData) {
364
+ for (const [key, value] of Object.entries(response)) {
365
+ if (Array.isArray(value) && value.length > 10) {
366
+ arrayData = value;
367
+ arrayName = key;
368
+ break;
369
+ }
370
+ }
371
+ }
372
+ }
373
+ if (!arrayData) {
374
+ // No array found - return original
375
+ return {
376
+ status: response.status || 200,
377
+ metadata,
378
+ data: {
379
+ _transformation: {
380
+ applied: false,
381
+ reason: "No transformable arrays found",
382
+ originalSize: JSON.stringify(response).length,
383
+ transformedSize: JSON.stringify(response).length,
384
+ timestamp: new Date().toISOString(),
385
+ },
386
+ full: response,
387
+ },
388
+ };
389
+ }
390
+ // Transform the array (pass schema for field detection)
391
+ const transformedArray = transformArray(arrayData, arrayName, options, responseSchema);
392
+ const originalSize = JSON.stringify(response).length;
393
+ const transformedSize = JSON.stringify({
394
+ status: response.status,
395
+ metadata,
396
+ data: transformedArray,
397
+ }).length;
398
+ const result = {
399
+ status: response.status || 200,
400
+ metadata,
401
+ data: {
402
+ ...transformedArray,
403
+ _transformation: {
404
+ applied: true,
405
+ reason: `Large response (${originalSize} bytes) transformed to preserve metadata and provide statistics`,
406
+ originalSize,
407
+ transformedSize,
408
+ timestamp: new Date().toISOString(),
409
+ },
410
+ },
411
+ _originalShape: {
412
+ topLevelKeys: Object.keys(response),
413
+ arrayFields: [{ name: arrayName, length: arrayData.length }],
414
+ scalarFields: Object.keys(response).filter((k) => !Array.isArray(response[k]) && typeof response[k] !== "object"),
415
+ },
416
+ };
417
+ const duration = Date.now() - startTime;
418
+ console.error(`[Response Transformer] Transformed ${arrayName} array (${arrayData.length} items) ` +
419
+ `in ${duration}ms. Size: ${originalSize} → ${transformedSize} bytes ` +
420
+ `(${(((originalSize - transformedSize) / originalSize) * 100).toFixed(1)}% reduction)`);
421
+ return result;
422
+ }
423
+ //# sourceMappingURL=response-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-transformer.js","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=response-transformer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-transformer.test.d.ts","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { transformResponse } from "./response-transformer.js";
3
+ describe("Response Transformer", () => {
4
+ describe("Numeric statistics with sum", () => {
5
+ it("should include sum in numeric field statistics", () => {
6
+ const response = {
7
+ data: [
8
+ { id: 1, price: 100, quantity: 5 },
9
+ { id: 2, price: 200, quantity: 3 },
10
+ { id: 3, price: 150, quantity: 7 },
11
+ { id: 4, price: 300, quantity: 2 },
12
+ { id: 5, price: 250, quantity: 4 },
13
+ { id: 6, price: 180, quantity: 6 },
14
+ { id: 7, price: 220, quantity: 8 },
15
+ { id: 8, price: 280, quantity: 1 },
16
+ { id: 9, price: 190, quantity: 9 },
17
+ { id: 10, price: 210, quantity: 3 },
18
+ { id: 11, price: 240, quantity: 5 },
19
+ ],
20
+ total: 11,
21
+ };
22
+ const result = transformResponse(response, {
23
+ enabled: true,
24
+ maxResponseSize: 100, // Force transformation
25
+ computeStats: true,
26
+ });
27
+ expect(result.data.statistics?.numericFields?.price).toBeDefined();
28
+ expect(result.data.statistics?.numericFields?.quantity).toBeDefined();
29
+ // Verify sum is included
30
+ expect(result.data.statistics?.numericFields?.price.sum).toBe(2320);
31
+ expect(result.data.statistics?.numericFields?.quantity.sum).toBe(53);
32
+ // Verify other stats are still present
33
+ expect(result.data.statistics?.numericFields?.price.min).toBe(100);
34
+ expect(result.data.statistics?.numericFields?.price.max).toBe(300);
35
+ expect(result.data.statistics?.numericFields?.price.avg).toBeCloseTo(210.91, 2);
36
+ });
37
+ it("should handle empty arrays with sum", () => {
38
+ const response = {
39
+ data: [],
40
+ total: 0,
41
+ };
42
+ const result = transformResponse(response, {
43
+ enabled: true,
44
+ maxResponseSize: 0,
45
+ computeStats: true,
46
+ });
47
+ // Empty array shouldn't transform
48
+ expect(result.data._transformation.applied).toBe(false);
49
+ });
50
+ it("should handle single numeric value with sum", () => {
51
+ const response = {
52
+ data: [
53
+ { id: 1, amount: 42 },
54
+ { id: 2, amount: 42 },
55
+ { id: 3, amount: 42 },
56
+ { id: 4, amount: 42 },
57
+ { id: 5, amount: 42 },
58
+ { id: 6, amount: 42 },
59
+ { id: 7, amount: 42 },
60
+ { id: 8, amount: 42 },
61
+ { id: 9, amount: 42 },
62
+ { id: 10, amount: 42 },
63
+ { id: 11, amount: 42 },
64
+ ],
65
+ };
66
+ const result = transformResponse(response, {
67
+ enabled: true,
68
+ maxResponseSize: 100,
69
+ computeStats: true,
70
+ });
71
+ expect(result.data.statistics?.numericFields?.amount).toBeDefined();
72
+ expect(result.data.statistics?.numericFields?.amount.sum).toBe(462); // 11 * 42
73
+ expect(result.data.statistics?.numericFields?.amount.min).toBe(42);
74
+ expect(result.data.statistics?.numericFields?.amount.max).toBe(42);
75
+ expect(result.data.statistics?.numericFields?.amount.avg).toBe(42);
76
+ });
77
+ it("should calculate sum correctly with decimal values", () => {
78
+ const response = {
79
+ data: [
80
+ { id: 1, score: 3.14 },
81
+ { id: 2, score: 2.71 },
82
+ { id: 3, score: 1.41 },
83
+ { id: 4, score: 1.73 },
84
+ { id: 5, score: 2.23 },
85
+ { id: 6, score: 0.57 },
86
+ { id: 7, score: 1.61 },
87
+ { id: 8, score: 2.44 },
88
+ { id: 9, score: 3.33 },
89
+ { id: 10, score: 1.99 },
90
+ { id: 11, score: 4.66 },
91
+ ],
92
+ };
93
+ const result = transformResponse(response, {
94
+ enabled: true,
95
+ maxResponseSize: 100,
96
+ computeStats: true,
97
+ });
98
+ expect(result.data.statistics?.numericFields?.score).toBeDefined();
99
+ expect(result.data.statistics?.numericFields?.score.sum).toBeCloseTo(25.82, 2);
100
+ });
101
+ });
102
+ });
103
+ //# sourceMappingURL=response-transformer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-transformer.test.js","sourceRoot":"","sources":["../../../src/server/utils/response-transformer.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ampeco/public-api-mcp",
3
- "version": "0.3.0",
3
+ "version": "3.98.0",
4
4
  "description": "MCP server that dynamically exposes the AMPECO.CHARGE Public API defined by an OpenAPI 3 specification",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -22,6 +22,7 @@
22
22
  "start": "node dist/cli/index.js",
23
23
  "type-check": "tsc --noEmit",
24
24
  "test": "vitest",
25
+ "package:mcpb": "bash scripts/package-mcpb.sh",
25
26
  "prepublishOnly": "npm run build"
26
27
  },
27
28
  "keywords": [