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.
- package/LICENSE +202 -0
- package/README.md +251 -417
- package/dist/handlers/CommentHandler.d.ts +9 -0
- package/dist/handlers/CommentHandler.d.ts.map +1 -0
- package/dist/handlers/CommentHandler.js +66 -0
- package/dist/handlers/CommentHandler.js.map +1 -0
- package/dist/handlers/CustomFieldHandler.d.ts +14 -0
- package/dist/handlers/CustomFieldHandler.d.ts.map +1 -0
- package/dist/handlers/CustomFieldHandler.js +95 -0
- package/dist/handlers/CustomFieldHandler.js.map +1 -0
- package/dist/handlers/HandlerFactory.d.ts +15 -0
- package/dist/handlers/HandlerFactory.d.ts.map +1 -0
- package/dist/handlers/HandlerFactory.js +58 -0
- package/dist/handlers/HandlerFactory.js.map +1 -0
- package/dist/handlers/ProjectHandler.d.ts +10 -0
- package/dist/handlers/ProjectHandler.d.ts.map +1 -0
- package/dist/handlers/ProjectHandler.js +63 -0
- package/dist/handlers/ProjectHandler.js.map +1 -0
- package/dist/handlers/RecurringTaskHandler.d.ts +10 -0
- package/dist/handlers/RecurringTaskHandler.d.ts.map +1 -0
- package/dist/handlers/RecurringTaskHandler.js +68 -0
- package/dist/handlers/RecurringTaskHandler.js.map +1 -0
- package/dist/handlers/ScheduleHandler.d.ts +8 -0
- package/dist/handlers/ScheduleHandler.d.ts.map +1 -0
- package/dist/handlers/ScheduleHandler.js +43 -0
- package/dist/handlers/ScheduleHandler.js.map +1 -0
- package/dist/handlers/SearchHandler.d.ts +10 -0
- package/dist/handlers/SearchHandler.d.ts.map +1 -0
- package/dist/handlers/SearchHandler.js +116 -0
- package/dist/handlers/SearchHandler.js.map +1 -0
- package/dist/handlers/StatusHandler.d.ts +8 -0
- package/dist/handlers/StatusHandler.d.ts.map +1 -0
- package/dist/handlers/StatusHandler.js +22 -0
- package/dist/handlers/StatusHandler.js.map +1 -0
- package/dist/handlers/TaskHandler.d.ts +22 -0
- package/dist/handlers/TaskHandler.d.ts.map +1 -0
- package/dist/handlers/TaskHandler.js +266 -0
- package/dist/handlers/TaskHandler.js.map +1 -0
- package/dist/handlers/UserHandler.d.ts +9 -0
- package/dist/handlers/UserHandler.d.ts.map +1 -0
- package/dist/handlers/UserHandler.js +36 -0
- package/dist/handlers/UserHandler.js.map +1 -0
- package/dist/handlers/WorkspaceHandler.d.ts +10 -0
- package/dist/handlers/WorkspaceHandler.d.ts.map +1 -0
- package/dist/handlers/WorkspaceHandler.js +49 -0
- package/dist/handlers/WorkspaceHandler.js.map +1 -0
- package/dist/handlers/base/BaseHandler.d.ts +16 -0
- package/dist/handlers/base/BaseHandler.d.ts.map +1 -0
- package/dist/handlers/base/BaseHandler.js +31 -0
- package/dist/handlers/base/BaseHandler.js.map +1 -0
- package/dist/handlers/base/HandlerInterface.d.ts +18 -0
- package/dist/handlers/base/HandlerInterface.d.ts.map +1 -0
- package/dist/handlers/base/HandlerInterface.js +3 -0
- package/dist/handlers/base/HandlerInterface.js.map +1 -0
- package/dist/handlers/index.d.ts +14 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +31 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/mcp-server-old.d.ts +29 -0
- package/dist/mcp-server-old.d.ts.map +1 -0
- package/dist/mcp-server-old.js +1304 -0
- package/dist/mcp-server-old.js.map +1 -0
- package/dist/mcp-server.d.ts +15 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +145 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/schemas/motion.d.ts +4971 -0
- package/dist/schemas/motion.d.ts.map +1 -0
- package/dist/schemas/motion.js +328 -0
- package/dist/schemas/motion.js.map +1 -0
- package/dist/services/motionApi.d.ts +186 -0
- package/dist/services/motionApi.d.ts.map +1 -0
- package/dist/services/motionApi.js +1912 -0
- package/dist/services/motionApi.js.map +1 -0
- package/dist/tools/ToolConfigurator.d.ts +19 -0
- package/dist/tools/ToolConfigurator.d.ts.map +1 -0
- package/dist/tools/ToolConfigurator.js +89 -0
- package/dist/tools/ToolConfigurator.js.map +1 -0
- package/dist/tools/ToolDefinitions.d.ts +25 -0
- package/dist/tools/ToolDefinitions.d.ts.map +1 -0
- package/dist/tools/ToolDefinitions.js +502 -0
- package/dist/tools/ToolDefinitions.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +16 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +89 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +21 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types/mcp-tool-args.d.ts +122 -0
- package/dist/types/mcp-tool-args.d.ts.map +1 -0
- package/dist/types/mcp-tool-args.js +7 -0
- package/dist/types/mcp-tool-args.js.map +1 -0
- package/dist/types/mcp.d.ts +32 -0
- package/dist/types/mcp.d.ts.map +1 -0
- package/dist/types/mcp.js +3 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/types/motion.d.ts +304 -0
- package/dist/types/motion.d.ts.map +1 -0
- package/dist/types/motion.js +3 -0
- package/dist/types/motion.js.map +1 -0
- package/dist/utils/cache.d.ts +25 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +135 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/constants.d.ts +83 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +151 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/errorHandling.d.ts +50 -0
- package/dist/utils/errorHandling.d.ts.map +1 -0
- package/dist/utils/errorHandling.js +86 -0
- package/dist/utils/errorHandling.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +38 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +47 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paginationNew.d.ts +44 -0
- package/dist/utils/paginationNew.d.ts.map +1 -0
- package/dist/utils/paginationNew.js +149 -0
- package/dist/utils/paginationNew.js.map +1 -0
- package/dist/utils/parameterUtils.d.ts +79 -0
- package/dist/utils/parameterUtils.d.ts.map +1 -0
- package/dist/utils/parameterUtils.js +189 -0
- package/dist/utils/parameterUtils.js.map +1 -0
- package/dist/utils/responseFormatters.d.ts +92 -0
- package/dist/utils/responseFormatters.d.ts.map +1 -0
- package/dist/utils/responseFormatters.js +331 -0
- package/dist/utils/responseFormatters.js.map +1 -0
- package/dist/utils/responseWrapper.d.ts +38 -0
- package/dist/utils/responseWrapper.d.ts.map +1 -0
- package/dist/utils/responseWrapper.js +201 -0
- package/dist/utils/responseWrapper.js.map +1 -0
- package/dist/utils/sanitize.d.ts +51 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +137 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/dist/utils/validator.d.ts +37 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +74 -0
- package/dist/utils/validator.js.map +1 -0
- package/dist/utils/workspaceResolver.d.ts +40 -0
- package/dist/utils/workspaceResolver.d.ts.map +1 -0
- package/dist/utils/workspaceResolver.js +207 -0
- package/dist/utils/workspaceResolver.js.map +1 -0
- package/package.json +41 -17
- package/.claude/settings.local.json +0 -15
- package/.env.example +0 -3
- package/sample.png +0 -0
- package/src/index.js +0 -49
- package/src/mcp-server.js +0 -1137
- package/src/routes/motion.js +0 -152
- package/src/services/motionApi.js +0 -1177
- 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, '<')
|
|
39
|
+
.replace(/>/g, '>')
|
|
40
|
+
// Escape quotes to prevent attribute injection
|
|
41
|
+
.replace(/"/g, '"')
|
|
42
|
+
.replace(/'/g, ''')
|
|
43
|
+
// Escape ampersands (but do it last to avoid double-escaping)
|
|
44
|
+
.replace(/&(?!(lt|gt|quot|#39|amp);)/g, '&');
|
|
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":";AAAA;;;;;GAKG;;AAWH,kDAiCC;AASD,0DAQC;AAQD,wDA4BC;AASD,kDAgBC;AAUD,oCAgBC;AAlJD,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,uCAAuC;SACtC,OAAO,CAAC,qDAAqD,EAAE,EAAE,CAAC;QACnE,wCAAwC;SACvC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;QACxB,kCAAkC;SACjC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,+CAA+C;SAC9C,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;QACvB,8DAA8D;SAC7D,OAAO,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAC;IAEnD,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"}
|
|
@@ -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":";AAAA;;;;;;GAMG;;;AAEH,2CAAiF;AAEjF,mDAAiD;AAEjD,qCAAkC;AAalC,MAAa,iBAAiB;IAG5B,YAAY,gBAAkC;QAC5C,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,gBAAgB,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAsB,EAAE,EACxB,UAAoC,EAAE;QAEtC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;QAC5C,MAAM,EACJ,iBAAiB,GAAG,oBAAQ,CAAC,6BAA6B,EAC1D,cAAc,GAAG,oBAAQ,CAAC,yBAAyB;QACnD,2FAA2F;UAC5F,GAAG,OAAO,CAAC;QAEZ,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,+BAA+B,EAAE;YACxD,MAAM,EAAE,kBAAkB;YAC1B,WAAW;YACX,aAAa;YACb,iBAAiB;YACjB,cAAc;SACf,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,IAAI,iBAAiB,GAA2B,IAAI,CAAC;YAErD,uCAAuC;YACvC,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,2BAA2B,EAAE;oBACpD,MAAM,EAAE,kBAAkB;oBAC1B,WAAW;iBACZ,CAAC,CAAC;gBAEH,IAAI,cAAc,EAAE,CAAC;oBACnB,iBAAiB,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;gBACnE,CAAC;qBAAM,CAAC;oBACN,gDAAgD;oBAChD,iBAAiB,GAAG;wBAClB,EAAE,EAAE,WAAW;wBACf,IAAI,EAAE,mBAAmB;wBACzB,MAAM,EAAE,SAAS;wBACjB,IAAI,EAAE,2BAAe,CAAC,OAAO;wBAC7B,MAAM,EAAE,EAAE;wBACV,QAAQ,EAAE,EAAE;qBACb,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,kCAAkC;iBAC7B,IAAI,aAAa,EAAE,CAAC;gBACvB,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,6BAA6B,EAAE;oBACtD,MAAM,EAAE,kBAAkB;oBAC1B,aAAa;iBACd,CAAC,CAAC;gBACH,iBAAiB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC;YACvE,CAAC;YAED,wCAAwC;iBACnC,IAAI,iBAAiB,EAAE,CAAC;gBAC3B,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,mCAAmC,EAAE;oBAC5D,MAAM,EAAE,kBAAkB;iBAC3B,CAAC,CAAC;gBACH,iBAAiB,GAAG,MAAM,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC3D,CAAC;YAED,yCAAyC;YACzC,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,MAAM,IAAI,8BAAc,CACtB,2DAA2D,EAC3D,uBAAW,CAAC,oBAAoB,EAChC,EAAE,iBAAiB,EAAE,CACtB,CAAC;YACJ,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,iCAAiC,EAAE;gBACzD,MAAM,EAAE,kBAAkB;gBAC1B,UAAU,EAAE,iBAAiB,CAAC,EAAE;gBAChC,YAAY,EAAE,iBAAiB,CAAC,IAAI;aACrC,CAAC,CAAC;YAEH,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,6BAA6B,EAAE;gBACtD,MAAM,EAAE,kBAAkB;gBAC1B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;gBAC/D,WAAW;gBACX,aAAa;aACd,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAAC,WAAmB;QACpD,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,0BAA0B,EAAE;YACnD,MAAM,EAAE,sBAAsB;YAC9B,WAAW;SACZ,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;YAEhF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,8BAAc,CACtB,sBAAsB,WAAW,aAAa,EAC9C,uBAAW,CAAC,mBAAmB,EAC/B,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,CAAC,MAAM,EAAE,CACnD,CAAC;YACJ,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,uBAAuB,EAAE;gBAC/C,MAAM,EAAE,sBAAsB;gBAC9B,WAAW;gBACX,aAAa,EAAE,SAAS,CAAC,IAAI;aAC9B,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,8BAAc,EAAE,CAAC;gBACpC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,iCAAiC,EAAE;gBAC1D,MAAM,EAAE,sBAAsB;gBAC9B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;YAEH,MAAM,IAAI,8BAAc,CACtB,oCAAoC,WAAW,GAAG,EAClD,uBAAW,CAAC,uBAAuB,EACnC,EAAE,WAAW,EAAE,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAAC,aAAqB;QACxD,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,4BAA4B,EAAE;YACrD,MAAM,EAAE,wBAAwB;YAChC,aAAa;SACd,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;YAE5D,oBAAoB;YACpB,IAAI,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAkB,EAAE,EAAE,CACrD,CAAC,CAAC,IAAI,KAAK,aAAa,CACzB,CAAC;YAEF,qCAAqC;YACrC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC;gBAC9C,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAkB,EAAE,EAAE,CACjD,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,SAAS,CACnC,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,uDAAuD;gBACvD,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjF,MAAM,IAAI,8BAAc,CACtB,cAAc,aAAa,sCAAsC,cAAc,EAAE,EACjF,uBAAW,CAAC,mBAAmB,EAC/B;oBACE,aAAa,EAAE,aAAa;oBAC5B,mBAAmB,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC;wBAC3D,EAAE,EAAE,CAAC,CAAC,EAAE;wBACR,IAAI,EAAE,CAAC,CAAC,IAAI;qBACb,CAAC,CAAC;iBACJ,CACF,CAAC;YACJ,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,yBAAyB,EAAE;gBACjD,MAAM,EAAE,wBAAwB;gBAChC,aAAa;gBACb,WAAW,EAAE,SAAS,CAAC,EAAE;aAC1B,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,8BAAc,EAAE,CAAC;gBACpC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,mCAAmC,EAAE;gBAC5D,MAAM,EAAE,wBAAwB;gBAChC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;YAEH,MAAM,IAAI,8BAAc,CACtB,qCAAqC,aAAa,GAAG,EACrD,uBAAW,CAAC,gBAAgB,EAC5B,EAAE,aAAa,EAAE,CAClB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,uBAAuB;QACnC,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,4BAA4B,EAAE;YACrD,MAAM,EAAE,yBAAyB;SAClC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;YAE5D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,8BAAc,CACtB,yBAAyB,EACzB,uBAAW,CAAC,oBAAoB,CACjC,CAAC;YACJ,CAAC;YAED,qCAAqC;YACrC,MAAM,gBAAgB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAEvC,IAAA,eAAM,EAAC,sBAAU,CAAC,IAAI,EAAE,yBAAyB,EAAE;gBACjD,MAAM,EAAE,yBAAyB;gBACjC,WAAW,EAAE,gBAAgB,CAAC,EAAE;gBAChC,aAAa,EAAE,gBAAgB,CAAC,IAAI;aACrC,CAAC,CAAC;YAEH,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,8BAAc,EAAE,CAAC;gBACpC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,IAAA,eAAM,EAAC,sBAAU,CAAC,KAAK,EAAE,mCAAmC,EAAE;gBAC5D,MAAM,EAAE,yBAAyB;gBACjC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;YAEH,MAAM,IAAI,8BAAc,CACtB,mCAAmC,EACnC,uBAAW,CAAC,gBAAgB,CAC7B,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAjQD,8CAiQC"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "motionmcp",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "
|
|
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": "./
|
|
7
|
+
"motionmcp": "./dist/mcp-server.js"
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
"
|
|
27
|
-
|
|
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
package/sample.png
DELETED
|
Binary file
|