motionmcp 1.0.2 → 2.1.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 (159) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +241 -450
  3. package/dist/handlers/CommentHandler.d.ts +9 -0
  4. package/dist/handlers/CommentHandler.d.ts.map +1 -0
  5. package/dist/handlers/CommentHandler.js +66 -0
  6. package/dist/handlers/CommentHandler.js.map +1 -0
  7. package/dist/handlers/CustomFieldHandler.d.ts +14 -0
  8. package/dist/handlers/CustomFieldHandler.d.ts.map +1 -0
  9. package/dist/handlers/CustomFieldHandler.js +95 -0
  10. package/dist/handlers/CustomFieldHandler.js.map +1 -0
  11. package/dist/handlers/HandlerFactory.d.ts +15 -0
  12. package/dist/handlers/HandlerFactory.d.ts.map +1 -0
  13. package/dist/handlers/HandlerFactory.js +58 -0
  14. package/dist/handlers/HandlerFactory.js.map +1 -0
  15. package/dist/handlers/ProjectHandler.d.ts +10 -0
  16. package/dist/handlers/ProjectHandler.d.ts.map +1 -0
  17. package/dist/handlers/ProjectHandler.js +63 -0
  18. package/dist/handlers/ProjectHandler.js.map +1 -0
  19. package/dist/handlers/RecurringTaskHandler.d.ts +10 -0
  20. package/dist/handlers/RecurringTaskHandler.d.ts.map +1 -0
  21. package/dist/handlers/RecurringTaskHandler.js +68 -0
  22. package/dist/handlers/RecurringTaskHandler.js.map +1 -0
  23. package/dist/handlers/ScheduleHandler.d.ts +8 -0
  24. package/dist/handlers/ScheduleHandler.d.ts.map +1 -0
  25. package/dist/handlers/ScheduleHandler.js +43 -0
  26. package/dist/handlers/ScheduleHandler.js.map +1 -0
  27. package/dist/handlers/SearchHandler.d.ts +10 -0
  28. package/dist/handlers/SearchHandler.d.ts.map +1 -0
  29. package/dist/handlers/SearchHandler.js +116 -0
  30. package/dist/handlers/SearchHandler.js.map +1 -0
  31. package/dist/handlers/StatusHandler.d.ts +8 -0
  32. package/dist/handlers/StatusHandler.d.ts.map +1 -0
  33. package/dist/handlers/StatusHandler.js +22 -0
  34. package/dist/handlers/StatusHandler.js.map +1 -0
  35. package/dist/handlers/TaskHandler.d.ts +22 -0
  36. package/dist/handlers/TaskHandler.d.ts.map +1 -0
  37. package/dist/handlers/TaskHandler.js +324 -0
  38. package/dist/handlers/TaskHandler.js.map +1 -0
  39. package/dist/handlers/UserHandler.d.ts +9 -0
  40. package/dist/handlers/UserHandler.d.ts.map +1 -0
  41. package/dist/handlers/UserHandler.js +36 -0
  42. package/dist/handlers/UserHandler.js.map +1 -0
  43. package/dist/handlers/WorkspaceHandler.d.ts +10 -0
  44. package/dist/handlers/WorkspaceHandler.d.ts.map +1 -0
  45. package/dist/handlers/WorkspaceHandler.js +49 -0
  46. package/dist/handlers/WorkspaceHandler.js.map +1 -0
  47. package/dist/handlers/base/BaseHandler.d.ts +16 -0
  48. package/dist/handlers/base/BaseHandler.d.ts.map +1 -0
  49. package/dist/handlers/base/BaseHandler.js +31 -0
  50. package/dist/handlers/base/BaseHandler.js.map +1 -0
  51. package/dist/handlers/base/HandlerInterface.d.ts +18 -0
  52. package/dist/handlers/base/HandlerInterface.d.ts.map +1 -0
  53. package/dist/handlers/base/HandlerInterface.js +3 -0
  54. package/dist/handlers/base/HandlerInterface.js.map +1 -0
  55. package/dist/handlers/index.d.ts +14 -0
  56. package/dist/handlers/index.d.ts.map +1 -0
  57. package/dist/handlers/index.js +31 -0
  58. package/dist/handlers/index.js.map +1 -0
  59. package/dist/mcp-server.d.ts +15 -0
  60. package/dist/mcp-server.d.ts.map +1 -0
  61. package/dist/mcp-server.js +145 -0
  62. package/dist/mcp-server.js.map +1 -0
  63. package/dist/schemas/motion.d.ts +4971 -0
  64. package/dist/schemas/motion.d.ts.map +1 -0
  65. package/dist/schemas/motion.js +328 -0
  66. package/dist/schemas/motion.js.map +1 -0
  67. package/dist/services/motionApi.d.ts +199 -0
  68. package/dist/services/motionApi.d.ts.map +1 -0
  69. package/dist/services/motionApi.js +1950 -0
  70. package/dist/services/motionApi.js.map +1 -0
  71. package/dist/tools/ToolConfigurator.d.ts +19 -0
  72. package/dist/tools/ToolConfigurator.d.ts.map +1 -0
  73. package/dist/tools/ToolConfigurator.js +89 -0
  74. package/dist/tools/ToolConfigurator.js.map +1 -0
  75. package/dist/tools/ToolDefinitions.d.ts +25 -0
  76. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  77. package/dist/tools/ToolDefinitions.js +508 -0
  78. package/dist/tools/ToolDefinitions.js.map +1 -0
  79. package/dist/tools/ToolRegistry.d.ts +16 -0
  80. package/dist/tools/ToolRegistry.d.ts.map +1 -0
  81. package/dist/tools/ToolRegistry.js +89 -0
  82. package/dist/tools/ToolRegistry.js.map +1 -0
  83. package/dist/tools/index.d.ts +4 -0
  84. package/dist/tools/index.d.ts.map +1 -0
  85. package/dist/tools/index.js +21 -0
  86. package/dist/tools/index.js.map +1 -0
  87. package/dist/types/mcp-tool-args.d.ts +123 -0
  88. package/dist/types/mcp-tool-args.d.ts.map +1 -0
  89. package/dist/types/mcp-tool-args.js +7 -0
  90. package/dist/types/mcp-tool-args.js.map +1 -0
  91. package/dist/types/mcp.d.ts +32 -0
  92. package/dist/types/mcp.d.ts.map +1 -0
  93. package/dist/types/mcp.js +3 -0
  94. package/dist/types/mcp.js.map +1 -0
  95. package/dist/types/motion.d.ts +304 -0
  96. package/dist/types/motion.d.ts.map +1 -0
  97. package/dist/types/motion.js +3 -0
  98. package/dist/types/motion.js.map +1 -0
  99. package/dist/utils/cache.d.ts +25 -0
  100. package/dist/utils/cache.d.ts.map +1 -0
  101. package/dist/utils/cache.js +135 -0
  102. package/dist/utils/cache.js.map +1 -0
  103. package/dist/utils/constants.d.ts +88 -0
  104. package/dist/utils/constants.d.ts.map +1 -0
  105. package/dist/utils/constants.js +188 -0
  106. package/dist/utils/constants.js.map +1 -0
  107. package/dist/utils/errorHandling.d.ts +50 -0
  108. package/dist/utils/errorHandling.d.ts.map +1 -0
  109. package/dist/utils/errorHandling.js +86 -0
  110. package/dist/utils/errorHandling.js.map +1 -0
  111. package/dist/utils/index.d.ts +13 -0
  112. package/dist/utils/index.d.ts.map +1 -0
  113. package/dist/utils/index.js +38 -0
  114. package/dist/utils/index.js.map +1 -0
  115. package/dist/utils/logger.d.ts +13 -0
  116. package/dist/utils/logger.d.ts.map +1 -0
  117. package/dist/utils/logger.js +47 -0
  118. package/dist/utils/logger.js.map +1 -0
  119. package/dist/utils/pagination.d.ts +61 -0
  120. package/dist/utils/pagination.d.ts.map +1 -0
  121. package/dist/utils/pagination.js +168 -0
  122. package/dist/utils/pagination.js.map +1 -0
  123. package/dist/utils/paginationNew.d.ts +44 -0
  124. package/dist/utils/paginationNew.d.ts.map +1 -0
  125. package/dist/utils/paginationNew.js +149 -0
  126. package/dist/utils/paginationNew.js.map +1 -0
  127. package/dist/utils/parameterUtils.d.ts +79 -0
  128. package/dist/utils/parameterUtils.d.ts.map +1 -0
  129. package/dist/utils/parameterUtils.js +189 -0
  130. package/dist/utils/parameterUtils.js.map +1 -0
  131. package/dist/utils/responseFormatters.d.ts +95 -0
  132. package/dist/utils/responseFormatters.d.ts.map +1 -0
  133. package/dist/utils/responseFormatters.js +342 -0
  134. package/dist/utils/responseFormatters.js.map +1 -0
  135. package/dist/utils/responseWrapper.d.ts +38 -0
  136. package/dist/utils/responseWrapper.d.ts.map +1 -0
  137. package/dist/utils/responseWrapper.js +201 -0
  138. package/dist/utils/responseWrapper.js.map +1 -0
  139. package/dist/utils/sanitize.d.ts +51 -0
  140. package/dist/utils/sanitize.d.ts.map +1 -0
  141. package/dist/utils/sanitize.js +138 -0
  142. package/dist/utils/sanitize.js.map +1 -0
  143. package/dist/utils/validator.d.ts +37 -0
  144. package/dist/utils/validator.d.ts.map +1 -0
  145. package/dist/utils/validator.js +74 -0
  146. package/dist/utils/validator.js.map +1 -0
  147. package/dist/utils/workspaceResolver.d.ts +40 -0
  148. package/dist/utils/workspaceResolver.d.ts.map +1 -0
  149. package/dist/utils/workspaceResolver.js +207 -0
  150. package/dist/utils/workspaceResolver.js.map +1 -0
  151. package/package.json +41 -17
  152. package/.claude/settings.local.json +0 -15
  153. package/.env.example +0 -3
  154. package/sample.png +0 -0
  155. package/src/index.js +0 -179
  156. package/src/mcp-server.js +0 -1137
  157. package/src/routes/motion.js +0 -152
  158. package/src/services/motionApi.js +0 -1177
  159. package/src/worker.js +0 -248
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Motion API Response Wrapper Utility
3
+ *
4
+ * Handles the inconsistent response patterns across Motion API endpoints:
5
+ * - Some return wrapped responses: { meta: {...}, [resource]: [...] }
6
+ * - Others return direct arrays: [...]
7
+ *
8
+ * This utility provides type-safe unwrapping with proper pagination support.
9
+ */
10
+ import { MotionPaginationMeta } from '../types/motion';
11
+ /**
12
+ * Standard unwrapped response structure for consistent internal handling
13
+ */
14
+ export interface UnwrappedResponse<T> {
15
+ data: T[];
16
+ meta?: MotionPaginationMeta;
17
+ }
18
+ /**
19
+ * Unwraps a Motion API response based on the known patterns
20
+ *
21
+ * @param response - The raw API response data
22
+ * @param apiEndpoint - The API endpoint name (e.g., 'tasks', 'projects', 'comments')
23
+ * @returns Standardized unwrapped response with data array and optional meta
24
+ */
25
+ export declare function unwrapApiResponse<T = unknown>(response: unknown, apiEndpoint: string): UnwrappedResponse<T>;
26
+ /**
27
+ * Checks if an API endpoint supports pagination based on known patterns
28
+ */
29
+ export declare function supportsPagination(apiEndpoint: string): boolean;
30
+ /**
31
+ * Gets the expected resource key for a wrapped API response
32
+ */
33
+ export declare function getResourceKey(apiEndpoint: string): string | undefined;
34
+ /**
35
+ * Updates the known pattern for an API endpoint (for runtime discovery)
36
+ */
37
+ export declare function updateApiPattern(apiEndpoint: string, isWrapped: boolean, resourceKey?: string): void;
38
+ //# sourceMappingURL=responseWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseWrapper.d.ts","sourceRoot":"","sources":["../../src/utils/responseWrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,IAAI,CAAC,EAAE,oBAAoB,CAAC;CAC7B;AA6DD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,QAAQ,EAAE,OAAO,EACjB,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,CAAC,CAAC,CAiBtB;AAyGD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,OAAO,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAYN"}
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ /**
3
+ * Motion API Response Wrapper Utility
4
+ *
5
+ * Handles the inconsistent response patterns across Motion API endpoints:
6
+ * - Some return wrapped responses: { meta: {...}, [resource]: [...] }
7
+ * - Others return direct arrays: [...]
8
+ *
9
+ * This utility provides type-safe unwrapping with proper pagination support.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.unwrapApiResponse = unwrapApiResponse;
13
+ exports.supportsPagination = supportsPagination;
14
+ exports.getResourceKey = getResourceKey;
15
+ exports.updateApiPattern = updateApiPattern;
16
+ const logger_1 = require("./logger");
17
+ const constants_1 = require("./constants");
18
+ /**
19
+ * Known API response patterns based on current codebase evidence and task documentation
20
+ */
21
+ const API_RESPONSE_PATTERNS = {
22
+ // Wrapped responses (with meta pagination)
23
+ tasks: {
24
+ isWrapped: true,
25
+ resourceKey: 'tasks',
26
+ apiName: 'Tasks'
27
+ },
28
+ projects: {
29
+ isWrapped: true,
30
+ resourceKey: 'projects',
31
+ apiName: 'Projects'
32
+ },
33
+ comments: {
34
+ isWrapped: true,
35
+ resourceKey: 'comments',
36
+ apiName: 'Comments'
37
+ },
38
+ 'recurring-tasks': {
39
+ isWrapped: true,
40
+ resourceKey: 'tasks', // Note: recurring tasks API returns { meta, tasks } not { meta, recurringTasks }
41
+ apiName: 'Recurring Tasks'
42
+ },
43
+ 'custom-fields': {
44
+ isWrapped: true,
45
+ resourceKey: 'customFields',
46
+ apiName: 'Custom Fields'
47
+ },
48
+ // Direct array responses (no wrapper)
49
+ schedules: {
50
+ isWrapped: false,
51
+ apiName: 'Schedules'
52
+ },
53
+ statuses: {
54
+ isWrapped: false,
55
+ apiName: 'Statuses'
56
+ },
57
+ workspaces: {
58
+ isWrapped: false,
59
+ apiName: 'Workspaces'
60
+ },
61
+ users: {
62
+ isWrapped: false, // TODO: Verify this - may be wrapped with 'users' key
63
+ apiName: 'Users'
64
+ }
65
+ };
66
+ /**
67
+ * Unwraps a Motion API response based on the known patterns
68
+ *
69
+ * @param response - The raw API response data
70
+ * @param apiEndpoint - The API endpoint name (e.g., 'tasks', 'projects', 'comments')
71
+ * @returns Standardized unwrapped response with data array and optional meta
72
+ */
73
+ function unwrapApiResponse(response, apiEndpoint) {
74
+ const config = API_RESPONSE_PATTERNS[apiEndpoint];
75
+ if (!config) {
76
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Unknown API endpoint pattern: ${apiEndpoint}`, {
77
+ endpoint: apiEndpoint,
78
+ availablePatterns: Object.keys(API_RESPONSE_PATTERNS)
79
+ });
80
+ // Fallback: try to extract array from common patterns
81
+ return fallbackUnwrap(response, apiEndpoint);
82
+ }
83
+ if (config.isWrapped) {
84
+ return unwrapWrappedResponse(response, config);
85
+ }
86
+ else {
87
+ return unwrapDirectResponse(response, config);
88
+ }
89
+ }
90
+ /**
91
+ * Unwraps a wrapped response: { meta: {...}, [resourceKey]: [...] }
92
+ */
93
+ function unwrapWrappedResponse(response, config) {
94
+ if (!response || typeof response !== 'object') {
95
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Expected wrapped response object for ${config.apiName}`, {
96
+ receivedType: typeof response,
97
+ response
98
+ });
99
+ return { data: [] };
100
+ }
101
+ const responseObj = response;
102
+ const resourceKey = config.resourceKey;
103
+ const data = responseObj[resourceKey];
104
+ const meta = responseObj.meta;
105
+ if (!Array.isArray(data)) {
106
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Expected array for ${resourceKey} in ${config.apiName} response`, {
107
+ resourceKey,
108
+ receivedType: typeof data,
109
+ hasMetaField: !!meta,
110
+ responseKeys: Object.keys(responseObj)
111
+ });
112
+ return { data: [] };
113
+ }
114
+ return {
115
+ data,
116
+ meta: meta && typeof meta === 'object' ? meta : undefined
117
+ };
118
+ }
119
+ /**
120
+ * Unwraps a direct array response: [...]
121
+ */
122
+ function unwrapDirectResponse(response, config) {
123
+ if (!Array.isArray(response)) {
124
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Expected direct array response for ${config.apiName}`, {
125
+ receivedType: typeof response,
126
+ response
127
+ });
128
+ return { data: [] };
129
+ }
130
+ return { data: response };
131
+ }
132
+ /**
133
+ * Fallback unwrapping logic for unknown endpoints
134
+ * Attempts to handle both wrapped and direct patterns
135
+ */
136
+ function fallbackUnwrap(response, apiEndpoint) {
137
+ // Case 1: Direct array
138
+ if (Array.isArray(response)) {
139
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Fallback: treating ${apiEndpoint} as direct array`, {
140
+ itemCount: response.length
141
+ });
142
+ return { data: response };
143
+ }
144
+ // Case 2: Wrapped response - try common resource keys
145
+ if (response && typeof response === 'object') {
146
+ const responseObj = response;
147
+ const possibleKeys = ['items', 'tasks', 'projects', 'comments', 'users', 'workspaces', 'schedules', 'statuses', 'customFields'];
148
+ for (const key of possibleKeys) {
149
+ if (Array.isArray(responseObj[key])) {
150
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, `Fallback: found array at ${key} for ${apiEndpoint}`, {
151
+ key,
152
+ itemCount: responseObj[key].length,
153
+ hasMeta: !!responseObj.meta
154
+ });
155
+ return {
156
+ data: responseObj[key],
157
+ meta: responseObj.meta
158
+ };
159
+ }
160
+ }
161
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.WARN, `Fallback: no array found in object response for ${apiEndpoint}`, {
162
+ responseKeys: Object.keys(responseObj)
163
+ });
164
+ }
165
+ // Case 3: Unexpected response
166
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, `Fallback: unexpected response format for ${apiEndpoint}`, {
167
+ responseType: typeof response,
168
+ response
169
+ });
170
+ return { data: [] };
171
+ }
172
+ /**
173
+ * Checks if an API endpoint supports pagination based on known patterns
174
+ */
175
+ function supportsPagination(apiEndpoint) {
176
+ const config = API_RESPONSE_PATTERNS[apiEndpoint];
177
+ return config?.isWrapped || false;
178
+ }
179
+ /**
180
+ * Gets the expected resource key for a wrapped API response
181
+ */
182
+ function getResourceKey(apiEndpoint) {
183
+ const config = API_RESPONSE_PATTERNS[apiEndpoint];
184
+ return config?.resourceKey;
185
+ }
186
+ /**
187
+ * Updates the known pattern for an API endpoint (for runtime discovery)
188
+ */
189
+ function updateApiPattern(apiEndpoint, isWrapped, resourceKey) {
190
+ API_RESPONSE_PATTERNS[apiEndpoint] = {
191
+ isWrapped,
192
+ resourceKey,
193
+ apiName: apiEndpoint
194
+ };
195
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.INFO, `Updated API pattern for ${apiEndpoint}`, {
196
+ endpoint: apiEndpoint,
197
+ isWrapped,
198
+ resourceKey
199
+ });
200
+ }
201
+ //# sourceMappingURL=responseWrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseWrapper.js","sourceRoot":"","sources":["../../src/utils/responseWrapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Input Sanitization Utilities
3
+ *
4
+ * Provides secure sanitization functions for user-provided content
5
+ * to prevent injection attacks and ensure data integrity.
6
+ */
7
+ /**
8
+ * Sanitize user-provided text content for safe storage and transmission
9
+ * Removes dangerous HTML tags, script content, and other potentially harmful input
10
+ *
11
+ * @param input - The user input to sanitize
12
+ * @returns Sanitized string safe for storage/transmission
13
+ */
14
+ export declare function sanitizeTextContent(input: string | undefined | null): string;
15
+ /**
16
+ * Validate that sanitized content is not empty after sanitization
17
+ *
18
+ * @param original - Original user input
19
+ * @param sanitized - Sanitized version
20
+ * @returns True if content is valid after sanitization
21
+ */
22
+ export declare function isValidSanitizedContent(original: string | undefined | null, sanitized: string): boolean;
23
+ /**
24
+ * Sanitize and validate comment content
25
+ *
26
+ * @param content - Comment content to sanitize
27
+ * @returns Object with sanitized content and validation result
28
+ */
29
+ export declare function sanitizeCommentContent(content: string | undefined | null): {
30
+ sanitized: string;
31
+ isValid: boolean;
32
+ error?: string;
33
+ };
34
+ /**
35
+ * Sanitize task/project description content
36
+ * Similar to comment content but allows empty descriptions
37
+ *
38
+ * @param description - Task or project description to sanitize
39
+ * @returns Sanitized description or undefined if empty/invalid
40
+ */
41
+ export declare function sanitizeDescription(description: string | undefined | null): string | undefined;
42
+ /**
43
+ * Sanitize task/project name content
44
+ * Names are required and must be non-empty after sanitization
45
+ *
46
+ * @param name - Task or project name to sanitize
47
+ * @returns Sanitized name
48
+ * @throws Error if name is empty or contains invalid content
49
+ */
50
+ export declare function sanitizeName(name: string | undefined | null): string;
51
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAmC5E;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAQvG;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAwBA;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAgB9F;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAgBpE"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ /**
3
+ * Input Sanitization Utilities
4
+ *
5
+ * Provides secure sanitization functions for user-provided content
6
+ * to prevent injection attacks and ensure data integrity.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.sanitizeTextContent = sanitizeTextContent;
10
+ exports.isValidSanitizedContent = isValidSanitizedContent;
11
+ exports.sanitizeCommentContent = sanitizeCommentContent;
12
+ exports.sanitizeDescription = sanitizeDescription;
13
+ exports.sanitizeName = sanitizeName;
14
+ const constants_1 = require("./constants");
15
+ /**
16
+ * Sanitize user-provided text content for safe storage and transmission
17
+ * Removes dangerous HTML tags, script content, and other potentially harmful input
18
+ *
19
+ * @param input - The user input to sanitize
20
+ * @returns Sanitized string safe for storage/transmission
21
+ */
22
+ function sanitizeTextContent(input) {
23
+ if (!input || typeof input !== 'string') {
24
+ return '';
25
+ }
26
+ // Trim whitespace
27
+ const trimmed = input.trim();
28
+ if (trimmed.length === 0) {
29
+ return '';
30
+ }
31
+ // Remove or escape potentially dangerous characters and patterns
32
+ let sanitized = trimmed
33
+ // Remove script tags and their content entirely
34
+ .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
35
+ // Remove any remaining HTML tags but keep inner text
36
+ .replace(/<[^>]*>/g, '')
37
+ // Normalize unicode non-breaking spaces
38
+ .replace(/\u00a0/g, ' ');
39
+ // Normalize whitespace introduced by stripping tags while preserving newlines
40
+ sanitized = sanitized
41
+ .replace(/\r\n/g, '\n')
42
+ .replace(/[ \t]{2,}/g, ' ')
43
+ .replace(/[ \t]+\n/g, '\n')
44
+ .replace(/\n{3,}/g, '\n\n')
45
+ .trim();
46
+ // Limit length to prevent abuse - use consistent limit from constants
47
+ if (sanitized.length > constants_1.LIMITS.COMMENT_MAX_LENGTH) {
48
+ sanitized = sanitized.substring(0, constants_1.LIMITS.COMMENT_MAX_LENGTH);
49
+ }
50
+ return sanitized;
51
+ }
52
+ /**
53
+ * Validate that sanitized content is not empty after sanitization
54
+ *
55
+ * @param original - Original user input
56
+ * @param sanitized - Sanitized version
57
+ * @returns True if content is valid after sanitization
58
+ */
59
+ function isValidSanitizedContent(original, sanitized) {
60
+ // If original had content but sanitized is empty, it was likely malicious
61
+ if (original && original.trim().length > 0 && sanitized.length === 0) {
62
+ return false;
63
+ }
64
+ // Must have some actual content
65
+ return sanitized.length > 0;
66
+ }
67
+ /**
68
+ * Sanitize and validate comment content
69
+ *
70
+ * @param content - Comment content to sanitize
71
+ * @returns Object with sanitized content and validation result
72
+ */
73
+ function sanitizeCommentContent(content) {
74
+ const sanitized = sanitizeTextContent(content);
75
+ const isValid = isValidSanitizedContent(content, sanitized);
76
+ if (!isValid && content && content.trim().length > 0) {
77
+ return {
78
+ sanitized: '',
79
+ isValid: false,
80
+ error: 'Comment content contains invalid or potentially harmful content'
81
+ };
82
+ }
83
+ if (!isValid) {
84
+ return {
85
+ sanitized: '',
86
+ isValid: false,
87
+ error: 'Comment content cannot be empty'
88
+ };
89
+ }
90
+ return {
91
+ sanitized,
92
+ isValid: true
93
+ };
94
+ }
95
+ /**
96
+ * Sanitize task/project description content
97
+ * Similar to comment content but allows empty descriptions
98
+ *
99
+ * @param description - Task or project description to sanitize
100
+ * @returns Sanitized description or undefined if empty/invalid
101
+ */
102
+ function sanitizeDescription(description) {
103
+ if (!description || typeof description !== 'string') {
104
+ return undefined;
105
+ }
106
+ const sanitized = sanitizeTextContent(description);
107
+ if (sanitized === '') {
108
+ return undefined;
109
+ }
110
+ // Check if sanitization removed significant content (potential attack)
111
+ if (description.trim().length > 0 && !isValidSanitizedContent(description, sanitized)) {
112
+ throw new Error('Description contains invalid or potentially harmful content');
113
+ }
114
+ return sanitized;
115
+ }
116
+ /**
117
+ * Sanitize task/project name content
118
+ * Names are required and must be non-empty after sanitization
119
+ *
120
+ * @param name - Task or project name to sanitize
121
+ * @returns Sanitized name
122
+ * @throws Error if name is empty or contains invalid content
123
+ */
124
+ function sanitizeName(name) {
125
+ if (!name || typeof name !== 'string') {
126
+ throw new Error('Name is required');
127
+ }
128
+ const sanitized = sanitizeTextContent(name);
129
+ if (sanitized === '') {
130
+ throw new Error('Name cannot be empty');
131
+ }
132
+ // Check if sanitization removed significant content (potential attack)
133
+ if (!isValidSanitizedContent(name, sanitized)) {
134
+ throw new Error('Name contains invalid or potentially harmful content');
135
+ }
136
+ return sanitized;
137
+ }
138
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAWH,kDAmCC;AASD,0DAQC;AAQD,wDA4BC;AASD,kDAgBC;AAUD,oCAgBC;AApJD,2CAAqC;AAErC;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,KAAgC;IAClE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iEAAiE;IACjE,IAAI,SAAS,GAAG,OAAO;QACrB,gDAAgD;SAC/C,OAAO,CAAC,qDAAqD,EAAE,EAAE,CAAC;QACnE,qDAAqD;SACpD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;QACxB,wCAAwC;SACvC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE3B,8EAA8E;IAC9E,SAAS,GAAG,SAAS;SAClB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC;SACtB,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;SAC1B,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;SAC1B,IAAI,EAAE,CAAC;IAEV,sEAAsE;IACtE,IAAI,SAAS,CAAC,MAAM,GAAG,kBAAM,CAAC,kBAAkB,EAAE,CAAC;QACjD,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAM,CAAC,kBAAkB,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,uBAAuB,CAAC,QAAmC,EAAE,SAAiB;IAC5F,0EAA0E;IAC1E,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gCAAgC;IAChC,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,OAAkC;IAKvE,MAAM,SAAS,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAE5D,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,iEAAiE;SACzE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,iCAAiC;SACzC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS;QACT,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,WAAsC;IACxE,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QACrB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,uEAAuE;IACvE,IAAI,WAAW,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;QACtF,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAC,IAA+B;IAC1D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,uEAAuE;IACvE,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Input Validation Service - Runtime validation for MCP requests
3
+ *
4
+ * This module provides runtime validation of incoming MCP requests
5
+ * against their defined schemas using AJV, ensuring type safety
6
+ * at runtime and preventing malformed inputs from causing errors.
7
+ */
8
+ import { McpToolDefinition } from '../types/mcp';
9
+ export declare class InputValidator {
10
+ private ajv;
11
+ private validators;
12
+ constructor();
13
+ /**
14
+ * Compile and cache validators for all tool definitions
15
+ */
16
+ initializeValidators(toolDefinitions: McpToolDefinition[]): void;
17
+ /**
18
+ * Validate input arguments against tool schema
19
+ */
20
+ validateInput(toolName: string, args: unknown): {
21
+ valid: boolean;
22
+ errors?: string;
23
+ };
24
+ /**
25
+ * Get detailed validation errors for debugging
26
+ */
27
+ getDetailedErrors(toolName: string): any[] | undefined;
28
+ /**
29
+ * Clear all cached validators
30
+ */
31
+ clearValidators(): void;
32
+ /**
33
+ * Check if a validator exists for a tool
34
+ */
35
+ hasValidator(toolName: string): boolean;
36
+ }
37
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/utils/validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,qBAAa,cAAc;IACzB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,UAAU,CAAgC;;IAWlD;;OAEG;IACH,oBAAoB,CAAC,eAAe,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAOhE;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAsBnF;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS;IAKtD;;OAEG;IACH,eAAe,IAAI,IAAI;IAIvB;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAGxC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * Input Validation Service - Runtime validation for MCP requests
4
+ *
5
+ * This module provides runtime validation of incoming MCP requests
6
+ * against their defined schemas using AJV, ensuring type safety
7
+ * at runtime and preventing malformed inputs from causing errors.
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.InputValidator = void 0;
14
+ const ajv_1 = __importDefault(require("ajv"));
15
+ class InputValidator {
16
+ constructor() {
17
+ this.ajv = new ajv_1.default({
18
+ allErrors: true,
19
+ coerceTypes: true, // Automatically coerce types when safe
20
+ allowUnionTypes: true // Allow union types in schemas
21
+ });
22
+ this.validators = new Map();
23
+ }
24
+ /**
25
+ * Compile and cache validators for all tool definitions
26
+ */
27
+ initializeValidators(toolDefinitions) {
28
+ for (const tool of toolDefinitions) {
29
+ const validator = this.ajv.compile(tool.inputSchema);
30
+ this.validators.set(tool.name, validator);
31
+ }
32
+ }
33
+ /**
34
+ * Validate input arguments against tool schema
35
+ */
36
+ validateInput(toolName, args) {
37
+ const validator = this.validators.get(toolName);
38
+ if (!validator) {
39
+ return {
40
+ valid: false,
41
+ errors: `No validator found for tool: ${toolName}`
42
+ };
43
+ }
44
+ const valid = validator(args);
45
+ if (!valid) {
46
+ return {
47
+ valid: false,
48
+ errors: this.ajv.errorsText(validator.errors)
49
+ };
50
+ }
51
+ return { valid: true };
52
+ }
53
+ /**
54
+ * Get detailed validation errors for debugging
55
+ */
56
+ getDetailedErrors(toolName) {
57
+ const validator = this.validators.get(toolName);
58
+ return validator?.errors || undefined;
59
+ }
60
+ /**
61
+ * Clear all cached validators
62
+ */
63
+ clearValidators() {
64
+ this.validators.clear();
65
+ }
66
+ /**
67
+ * Check if a validator exists for a tool
68
+ */
69
+ hasValidator(toolName) {
70
+ return this.validators.has(toolName);
71
+ }
72
+ }
73
+ exports.InputValidator = InputValidator;
74
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/utils/validator.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;AAEH,8CAA4C;AAG5C,MAAa,cAAc;IAIzB;QACE,IAAI,CAAC,GAAG,GAAG,IAAI,aAAG,CAAC;YACjB,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,IAAI,EAAG,uCAAuC;YAC3D,eAAe,EAAE,IAAI,CAAE,+BAA+B;SACvD,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,eAAoC;QACvD,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,QAAgB,EAAE,IAAa;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEhD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,gCAAgC,QAAQ,EAAE;aACnD,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAE9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC;aAC9C,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,QAAgB;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChD,OAAO,SAAS,EAAE,MAAM,IAAI,SAAS,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,QAAgB;QAC3B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;CACF;AArED,wCAqEC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * WorkspaceResolver - Centralized workspace resolution logic
3
+ *
4
+ * This class handles all workspace resolution patterns used throughout
5
+ * the Motion MCP Server, including ID resolution, name lookups, and
6
+ * fallback to default workspace behavior.
7
+ */
8
+ import { MotionWorkspace } from '../types/motion';
9
+ import { MotionApiService } from '../services/motionApi';
10
+ interface WorkspaceResolverOptions {
11
+ fallbackToDefault?: boolean;
12
+ validateAccess?: boolean;
13
+ useCache?: boolean;
14
+ }
15
+ interface WorkspaceArgs {
16
+ workspaceId?: string;
17
+ workspaceName?: string;
18
+ }
19
+ export declare class WorkspaceResolver {
20
+ private motionService;
21
+ constructor(motionApiService: MotionApiService);
22
+ /**
23
+ * Main workspace resolution method - handles all workspace resolution patterns
24
+ */
25
+ resolveWorkspace(args?: WorkspaceArgs, options?: WorkspaceResolverOptions): Promise<MotionWorkspace>;
26
+ /**
27
+ * Resolve workspace by ID - validates the workspace exists
28
+ */
29
+ private resolveByWorkspaceId;
30
+ /**
31
+ * Resolve workspace by name - finds matching workspace
32
+ */
33
+ private resolveByWorkspaceName;
34
+ /**
35
+ * Resolve default workspace - gets the first available workspace
36
+ */
37
+ private resolveDefaultWorkspace;
38
+ }
39
+ export {};
40
+ //# sourceMappingURL=workspaceResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceResolver.d.ts","sourceRoot":"","sources":["../../src/utils/workspaceResolver.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,UAAU,wBAAwB;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,aAAa;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,aAAa,CAAmB;gBAE5B,gBAAgB,EAAE,gBAAgB;IAO9C;;OAEG;IACG,gBAAgB,CACpB,IAAI,GAAE,aAAkB,EACxB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,eAAe,CAAC;IAqF3B;;OAEG;YACW,oBAAoB;IA2ClC;;OAEG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,uBAAuB;CAyCtC"}