@geanatz/cortex-mcp 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +281 -0
  3. package/dist/errors/errors.d.ts +109 -0
  4. package/dist/errors/errors.js +199 -0
  5. package/dist/errors/index.d.ts +4 -0
  6. package/dist/errors/index.js +4 -0
  7. package/dist/features/task-management/models/artifact.d.ts +169 -0
  8. package/dist/features/task-management/models/artifact.js +155 -0
  9. package/dist/features/task-management/models/config.d.ts +54 -0
  10. package/dist/features/task-management/models/config.js +54 -0
  11. package/dist/features/task-management/models/index.d.ts +6 -0
  12. package/dist/features/task-management/models/index.js +6 -0
  13. package/dist/features/task-management/models/task.d.ts +173 -0
  14. package/dist/features/task-management/models/task.js +84 -0
  15. package/dist/features/task-management/storage/file-storage.d.ts +130 -0
  16. package/dist/features/task-management/storage/file-storage.js +575 -0
  17. package/dist/features/task-management/storage/index.d.ts +5 -0
  18. package/dist/features/task-management/storage/index.js +5 -0
  19. package/dist/features/task-management/storage/storage.d.ts +159 -0
  20. package/dist/features/task-management/storage/storage.js +37 -0
  21. package/dist/features/task-management/tools/artifacts/index.d.ts +6 -0
  22. package/dist/features/task-management/tools/artifacts/index.js +174 -0
  23. package/dist/features/task-management/tools/base/handlers.d.ts +7 -0
  24. package/dist/features/task-management/tools/base/handlers.js +15 -0
  25. package/dist/features/task-management/tools/base/index.d.ts +3 -0
  26. package/dist/features/task-management/tools/base/index.js +3 -0
  27. package/dist/features/task-management/tools/base/schemas.d.ts +3 -0
  28. package/dist/features/task-management/tools/base/schemas.js +6 -0
  29. package/dist/features/task-management/tools/base/types.d.ts +13 -0
  30. package/dist/features/task-management/tools/base/types.js +1 -0
  31. package/dist/features/task-management/tools/tasks/index.d.ts +10 -0
  32. package/dist/features/task-management/tools/tasks/index.js +500 -0
  33. package/dist/index.d.ts +2 -0
  34. package/dist/index.js +57 -0
  35. package/dist/server.d.ts +11 -0
  36. package/dist/server.js +61 -0
  37. package/dist/types/common.d.ts +10 -0
  38. package/dist/types/common.js +1 -0
  39. package/dist/types/index.d.ts +5 -0
  40. package/dist/types/index.js +5 -0
  41. package/dist/utils/cache.d.ts +104 -0
  42. package/dist/utils/cache.js +196 -0
  43. package/dist/utils/file-utils.d.ts +101 -0
  44. package/dist/utils/file-utils.js +270 -0
  45. package/dist/utils/index.d.ts +12 -0
  46. package/dist/utils/index.js +12 -0
  47. package/dist/utils/logger.d.ts +77 -0
  48. package/dist/utils/logger.js +173 -0
  49. package/dist/utils/response-builder.d.ts +4 -0
  50. package/dist/utils/response-builder.js +19 -0
  51. package/dist/utils/storage-config.d.ts +29 -0
  52. package/dist/utils/storage-config.js +51 -0
  53. package/dist/utils/string-utils.d.ts +2 -0
  54. package/dist/utils/string-utils.js +16 -0
  55. package/dist/utils/validation.d.ts +9 -0
  56. package/dist/utils/validation.js +9 -0
  57. package/dist/utils/version.d.ts +9 -0
  58. package/dist/utils/version.js +41 -0
  59. package/package.json +60 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Logger utility with levels and formatting
3
+ * Provides consistent logging throughout the application
4
+ */
5
+ /**
6
+ * Log levels
7
+ */
8
+ export declare enum LogLevel {
9
+ DEBUG = 0,
10
+ INFO = 1,
11
+ WARN = 2,
12
+ ERROR = 3,
13
+ SILENT = 4
14
+ }
15
+ /**
16
+ * Logger configuration
17
+ */
18
+ export interface LoggerConfig {
19
+ level: LogLevel;
20
+ prefix?: string;
21
+ timestamps?: boolean;
22
+ colors?: boolean;
23
+ }
24
+ /**
25
+ * Simple structured logger
26
+ */
27
+ export declare class Logger {
28
+ private level;
29
+ private prefix;
30
+ private timestamps;
31
+ private colors;
32
+ constructor(config?: Partial<LoggerConfig>);
33
+ /**
34
+ * Set log level
35
+ */
36
+ setLevel(level: LogLevel): void;
37
+ /**
38
+ * Format a log message
39
+ */
40
+ private format;
41
+ /**
42
+ * Log at DEBUG level
43
+ */
44
+ debug(message: string, data?: Record<string, unknown>): void;
45
+ /**
46
+ * Log at INFO level
47
+ */
48
+ info(message: string, data?: Record<string, unknown>): void;
49
+ /**
50
+ * Log at WARN level
51
+ */
52
+ warn(message: string, data?: Record<string, unknown>): void;
53
+ /**
54
+ * Log at ERROR level
55
+ */
56
+ error(message: string, error?: Error | unknown, data?: Record<string, unknown>): void;
57
+ /**
58
+ * Create a child logger with a prefix
59
+ */
60
+ child(prefix: string): Logger;
61
+ /**
62
+ * Log operation timing
63
+ */
64
+ time<T>(label: string, fn: () => T): T;
65
+ /**
66
+ * Log async operation timing
67
+ */
68
+ timeAsync<T>(label: string, fn: () => Promise<T>): Promise<T>;
69
+ }
70
+ /**
71
+ * Default application logger
72
+ */
73
+ export declare const logger: Logger;
74
+ /**
75
+ * Create a logger for a specific module
76
+ */
77
+ export declare function createLogger(module: string): Logger;
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Logger utility with levels and formatting
3
+ * Provides consistent logging throughout the application
4
+ */
5
+ /**
6
+ * Log levels
7
+ */
8
+ export var LogLevel;
9
+ (function (LogLevel) {
10
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
11
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
12
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
13
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
14
+ LogLevel[LogLevel["SILENT"] = 4] = "SILENT";
15
+ })(LogLevel || (LogLevel = {}));
16
+ /**
17
+ * ANSI color codes for terminal output
18
+ */
19
+ const Colors = {
20
+ reset: '\x1b[0m',
21
+ dim: '\x1b[2m',
22
+ red: '\x1b[31m',
23
+ green: '\x1b[32m',
24
+ yellow: '\x1b[33m',
25
+ blue: '\x1b[34m',
26
+ magenta: '\x1b[35m',
27
+ cyan: '\x1b[36m',
28
+ };
29
+ /**
30
+ * Log level configurations
31
+ */
32
+ const LevelConfig = {
33
+ [LogLevel.DEBUG]: { label: 'DEBUG', color: Colors.dim },
34
+ [LogLevel.INFO]: { label: 'INFO', color: Colors.blue },
35
+ [LogLevel.WARN]: { label: 'WARN', color: Colors.yellow },
36
+ [LogLevel.ERROR]: { label: 'ERROR', color: Colors.red },
37
+ };
38
+ /**
39
+ * Simple structured logger
40
+ */
41
+ export class Logger {
42
+ level;
43
+ prefix;
44
+ timestamps;
45
+ colors;
46
+ constructor(config = {}) {
47
+ this.level = config.level ?? LogLevel.INFO;
48
+ this.prefix = config.prefix ?? '';
49
+ this.timestamps = config.timestamps ?? true;
50
+ this.colors = config.colors ?? true;
51
+ }
52
+ /**
53
+ * Set log level
54
+ */
55
+ setLevel(level) {
56
+ this.level = level;
57
+ }
58
+ /**
59
+ * Format a log message
60
+ */
61
+ format(level, message, data) {
62
+ const parts = [];
63
+ const config = LevelConfig[level];
64
+ if (this.timestamps) {
65
+ const time = new Date().toISOString().slice(11, 19);
66
+ parts.push(this.colors ? `${Colors.dim}[${time}]${Colors.reset}` : `[${time}]`);
67
+ }
68
+ if (config) {
69
+ const label = this.colors
70
+ ? `${config.color}[${config.label}]${Colors.reset}`
71
+ : `[${config.label}]`;
72
+ parts.push(label);
73
+ }
74
+ if (this.prefix) {
75
+ parts.push(this.colors ? `${Colors.cyan}${this.prefix}${Colors.reset}` : this.prefix);
76
+ }
77
+ parts.push(message);
78
+ if (data && Object.keys(data).length > 0) {
79
+ parts.push(JSON.stringify(data));
80
+ }
81
+ return parts.join(' ');
82
+ }
83
+ /**
84
+ * Log at DEBUG level
85
+ */
86
+ debug(message, data) {
87
+ if (this.level <= LogLevel.DEBUG) {
88
+ console.error(this.format(LogLevel.DEBUG, message, data));
89
+ }
90
+ }
91
+ /**
92
+ * Log at INFO level
93
+ */
94
+ info(message, data) {
95
+ if (this.level <= LogLevel.INFO) {
96
+ console.error(this.format(LogLevel.INFO, message, data));
97
+ }
98
+ }
99
+ /**
100
+ * Log at WARN level
101
+ */
102
+ warn(message, data) {
103
+ if (this.level <= LogLevel.WARN) {
104
+ console.error(this.format(LogLevel.WARN, message, data));
105
+ }
106
+ }
107
+ /**
108
+ * Log at ERROR level
109
+ */
110
+ error(message, error, data) {
111
+ if (this.level <= LogLevel.ERROR) {
112
+ const errorData = error instanceof Error
113
+ ? { error: error.message, stack: error.stack, ...data }
114
+ : { error, ...data };
115
+ console.error(this.format(LogLevel.ERROR, message, errorData));
116
+ }
117
+ }
118
+ /**
119
+ * Create a child logger with a prefix
120
+ */
121
+ child(prefix) {
122
+ return new Logger({
123
+ level: this.level,
124
+ prefix: this.prefix ? `${this.prefix}:${prefix}` : prefix,
125
+ timestamps: this.timestamps,
126
+ colors: this.colors,
127
+ });
128
+ }
129
+ /**
130
+ * Log operation timing
131
+ */
132
+ time(label, fn) {
133
+ const start = performance.now();
134
+ try {
135
+ const result = fn();
136
+ const duration = performance.now() - start;
137
+ this.debug(`${label} completed`, { duration: `${duration.toFixed(2)}ms` });
138
+ return result;
139
+ }
140
+ catch (error) {
141
+ const duration = performance.now() - start;
142
+ this.error(`${label} failed`, error, { duration: `${duration.toFixed(2)}ms` });
143
+ throw error;
144
+ }
145
+ }
146
+ /**
147
+ * Log async operation timing
148
+ */
149
+ async timeAsync(label, fn) {
150
+ const start = performance.now();
151
+ try {
152
+ const result = await fn();
153
+ const duration = performance.now() - start;
154
+ this.debug(`${label} completed`, { duration: `${duration.toFixed(2)}ms` });
155
+ return result;
156
+ }
157
+ catch (error) {
158
+ const duration = performance.now() - start;
159
+ this.error(`${label} failed`, error, { duration: `${duration.toFixed(2)}ms` });
160
+ throw error;
161
+ }
162
+ }
163
+ }
164
+ /**
165
+ * Default application logger
166
+ */
167
+ export const logger = new Logger({ prefix: 'cortex' });
168
+ /**
169
+ * Create a logger for a specific module
170
+ */
171
+ export function createLogger(module) {
172
+ return logger.child(module);
173
+ }
@@ -0,0 +1,4 @@
1
+ import { McpToolResponse } from '../types/common.js';
2
+ export declare function successResponse(text: string): McpToolResponse;
3
+ export declare function errorResponse(text: string): McpToolResponse;
4
+ export declare function createErrorResponse(error: unknown): McpToolResponse;
@@ -0,0 +1,19 @@
1
+ import { getErrorMessage } from '../errors/errors.js';
2
+ function textContent(text) {
3
+ return { type: 'text', text };
4
+ }
5
+ export function successResponse(text) {
6
+ return {
7
+ content: [textContent(text)],
8
+ };
9
+ }
10
+ export function errorResponse(text) {
11
+ return {
12
+ content: [textContent(`Error: ${text}`)],
13
+ isError: true,
14
+ };
15
+ }
16
+ export function createErrorResponse(error) {
17
+ const message = getErrorMessage(error);
18
+ return errorResponse(message);
19
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Configuration for storage directory resolution
3
+ */
4
+ export interface StorageConfig {
5
+ /** Whether to use global user directory instead of project-specific directories */
6
+ useGlobalDirectory: boolean;
7
+ }
8
+ /**
9
+ * Parse command-line arguments to determine storage configuration
10
+ */
11
+ export declare function parseCommandLineArgs(): StorageConfig;
12
+ /**
13
+ * Get the global storage directory path
14
+ * - Windows: C:\Users\{username}\.cortex\
15
+ * - macOS/Linux: ~/.cortex/
16
+ */
17
+ export declare function getGlobalStorageDirectory(): string;
18
+ /**
19
+ * Resolve the actual working directory based on configuration
20
+ *
21
+ * @param providedPath - The working directory path provided by the user
22
+ * @param config - Storage configuration including global directory flag
23
+ * @returns The actual working directory to use for storage
24
+ */
25
+ export declare function resolveWorkingDirectory(providedPath: string, config: StorageConfig): string;
26
+ /**
27
+ * Get parameter description for workingDirectory
28
+ */
29
+ export declare function getWorkingDirectoryDescription(config: StorageConfig): string;
@@ -0,0 +1,51 @@
1
+ import { homedir } from 'os';
2
+ import { join } from 'path';
3
+ /**
4
+ * Parse command-line arguments to determine storage configuration
5
+ */
6
+ export function parseCommandLineArgs() {
7
+ try {
8
+ const args = process.argv.slice(2);
9
+ const useGlobalDirectory = args.includes('--claude');
10
+ return {
11
+ useGlobalDirectory
12
+ };
13
+ }
14
+ catch (error) {
15
+ // Default to project-specific mode if there's any issue parsing args
16
+ return {
17
+ useGlobalDirectory: false
18
+ };
19
+ }
20
+ }
21
+ /**
22
+ * Get the global storage directory path
23
+ * - Windows: C:\Users\{username}\.cortex\
24
+ * - macOS/Linux: ~/.cortex/
25
+ */
26
+ export function getGlobalStorageDirectory() {
27
+ const userHome = homedir();
28
+ return join(userHome, '.cortex');
29
+ }
30
+ /**
31
+ * Resolve the actual working directory based on configuration
32
+ *
33
+ * @param providedPath - The working directory path provided by the user
34
+ * @param config - Storage configuration including global directory flag
35
+ * @returns The actual working directory to use for storage
36
+ */
37
+ export function resolveWorkingDirectory(providedPath, config) {
38
+ if (config.useGlobalDirectory) {
39
+ return getGlobalStorageDirectory();
40
+ }
41
+ return providedPath;
42
+ }
43
+ /**
44
+ * Get parameter description for workingDirectory
45
+ */
46
+ export function getWorkingDirectoryDescription(config) {
47
+ const baseDescription = 'The full absolute path to the working directory where data is stored. MUST be an absolute path, never relative.';
48
+ return config.useGlobalDirectory
49
+ ? baseDescription + ' NOTE: Server started with --claude flag, so this parameter is ignored.'
50
+ : baseDescription;
51
+ }
@@ -0,0 +1,2 @@
1
+ export declare function sanitizeFileName(input: string, maxLength?: number): string;
2
+ export declare function padNumber(num: number, length: number): string;
@@ -0,0 +1,16 @@
1
+ export function sanitizeFileName(input, maxLength = 50) {
2
+ let sanitized = input
3
+ .toLowerCase()
4
+ .replace(/[/\\:*?"<>|]/g, '-')
5
+ .replace(/\s+/g, '-')
6
+ .replace(/-{2,}/g, '-')
7
+ .replace(/^-+|-+$/g, '');
8
+ if (sanitized.length > maxLength) {
9
+ sanitized = sanitized.substring(0, maxLength);
10
+ sanitized = sanitized.replace(/-+$/, '');
11
+ }
12
+ return sanitized || 'file';
13
+ }
14
+ export function padNumber(num, length) {
15
+ return String(num).padStart(length, '0');
16
+ }
@@ -0,0 +1,9 @@
1
+ export declare const ValidationLimits: {
2
+ readonly TASK_DETAILS_MAX_LENGTH: 2000;
3
+ readonly TASK_DETAILS_MIN_LENGTH: 1;
4
+ readonly TAG_MAX_LENGTH: 50;
5
+ readonly TAG_MIN_LENGTH: 1;
6
+ readonly MAX_TAGS: 20;
7
+ readonly MAX_DEPENDENCIES: 50;
8
+ readonly TASK_ID_MAX_LENGTH: 100;
9
+ };
@@ -0,0 +1,9 @@
1
+ export const ValidationLimits = {
2
+ TASK_DETAILS_MAX_LENGTH: 2000,
3
+ TASK_DETAILS_MIN_LENGTH: 1,
4
+ TAG_MAX_LENGTH: 50,
5
+ TAG_MIN_LENGTH: 1,
6
+ MAX_TAGS: 20,
7
+ MAX_DEPENDENCIES: 50,
8
+ TASK_ID_MAX_LENGTH: 100,
9
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Read the version from package.json
3
+ * Works in both development (src/) and compiled (dist/) versions
4
+ */
5
+ export declare function getVersion(): string;
6
+ /**
7
+ * Get formatted version string for display
8
+ */
9
+ export declare function getVersionString(): string;
@@ -0,0 +1,41 @@
1
+ import { readFileSync } from 'fs';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+ /**
5
+ * Read the version from package.json
6
+ * Works in both development (src/) and compiled (dist/) versions
7
+ */
8
+ export function getVersion() {
9
+ try {
10
+ const currentDir = dirname(fileURLToPath(import.meta.url));
11
+ // Try multiple paths to find package.json
12
+ const pathsToTry = [
13
+ join(currentDir, '..', '..', 'package.json'), // dist/utils/version.js -> ../../package.json
14
+ join(currentDir, '..', '..', '..', 'package.json'), // src/utils/version.ts -> ../../../package.json
15
+ join(process.cwd(), 'package.json'), // fallback to cwd
16
+ ];
17
+ for (const packageJsonPath of pathsToTry) {
18
+ try {
19
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
20
+ if (packageJson.version) {
21
+ return packageJson.version;
22
+ }
23
+ }
24
+ catch {
25
+ // Try next path
26
+ continue;
27
+ }
28
+ }
29
+ return '5.0.0'; // Fallback version — keep in sync with package.json
30
+ }
31
+ catch {
32
+ return '5.0.0'; // Fallback version — keep in sync with package.json
33
+ }
34
+ }
35
+ /**
36
+ * Get formatted version string for display
37
+ */
38
+ export function getVersionString() {
39
+ const version = getVersion();
40
+ return `v${version}`;
41
+ }
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@geanatz/cortex-mcp",
3
+ "version": "5.0.1",
4
+ "description": "An MCP server for task-based orchestration workflows with phase artifacts for agentic development",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "cortex-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "task-management",
20
+ "orchestration",
21
+ "agentic-workflow",
22
+ "file-storage",
23
+ "productivity",
24
+ "ai-tools",
25
+ "opencode"
26
+ ],
27
+ "author": "Geanatz",
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.12.0",
31
+ "zod": "^3.23.8"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20.0.0",
35
+ "typescript": "^5.0.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/geanatz/cortex-mcp.git"
43
+ },
44
+ "files": [
45
+ "dist/**/*",
46
+ "!dist/.tsbuildinfo",
47
+ "README.md",
48
+ "LICENSE"
49
+ ],
50
+ "types": "dist/index.d.ts",
51
+ "exports": {
52
+ ".": {
53
+ "import": "./dist/index.js",
54
+ "types": "./dist/index.d.ts"
55
+ }
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ }
60
+ }