truss-api-mcp 1.0.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +89 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/code-generator.d.ts +6 -0
  8. package/dist/lib/code-generator.d.ts.map +1 -0
  9. package/dist/lib/code-generator.js +890 -0
  10. package/dist/lib/code-generator.js.map +1 -0
  11. package/dist/lib/http-client.d.ts +6 -0
  12. package/dist/lib/http-client.d.ts.map +1 -0
  13. package/dist/lib/http-client.js +76 -0
  14. package/dist/lib/http-client.js.map +1 -0
  15. package/dist/lib/license.d.ts +4 -0
  16. package/dist/lib/license.d.ts.map +1 -0
  17. package/dist/lib/license.js +97 -0
  18. package/dist/lib/license.js.map +1 -0
  19. package/dist/lib/openapi-parser.d.ts +11 -0
  20. package/dist/lib/openapi-parser.d.ts.map +1 -0
  21. package/dist/lib/openapi-parser.js +390 -0
  22. package/dist/lib/openapi-parser.js.map +1 -0
  23. package/dist/lib/schema-validator.d.ts +15 -0
  24. package/dist/lib/schema-validator.d.ts.map +1 -0
  25. package/dist/lib/schema-validator.js +206 -0
  26. package/dist/lib/schema-validator.js.map +1 -0
  27. package/dist/tools/compare-specs.d.ts +3 -0
  28. package/dist/tools/compare-specs.d.ts.map +1 -0
  29. package/dist/tools/compare-specs.js +59 -0
  30. package/dist/tools/compare-specs.js.map +1 -0
  31. package/dist/tools/generate-client.d.ts +3 -0
  32. package/dist/tools/generate-client.d.ts.map +1 -0
  33. package/dist/tools/generate-client.js +65 -0
  34. package/dist/tools/generate-client.js.map +1 -0
  35. package/dist/tools/generate-openapi.d.ts +3 -0
  36. package/dist/tools/generate-openapi.d.ts.map +1 -0
  37. package/dist/tools/generate-openapi.js +57 -0
  38. package/dist/tools/generate-openapi.js.map +1 -0
  39. package/dist/tools/generate-tests.d.ts +3 -0
  40. package/dist/tools/generate-tests.d.ts.map +1 -0
  41. package/dist/tools/generate-tests.js +59 -0
  42. package/dist/tools/generate-tests.js.map +1 -0
  43. package/dist/tools/mock-server.d.ts +3 -0
  44. package/dist/tools/mock-server.d.ts.map +1 -0
  45. package/dist/tools/mock-server.js +60 -0
  46. package/dist/tools/mock-server.js.map +1 -0
  47. package/dist/tools/parse-openapi.d.ts +3 -0
  48. package/dist/tools/parse-openapi.d.ts.map +1 -0
  49. package/dist/tools/parse-openapi.js +48 -0
  50. package/dist/tools/parse-openapi.js.map +1 -0
  51. package/dist/tools/test-endpoint.d.ts +3 -0
  52. package/dist/tools/test-endpoint.d.ts.map +1 -0
  53. package/dist/tools/test-endpoint.js +66 -0
  54. package/dist/tools/test-endpoint.js.map +1 -0
  55. package/dist/tools/validate-response.d.ts +3 -0
  56. package/dist/tools/validate-response.d.ts.map +1 -0
  57. package/dist/tools/validate-response.js +44 -0
  58. package/dist/tools/validate-response.js.map +1 -0
  59. package/dist/types.d.ts +121 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +3 -0
  62. package/dist/types.js.map +1 -0
  63. package/evals/eval-http.ts +163 -0
  64. package/evals/eval-openapi.ts +506 -0
  65. package/evals/run-evals.ts +29 -0
  66. package/glama.json +4 -0
  67. package/package.json +37 -0
  68. package/smithery.yaml +9 -0
  69. package/src/index.ts +110 -0
  70. package/src/lib/code-generator.ts +1045 -0
  71. package/src/lib/http-client.ts +87 -0
  72. package/src/lib/license.ts +121 -0
  73. package/src/lib/openapi-parser.ts +456 -0
  74. package/src/lib/schema-validator.ts +234 -0
  75. package/src/tools/compare-specs.ts +67 -0
  76. package/src/tools/generate-client.ts +75 -0
  77. package/src/tools/generate-openapi.ts +67 -0
  78. package/src/tools/generate-tests.ts +69 -0
  79. package/src/tools/mock-server.ts +68 -0
  80. package/src/tools/parse-openapi.ts +54 -0
  81. package/src/tools/test-endpoint.ts +71 -0
  82. package/src/tools/validate-response.ts +54 -0
  83. package/src/types.ts +156 -0
  84. package/tsconfig.json +19 -0
@@ -0,0 +1,121 @@
1
+ export type LicenseTier = 'free' | 'pro';
2
+ export interface LicenseStatus {
3
+ tier: LicenseTier;
4
+ valid: boolean;
5
+ expiresAt: string | null;
6
+ }
7
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
8
+ export interface HttpRequest {
9
+ method: HttpMethod;
10
+ url: string;
11
+ headers?: Record<string, string>;
12
+ body?: unknown;
13
+ timeout?: number;
14
+ }
15
+ export interface HttpResponse {
16
+ status: number;
17
+ statusText: string;
18
+ headers: Record<string, string>;
19
+ body: unknown;
20
+ timing_ms: number;
21
+ size_bytes: number;
22
+ }
23
+ export interface OpenApiInfo {
24
+ title: string;
25
+ version: string;
26
+ description?: string;
27
+ }
28
+ export interface OpenApiParameter {
29
+ name: string;
30
+ in: 'query' | 'path' | 'header' | 'cookie';
31
+ required: boolean;
32
+ description?: string;
33
+ schema?: JsonSchema;
34
+ }
35
+ export interface OpenApiResponse {
36
+ status: string;
37
+ description: string;
38
+ schema?: JsonSchema;
39
+ }
40
+ export interface OpenApiEndpoint {
41
+ method: string;
42
+ path: string;
43
+ summary: string;
44
+ operationId?: string;
45
+ parameters: OpenApiParameter[];
46
+ requestBody?: JsonSchema;
47
+ responses: OpenApiResponse[];
48
+ tags?: string[];
49
+ }
50
+ export interface ParsedOpenApiSpec {
51
+ info: OpenApiInfo;
52
+ servers?: Array<{
53
+ url: string;
54
+ description?: string;
55
+ }>;
56
+ endpoints: OpenApiEndpoint[];
57
+ }
58
+ export interface JsonSchema {
59
+ type?: string | string[];
60
+ properties?: Record<string, JsonSchema>;
61
+ items?: JsonSchema;
62
+ required?: string[];
63
+ enum?: unknown[];
64
+ format?: string;
65
+ description?: string;
66
+ minimum?: number;
67
+ maximum?: number;
68
+ minLength?: number;
69
+ maxLength?: number;
70
+ pattern?: string;
71
+ additionalProperties?: boolean | JsonSchema;
72
+ oneOf?: JsonSchema[];
73
+ anyOf?: JsonSchema[];
74
+ allOf?: JsonSchema[];
75
+ $ref?: string;
76
+ nullable?: boolean;
77
+ }
78
+ export interface ValidationError {
79
+ path: string;
80
+ message: string;
81
+ expected?: string;
82
+ actual?: string;
83
+ }
84
+ export interface ValidationResult {
85
+ valid: boolean;
86
+ errors: ValidationError[];
87
+ }
88
+ export type CodeLanguage = 'typescript' | 'python' | 'go';
89
+ export type HttpStyle = 'fetch' | 'axios';
90
+ export type TestFramework = 'jest' | 'vitest' | 'pytest';
91
+ export interface SpecChange {
92
+ path: string;
93
+ method?: string;
94
+ description: string;
95
+ }
96
+ export interface SpecComparison {
97
+ breaking_changes: SpecChange[];
98
+ non_breaking: SpecChange[];
99
+ new_endpoints: SpecChange[];
100
+ removed_endpoints: SpecChange[];
101
+ }
102
+ export interface MockRoute {
103
+ method: string;
104
+ path: string;
105
+ status: number;
106
+ response: unknown;
107
+ headers?: Record<string, string>;
108
+ }
109
+ export interface MockServerConfig {
110
+ routes: MockRoute[];
111
+ mock_data: Record<string, unknown>;
112
+ }
113
+ export interface RequestExample {
114
+ method: string;
115
+ url: string;
116
+ request_body?: unknown;
117
+ response_body: unknown;
118
+ status: number;
119
+ headers?: Record<string, string>;
120
+ }
121
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // ── License Types ────────────────────────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,wEAAwE"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Evaluation: HTTP client and response validation
3
+ */
4
+
5
+ import { executeRequest } from '../src/lib/http-client.js';
6
+ import { validateResponse, validateSchema } from '../src/lib/schema-validator.js';
7
+
8
+ interface EvalResult {
9
+ name: string;
10
+ passed: boolean;
11
+ error?: string;
12
+ duration_ms?: number;
13
+ }
14
+
15
+ const results: EvalResult[] = [];
16
+
17
+ async function run(name: string, fn: () => Promise<void>): Promise<void> {
18
+ const start = performance.now();
19
+ try {
20
+ await fn();
21
+ results.push({ name, passed: true, duration_ms: Math.round(performance.now() - start) });
22
+ } catch (err) {
23
+ results.push({
24
+ name,
25
+ passed: false,
26
+ error: err instanceof Error ? err.message : String(err),
27
+ duration_ms: Math.round(performance.now() - start),
28
+ });
29
+ }
30
+ }
31
+
32
+ function assert(condition: boolean, message: string): void {
33
+ if (!condition) throw new Error(message);
34
+ }
35
+
36
+ // ── Tests ───────────────────────────────────────────────────────────
37
+
38
+ await run('GET request to httpbin', async () => {
39
+ const resp = await executeRequest({
40
+ method: 'GET',
41
+ url: 'https://httpbin.org/get',
42
+ headers: { 'X-Test': 'eval' },
43
+ });
44
+
45
+ assert(resp.status === 200, `Expected 200, got ${resp.status}`);
46
+ assert(resp.timing_ms > 0, 'Timing should be positive');
47
+ assert(resp.size_bytes > 0, 'Size should be positive');
48
+ assert(typeof resp.body === 'object', 'Body should be an object');
49
+ });
50
+
51
+ await run('POST request with JSON body', async () => {
52
+ const resp = await executeRequest({
53
+ method: 'POST',
54
+ url: 'https://httpbin.org/post',
55
+ body: { key: 'value', number: 42 },
56
+ });
57
+
58
+ assert(resp.status === 200, `Expected 200, got ${resp.status}`);
59
+ const body = resp.body as Record<string, unknown>;
60
+ assert(typeof body.json === 'object', 'Body should contain parsed JSON');
61
+ });
62
+
63
+ await run('Validate response — matching schema', async () => {
64
+ const result = validateResponse(
65
+ { status: 200, body: { name: 'Test', age: 25, active: true } },
66
+ 200,
67
+ {
68
+ type: 'object',
69
+ required: ['name', 'age'],
70
+ properties: {
71
+ name: { type: 'string' },
72
+ age: { type: 'integer', minimum: 0 },
73
+ active: { type: 'boolean' },
74
+ },
75
+ }
76
+ );
77
+
78
+ assert(result.valid === true, `Expected valid, got errors: ${JSON.stringify(result.errors)}`);
79
+ });
80
+
81
+ await run('Validate response — wrong status', async () => {
82
+ const result = validateResponse(
83
+ { status: 404, body: { error: 'not found' } },
84
+ 200
85
+ );
86
+
87
+ assert(result.valid === false, 'Expected validation failure');
88
+ assert(result.errors.length > 0, 'Expected at least one error');
89
+ assert(result.errors[0].path === '$.status', 'Error should be on status');
90
+ });
91
+
92
+ await run('Validate response — schema mismatch', async () => {
93
+ const result = validateResponse(
94
+ { status: 200, body: { name: 123 } },
95
+ 200,
96
+ {
97
+ type: 'object',
98
+ properties: {
99
+ name: { type: 'string' },
100
+ },
101
+ }
102
+ );
103
+
104
+ assert(result.valid === false, 'Expected validation failure');
105
+ assert(result.errors.some((e) => e.path.includes('name')), 'Error should mention name');
106
+ });
107
+
108
+ await run('Schema validation — required fields', async () => {
109
+ const result = validateSchema(
110
+ { a: 1 },
111
+ { type: 'object', required: ['a', 'b'], properties: { a: { type: 'integer' }, b: { type: 'string' } } }
112
+ );
113
+
114
+ assert(result.valid === false, 'Expected failure — missing required field b');
115
+ assert(result.errors.some((e) => e.message.includes('b')), 'Error should mention field b');
116
+ });
117
+
118
+ await run('Schema validation — enum', async () => {
119
+ const result = validateSchema('red', { enum: ['red', 'green', 'blue'] });
120
+ assert(result.valid === true, 'red should be valid enum value');
121
+
122
+ const result2 = validateSchema('purple', { enum: ['red', 'green', 'blue'] });
123
+ assert(result2.valid === false, 'purple should not be valid enum value');
124
+ });
125
+
126
+ await run('Schema validation — array items', async () => {
127
+ const result = validateSchema(
128
+ [1, 2, 'three'],
129
+ { type: 'array', items: { type: 'integer' } }
130
+ );
131
+
132
+ assert(result.valid === false, 'Array with string item should fail integer validation');
133
+ });
134
+
135
+ await run('Schema validation — string constraints', async () => {
136
+ const result = validateSchema('ab', { type: 'string', minLength: 3 });
137
+ assert(result.valid === false, 'String too short');
138
+
139
+ const result2 = validateSchema('abc', { type: 'string', minLength: 3, maxLength: 5 });
140
+ assert(result2.valid === true, 'String within range');
141
+ });
142
+
143
+ await run('Schema validation — number constraints', async () => {
144
+ const result = validateSchema(5, { type: 'number', minimum: 10 });
145
+ assert(result.valid === false, '5 < minimum 10');
146
+
147
+ const result2 = validateSchema(15, { type: 'number', minimum: 10, maximum: 20 });
148
+ assert(result2.valid === true, '15 within [10, 20]');
149
+ });
150
+
151
+ // ── Report ──────────────────────────────────────────────────────────
152
+
153
+ export { results };
154
+
155
+ const passed = results.filter((r) => r.passed).length;
156
+ const failed = results.filter((r) => !r.passed).length;
157
+
158
+ console.log(`\nHTTP & Validation Evals: ${passed} passed, ${failed} failed\n`);
159
+ for (const r of results) {
160
+ const icon = r.passed ? 'PASS' : 'FAIL';
161
+ console.log(` [${icon}] ${r.name}${r.duration_ms ? ` (${r.duration_ms}ms)` : ''}`);
162
+ if (r.error) console.log(` ${r.error}`);
163
+ }