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,71 @@
1
+ import { z } from 'zod';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { executeRequest } from '../lib/http-client.js';
4
+
5
+ export function registerTestEndpoint(server: McpServer): void {
6
+ server.tool(
7
+ 'test_endpoint',
8
+ 'Send an HTTP request and get a structured response with status, headers, body, timing, and size. Supports GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS.',
9
+ {
10
+ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']).describe('HTTP method'),
11
+ url: z.string().url().describe('Full URL to send the request to'),
12
+ headers: z.record(z.string(), z.string()).optional().describe('Request headers as key-value pairs'),
13
+ body: z.unknown().optional().describe('Request body (auto-serialized to JSON for objects)'),
14
+ timeout: z.number().min(100).max(120000).optional().describe('Request timeout in milliseconds (default: 30000, max: 120000)'),
15
+ },
16
+ async ({ method, url, headers, body, timeout }) => {
17
+ try {
18
+ const response = await executeRequest({
19
+ method,
20
+ url,
21
+ headers: headers as Record<string, string> | undefined,
22
+ body,
23
+ timeout,
24
+ });
25
+
26
+ return {
27
+ content: [
28
+ {
29
+ type: 'text' as const,
30
+ text: JSON.stringify({
31
+ status: response.status,
32
+ statusText: response.statusText,
33
+ headers: response.headers,
34
+ body: response.body,
35
+ timing_ms: response.timing_ms,
36
+ size_bytes: response.size_bytes,
37
+ }, null, 2),
38
+ },
39
+ ],
40
+ };
41
+ } catch (err) {
42
+ const message = err instanceof Error ? err.message : String(err);
43
+
44
+ // Provide helpful error context
45
+ let hint = '';
46
+ if (message.includes('ECONNREFUSED')) {
47
+ hint = 'The server is not running or not accepting connections.';
48
+ } else if (message.includes('ENOTFOUND')) {
49
+ hint = 'DNS lookup failed. Check the URL hostname.';
50
+ } else if (message.includes('timeout') || message.includes('abort')) {
51
+ hint = 'Request timed out. Try increasing the timeout parameter.';
52
+ } else if (message.includes('certificate')) {
53
+ hint = 'SSL/TLS certificate error. The server may have an invalid certificate.';
54
+ }
55
+
56
+ return {
57
+ content: [
58
+ {
59
+ type: 'text' as const,
60
+ text: JSON.stringify({
61
+ error: message,
62
+ hint: hint || undefined,
63
+ }, null, 2),
64
+ },
65
+ ],
66
+ isError: true,
67
+ };
68
+ }
69
+ }
70
+ );
71
+ }
@@ -0,0 +1,54 @@
1
+ import { z } from 'zod';
2
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { validateResponse } from '../lib/schema-validator.js';
4
+
5
+ export function registerValidateResponse(server: McpServer): void {
6
+ server.tool(
7
+ 'validate_response',
8
+ 'Validate an API response against an expected HTTP status code and optional JSON Schema. Returns validation result with detailed error messages.',
9
+ {
10
+ response: z.object({
11
+ status: z.number().describe('HTTP status code from the response'),
12
+ body: z.unknown().describe('Response body to validate'),
13
+ }).describe('The API response to validate'),
14
+ expected_status: z.number().describe('Expected HTTP status code'),
15
+ expected_schema: z.unknown().optional().describe('Expected JSON Schema (draft-07) for the response body'),
16
+ },
17
+ async ({ response, expected_status, expected_schema }) => {
18
+ try {
19
+ const result = validateResponse(
20
+ response as { status: number; body: unknown },
21
+ expected_status,
22
+ (expected_schema as import('../types.js').JsonSchema) ?? undefined,
23
+ );
24
+
25
+ return {
26
+ content: [
27
+ {
28
+ type: 'text' as const,
29
+ text: JSON.stringify({
30
+ valid: result.valid,
31
+ errors: result.errors,
32
+ ...(result.valid
33
+ ? { message: 'Response matches expected status and schema.' }
34
+ : { message: `Validation failed with ${result.errors.length} error(s).` }),
35
+ }, null, 2),
36
+ },
37
+ ],
38
+ };
39
+ } catch (err) {
40
+ return {
41
+ content: [
42
+ {
43
+ type: 'text' as const,
44
+ text: JSON.stringify({
45
+ error: err instanceof Error ? err.message : String(err),
46
+ }, null, 2),
47
+ },
48
+ ],
49
+ isError: true,
50
+ };
51
+ }
52
+ }
53
+ );
54
+ }
package/src/types.ts ADDED
@@ -0,0 +1,156 @@
1
+ // ── License Types ────────────────────────────────────────────────────
2
+
3
+ export type LicenseTier = 'free' | 'pro';
4
+
5
+ export interface LicenseStatus {
6
+ tier: LicenseTier;
7
+ valid: boolean;
8
+ expiresAt: string | null;
9
+ }
10
+
11
+ // ── HTTP Types ──────────────────────────────────────────────────────
12
+
13
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
14
+
15
+ export interface HttpRequest {
16
+ method: HttpMethod;
17
+ url: string;
18
+ headers?: Record<string, string>;
19
+ body?: unknown;
20
+ timeout?: number;
21
+ }
22
+
23
+ export interface HttpResponse {
24
+ status: number;
25
+ statusText: string;
26
+ headers: Record<string, string>;
27
+ body: unknown;
28
+ timing_ms: number;
29
+ size_bytes: number;
30
+ }
31
+
32
+ // ── OpenAPI Types ───────────────────────────────────────────────────
33
+
34
+ export interface OpenApiInfo {
35
+ title: string;
36
+ version: string;
37
+ description?: string;
38
+ }
39
+
40
+ export interface OpenApiParameter {
41
+ name: string;
42
+ in: 'query' | 'path' | 'header' | 'cookie';
43
+ required: boolean;
44
+ description?: string;
45
+ schema?: JsonSchema;
46
+ }
47
+
48
+ export interface OpenApiResponse {
49
+ status: string;
50
+ description: string;
51
+ schema?: JsonSchema;
52
+ }
53
+
54
+ export interface OpenApiEndpoint {
55
+ method: string;
56
+ path: string;
57
+ summary: string;
58
+ operationId?: string;
59
+ parameters: OpenApiParameter[];
60
+ requestBody?: JsonSchema;
61
+ responses: OpenApiResponse[];
62
+ tags?: string[];
63
+ }
64
+
65
+ export interface ParsedOpenApiSpec {
66
+ info: OpenApiInfo;
67
+ servers?: Array<{ url: string; description?: string }>;
68
+ endpoints: OpenApiEndpoint[];
69
+ }
70
+
71
+ // ── JSON Schema Types ───────────────────────────────────────────────
72
+
73
+ export interface JsonSchema {
74
+ type?: string | string[];
75
+ properties?: Record<string, JsonSchema>;
76
+ items?: JsonSchema;
77
+ required?: string[];
78
+ enum?: unknown[];
79
+ format?: string;
80
+ description?: string;
81
+ minimum?: number;
82
+ maximum?: number;
83
+ minLength?: number;
84
+ maxLength?: number;
85
+ pattern?: string;
86
+ additionalProperties?: boolean | JsonSchema;
87
+ oneOf?: JsonSchema[];
88
+ anyOf?: JsonSchema[];
89
+ allOf?: JsonSchema[];
90
+ $ref?: string;
91
+ nullable?: boolean;
92
+ }
93
+
94
+ // ── Validation Types ────────────────────────────────────────────────
95
+
96
+ export interface ValidationError {
97
+ path: string;
98
+ message: string;
99
+ expected?: string;
100
+ actual?: string;
101
+ }
102
+
103
+ export interface ValidationResult {
104
+ valid: boolean;
105
+ errors: ValidationError[];
106
+ }
107
+
108
+ // ── Code Generation Types ───────────────────────────────────────────
109
+
110
+ export type CodeLanguage = 'typescript' | 'python' | 'go';
111
+ export type HttpStyle = 'fetch' | 'axios';
112
+
113
+ // ── Test Generation Types ───────────────────────────────────────────
114
+
115
+ export type TestFramework = 'jest' | 'vitest' | 'pytest';
116
+
117
+ // ── Spec Comparison Types ───────────────────────────────────────────
118
+
119
+ export interface SpecChange {
120
+ path: string;
121
+ method?: string;
122
+ description: string;
123
+ }
124
+
125
+ export interface SpecComparison {
126
+ breaking_changes: SpecChange[];
127
+ non_breaking: SpecChange[];
128
+ new_endpoints: SpecChange[];
129
+ removed_endpoints: SpecChange[];
130
+ }
131
+
132
+ // ── Mock Server Types ───────────────────────────────────────────────
133
+
134
+ export interface MockRoute {
135
+ method: string;
136
+ path: string;
137
+ status: number;
138
+ response: unknown;
139
+ headers?: Record<string, string>;
140
+ }
141
+
142
+ export interface MockServerConfig {
143
+ routes: MockRoute[];
144
+ mock_data: Record<string, unknown>;
145
+ }
146
+
147
+ // ── Example Types (for generate_openapi) ────────────────────────────
148
+
149
+ export interface RequestExample {
150
+ method: string;
151
+ url: string;
152
+ request_body?: unknown;
153
+ response_body: unknown;
154
+ status: number;
155
+ headers?: Record<string, string>;
156
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true
16
+ },
17
+ "include": ["src/**/*"],
18
+ "exclude": ["node_modules", "dist", "evals"]
19
+ }