motionmcp 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +251 -417
  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 +266 -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-old.d.ts +29 -0
  60. package/dist/mcp-server-old.d.ts.map +1 -0
  61. package/dist/mcp-server-old.js +1304 -0
  62. package/dist/mcp-server-old.js.map +1 -0
  63. package/dist/mcp-server.d.ts +15 -0
  64. package/dist/mcp-server.d.ts.map +1 -0
  65. package/dist/mcp-server.js +145 -0
  66. package/dist/mcp-server.js.map +1 -0
  67. package/dist/schemas/motion.d.ts +4971 -0
  68. package/dist/schemas/motion.d.ts.map +1 -0
  69. package/dist/schemas/motion.js +328 -0
  70. package/dist/schemas/motion.js.map +1 -0
  71. package/dist/services/motionApi.d.ts +186 -0
  72. package/dist/services/motionApi.d.ts.map +1 -0
  73. package/dist/services/motionApi.js +1912 -0
  74. package/dist/services/motionApi.js.map +1 -0
  75. package/dist/tools/ToolConfigurator.d.ts +19 -0
  76. package/dist/tools/ToolConfigurator.d.ts.map +1 -0
  77. package/dist/tools/ToolConfigurator.js +89 -0
  78. package/dist/tools/ToolConfigurator.js.map +1 -0
  79. package/dist/tools/ToolDefinitions.d.ts +25 -0
  80. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  81. package/dist/tools/ToolDefinitions.js +502 -0
  82. package/dist/tools/ToolDefinitions.js.map +1 -0
  83. package/dist/tools/ToolRegistry.d.ts +16 -0
  84. package/dist/tools/ToolRegistry.d.ts.map +1 -0
  85. package/dist/tools/ToolRegistry.js +89 -0
  86. package/dist/tools/ToolRegistry.js.map +1 -0
  87. package/dist/tools/index.d.ts +4 -0
  88. package/dist/tools/index.d.ts.map +1 -0
  89. package/dist/tools/index.js +21 -0
  90. package/dist/tools/index.js.map +1 -0
  91. package/dist/types/mcp-tool-args.d.ts +122 -0
  92. package/dist/types/mcp-tool-args.d.ts.map +1 -0
  93. package/dist/types/mcp-tool-args.js +7 -0
  94. package/dist/types/mcp-tool-args.js.map +1 -0
  95. package/dist/types/mcp.d.ts +32 -0
  96. package/dist/types/mcp.d.ts.map +1 -0
  97. package/dist/types/mcp.js +3 -0
  98. package/dist/types/mcp.js.map +1 -0
  99. package/dist/types/motion.d.ts +304 -0
  100. package/dist/types/motion.d.ts.map +1 -0
  101. package/dist/types/motion.js +3 -0
  102. package/dist/types/motion.js.map +1 -0
  103. package/dist/utils/cache.d.ts +25 -0
  104. package/dist/utils/cache.d.ts.map +1 -0
  105. package/dist/utils/cache.js +135 -0
  106. package/dist/utils/cache.js.map +1 -0
  107. package/dist/utils/constants.d.ts +83 -0
  108. package/dist/utils/constants.d.ts.map +1 -0
  109. package/dist/utils/constants.js +151 -0
  110. package/dist/utils/constants.js.map +1 -0
  111. package/dist/utils/errorHandling.d.ts +50 -0
  112. package/dist/utils/errorHandling.d.ts.map +1 -0
  113. package/dist/utils/errorHandling.js +86 -0
  114. package/dist/utils/errorHandling.js.map +1 -0
  115. package/dist/utils/index.d.ts +13 -0
  116. package/dist/utils/index.d.ts.map +1 -0
  117. package/dist/utils/index.js +38 -0
  118. package/dist/utils/index.js.map +1 -0
  119. package/dist/utils/logger.d.ts +13 -0
  120. package/dist/utils/logger.d.ts.map +1 -0
  121. package/dist/utils/logger.js +47 -0
  122. package/dist/utils/logger.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 +92 -0
  132. package/dist/utils/responseFormatters.d.ts.map +1 -0
  133. package/dist/utils/responseFormatters.js +331 -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 +137 -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 -49
  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,137 @@
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
34
+ .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
35
+ // Remove HTML tags but keep the content
36
+ .replace(/<[^>]*>/g, '')
37
+ // Escape remaining angle brackets
38
+ .replace(/</g, '&lt;')
39
+ .replace(/>/g, '&gt;')
40
+ // Escape quotes to prevent attribute injection
41
+ .replace(/"/g, '&quot;')
42
+ .replace(/'/g, '&#39;')
43
+ // Escape ampersands (but do it last to avoid double-escaping)
44
+ .replace(/&(?!(lt|gt|quot|#39|amp);)/g, '&amp;');
45
+ // Limit length to prevent abuse - use consistent limit from constants
46
+ if (sanitized.length > constants_1.LIMITS.COMMENT_MAX_LENGTH) {
47
+ sanitized = sanitized.substring(0, constants_1.LIMITS.COMMENT_MAX_LENGTH);
48
+ }
49
+ return sanitized;
50
+ }
51
+ /**
52
+ * Validate that sanitized content is not empty after sanitization
53
+ *
54
+ * @param original - Original user input
55
+ * @param sanitized - Sanitized version
56
+ * @returns True if content is valid after sanitization
57
+ */
58
+ function isValidSanitizedContent(original, sanitized) {
59
+ // If original had content but sanitized is empty, it was likely malicious
60
+ if (original && original.trim().length > 0 && sanitized.length === 0) {
61
+ return false;
62
+ }
63
+ // Must have some actual content
64
+ return sanitized.length > 0;
65
+ }
66
+ /**
67
+ * Sanitize and validate comment content
68
+ *
69
+ * @param content - Comment content to sanitize
70
+ * @returns Object with sanitized content and validation result
71
+ */
72
+ function sanitizeCommentContent(content) {
73
+ const sanitized = sanitizeTextContent(content);
74
+ const isValid = isValidSanitizedContent(content, sanitized);
75
+ if (!isValid && content && content.trim().length > 0) {
76
+ return {
77
+ sanitized: '',
78
+ isValid: false,
79
+ error: 'Comment content contains invalid or potentially harmful content'
80
+ };
81
+ }
82
+ if (!isValid) {
83
+ return {
84
+ sanitized: '',
85
+ isValid: false,
86
+ error: 'Comment content cannot be empty'
87
+ };
88
+ }
89
+ return {
90
+ sanitized,
91
+ isValid: true
92
+ };
93
+ }
94
+ /**
95
+ * Sanitize task/project description content
96
+ * Similar to comment content but allows empty descriptions
97
+ *
98
+ * @param description - Task or project description to sanitize
99
+ * @returns Sanitized description or undefined if empty/invalid
100
+ */
101
+ function sanitizeDescription(description) {
102
+ if (!description || typeof description !== 'string') {
103
+ return undefined;
104
+ }
105
+ const sanitized = sanitizeTextContent(description);
106
+ if (sanitized === '') {
107
+ return undefined;
108
+ }
109
+ // Check if sanitization removed significant content (potential attack)
110
+ if (description.trim().length > 0 && !isValidSanitizedContent(description, sanitized)) {
111
+ throw new Error('Description contains invalid or potentially harmful content');
112
+ }
113
+ return sanitized;
114
+ }
115
+ /**
116
+ * Sanitize task/project name content
117
+ * Names are required and must be non-empty after sanitization
118
+ *
119
+ * @param name - Task or project name to sanitize
120
+ * @returns Sanitized name
121
+ * @throws Error if name is empty or contains invalid content
122
+ */
123
+ function sanitizeName(name) {
124
+ if (!name || typeof name !== 'string') {
125
+ throw new Error('Name is required');
126
+ }
127
+ const sanitized = sanitizeTextContent(name);
128
+ if (sanitized === '') {
129
+ throw new Error('Name cannot be empty');
130
+ }
131
+ // Check if sanitization removed significant content (potential attack)
132
+ if (!isValidSanitizedContent(name, sanitized)) {
133
+ throw new Error('Name contains invalid or potentially harmful content');
134
+ }
135
+ return sanitized;
136
+ }
137
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * WorkspaceResolver - Centralized workspace resolution logic
4
+ *
5
+ * This class handles all workspace resolution patterns used throughout
6
+ * the Motion MCP Server, including ID resolution, name lookups, and
7
+ * fallback to default workspace behavior.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.WorkspaceResolver = void 0;
11
+ const constants_1 = require("./constants");
12
+ const errorHandling_1 = require("./errorHandling");
13
+ const logger_1 = require("./logger");
14
+ class WorkspaceResolver {
15
+ constructor(motionApiService) {
16
+ if (!motionApiService) {
17
+ throw new Error('MotionApiService is required for WorkspaceResolver');
18
+ }
19
+ this.motionService = motionApiService;
20
+ }
21
+ /**
22
+ * Main workspace resolution method - handles all workspace resolution patterns
23
+ */
24
+ async resolveWorkspace(args = {}, options = {}) {
25
+ const { workspaceId, workspaceName } = args;
26
+ const { fallbackToDefault = constants_1.DEFAULTS.WORKSPACE_FALLBACK_TO_DEFAULT, validateAccess = constants_1.DEFAULTS.WORKSPACE_VALIDATE_ACCESS
27
+ // useCache = DEFAULTS.WORKSPACE_USE_CACHE // Will be used in future caching implementation
28
+ } = options;
29
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Starting workspace resolution', {
30
+ method: 'resolveWorkspace',
31
+ workspaceId,
32
+ workspaceName,
33
+ fallbackToDefault,
34
+ validateAccess
35
+ });
36
+ try {
37
+ let resolvedWorkspace = null;
38
+ // Case 1: Direct workspace ID provided
39
+ if (workspaceId) {
40
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Resolving by workspace ID', {
41
+ method: 'resolveWorkspace',
42
+ workspaceId
43
+ });
44
+ if (validateAccess) {
45
+ resolvedWorkspace = await this.resolveByWorkspaceId(workspaceId);
46
+ }
47
+ else {
48
+ // When not validating, just return the ID as-is
49
+ resolvedWorkspace = {
50
+ id: workspaceId,
51
+ name: 'Unknown Workspace',
52
+ teamId: 'unknown',
53
+ type: constants_1.WORKSPACE_TYPES.UNKNOWN,
54
+ labels: [],
55
+ statuses: []
56
+ };
57
+ }
58
+ }
59
+ // Case 2: Workspace name provided
60
+ else if (workspaceName) {
61
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Resolving by workspace name', {
62
+ method: 'resolveWorkspace',
63
+ workspaceName
64
+ });
65
+ resolvedWorkspace = await this.resolveByWorkspaceName(workspaceName);
66
+ }
67
+ // Case 3: Fallback to default workspace
68
+ else if (fallbackToDefault) {
69
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Falling back to default workspace', {
70
+ method: 'resolveWorkspace'
71
+ });
72
+ resolvedWorkspace = await this.resolveDefaultWorkspace();
73
+ }
74
+ // Case 4: No workspace could be resolved
75
+ if (!resolvedWorkspace) {
76
+ throw new errorHandling_1.WorkspaceError('No workspace specified and no default workspace available', constants_1.ERROR_CODES.NO_DEFAULT_WORKSPACE, { fallbackToDefault });
77
+ }
78
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.INFO, 'Workspace resolved successfully', {
79
+ method: 'resolveWorkspace',
80
+ resolvedId: resolvedWorkspace.id,
81
+ resolvedName: resolvedWorkspace.name
82
+ });
83
+ return resolvedWorkspace;
84
+ }
85
+ catch (error) {
86
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, 'Failed to resolve workspace', {
87
+ method: 'resolveWorkspace',
88
+ error: error instanceof Error ? error.message : 'Unknown error',
89
+ workspaceId,
90
+ workspaceName
91
+ });
92
+ throw error;
93
+ }
94
+ }
95
+ /**
96
+ * Resolve workspace by ID - validates the workspace exists
97
+ */
98
+ async resolveByWorkspaceId(workspaceId) {
99
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Fetching workspace by ID', {
100
+ method: 'resolveByWorkspaceId',
101
+ workspaceId
102
+ });
103
+ try {
104
+ const workspaces = await this.motionService.getWorkspaces();
105
+ const workspace = workspaces.find((w) => w.id === workspaceId);
106
+ if (!workspace) {
107
+ throw new errorHandling_1.WorkspaceError(`Workspace with ID "${workspaceId}" not found`, constants_1.ERROR_CODES.WORKSPACE_NOT_FOUND, { workspaceId, availableCount: workspaces.length });
108
+ }
109
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.INFO, 'Workspace found by ID', {
110
+ method: 'resolveByWorkspaceId',
111
+ workspaceId,
112
+ workspaceName: workspace.name
113
+ });
114
+ return workspace;
115
+ }
116
+ catch (error) {
117
+ if (error instanceof errorHandling_1.WorkspaceError) {
118
+ throw error;
119
+ }
120
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, 'Failed to fetch workspace by ID', {
121
+ method: 'resolveByWorkspaceId',
122
+ error: error instanceof Error ? error.message : 'Unknown error'
123
+ });
124
+ throw new errorHandling_1.WorkspaceError(`Failed to validate workspace ID "${workspaceId}"`, constants_1.ERROR_CODES.WORKSPACE_ACCESS_DENIED, { workspaceId });
125
+ }
126
+ }
127
+ /**
128
+ * Resolve workspace by name - finds matching workspace
129
+ */
130
+ async resolveByWorkspaceName(workspaceName) {
131
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Fetching workspace by name', {
132
+ method: 'resolveByWorkspaceName',
133
+ workspaceName
134
+ });
135
+ try {
136
+ const workspaces = await this.motionService.getWorkspaces();
137
+ // Exact match first
138
+ let workspace = workspaces.find((w) => w.name === workspaceName);
139
+ // Case-insensitive match as fallback
140
+ if (!workspace) {
141
+ const lowerName = workspaceName.toLowerCase();
142
+ workspace = workspaces.find((w) => w.name.toLowerCase() === lowerName);
143
+ }
144
+ if (!workspace) {
145
+ // Provide helpful error with available workspace names
146
+ const availableNames = workspaces.map((w) => w.name).join(', ');
147
+ throw new errorHandling_1.WorkspaceError(`Workspace "${workspaceName}" not found. Available workspaces: ${availableNames}`, constants_1.ERROR_CODES.WORKSPACE_NOT_FOUND, {
148
+ requestedName: workspaceName,
149
+ availableWorkspaces: workspaces.map((w) => ({
150
+ id: w.id,
151
+ name: w.name
152
+ }))
153
+ });
154
+ }
155
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.INFO, 'Workspace found by name', {
156
+ method: 'resolveByWorkspaceName',
157
+ workspaceName,
158
+ workspaceId: workspace.id
159
+ });
160
+ return workspace;
161
+ }
162
+ catch (error) {
163
+ if (error instanceof errorHandling_1.WorkspaceError) {
164
+ throw error;
165
+ }
166
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, 'Failed to fetch workspace by name', {
167
+ method: 'resolveByWorkspaceName',
168
+ error: error instanceof Error ? error.message : 'Unknown error'
169
+ });
170
+ throw new errorHandling_1.WorkspaceError(`Failed to resolve workspace name "${workspaceName}"`, constants_1.ERROR_CODES.MOTION_API_ERROR, { workspaceName });
171
+ }
172
+ }
173
+ /**
174
+ * Resolve default workspace - gets the first available workspace
175
+ */
176
+ async resolveDefaultWorkspace() {
177
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.DEBUG, 'Fetching default workspace', {
178
+ method: 'resolveDefaultWorkspace'
179
+ });
180
+ try {
181
+ const workspaces = await this.motionService.getWorkspaces();
182
+ if (!workspaces || workspaces.length === 0) {
183
+ throw new errorHandling_1.WorkspaceError('No workspaces available', constants_1.ERROR_CODES.NO_DEFAULT_WORKSPACE);
184
+ }
185
+ // Use the first workspace as default
186
+ const defaultWorkspace = workspaces[0];
187
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.INFO, 'Using default workspace', {
188
+ method: 'resolveDefaultWorkspace',
189
+ workspaceId: defaultWorkspace.id,
190
+ workspaceName: defaultWorkspace.name
191
+ });
192
+ return defaultWorkspace;
193
+ }
194
+ catch (error) {
195
+ if (error instanceof errorHandling_1.WorkspaceError) {
196
+ throw error;
197
+ }
198
+ (0, logger_1.mcpLog)(constants_1.LOG_LEVELS.ERROR, 'Failed to fetch default workspace', {
199
+ method: 'resolveDefaultWorkspace',
200
+ error: error instanceof Error ? error.message : 'Unknown error'
201
+ });
202
+ throw new errorHandling_1.WorkspaceError('Failed to fetch default workspace', constants_1.ERROR_CODES.MOTION_API_ERROR);
203
+ }
204
+ }
205
+ }
206
+ exports.WorkspaceResolver = WorkspaceResolver;
207
+ //# sourceMappingURL=workspaceResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaceResolver.js","sourceRoot":"","sources":["../../src/utils/workspaceResolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,29 +1,53 @@
1
1
  {
2
2
  "name": "motionmcp",
3
- "version": "1.0.1",
4
- "description": "",
5
- "main": "index.js",
3
+ "version": "2.0.0",
4
+ "description": "MCP server for Motion API integration - manage projects, tasks, and workspaces from LLMs",
5
+ "main": "dist/mcp-server.js",
6
6
  "bin": {
7
- "motionmcp": "./src/index.js"
7
+ "motionmcp": "./dist/mcp-server.js"
8
8
  },
9
- "scripts": {
10
- "start": "node src/index.js",
11
- "dev": "node src/index.js",
12
- "mcp": "node src/mcp-server.js",
13
- "test": "echo \"Error: no test specified\" && exit 1",
14
- "worker:dev": "wrangler dev",
15
- "worker:deploy": "wrangler deploy"
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "keywords": ["mcp", "model-context-protocol", "motion", "api", "task-management", "project-management", "llm", "ai"],
15
+ "author": "Devon Hillard devon@digitalsanctuary.com",
16
+ "license": "Apache-2.0",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/devondragon/MotionMCP.git"
20
+ },
21
+ "homepage": "https://github.com/devondragon/MotionMCP",
22
+ "bugs": {
23
+ "url": "https://github.com/devondragon/MotionMCP/issues"
16
24
  },
17
- "keywords": [],
18
- "author": "",
19
- "license": "ISC",
20
25
  "type": "commonjs",
26
+ "engines": {
27
+ "node": ">=18"
28
+ },
21
29
  "dependencies": {
22
30
  "@modelcontextprotocol/sdk": "^1.12.0",
31
+ "ajv": "^8.17.1",
23
32
  "axios": "^1.9.0",
24
- "cors": "^2.8.5",
25
33
  "dotenv": "^16.5.0",
26
- "express": "^5.1.0",
27
- "winston": "^3.17.0"
34
+ "zod": "^3.25.76"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^24.2.1",
38
+ "ts-node": "^10.9.2",
39
+ "typescript": "^5.9.2",
40
+ "vitest": "^3.2.4"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc",
44
+ "mcp": "node dist/mcp-server.js",
45
+ "mcp:dev": "ts-node src/mcp-server.ts",
46
+ "watch": "tsc --watch",
47
+ "type-check": "tsc --noEmit",
48
+ "test": "vitest run",
49
+ "worker:dev": "wrangler dev",
50
+ "worker:deploy": "wrangler deploy",
51
+ "prepublishOnly": "npm run type-check && npm run build"
28
52
  }
29
53
  }
@@ -1,15 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npm init:*)",
5
- "Bash(npm install:*)",
6
- "Bash(mkdir:*)",
7
- "Bash(git init:*)",
8
- "Bash(git add:*)",
9
- "WebFetch(domain:modelcontextprotocol.io)",
10
- "WebFetch(domain:github.com)",
11
- "Bash(chmod:*)"
12
- ],
13
- "deny": []
14
- }
15
- }
package/.env.example DELETED
@@ -1,3 +0,0 @@
1
- MOTION_API_KEY=your_motion_api_key_here
2
- PORT=3000
3
- NODE_ENV=development
package/sample.png DELETED
Binary file