@uluops/ops-mcp 0.2.1

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 (269) hide show
  1. package/CHANGELOG.md +383 -0
  2. package/LICENSE +21 -0
  3. package/README.md +272 -0
  4. package/dist/client/sdk-error-mapper.d.ts +24 -0
  5. package/dist/client/sdk-error-mapper.d.ts.map +1 -0
  6. package/dist/client/sdk-error-mapper.js +205 -0
  7. package/dist/client/sdk-error-mapper.js.map +1 -0
  8. package/dist/config/index.d.ts +26 -0
  9. package/dist/config/index.d.ts.map +1 -0
  10. package/dist/config/index.js +121 -0
  11. package/dist/config/index.js.map +1 -0
  12. package/dist/config/tool-registry.d.ts +25 -0
  13. package/dist/config/tool-registry.d.ts.map +1 -0
  14. package/dist/config/tool-registry.js +439 -0
  15. package/dist/config/tool-registry.js.map +1 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +245 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/resources/index.d.ts +12 -0
  21. package/dist/resources/index.d.ts.map +1 -0
  22. package/dist/resources/index.js +16 -0
  23. package/dist/resources/index.js.map +1 -0
  24. package/dist/resources/projects.d.ts +12 -0
  25. package/dist/resources/projects.d.ts.map +1 -0
  26. package/dist/resources/projects.js +45 -0
  27. package/dist/resources/projects.js.map +1 -0
  28. package/dist/resources/response-helpers.d.ts +15 -0
  29. package/dist/resources/response-helpers.d.ts.map +1 -0
  30. package/dist/resources/response-helpers.js +34 -0
  31. package/dist/resources/response-helpers.js.map +1 -0
  32. package/dist/resources/taxonomy.d.ts +19 -0
  33. package/dist/resources/taxonomy.d.ts.map +1 -0
  34. package/dist/resources/taxonomy.js +45 -0
  35. package/dist/resources/taxonomy.js.map +1 -0
  36. package/dist/tools/add-issue-note.d.ts +25 -0
  37. package/dist/tools/add-issue-note.d.ts.map +1 -0
  38. package/dist/tools/add-issue-note.js +19 -0
  39. package/dist/tools/add-issue-note.js.map +1 -0
  40. package/dist/tools/archive-runs.d.ts +33 -0
  41. package/dist/tools/archive-runs.d.ts.map +1 -0
  42. package/dist/tools/archive-runs.js +21 -0
  43. package/dist/tools/archive-runs.js.map +1 -0
  44. package/dist/tools/bulk-update-status.d.ts +54 -0
  45. package/dist/tools/bulk-update-status.d.ts.map +1 -0
  46. package/dist/tools/bulk-update-status.js +22 -0
  47. package/dist/tools/bulk-update-status.js.map +1 -0
  48. package/dist/tools/create-issue.d.ts +52 -0
  49. package/dist/tools/create-issue.d.ts.map +1 -0
  50. package/dist/tools/create-issue.js +25 -0
  51. package/dist/tools/create-issue.js.map +1 -0
  52. package/dist/tools/create-project.d.ts +21 -0
  53. package/dist/tools/create-project.d.ts.map +1 -0
  54. package/dist/tools/create-project.js +17 -0
  55. package/dist/tools/create-project.js.map +1 -0
  56. package/dist/tools/delete-project.d.ts +28 -0
  57. package/dist/tools/delete-project.d.ts.map +1 -0
  58. package/dist/tools/delete-project.js +34 -0
  59. package/dist/tools/delete-project.js.map +1 -0
  60. package/dist/tools/delete-run.d.ts +24 -0
  61. package/dist/tools/delete-run.d.ts.map +1 -0
  62. package/dist/tools/delete-run.js +18 -0
  63. package/dist/tools/delete-run.js.map +1 -0
  64. package/dist/tools/diff-runs.d.ts +30 -0
  65. package/dist/tools/diff-runs.d.ts.map +1 -0
  66. package/dist/tools/diff-runs.js +20 -0
  67. package/dist/tools/diff-runs.js.map +1 -0
  68. package/dist/tools/edit-issue.d.ts +34 -0
  69. package/dist/tools/edit-issue.d.ts.map +1 -0
  70. package/dist/tools/edit-issue.js +25 -0
  71. package/dist/tools/edit-issue.js.map +1 -0
  72. package/dist/tools/get-agent-lifecycle.d.ts +10 -0
  73. package/dist/tools/get-agent-lifecycle.d.ts.map +1 -0
  74. package/dist/tools/get-agent-lifecycle.js +20 -0
  75. package/dist/tools/get-agent-lifecycle.js.map +1 -0
  76. package/dist/tools/get-agent-matrix.d.ts +24 -0
  77. package/dist/tools/get-agent-matrix.d.ts.map +1 -0
  78. package/dist/tools/get-agent-matrix.js +29 -0
  79. package/dist/tools/get-agent-matrix.js.map +1 -0
  80. package/dist/tools/get-agent-reliability.d.ts +22 -0
  81. package/dist/tools/get-agent-reliability.d.ts.map +1 -0
  82. package/dist/tools/get-agent-reliability.js +14 -0
  83. package/dist/tools/get-agent-reliability.js.map +1 -0
  84. package/dist/tools/get-agent-runs-analysis.d.ts +33 -0
  85. package/dist/tools/get-agent-runs-analysis.d.ts.map +1 -0
  86. package/dist/tools/get-agent-runs-analysis.js +26 -0
  87. package/dist/tools/get-agent-runs-analysis.js.map +1 -0
  88. package/dist/tools/get-analytics.d.ts +30 -0
  89. package/dist/tools/get-analytics.d.ts.map +1 -0
  90. package/dist/tools/get-analytics.js +29 -0
  91. package/dist/tools/get-analytics.js.map +1 -0
  92. package/dist/tools/get-burndown.d.ts +24 -0
  93. package/dist/tools/get-burndown.d.ts.map +1 -0
  94. package/dist/tools/get-burndown.js +26 -0
  95. package/dist/tools/get-burndown.js.map +1 -0
  96. package/dist/tools/get-discovery.d.ts +24 -0
  97. package/dist/tools/get-discovery.d.ts.map +1 -0
  98. package/dist/tools/get-discovery.js +26 -0
  99. package/dist/tools/get-discovery.js.map +1 -0
  100. package/dist/tools/get-full-taxonomy-analytics.d.ts +27 -0
  101. package/dist/tools/get-full-taxonomy-analytics.d.ts.map +1 -0
  102. package/dist/tools/get-full-taxonomy-analytics.js +19 -0
  103. package/dist/tools/get-full-taxonomy-analytics.js.map +1 -0
  104. package/dist/tools/get-issue-by-fingerprint.d.ts +24 -0
  105. package/dist/tools/get-issue-by-fingerprint.d.ts.map +1 -0
  106. package/dist/tools/get-issue-by-fingerprint.js +18 -0
  107. package/dist/tools/get-issue-by-fingerprint.js.map +1 -0
  108. package/dist/tools/get-issue-details.d.ts +27 -0
  109. package/dist/tools/get-issue-details.d.ts.map +1 -0
  110. package/dist/tools/get-issue-details.js +19 -0
  111. package/dist/tools/get-issue-details.js.map +1 -0
  112. package/dist/tools/get-issue-history.d.ts +19 -0
  113. package/dist/tools/get-issue-history.d.ts.map +1 -0
  114. package/dist/tools/get-issue-history.js +13 -0
  115. package/dist/tools/get-issue-history.js.map +1 -0
  116. package/dist/tools/get-latest-run.d.ts +24 -0
  117. package/dist/tools/get-latest-run.d.ts.map +1 -0
  118. package/dist/tools/get-latest-run.js +18 -0
  119. package/dist/tools/get-latest-run.js.map +1 -0
  120. package/dist/tools/get-project-analysis.d.ts +36 -0
  121. package/dist/tools/get-project-analysis.d.ts.map +1 -0
  122. package/dist/tools/get-project-analysis.js +28 -0
  123. package/dist/tools/get-project-analysis.js.map +1 -0
  124. package/dist/tools/get-project-summary.d.ts +21 -0
  125. package/dist/tools/get-project-summary.d.ts.map +1 -0
  126. package/dist/tools/get-project-summary.js +17 -0
  127. package/dist/tools/get-project-summary.js.map +1 -0
  128. package/dist/tools/get-project-trends.d.ts +24 -0
  129. package/dist/tools/get-project-trends.d.ts.map +1 -0
  130. package/dist/tools/get-project-trends.js +27 -0
  131. package/dist/tools/get-project-trends.js.map +1 -0
  132. package/dist/tools/get-project.d.ts +21 -0
  133. package/dist/tools/get-project.d.ts.map +1 -0
  134. package/dist/tools/get-project.js +17 -0
  135. package/dist/tools/get-project.js.map +1 -0
  136. package/dist/tools/get-run-analysis.d.ts +21 -0
  137. package/dist/tools/get-run-analysis.d.ts.map +1 -0
  138. package/dist/tools/get-run-analysis.js +17 -0
  139. package/dist/tools/get-run-analysis.js.map +1 -0
  140. package/dist/tools/get-run-details.d.ts +27 -0
  141. package/dist/tools/get-run-details.d.ts.map +1 -0
  142. package/dist/tools/get-run-details.js +19 -0
  143. package/dist/tools/get-run-details.js.map +1 -0
  144. package/dist/tools/get-run.d.ts +21 -0
  145. package/dist/tools/get-run.d.ts.map +1 -0
  146. package/dist/tools/get-run.js +17 -0
  147. package/dist/tools/get-run.js.map +1 -0
  148. package/dist/tools/get-taxonomy.d.ts +15 -0
  149. package/dist/tools/get-taxonomy.d.ts.map +1 -0
  150. package/dist/tools/get-taxonomy.js +15 -0
  151. package/dist/tools/get-taxonomy.js.map +1 -0
  152. package/dist/tools/get-velocity.d.ts +24 -0
  153. package/dist/tools/get-velocity.d.ts.map +1 -0
  154. package/dist/tools/get-velocity.js +28 -0
  155. package/dist/tools/get-velocity.js.map +1 -0
  156. package/dist/tools/index.d.ts +10 -0
  157. package/dist/tools/index.d.ts.map +1 -0
  158. package/dist/tools/index.js +119 -0
  159. package/dist/tools/index.js.map +1 -0
  160. package/dist/tools/list-agents.d.ts +15 -0
  161. package/dist/tools/list-agents.d.ts.map +1 -0
  162. package/dist/tools/list-agents.js +29 -0
  163. package/dist/tools/list-agents.js.map +1 -0
  164. package/dist/tools/list-projects.d.ts +15 -0
  165. package/dist/tools/list-projects.d.ts.map +1 -0
  166. package/dist/tools/list-projects.js +15 -0
  167. package/dist/tools/list-projects.js.map +1 -0
  168. package/dist/tools/list-runs.d.ts +30 -0
  169. package/dist/tools/list-runs.d.ts.map +1 -0
  170. package/dist/tools/list-runs.js +23 -0
  171. package/dist/tools/list-runs.js.map +1 -0
  172. package/dist/tools/merge-issues.d.ts +25 -0
  173. package/dist/tools/merge-issues.d.ts.map +1 -0
  174. package/dist/tools/merge-issues.js +19 -0
  175. package/dist/tools/merge-issues.js.map +1 -0
  176. package/dist/tools/query-analysis-records.d.ts +39 -0
  177. package/dist/tools/query-analysis-records.d.ts.map +1 -0
  178. package/dist/tools/query-analysis-records.js +31 -0
  179. package/dist/tools/query-analysis-records.js.map +1 -0
  180. package/dist/tools/query-issues.d.ts +54 -0
  181. package/dist/tools/query-issues.d.ts.map +1 -0
  182. package/dist/tools/query-issues.js +41 -0
  183. package/dist/tools/query-issues.js.map +1 -0
  184. package/dist/tools/restore-issue.d.ts +21 -0
  185. package/dist/tools/restore-issue.d.ts.map +1 -0
  186. package/dist/tools/restore-issue.js +17 -0
  187. package/dist/tools/restore-issue.js.map +1 -0
  188. package/dist/tools/restore-project.d.ts +21 -0
  189. package/dist/tools/restore-project.d.ts.map +1 -0
  190. package/dist/tools/restore-project.js +17 -0
  191. package/dist/tools/restore-project.js.map +1 -0
  192. package/dist/tools/save-run.d.ts +1570 -0
  193. package/dist/tools/save-run.d.ts.map +1 -0
  194. package/dist/tools/save-run.js +50 -0
  195. package/dist/tools/save-run.js.map +1 -0
  196. package/dist/tools/search-issues.d.ts +42 -0
  197. package/dist/tools/search-issues.d.ts.map +1 -0
  198. package/dist/tools/search-issues.js +25 -0
  199. package/dist/tools/search-issues.js.map +1 -0
  200. package/dist/tools/soft-delete-issue.d.ts +21 -0
  201. package/dist/tools/soft-delete-issue.d.ts.map +1 -0
  202. package/dist/tools/soft-delete-issue.js +17 -0
  203. package/dist/tools/soft-delete-issue.js.map +1 -0
  204. package/dist/tools/soft-delete-project.d.ts +27 -0
  205. package/dist/tools/soft-delete-project.d.ts.map +1 -0
  206. package/dist/tools/soft-delete-project.js +22 -0
  207. package/dist/tools/soft-delete-project.js.map +1 -0
  208. package/dist/tools/undo-issue-status.d.ts +21 -0
  209. package/dist/tools/undo-issue-status.d.ts.map +1 -0
  210. package/dist/tools/undo-issue-status.js +17 -0
  211. package/dist/tools/undo-issue-status.js.map +1 -0
  212. package/dist/tools/update-issue-by-fingerprint.d.ts +30 -0
  213. package/dist/tools/update-issue-by-fingerprint.d.ts.map +1 -0
  214. package/dist/tools/update-issue-by-fingerprint.js +24 -0
  215. package/dist/tools/update-issue-by-fingerprint.js.map +1 -0
  216. package/dist/tools/update-project.d.ts +24 -0
  217. package/dist/tools/update-project.d.ts.map +1 -0
  218. package/dist/tools/update-project.js +21 -0
  219. package/dist/tools/update-project.js.map +1 -0
  220. package/dist/tools/update-run.d.ts +1495 -0
  221. package/dist/tools/update-run.d.ts.map +1 -0
  222. package/dist/tools/update-run.js +60 -0
  223. package/dist/tools/update-run.js.map +1 -0
  224. package/dist/tools/update-status.d.ts +64 -0
  225. package/dist/tools/update-status.d.ts.map +1 -0
  226. package/dist/tools/update-status.js +28 -0
  227. package/dist/tools/update-status.js.map +1 -0
  228. package/dist/tools/validate-run.d.ts +228 -0
  229. package/dist/tools/validate-run.d.ts.map +1 -0
  230. package/dist/tools/validate-run.js +25 -0
  231. package/dist/tools/validate-run.js.map +1 -0
  232. package/dist/types/config.d.ts +33 -0
  233. package/dist/types/config.d.ts.map +1 -0
  234. package/dist/types/config.js +5 -0
  235. package/dist/types/config.js.map +1 -0
  236. package/dist/types/index.d.ts +12 -0
  237. package/dist/types/index.d.ts.map +1 -0
  238. package/dist/types/index.js +12 -0
  239. package/dist/types/index.js.map +1 -0
  240. package/dist/types/mcp.d.ts +21 -0
  241. package/dist/types/mcp.d.ts.map +1 -0
  242. package/dist/types/mcp.js +30 -0
  243. package/dist/types/mcp.js.map +1 -0
  244. package/dist/types/run-schemas.d.ts +996 -0
  245. package/dist/types/run-schemas.d.ts.map +1 -0
  246. package/dist/types/run-schemas.js +91 -0
  247. package/dist/types/run-schemas.js.map +1 -0
  248. package/dist/types/schemas.d.ts +288 -0
  249. package/dist/types/schemas.d.ts.map +1 -0
  250. package/dist/types/schemas.js +218 -0
  251. package/dist/types/schemas.js.map +1 -0
  252. package/dist/types/server.d.ts +59 -0
  253. package/dist/types/server.d.ts.map +1 -0
  254. package/dist/types/server.js +7 -0
  255. package/dist/types/server.js.map +1 -0
  256. package/dist/utils/logger.d.ts +24 -0
  257. package/dist/utils/logger.d.ts.map +1 -0
  258. package/dist/utils/logger.js +90 -0
  259. package/dist/utils/logger.js.map +1 -0
  260. package/dist/utils/normalize-keys.d.ts +20 -0
  261. package/dist/utils/normalize-keys.d.ts.map +1 -0
  262. package/dist/utils/normalize-keys.js +38 -0
  263. package/dist/utils/normalize-keys.js.map +1 -0
  264. package/dist/utils/tool-handler.d.ts +64 -0
  265. package/dist/utils/tool-handler.d.ts.map +1 -0
  266. package/dist/utils/tool-handler.js +138 -0
  267. package/dist/utils/tool-handler.js.map +1 -0
  268. package/package.json +83 -0
  269. package/tool-policies.json +96 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Error mapper for converting SDK errors to MCP-safe responses
3
+ *
4
+ * Maps @uluops/ops-sdk error hierarchy to sanitized MCP tool responses.
5
+ * Strips actual credentials (API keys, bearer tokens) before exposure
6
+ * while preserving field names, validation details, and actionable context.
7
+ */
8
+ import type { McpToolResponse } from '../types/index.js';
9
+ /**
10
+ * Map an SDK error to an MCP tool response.
11
+ *
12
+ * Preserves error context including:
13
+ * - Original error messages (with credential redaction only)
14
+ * - HTTP status codes when available
15
+ * - Retry-after information for rate limits
16
+ * - Field-level validation details
17
+ */
18
+ export declare function mapSdkErrorToMcp(error: unknown, toolName?: string): McpToolResponse;
19
+ /**
20
+ * Map a Zod validation error to an MCP tool response.
21
+ * Shows all validation errors with field paths and expected values.
22
+ */
23
+ export declare function mapZodErrorToMcp(error: unknown, toolName?: string): McpToolResponse;
24
+ //# sourceMappingURL=sdk-error-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-error-mapper.d.ts","sourceRoot":"","sources":["../../src/client/sdk-error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAiGzD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAuInF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAoBnF"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Error mapper for converting SDK errors to MCP-safe responses
3
+ *
4
+ * Maps @uluops/ops-sdk error hierarchy to sanitized MCP tool responses.
5
+ * Strips actual credentials (API keys, bearer tokens) before exposure
6
+ * while preserving field names, validation details, and actionable context.
7
+ */
8
+ import { isOpsApiError, isNotFoundError, isRateLimitError, isValidationError, isNetworkError, isTimeoutError, UnauthorizedError, ForbiddenError, isConflictError, isUnprocessableError, } from '@uluops/ops-sdk/errors';
9
+ const MAX_ERROR_MESSAGE_LENGTH = 1000;
10
+ /**
11
+ * Patterns that indicate actual credential values in error messages.
12
+ * Only matches credential values, not field names that mention credentials.
13
+ */
14
+ const CREDENTIAL_PATTERNS = [
15
+ // Actual key/token values (not field names)
16
+ /(?:api[_-]?key|apiKey)\s*[:=]\s*\S+/i,
17
+ /bearer\s+[a-zA-Z0-9_\-.]+/i,
18
+ /authorization:\s*\S+/i,
19
+ /ulr_[a-zA-Z0-9]{20,}/,
20
+ // Token/secret assignments with actual values
21
+ /(?:token|secret)\s*[:=]\s*\S+/i,
22
+ // Stack traces (internal implementation details)
23
+ /at\s+\S+\s+\(\S+:\d+:\d+\)/,
24
+ ];
25
+ /**
26
+ * Check if a message contains actual credential values
27
+ */
28
+ function containsCredentials(message) {
29
+ return CREDENTIAL_PATTERNS.some((pattern) => pattern.test(message));
30
+ }
31
+ /**
32
+ * Redact credential values from a message while preserving the rest.
33
+ * Returns the original message with only credential values replaced.
34
+ */
35
+ function redactCredentials(message) {
36
+ let redacted = message;
37
+ for (const pattern of CREDENTIAL_PATTERNS) {
38
+ redacted = redacted.replace(pattern, '[REDACTED]');
39
+ }
40
+ return redacted;
41
+ }
42
+ /**
43
+ * Sanitize an error message for safe client exposure.
44
+ * Redacts credentials and truncates if needed, but preserves all other context.
45
+ */
46
+ function sanitizeErrorMessage(message) {
47
+ let safe = containsCredentials(message) ? redactCredentials(message) : message;
48
+ if (safe.length > MAX_ERROR_MESSAGE_LENGTH) {
49
+ safe = safe.slice(0, MAX_ERROR_MESSAGE_LENGTH) + '... (truncated)';
50
+ }
51
+ return safe;
52
+ }
53
+ /**
54
+ * Extract HTTP status code from SDK errors when available
55
+ */
56
+ function getStatusCode(error) {
57
+ if (error && typeof error === 'object' && 'statusCode' in error) {
58
+ return error.statusCode;
59
+ }
60
+ return undefined;
61
+ }
62
+ /** Actionable suggestions per error type to help MCP clients self-correct. */
63
+ const ERROR_SUGGESTIONS = {
64
+ NotFoundError: 'Verify the resource ID/name exists. Use a query or list tool to find valid identifiers.',
65
+ RateLimitError: 'Wait for the retry_after_seconds period, then retry.',
66
+ ValidationError: 'Check parameter types and required fields against the tool schema.',
67
+ UnauthorizedError: 'Verify ULUOPS_API_KEY is set to a valid ulr_* key.',
68
+ ForbiddenError: 'This operation requires elevated permissions or a different subscription tier.',
69
+ NetworkError: 'The API server may be down. Check that the service is running.',
70
+ TimeoutError: 'The request took too long. Try reducing payload size or increasing timeout.',
71
+ ConflictError: 'The resource was modified concurrently. Refresh and retry.',
72
+ UnprocessableError: 'The request is well-formed but cannot be processed. Check business logic constraints.',
73
+ InputValidationError: 'SDK-level validation failed before reaching the API. Check input shapes.',
74
+ };
75
+ /**
76
+ * Build a structured error response with context for MCP clients.
77
+ */
78
+ function buildErrorResponse(message, metadata) {
79
+ const payload = { error: message };
80
+ if (metadata) {
81
+ Object.assign(payload, metadata);
82
+ }
83
+ return {
84
+ content: [{ type: 'text', text: JSON.stringify(payload) }],
85
+ isError: true,
86
+ };
87
+ }
88
+ function getErrorTypeName(error) {
89
+ if (error instanceof Error)
90
+ return error.constructor.name;
91
+ return 'unknown';
92
+ }
93
+ /**
94
+ * Map an SDK error to an MCP tool response.
95
+ *
96
+ * Preserves error context including:
97
+ * - Original error messages (with credential redaction only)
98
+ * - HTTP status codes when available
99
+ * - Retry-after information for rate limits
100
+ * - Field-level validation details
101
+ */
102
+ export function mapSdkErrorToMcp(error, toolName) {
103
+ const statusCode = getStatusCode(error);
104
+ const errorType = getErrorTypeName(error);
105
+ const suggestion = ERROR_SUGGESTIONS[errorType];
106
+ const context = {
107
+ ...(statusCode ? { status: statusCode } : {}),
108
+ error_type: errorType,
109
+ ...(toolName ? { tool: toolName } : {}),
110
+ ...(suggestion ? { suggestion } : {}),
111
+ };
112
+ if (isNotFoundError(error)) {
113
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Resource not found'), context);
114
+ }
115
+ if (isRateLimitError(error)) {
116
+ const retryAfter = error.retryAfter;
117
+ return buildErrorResponse(retryAfter
118
+ ? `Rate limit exceeded. Retry after ${String(retryAfter)} seconds.`
119
+ : 'Rate limit exceeded, please retry later.', { ...context, status: 429, ...(retryAfter ? { retry_after_seconds: retryAfter } : {}) });
120
+ }
121
+ if (isValidationError(error)) {
122
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Invalid request parameters'), context);
123
+ }
124
+ if (error instanceof UnauthorizedError) {
125
+ return buildErrorResponse('Authentication required. Verify ULUOPS_API_KEY is set to a valid ulr_* key.', { ...context, status: 401 });
126
+ }
127
+ if (error instanceof ForbiddenError) {
128
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Access denied'), { ...context, status: 403 });
129
+ }
130
+ if (isNetworkError(error)) {
131
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Network error: verify the API server is running'), context);
132
+ }
133
+ if (isTimeoutError(error)) {
134
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Request timed out. Consider increasing ULUOPS_TRACKER_TIMEOUT.'), context);
135
+ }
136
+ // 402 Subscription Required — run submission tier gating (spec Section 9.2)
137
+ if (statusCode === 402) {
138
+ const rawDetails = error.details;
139
+ const details = typeof rawDetails === 'object' && rawDetails !== null
140
+ ? rawDetails
141
+ : {};
142
+ const defs = Array.isArray(details['definitions'])
143
+ ? details['definitions'].filter((d) => typeof d === 'object' && d !== null)
144
+ : undefined;
145
+ const currentTier = typeof details['currentTier'] === 'string' ? details['currentTier'] : undefined;
146
+ const upgradeUrl = typeof details['upgradeUrl'] === 'string' ? details['upgradeUrl'] : undefined;
147
+ const sep = upgradeUrl?.includes('?') ? '&' : '?';
148
+ const trackedUrl = upgradeUrl ? `${upgradeUrl}${sep}source=mcp` : undefined;
149
+ const defList = defs?.map(d => {
150
+ const name = typeof d['name'] === 'string' ? d['name'] : 'unknown';
151
+ const tier = typeof d['requiredTier'] === 'string' ? d['requiredTier'] : 'unknown';
152
+ return `${name} (requires ${tier})`;
153
+ }).join(', ') ?? 'above-tier definitions';
154
+ return buildErrorResponse(`Subscription required. Run references: ${defList}.` +
155
+ (currentTier ? ` Your current tier: ${currentTier}.` : '') +
156
+ (trackedUrl ? ` Upgrade: ${trackedUrl}` : ''), {
157
+ ...context,
158
+ status: 402,
159
+ ...(currentTier ? { current_tier: currentTier } : {}),
160
+ ...(defs ? { rejected_definitions: defs } : {}),
161
+ ...(trackedUrl ? { upgrade_url: trackedUrl } : {}),
162
+ });
163
+ }
164
+ if (isConflictError(error)) {
165
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Resource conflict'), {
166
+ ...context,
167
+ status: error.statusCode,
168
+ ...error.details,
169
+ });
170
+ }
171
+ if (isUnprocessableError(error)) {
172
+ return buildErrorResponse(sanitizeErrorMessage(error.message || 'Unprocessable request'), context);
173
+ }
174
+ if (isOpsApiError(error)) {
175
+ return buildErrorResponse(sanitizeErrorMessage(error.message), context);
176
+ }
177
+ if (error instanceof Error) {
178
+ return buildErrorResponse(sanitizeErrorMessage(error.message), context);
179
+ }
180
+ return buildErrorResponse('An unexpected error occurred', context);
181
+ }
182
+ /**
183
+ * Map a Zod validation error to an MCP tool response.
184
+ * Shows all validation errors with field paths and expected values.
185
+ */
186
+ export function mapZodErrorToMcp(error, toolName) {
187
+ let message = 'Invalid input parameters';
188
+ if (error instanceof Error) {
189
+ const zodError = error;
190
+ if (zodError.errors && Array.isArray(zodError.errors)) {
191
+ const details = zodError.errors
192
+ .map((e) => `${e.path.join('.')}: ${e.message}`)
193
+ .join('; ');
194
+ const count = zodError.errors.length;
195
+ message = `Validation failed (${String(count)} error${count > 1 ? 's' : ''}): ${details}`;
196
+ }
197
+ }
198
+ return buildErrorResponse(message, {
199
+ status: 400,
200
+ error_type: 'ZodValidationError',
201
+ ...(toolName ? { tool: toolName } : {}),
202
+ suggestion: 'Check parameter types and required fields against the tool schema.',
203
+ });
204
+ }
205
+ //# sourceMappingURL=sdk-error-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-error-mapper.js","sourceRoot":"","sources":["../../src/client/sdk-error-mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Configuration loader for @uluops/ops-mcp.
3
+ *
4
+ * Loads configuration from environment variables with sensible defaults.
5
+ */
6
+ import type { UluopsTrackerConfig } from '../types/index.js';
7
+ /**
8
+ * Load configuration from environment variables.
9
+ *
10
+ * @returns Object with `config` and `warnings` (deprecation messages for deferred logging)
11
+ */
12
+ export declare function loadConfig(): {
13
+ config: UluopsTrackerConfig;
14
+ warnings: string[];
15
+ };
16
+ /**
17
+ * Build a short, redacted fingerprint for the API key so operators can
18
+ * distinguish which key the server loaded across multiple deployments
19
+ * without leaking the secret. Returns "ulr_…XXXX" using the last 4 chars.
20
+ */
21
+ export declare function apiKeyFingerprint(apiKey: string | undefined): string;
22
+ /**
23
+ * Validate that required configuration is present and well-formed.
24
+ */
25
+ export declare function validateConfig(config: UluopsTrackerConfig): void;
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAY,MAAM,mBAAmB,CAAC;AA2CvE;;;;GAIG;AACH,wBAAgB,UAAU,IAAI;IAAE,MAAM,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuChF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CA+BhE"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Configuration loader for @uluops/ops-mcp.
3
+ *
4
+ * Loads configuration from environment variables with sensible defaults.
5
+ */
6
+ const DEFAULT_BASE_URL = 'https://api.uluops.ai/api/v1';
7
+ const DEFAULT_TIMEOUT = 30000;
8
+ const DEFAULT_RETRIES = 3;
9
+ const DEFAULT_LOG_LEVEL = 'info';
10
+ /**
11
+ * Parse a log level string, returning a valid LogLevel.
12
+ * @param value - Raw string from environment variable
13
+ * @returns Valid LogLevel, defaults to 'info' if undefined or invalid
14
+ */
15
+ function parseLogLevel(value) {
16
+ const validLevels = ['debug', 'info', 'warn', 'error'];
17
+ if (value !== undefined && value !== '' && validLevels.includes(value)) {
18
+ return value;
19
+ }
20
+ return DEFAULT_LOG_LEVEL;
21
+ }
22
+ /**
23
+ * Parse a boolean environment variable ('true'/'1' = true).
24
+ * @param value - Raw string from environment variable
25
+ * @param defaultValue - Value to return if undefined
26
+ * @returns Parsed boolean or default
27
+ */
28
+ function parseBoolean(value, defaultValue) {
29
+ if (value === undefined)
30
+ return defaultValue;
31
+ return value.toLowerCase() === 'true' || value === '1';
32
+ }
33
+ /**
34
+ * Parse an integer environment variable (base 10).
35
+ * @param value - Raw string from environment variable
36
+ * @param defaultValue - Value to return if undefined or NaN
37
+ * @returns Parsed integer or default
38
+ */
39
+ function parseInteger(value, defaultValue) {
40
+ if (value === undefined)
41
+ return defaultValue;
42
+ const parsed = parseInt(value, 10);
43
+ return isNaN(parsed) ? defaultValue : parsed;
44
+ }
45
+ /**
46
+ * Load configuration from environment variables.
47
+ *
48
+ * @returns Object with `config` and `warnings` (deprecation messages for deferred logging)
49
+ */
50
+ export function loadConfig() {
51
+ const warnings = [];
52
+ const apiUrl = process.env['ULUOPS_BASE_URL'] ?? DEFAULT_BASE_URL;
53
+ const apiKey = process.env['ULUOPS_API_KEY'];
54
+ const orgSlug = process.env['ULUOPS_ORG_SLUG'];
55
+ const config = {
56
+ api: {
57
+ baseUrl: apiUrl,
58
+ apiKey,
59
+ orgSlug,
60
+ timeout: parseInteger(process.env['ULUOPS_TRACKER_TIMEOUT'], DEFAULT_TIMEOUT),
61
+ retries: parseInteger(process.env['ULUOPS_TRACKER_RETRIES'], DEFAULT_RETRIES),
62
+ },
63
+ security: {
64
+ logLevel: parseLogLevel(process.env['LOG_LEVEL']),
65
+ enableLogging: parseBoolean(process.env['ENABLE_FILE_LOGGING'], false),
66
+ logDir: process.env['LOG_DIR'],
67
+ verboseLogging: parseBoolean(process.env['VERBOSE_LOGGING'], false),
68
+ logPerformanceMetrics: parseBoolean(process.env['LOG_PERFORMANCE_METRICS'], false),
69
+ },
70
+ };
71
+ // Warn on non-HTTPS base URL outside development — ULUOPS_API_KEY would be
72
+ // transmitted in cleartext.
73
+ try {
74
+ const parsed = new URL(apiUrl);
75
+ if (parsed.protocol !== 'https:' && process.env['NODE_ENV'] !== 'development') {
76
+ warnings.push(`ULUOPS_BASE_URL uses ${parsed.protocol} (not HTTPS). Your API key will be transmitted in cleartext. Set NODE_ENV=development to silence this warning for local testing.`);
77
+ }
78
+ }
79
+ catch {
80
+ // URL parse failure is handled in validateConfig with a clearer error.
81
+ }
82
+ return { config, warnings };
83
+ }
84
+ /**
85
+ * Build a short, redacted fingerprint for the API key so operators can
86
+ * distinguish which key the server loaded across multiple deployments
87
+ * without leaking the secret. Returns "ulr_…XXXX" using the last 4 chars.
88
+ */
89
+ export function apiKeyFingerprint(apiKey) {
90
+ if (apiKey === undefined || apiKey.length < 4)
91
+ return 'unknown';
92
+ return `ulr_…${apiKey.slice(-4)}`;
93
+ }
94
+ /**
95
+ * Validate that required configuration is present and well-formed.
96
+ */
97
+ export function validateConfig(config) {
98
+ if (!config.api.baseUrl) {
99
+ throw new Error('API base URL is required');
100
+ }
101
+ // Validate URL format
102
+ try {
103
+ new URL(config.api.baseUrl);
104
+ }
105
+ catch {
106
+ throw new Error(`Invalid API URL: ${config.api.baseUrl}`);
107
+ }
108
+ if (config.api.apiKey === undefined || config.api.apiKey === '') {
109
+ throw new Error('API key is required. Set ULUOPS_API_KEY to a value starting with "ulr_" (min 20 chars).');
110
+ }
111
+ if (!/^ulr_[A-Za-z0-9_-]{16,}$/.test(config.api.apiKey)) {
112
+ throw new Error('ULUOPS_API_KEY must start with "ulr_" and be at least 20 characters. Check for typos or leading whitespace.');
113
+ }
114
+ if (config.api.timeout <= 0) {
115
+ throw new Error('Timeout must be a positive number');
116
+ }
117
+ if (config.api.retries < 0) {
118
+ throw new Error('Retries must be a non-negative number');
119
+ }
120
+ }
121
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tool Registry Configuration
3
+ *
4
+ * Per-tool security policies for the MCP server.
5
+ * Required by mcp-secure-server's semantic validation layer.
6
+ *
7
+ * Since this is a thin client adapter (security enforced at API layer),
8
+ * we use permissive defaults with generous limits.
9
+ */
10
+ import type { ToolSpec } from 'mcp-secure-server';
11
+ /**
12
+ * All uluops-tracker tools (P0 + P1 + P2)
13
+ *
14
+ * Limits are set high since:
15
+ * 1. Security is enforced at the API layer
16
+ * 2. Claude Code is trusted automation
17
+ * 3. Validation workflows can produce large payloads
18
+ *
19
+ * Quota rationale (per-tool rate limits):
20
+ * - quotaPerMinute: 240 for reads (4/sec), 120 for writes (2/sec), 60 for bulk ops
21
+ * - quotaPerHour: 5000 for frequent reads, 2000 for writes, 1000 for batch ops
22
+ * - Destructive ops (delete_*): 10/min, 50/hr to prevent accidental mass deletion
23
+ */
24
+ export declare const toolRegistry: ToolSpec[];
25
+ //# sourceMappingURL=tool-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/config/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAMlD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,EAialC,CAAC"}