@defai.digital/mcp-server 13.0.3

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 (178) hide show
  1. package/LICENSE +214 -0
  2. package/dist/bin.d.ts +3 -0
  3. package/dist/bin.d.ts.map +1 -0
  4. package/dist/bin.js +7 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/bootstrap.d.ts +89 -0
  7. package/dist/bootstrap.d.ts.map +1 -0
  8. package/dist/bootstrap.js +161 -0
  9. package/dist/bootstrap.js.map +1 -0
  10. package/dist/index.d.ts +10 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +17 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/middleware/rate-limiter.d.ts +136 -0
  15. package/dist/middleware/rate-limiter.d.ts.map +1 -0
  16. package/dist/middleware/rate-limiter.js +262 -0
  17. package/dist/middleware/rate-limiter.js.map +1 -0
  18. package/dist/prompts/agent-guide.d.ts +16 -0
  19. package/dist/prompts/agent-guide.d.ts.map +1 -0
  20. package/dist/prompts/agent-guide.js +391 -0
  21. package/dist/prompts/agent-guide.js.map +1 -0
  22. package/dist/prompts/explain-workflow.d.ts +15 -0
  23. package/dist/prompts/explain-workflow.d.ts.map +1 -0
  24. package/dist/prompts/explain-workflow.js +157 -0
  25. package/dist/prompts/explain-workflow.js.map +1 -0
  26. package/dist/prompts/index.d.ts +39 -0
  27. package/dist/prompts/index.d.ts.map +1 -0
  28. package/dist/prompts/index.js +83 -0
  29. package/dist/prompts/index.js.map +1 -0
  30. package/dist/prompts/review-changes.d.ts +15 -0
  31. package/dist/prompts/review-changes.d.ts.map +1 -0
  32. package/dist/prompts/review-changes.js +102 -0
  33. package/dist/prompts/review-changes.js.map +1 -0
  34. package/dist/prompts/troubleshoot-session.d.ts +15 -0
  35. package/dist/prompts/troubleshoot-session.d.ts.map +1 -0
  36. package/dist/prompts/troubleshoot-session.js +156 -0
  37. package/dist/prompts/troubleshoot-session.js.map +1 -0
  38. package/dist/registry-accessor.d.ts +83 -0
  39. package/dist/registry-accessor.d.ts.map +1 -0
  40. package/dist/registry-accessor.js +153 -0
  41. package/dist/registry-accessor.js.map +1 -0
  42. package/dist/resources/agents.d.ts +40 -0
  43. package/dist/resources/agents.d.ts.map +1 -0
  44. package/dist/resources/agents.js +123 -0
  45. package/dist/resources/agents.js.map +1 -0
  46. package/dist/resources/config.d.ts +57 -0
  47. package/dist/resources/config.d.ts.map +1 -0
  48. package/dist/resources/config.js +222 -0
  49. package/dist/resources/config.js.map +1 -0
  50. package/dist/resources/index.d.ts +38 -0
  51. package/dist/resources/index.d.ts.map +1 -0
  52. package/dist/resources/index.js +132 -0
  53. package/dist/resources/index.js.map +1 -0
  54. package/dist/resources/policies.d.ts +40 -0
  55. package/dist/resources/policies.d.ts.map +1 -0
  56. package/dist/resources/policies.js +122 -0
  57. package/dist/resources/policies.js.map +1 -0
  58. package/dist/resources/sessions.d.ts +30 -0
  59. package/dist/resources/sessions.d.ts.map +1 -0
  60. package/dist/resources/sessions.js +64 -0
  61. package/dist/resources/sessions.js.map +1 -0
  62. package/dist/resources/workflows.d.ts +40 -0
  63. package/dist/resources/workflows.d.ts.map +1 -0
  64. package/dist/resources/workflows.js +143 -0
  65. package/dist/resources/workflows.js.map +1 -0
  66. package/dist/schema-registry.d.ts +23 -0
  67. package/dist/schema-registry.d.ts.map +1 -0
  68. package/dist/schema-registry.js +225 -0
  69. package/dist/schema-registry.js.map +1 -0
  70. package/dist/server.d.ts +63 -0
  71. package/dist/server.d.ts.map +1 -0
  72. package/dist/server.js +393 -0
  73. package/dist/server.js.map +1 -0
  74. package/dist/session-accessor.d.ts +23 -0
  75. package/dist/session-accessor.d.ts.map +1 -0
  76. package/dist/session-accessor.js +39 -0
  77. package/dist/session-accessor.js.map +1 -0
  78. package/dist/shared-registry.d.ts +23 -0
  79. package/dist/shared-registry.d.ts.map +1 -0
  80. package/dist/shared-registry.js +235 -0
  81. package/dist/shared-registry.js.map +1 -0
  82. package/dist/stdio.d.ts +6 -0
  83. package/dist/stdio.d.ts.map +1 -0
  84. package/dist/stdio.js +152 -0
  85. package/dist/stdio.js.map +1 -0
  86. package/dist/tool-namespacing.d.ts +28 -0
  87. package/dist/tool-namespacing.d.ts.map +1 -0
  88. package/dist/tool-namespacing.js +80 -0
  89. package/dist/tool-namespacing.js.map +1 -0
  90. package/dist/tools/ability.d.ts +55 -0
  91. package/dist/tools/ability.d.ts.map +1 -0
  92. package/dist/tools/ability.js +560 -0
  93. package/dist/tools/ability.js.map +1 -0
  94. package/dist/tools/agent.d.ts +73 -0
  95. package/dist/tools/agent.d.ts.map +1 -0
  96. package/dist/tools/agent.js +895 -0
  97. package/dist/tools/agent.js.map +1 -0
  98. package/dist/tools/config.d.ts +36 -0
  99. package/dist/tools/config.d.ts.map +1 -0
  100. package/dist/tools/config.js +265 -0
  101. package/dist/tools/config.js.map +1 -0
  102. package/dist/tools/design.d.ts +42 -0
  103. package/dist/tools/design.d.ts.map +1 -0
  104. package/dist/tools/design.js +736 -0
  105. package/dist/tools/design.js.map +1 -0
  106. package/dist/tools/discuss.d.ts +40 -0
  107. package/dist/tools/discuss.d.ts.map +1 -0
  108. package/dist/tools/discuss.js +331 -0
  109. package/dist/tools/discuss.js.map +1 -0
  110. package/dist/tools/file-system.d.ts +63 -0
  111. package/dist/tools/file-system.d.ts.map +1 -0
  112. package/dist/tools/file-system.js +513 -0
  113. package/dist/tools/file-system.js.map +1 -0
  114. package/dist/tools/guard.d.ts +29 -0
  115. package/dist/tools/guard.d.ts.map +1 -0
  116. package/dist/tools/guard.js +311 -0
  117. package/dist/tools/guard.js.map +1 -0
  118. package/dist/tools/index.d.ts +35 -0
  119. package/dist/tools/index.d.ts.map +1 -0
  120. package/dist/tools/index.js +178 -0
  121. package/dist/tools/index.js.map +1 -0
  122. package/dist/tools/memory.d.ts +101 -0
  123. package/dist/tools/memory.d.ts.map +1 -0
  124. package/dist/tools/memory.js +704 -0
  125. package/dist/tools/memory.js.map +1 -0
  126. package/dist/tools/orchestration.d.ts +58 -0
  127. package/dist/tools/orchestration.d.ts.map +1 -0
  128. package/dist/tools/orchestration.js +714 -0
  129. package/dist/tools/orchestration.js.map +1 -0
  130. package/dist/tools/review.d.ts +40 -0
  131. package/dist/tools/review.d.ts.map +1 -0
  132. package/dist/tools/review.js +319 -0
  133. package/dist/tools/review.js.map +1 -0
  134. package/dist/tools/scaffold.d.ts +27 -0
  135. package/dist/tools/scaffold.d.ts.map +1 -0
  136. package/dist/tools/scaffold.js +495 -0
  137. package/dist/tools/scaffold.js.map +1 -0
  138. package/dist/tools/session.d.ts +75 -0
  139. package/dist/tools/session.d.ts.map +1 -0
  140. package/dist/tools/session.js +749 -0
  141. package/dist/tools/session.js.map +1 -0
  142. package/dist/tools/telemetry.d.ts +58 -0
  143. package/dist/tools/telemetry.d.ts.map +1 -0
  144. package/dist/tools/telemetry.js +638 -0
  145. package/dist/tools/telemetry.js.map +1 -0
  146. package/dist/tools/trace.d.ts +29 -0
  147. package/dist/tools/trace.d.ts.map +1 -0
  148. package/dist/tools/trace.js +191 -0
  149. package/dist/tools/trace.js.map +1 -0
  150. package/dist/tools/workflow.d.ts +26 -0
  151. package/dist/tools/workflow.d.ts.map +1 -0
  152. package/dist/tools/workflow.js +269 -0
  153. package/dist/tools/workflow.js.map +1 -0
  154. package/dist/trace-wrapper.d.ts +79 -0
  155. package/dist/trace-wrapper.d.ts.map +1 -0
  156. package/dist/trace-wrapper.js +151 -0
  157. package/dist/trace-wrapper.js.map +1 -0
  158. package/dist/types.d.ts +185 -0
  159. package/dist/types.d.ts.map +1 -0
  160. package/dist/types.js +11 -0
  161. package/dist/types.js.map +1 -0
  162. package/dist/utils/artifact-store.d.ts +49 -0
  163. package/dist/utils/artifact-store.d.ts.map +1 -0
  164. package/dist/utils/artifact-store.js +102 -0
  165. package/dist/utils/artifact-store.js.map +1 -0
  166. package/dist/utils/index.d.ts +6 -0
  167. package/dist/utils/index.d.ts.map +1 -0
  168. package/dist/utils/index.js +10 -0
  169. package/dist/utils/index.js.map +1 -0
  170. package/dist/utils/response.d.ts +139 -0
  171. package/dist/utils/response.d.ts.map +1 -0
  172. package/dist/utils/response.js +293 -0
  173. package/dist/utils/response.js.map +1 -0
  174. package/dist/validation.d.ts +223 -0
  175. package/dist/validation.d.ts.map +1 -0
  176. package/dist/validation.js +372 -0
  177. package/dist/validation.js.map +1 -0
  178. package/package.json +67 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * MCP Response Optimization Utilities
3
+ *
4
+ * Ensures all MCP responses are "Claude-safe" by enforcing:
5
+ * - INV-MCP-RESP-001: All responses < 10 KB
6
+ * - INV-MCP-RESP-002: Arrays limited to 10 items
7
+ * - INV-MCP-RESP-003: Strings truncated at 500 chars
8
+ * - INV-MCP-RESP-004: JSON depth <= 4 levels
9
+ * - INV-MCP-RESP-005: Large results stored as artifacts
10
+ * - INV-MCP-RESP-006: All responses include summary field
11
+ */
12
+ import type { MCPToolResult } from '../types.js';
13
+ type ToolResult = MCPToolResult;
14
+ export interface ResponseLimits {
15
+ /** Maximum response size in bytes (default: 10KB) */
16
+ maxBytes: number;
17
+ /** Maximum array items before truncation (default: 10) */
18
+ maxArrayItems: number;
19
+ /** Maximum string length before truncation (default: 500) */
20
+ maxStringLength: number;
21
+ /** Maximum JSON nesting depth (default: 4) */
22
+ maxJsonDepth: number;
23
+ /** Maximum summary length (default: 100) */
24
+ maxSummaryLength: number;
25
+ }
26
+ export declare const DEFAULT_LIMITS: ResponseLimits;
27
+ /**
28
+ * Standard MCP response structure for Claude-safe responses
29
+ */
30
+ export interface MCPResponseContract {
31
+ /** One-line summary (max 100 chars) - REQUIRED */
32
+ summary: string;
33
+ /** Action success status */
34
+ success: boolean;
35
+ /** Optional count for list/scan results */
36
+ count?: number;
37
+ /** Optional top N items */
38
+ items?: {
39
+ id: string;
40
+ label: string;
41
+ severity?: 'critical' | 'high' | 'medium' | 'low' | 'info';
42
+ [key: string]: unknown;
43
+ }[];
44
+ /** Reference to full data stored externally */
45
+ artifactRef?: string;
46
+ /** Indicates more data available */
47
+ hasMore?: boolean;
48
+ /** Cursor for pagination */
49
+ nextCursor?: string;
50
+ /** Additional fields */
51
+ [key: string]: unknown;
52
+ }
53
+ /**
54
+ * Artifact store function type
55
+ */
56
+ export type ArtifactStoreFn = (key: string, data: unknown) => Promise<string>;
57
+ export interface WrapResponseOptions {
58
+ /** One-line summary (will be truncated to 100 chars) */
59
+ summary: string;
60
+ /** Whether the operation succeeded */
61
+ success?: boolean;
62
+ /** Custom response limits */
63
+ limits?: Partial<ResponseLimits>;
64
+ /** Function to store large artifacts externally */
65
+ artifactStore?: ArtifactStoreFn;
66
+ /** Artifact key prefix */
67
+ artifactKeyPrefix?: string;
68
+ /** Force artifact storage regardless of size */
69
+ forceArtifact?: boolean;
70
+ }
71
+ /**
72
+ * Wrap MCP response to enforce Claude-safe limits
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * return wrapResponse(bugs, {
77
+ * summary: `Found ${bugs.length} bugs`,
78
+ * artifactStore: storeArtifact,
79
+ * artifactKeyPrefix: 'bugfix:scan',
80
+ * });
81
+ * ```
82
+ */
83
+ export declare function wrapResponse<T>(data: T, options: WrapResponseOptions): Promise<ToolResult>;
84
+ /**
85
+ * Create a simple success response
86
+ */
87
+ export declare function successResponse(summary: string, data?: Record<string, unknown>): ToolResult;
88
+ /**
89
+ * Create a simple error response
90
+ */
91
+ export declare function errorResponse(code: string, message: string, details?: Record<string, unknown>): ToolResult;
92
+ /**
93
+ * Create summary for count-based results
94
+ */
95
+ export declare function createCountSummary(action: string, count: number, bySeverity?: Record<string, number>): string;
96
+ /**
97
+ * Create summary for list results
98
+ */
99
+ export declare function createListSummary(domain: string, total: number, showing: number): string;
100
+ export interface ListResponseOptions<T> {
101
+ /** Domain name for summary (e.g., "agents", "sessions") */
102
+ domain: string;
103
+ /** Field to use as label (default: 'id') */
104
+ labelField?: keyof T;
105
+ /** Field to use as id (default: 'id') */
106
+ idField?: keyof T;
107
+ /** Maximum items to return (default: 10) */
108
+ limit?: number;
109
+ /** Custom limits */
110
+ limits?: Partial<ResponseLimits>;
111
+ }
112
+ /**
113
+ * Create a paginated list response
114
+ */
115
+ export declare function createListResponse<T extends Record<string, unknown>>(items: T[], options: ListResponseOptions<T>): ToolResult;
116
+ export interface ScanResultItem {
117
+ id: string;
118
+ severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
119
+ message: string;
120
+ file?: string | undefined;
121
+ line?: number | undefined;
122
+ [key: string]: unknown;
123
+ }
124
+ export interface ScanResponseOptions {
125
+ /** Scan type for summary (e.g., "bugs", "refactoring opportunities") */
126
+ scanType: string;
127
+ /** Scan ID for artifact reference */
128
+ scanId: string;
129
+ /** Maximum items to include in response (default: 5) */
130
+ topN?: number;
131
+ /** Artifact store function */
132
+ artifactStore?: ArtifactStoreFn;
133
+ }
134
+ /**
135
+ * Create a scan response with severity breakdown
136
+ */
137
+ export declare function createScanResponse(results: ScanResultItem[], options: ScanResponseOptions): Promise<ToolResult>;
138
+ export {};
139
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,293 @@
1
+ /**
2
+ * MCP Response Optimization Utilities
3
+ *
4
+ * Ensures all MCP responses are "Claude-safe" by enforcing:
5
+ * - INV-MCP-RESP-001: All responses < 10 KB
6
+ * - INV-MCP-RESP-002: Arrays limited to 10 items
7
+ * - INV-MCP-RESP-003: Strings truncated at 500 chars
8
+ * - INV-MCP-RESP-004: JSON depth <= 4 levels
9
+ * - INV-MCP-RESP-005: Large results stored as artifacts
10
+ * - INV-MCP-RESP-006: All responses include summary field
11
+ */
12
+ export const DEFAULT_LIMITS = {
13
+ maxBytes: 10240, // 10 KB
14
+ maxArrayItems: 10,
15
+ maxStringLength: 500,
16
+ maxJsonDepth: 4,
17
+ maxSummaryLength: 100,
18
+ };
19
+ /**
20
+ * Wrap MCP response to enforce Claude-safe limits
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * return wrapResponse(bugs, {
25
+ * summary: `Found ${bugs.length} bugs`,
26
+ * artifactStore: storeArtifact,
27
+ * artifactKeyPrefix: 'bugfix:scan',
28
+ * });
29
+ * ```
30
+ */
31
+ export async function wrapResponse(data, options) {
32
+ const limits = { ...DEFAULT_LIMITS, ...options.limits };
33
+ const success = options.success ?? true;
34
+ // Calculate original size
35
+ const originalJson = JSON.stringify(data);
36
+ const originalSize = originalJson.length;
37
+ const needsArtifact = originalSize > limits.maxBytes || options.forceArtifact;
38
+ // Store artifact if needed
39
+ let artifactRef;
40
+ if (needsArtifact && options.artifactStore && options.artifactKeyPrefix) {
41
+ const artifactKey = `${options.artifactKeyPrefix}:${Date.now()}`;
42
+ artifactRef = await options.artifactStore(artifactKey, data);
43
+ }
44
+ // Truncate response to fit limits
45
+ const truncated = truncateValue(data, limits, 0);
46
+ // Build response
47
+ const response = {
48
+ summary: options.summary.slice(0, limits.maxSummaryLength),
49
+ success,
50
+ ...truncated,
51
+ };
52
+ // Add artifact reference if stored
53
+ if (artifactRef) {
54
+ response.artifactRef = artifactRef;
55
+ response.hasMore = true;
56
+ }
57
+ // Final size check
58
+ const finalJson = JSON.stringify(response, null, 2);
59
+ if (finalJson.length > limits.maxBytes) {
60
+ // Emergency truncation - return minimal response
61
+ return {
62
+ content: [{
63
+ type: 'text',
64
+ text: JSON.stringify({
65
+ summary: options.summary.slice(0, limits.maxSummaryLength),
66
+ success,
67
+ truncated: true,
68
+ originalSize,
69
+ artifactRef,
70
+ hasMore: true,
71
+ message: 'Response truncated due to size limits',
72
+ }, null, 2),
73
+ }],
74
+ };
75
+ }
76
+ return {
77
+ content: [{
78
+ type: 'text',
79
+ text: finalJson,
80
+ }],
81
+ };
82
+ }
83
+ /**
84
+ * Create a simple success response
85
+ */
86
+ export function successResponse(summary, data) {
87
+ return {
88
+ content: [{
89
+ type: 'text',
90
+ text: JSON.stringify({
91
+ summary: summary.slice(0, DEFAULT_LIMITS.maxSummaryLength),
92
+ success: true,
93
+ ...data,
94
+ }, null, 2),
95
+ }],
96
+ };
97
+ }
98
+ /**
99
+ * Create a simple error response
100
+ */
101
+ export function errorResponse(code, message, details) {
102
+ return {
103
+ content: [{
104
+ type: 'text',
105
+ text: JSON.stringify({
106
+ summary: `Error: ${message}`.slice(0, DEFAULT_LIMITS.maxSummaryLength),
107
+ success: false,
108
+ error: { code, message, ...details },
109
+ }, null, 2),
110
+ }],
111
+ isError: true,
112
+ };
113
+ }
114
+ // ============================================================================
115
+ // Truncation Utilities
116
+ // ============================================================================
117
+ /**
118
+ * Truncate a value to fit within limits
119
+ */
120
+ function truncateValue(value, limits, depth) {
121
+ // Max depth check
122
+ if (depth > limits.maxJsonDepth) {
123
+ return '[depth limit exceeded]';
124
+ }
125
+ // Handle arrays
126
+ if (Array.isArray(value)) {
127
+ return truncateArray(value, limits, depth);
128
+ }
129
+ // Handle strings
130
+ if (typeof value === 'string') {
131
+ return truncateString(value, limits.maxStringLength);
132
+ }
133
+ // Handle objects
134
+ if (typeof value === 'object' && value !== null) {
135
+ return truncateObject(value, limits, depth);
136
+ }
137
+ // Primitives pass through
138
+ return value;
139
+ }
140
+ /**
141
+ * Truncate array to max items
142
+ */
143
+ function truncateArray(arr, limits, depth) {
144
+ if (arr.length <= limits.maxArrayItems) {
145
+ return arr.map(item => truncateValue(item, limits, depth + 1));
146
+ }
147
+ // Return truncated array with metadata
148
+ const truncated = arr
149
+ .slice(0, limits.maxArrayItems)
150
+ .map(item => truncateValue(item, limits, depth + 1));
151
+ return {
152
+ items: truncated,
153
+ totalCount: arr.length,
154
+ showing: limits.maxArrayItems,
155
+ hasMore: true,
156
+ };
157
+ }
158
+ /**
159
+ * Truncate string to max length
160
+ */
161
+ function truncateString(str, maxLength) {
162
+ if (str.length <= maxLength) {
163
+ return str;
164
+ }
165
+ return str.slice(0, maxLength - 3) + '...';
166
+ }
167
+ /**
168
+ * Truncate object properties recursively
169
+ */
170
+ function truncateObject(obj, limits, depth) {
171
+ const result = {};
172
+ for (const [key, value] of Object.entries(obj)) {
173
+ result[key] = truncateValue(value, limits, depth + 1);
174
+ }
175
+ return result;
176
+ }
177
+ // ============================================================================
178
+ // Summary Helpers
179
+ // ============================================================================
180
+ /**
181
+ * Create summary for count-based results
182
+ */
183
+ export function createCountSummary(action, count, bySeverity) {
184
+ if (bySeverity) {
185
+ const parts = Object.entries(bySeverity)
186
+ .filter(([, v]) => v > 0)
187
+ .map(([k, v]) => `${v} ${k}`)
188
+ .join(', ');
189
+ return `${action}: ${count} total${parts ? ` (${parts})` : ''}`;
190
+ }
191
+ return `${action}: ${count} item${count !== 1 ? 's' : ''}`;
192
+ }
193
+ /**
194
+ * Create summary for list results
195
+ */
196
+ export function createListSummary(domain, total, showing) {
197
+ if (showing < total) {
198
+ return `${domain}: showing ${showing} of ${total}`;
199
+ }
200
+ return `${domain}: ${total} item${total !== 1 ? 's' : ''}`;
201
+ }
202
+ /**
203
+ * Create a paginated list response
204
+ */
205
+ export function createListResponse(items, options) {
206
+ const limit = options.limit ?? DEFAULT_LIMITS.maxArrayItems;
207
+ const idField = options.idField ?? 'id';
208
+ const labelField = options.labelField ?? idField;
209
+ const showing = items.slice(0, limit);
210
+ const hasMore = items.length > limit;
211
+ const response = {
212
+ summary: createListSummary(options.domain, items.length, showing.length),
213
+ success: true,
214
+ items: showing.map(item => ({
215
+ id: String(item[idField] ?? ''),
216
+ label: truncateString(String(item[labelField] ?? ''), 50),
217
+ ...pickFields(item, ['status', 'severity', 'type', 'enabled']),
218
+ })),
219
+ totalCount: items.length,
220
+ showing: showing.length,
221
+ hasMore,
222
+ };
223
+ return {
224
+ content: [{
225
+ type: 'text',
226
+ text: JSON.stringify(response, null, 2),
227
+ }],
228
+ };
229
+ }
230
+ /**
231
+ * Pick specific fields from an object
232
+ */
233
+ function pickFields(obj, fields) {
234
+ const result = {};
235
+ for (const field of fields) {
236
+ if (field in obj && obj[field] !== undefined) {
237
+ result[field] = obj[field];
238
+ }
239
+ }
240
+ return result;
241
+ }
242
+ /**
243
+ * Create a scan response with severity breakdown
244
+ */
245
+ export async function createScanResponse(results, options) {
246
+ const topN = options.topN ?? 5;
247
+ // Count by severity
248
+ const bySeverity = {
249
+ critical: 0,
250
+ high: 0,
251
+ medium: 0,
252
+ low: 0,
253
+ info: 0,
254
+ };
255
+ for (const item of results) {
256
+ bySeverity[item.severity] = (bySeverity[item.severity] ?? 0) + 1;
257
+ }
258
+ // Sort by severity (critical first)
259
+ const severityOrder = ['critical', 'high', 'medium', 'low', 'info'];
260
+ const sorted = [...results].sort((a, b) => {
261
+ return severityOrder.indexOf(a.severity) - severityOrder.indexOf(b.severity);
262
+ });
263
+ // Take top N
264
+ const topItems = sorted.slice(0, topN).map(item => ({
265
+ id: item.id,
266
+ severity: item.severity,
267
+ message: truncateString(item.message, 100),
268
+ file: item.file,
269
+ line: item.line,
270
+ }));
271
+ // Store full results if artifact store provided
272
+ let artifactRef;
273
+ if (options.artifactStore && results.length > topN) {
274
+ artifactRef = await options.artifactStore(`${options.scanType}:${options.scanId}`, results);
275
+ }
276
+ const response = {
277
+ summary: createCountSummary(`Found ${options.scanType}`, results.length, bySeverity),
278
+ success: true,
279
+ scanId: options.scanId,
280
+ count: results.length,
281
+ bySeverity,
282
+ topItems,
283
+ hasMore: results.length > topN,
284
+ artifactRef,
285
+ };
286
+ return {
287
+ content: [{
288
+ type: 'text',
289
+ text: JSON.stringify(response, null, 2),
290
+ }],
291
+ };
292
+ }
293
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * MCP Tool Input/Output Validation
3
+ *
4
+ * Validates tool inputs and outputs against Zod schemas.
5
+ *
6
+ * Invariants:
7
+ * - INV-MCP-001: Input validation MUST occur before tool execution
8
+ * - INV-MCP-003: Standardized error codes for all failures
9
+ * - INV-MCP-005: Input isolation - inputs MUST NOT be mutated
10
+ * - INV-MCP-VAL-001: Output validation failures logged but don't break response
11
+ * - INV-MCP-VAL-002: All schemas defined in contracts package
12
+ */
13
+ import type { ToolHandler, MCPToolResult } from './types.js';
14
+ /**
15
+ * Standard error codes per INV-MCP-003
16
+ * Must match StandardErrorCodes from @defai.digital/contracts
17
+ */
18
+ export declare const ToolErrorCodes: {
19
+ readonly INVALID_INPUT: "INVALID_INPUT";
20
+ readonly INVALID_OUTPUT: "INVALID_OUTPUT";
21
+ readonly RESOURCE_NOT_FOUND: "RESOURCE_NOT_FOUND";
22
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
23
+ readonly RATE_LIMITED: "RATE_LIMITED";
24
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
25
+ readonly TIMEOUT: "TIMEOUT";
26
+ readonly NOT_IMPLEMENTED: "NOT_IMPLEMENTED";
27
+ };
28
+ export type ToolErrorCode = (typeof ToolErrorCodes)[keyof typeof ToolErrorCodes];
29
+ /**
30
+ * Tool error structure per INV-MCP-003
31
+ */
32
+ export interface ToolError {
33
+ /** Standard error code */
34
+ code: ToolErrorCode | string;
35
+ /** Human-readable message */
36
+ message: string;
37
+ /** Tool name */
38
+ tool: string;
39
+ /** Additional context */
40
+ details?: unknown;
41
+ }
42
+ /**
43
+ * Creates a standardized tool error response
44
+ * INV-MCP-003: All failures MUST return standardized error codes
45
+ */
46
+ export declare function createToolError(code: ToolErrorCode | string, message: string, toolName: string, details?: unknown): MCPToolResult;
47
+ /**
48
+ * Creates an INVALID_INPUT error
49
+ * INV-MCP-003: Standardized error codes
50
+ */
51
+ export declare function createInputError(toolName: string, message: string, details?: unknown): MCPToolResult;
52
+ /**
53
+ * Creates an INTERNAL_ERROR error
54
+ * INV-MCP-003: Standardized error codes
55
+ */
56
+ export declare function createInternalError(toolName: string, message: string, details?: unknown): MCPToolResult;
57
+ /**
58
+ * Creates a RESOURCE_NOT_FOUND error
59
+ * INV-MCP-003: Standardized error codes
60
+ */
61
+ export declare function createNotFoundError(toolName: string, message: string, details?: unknown): MCPToolResult;
62
+ /**
63
+ * Creates a NOT_IMPLEMENTED error
64
+ * INV-MCP-003: Standardized error codes
65
+ */
66
+ export declare function createNotImplementedError(toolName: string, message: string): MCPToolResult;
67
+ /**
68
+ * Deep freezes an object to prevent mutation
69
+ * INV-MCP-005: Tools MUST NOT modify their input objects
70
+ *
71
+ * Handles circular references by tracking visited objects
72
+ */
73
+ export declare function deepFreeze<T>(obj: T, visited?: WeakSet<object>): T;
74
+ /**
75
+ * Zod-like schema interface for validation
76
+ * This allows using schemas from contracts without direct zod dependency
77
+ */
78
+ interface ZodLikeSchema<T> {
79
+ safeParse(data: unknown): {
80
+ success: true;
81
+ data: T;
82
+ } | {
83
+ success: false;
84
+ error: {
85
+ errors: {
86
+ path: (string | number)[];
87
+ message: string;
88
+ }[];
89
+ };
90
+ };
91
+ }
92
+ /**
93
+ * Result of output validation
94
+ */
95
+ export interface ValidationResult<T> {
96
+ /** Whether validation passed */
97
+ valid: boolean;
98
+ /** Validated data (or original if validation failed) */
99
+ data: T;
100
+ /** Validation errors if any */
101
+ errors?: string[];
102
+ }
103
+ /**
104
+ * Validation logger interface
105
+ */
106
+ export interface ValidationLogger {
107
+ warn(message: string, context?: Record<string, unknown>): void;
108
+ }
109
+ /**
110
+ * Sets the validation logger
111
+ */
112
+ export declare function setValidationLogger(logger: ValidationLogger): void;
113
+ /**
114
+ * Validates output against a Zod schema
115
+ *
116
+ * INV-MCP-VAL-001: Logs failures but returns original data
117
+ */
118
+ export declare function validateOutput<T>(schema: ZodLikeSchema<T>, toolName: string, output: unknown): ValidationResult<T>;
119
+ /**
120
+ * Parses JSON from tool result content
121
+ */
122
+ export declare function parseToolResultContent(result: MCPToolResult): unknown | undefined;
123
+ /**
124
+ * Wraps a tool handler with output validation
125
+ *
126
+ * INV-MCP-VAL-001: Validation failures logged but response still returned
127
+ */
128
+ export declare function withValidation<T>(handler: ToolHandler, outputSchema: ZodLikeSchema<T>, toolName: string): ToolHandler;
129
+ /**
130
+ * Schema registry for tool outputs
131
+ */
132
+ export type OutputSchemaRegistry = Record<string, ZodLikeSchema<unknown>>;
133
+ /**
134
+ * Wraps all handlers with validation using a schema registry
135
+ */
136
+ export declare function wrapHandlersWithValidation(handlers: Record<string, ToolHandler>, schemas: OutputSchemaRegistry): Record<string, ToolHandler>;
137
+ /**
138
+ * Input schema registry type
139
+ */
140
+ export type InputSchemaRegistry = Record<string, ZodLikeSchema<unknown>>;
141
+ /**
142
+ * Creates an INVALID_INPUT error response for schema validation failures
143
+ * INV-MCP-001: Validation failures return INVALID_INPUT error
144
+ * INV-MCP-003: Uses standardized error code
145
+ */
146
+ export declare function createInvalidInputError(toolName: string, errors: string[]): MCPToolResult;
147
+ /**
148
+ * Validates input against a Zod schema
149
+ * INV-MCP-001: Input validation MUST occur before tool execution
150
+ *
151
+ * @returns validated data or null if validation fails
152
+ */
153
+ export declare function validateInput<T>(schema: ZodLikeSchema<T>, data: unknown): {
154
+ success: true;
155
+ data: T;
156
+ } | {
157
+ success: false;
158
+ errors: string[];
159
+ };
160
+ /**
161
+ * Wraps a tool handler with input validation and isolation
162
+ * INV-MCP-001: Input validation MUST occur before tool execution
163
+ * INV-MCP-005: Input isolation - inputs MUST NOT be mutated
164
+ */
165
+ export declare function withInputValidation<T>(handler: ToolHandler, inputSchema: ZodLikeSchema<T>, toolName: string): ToolHandler;
166
+ /**
167
+ * Wraps a tool handler with both input and output validation
168
+ * INV-MCP-001: Input validation before execution
169
+ * INV-MCP-005: Input isolation - inputs MUST NOT be mutated
170
+ * INV-MCP-VAL-001: Output validation after execution
171
+ */
172
+ export declare function withFullValidation<TInput, TOutput>(handler: ToolHandler, inputSchema: ZodLikeSchema<TInput>, outputSchema: ZodLikeSchema<TOutput>, toolName: string): ToolHandler;
173
+ /**
174
+ * Wraps all handlers with input validation using a schema registry
175
+ */
176
+ export declare function wrapHandlersWithInputValidation(handlers: Record<string, ToolHandler>, inputSchemas: InputSchemaRegistry): Record<string, ToolHandler>;
177
+ /**
178
+ * Wraps all handlers with both input and output validation
179
+ */
180
+ export declare function wrapHandlersWithFullValidation(handlers: Record<string, ToolHandler>, inputSchemas: InputSchemaRegistry, outputSchemas: OutputSchemaRegistry): Record<string, ToolHandler>;
181
+ /**
182
+ * Type-safe typed handler signature
183
+ * Handlers receive validated input with proper TypeScript types
184
+ */
185
+ export type TypedToolHandler<T> = (input: T) => Promise<MCPToolResult>;
186
+ /**
187
+ * Creates a type-safe tool handler
188
+ * Input is already validated by withInputValidation wrapper
189
+ *
190
+ * INV-MCP-001: Input has been validated before this handler is called
191
+ * INV-MCP-005: Input is frozen and MUST NOT be mutated
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * export const handleMemoryStore = createTypedHandler<MemoryStoreInput>((input) => {
196
+ * const { key, value, namespace } = input;
197
+ * // Type-safe access without casts!
198
+ * });
199
+ * ```
200
+ */
201
+ export declare function createTypedHandler<T>(handler: TypedToolHandler<T>): ToolHandler;
202
+ /**
203
+ * Extracts typed input from validated args
204
+ * Use when you can't use createTypedHandler pattern
205
+ *
206
+ * INV-MCP-001: Only use AFTER validation wrapper has run
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * export const handleTool: ToolHandler = (args) => {
211
+ * const input = getValidatedInput<MyInputType>(args);
212
+ * // Now input is properly typed
213
+ * };
214
+ * ```
215
+ */
216
+ export declare function getValidatedInput<T>(args: Record<string, unknown>): T;
217
+ /**
218
+ * Creates a success response with JSON content
219
+ * INV-MCP-003: Consistent response format
220
+ */
221
+ export declare function createSuccessResponse(data: unknown): MCPToolResult;
222
+ export {};
223
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}