cucumberstudio-mcp 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +36 -0
- package/.github/workflows/pr-checks.yml +41 -0
- package/.github/workflows/release.yml +194 -0
- package/.prettierignore +26 -0
- package/.prettierrc +14 -0
- package/CLAUDE.md +140 -0
- package/Dockerfile +50 -0
- package/Dockerfile.dev +31 -0
- package/LICENSE +21 -0
- package/README.md +395 -0
- package/build/api/client.d.ts +49 -0
- package/build/api/client.d.ts.map +1 -0
- package/build/api/client.js +204 -0
- package/build/api/client.js.map +1 -0
- package/build/api/types.d.ts +113 -0
- package/build/api/types.d.ts.map +1 -0
- package/build/api/types.js +2 -0
- package/build/api/types.js.map +1 -0
- package/build/config/settings.d.ts +123 -0
- package/build/config/settings.d.ts.map +1 -0
- package/build/config/settings.js +97 -0
- package/build/config/settings.js.map +1 -0
- package/build/constants.d.ts +16 -0
- package/build/constants.d.ts.map +1 -0
- package/build/constants.js +24 -0
- package/build/constants.js.map +1 -0
- package/build/generated/version.d.ts +3 -0
- package/build/generated/version.d.ts.map +1 -0
- package/build/generated/version.js +5 -0
- package/build/generated/version.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +81 -0
- package/build/index.js.map +1 -0
- package/build/mcp-server.d.ts +6 -0
- package/build/mcp-server.d.ts.map +1 -0
- package/build/mcp-server.js +263 -0
- package/build/mcp-server.js.map +1 -0
- package/build/tools/action-words.d.ts +18 -0
- package/build/tools/action-words.d.ts.map +1 -0
- package/build/tools/action-words.js +191 -0
- package/build/tools/action-words.js.map +1 -0
- package/build/tools/projects.d.ts +19 -0
- package/build/tools/projects.d.ts.map +1 -0
- package/build/tools/projects.js +123 -0
- package/build/tools/projects.js.map +1 -0
- package/build/tools/scenarios.d.ts +18 -0
- package/build/tools/scenarios.d.ts.map +1 -0
- package/build/tools/scenarios.js +194 -0
- package/build/tools/scenarios.js.map +1 -0
- package/build/tools/test-runs.d.ts +21 -0
- package/build/tools/test-runs.d.ts.map +1 -0
- package/build/tools/test-runs.js +324 -0
- package/build/tools/test-runs.js.map +1 -0
- package/build/transports/http.d.ts +38 -0
- package/build/transports/http.d.ts.map +1 -0
- package/build/transports/http.js +381 -0
- package/build/transports/http.js.map +1 -0
- package/build/transports/index.d.ts +22 -0
- package/build/transports/index.d.ts.map +1 -0
- package/build/transports/index.js +10 -0
- package/build/transports/index.js.map +1 -0
- package/build/transports/stdio.d.ts +13 -0
- package/build/transports/stdio.d.ts.map +1 -0
- package/build/transports/stdio.js +24 -0
- package/build/transports/stdio.js.map +1 -0
- package/build/utils/errors.d.ts +10 -0
- package/build/utils/errors.d.ts.map +1 -0
- package/build/utils/errors.js +35 -0
- package/build/utils/errors.js.map +1 -0
- package/build/utils/logger-constants.d.ts +15 -0
- package/build/utils/logger-constants.d.ts.map +1 -0
- package/build/utils/logger-constants.js +16 -0
- package/build/utils/logger-constants.js.map +1 -0
- package/build/utils/logger.d.ts +55 -0
- package/build/utils/logger.d.ts.map +1 -0
- package/build/utils/logger.js +113 -0
- package/build/utils/logger.js.map +1 -0
- package/build/utils/validation.d.ts +89 -0
- package/build/utils/validation.d.ts.map +1 -0
- package/build/utils/validation.js +78 -0
- package/build/utils/validation.js.map +1 -0
- package/docker-compose.yml +20 -0
- package/eslint.config.js +97 -0
- package/package.json +92 -0
- package/scripts/generate-version.js +31 -0
- package/src/api/client.ts +286 -0
- package/src/api/types.ts +137 -0
- package/src/config/settings.ts +113 -0
- package/src/constants.ts +29 -0
- package/src/index.ts +99 -0
- package/src/mcp-server.ts +342 -0
- package/src/tools/action-words.ts +240 -0
- package/src/tools/projects.ts +144 -0
- package/src/tools/scenarios.ts +231 -0
- package/src/tools/test-runs.ts +400 -0
- package/src/transports/http.ts +467 -0
- package/src/transports/index.ts +26 -0
- package/src/transports/stdio.ts +28 -0
- package/src/utils/errors.ts +45 -0
- package/src/utils/logger-constants.ts +18 -0
- package/src/utils/logger.ts +150 -0
- package/src/utils/validation.ts +94 -0
- package/test/api/client-with-msw.test.ts +122 -0
- package/test/api/client.test.ts +326 -0
- package/test/api/types.test.ts +88 -0
- package/test/config/settings.test.ts +204 -0
- package/test/mocks/data/action-words.ts +40 -0
- package/test/mocks/data/index.ts +13 -0
- package/test/mocks/data/projects.ts +38 -0
- package/test/mocks/data/scenarios.ts +53 -0
- package/test/mocks/data/test-runs.ts +101 -0
- package/test/mocks/handlers/action-words.ts +52 -0
- package/test/mocks/handlers/index.ts +10 -0
- package/test/mocks/handlers/projects.ts +45 -0
- package/test/mocks/handlers/scenarios.ts +72 -0
- package/test/mocks/handlers/test-runs.ts +106 -0
- package/test/mocks/server.ts +26 -0
- package/test/setup/vitest.setup.ts +18 -0
- package/test/tools/coverage-boost.test.ts +252 -0
- package/test/tools/projects.test.ts +290 -0
- package/test/tools/tools-basic.test.ts +146 -0
- package/test/transports/http-basic.test.ts +87 -0
- package/test/transports/http-simple.test.ts +33 -0
- package/test/transports/stdio.test.ts +73 -0
- package/test/utils/errors.test.ts +117 -0
- package/test/utils/validation.test.ts +261 -0
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +27 -0
- package/vitest.config.ts +43 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { DEFAULT_LOG_LEVEL } from '../constants.js';
|
|
2
|
+
import { LOG_COLORS as ANSI_COLORS } from './logger-constants.js';
|
|
3
|
+
const LOG_LEVELS = {
|
|
4
|
+
error: 0,
|
|
5
|
+
warn: 1,
|
|
6
|
+
info: 2,
|
|
7
|
+
debug: 3,
|
|
8
|
+
trace: 4,
|
|
9
|
+
};
|
|
10
|
+
const LOG_COLORS = {
|
|
11
|
+
error: ANSI_COLORS.ERROR,
|
|
12
|
+
warn: ANSI_COLORS.WARN,
|
|
13
|
+
info: ANSI_COLORS.INFO,
|
|
14
|
+
debug: ANSI_COLORS.DEBUG,
|
|
15
|
+
trace: ANSI_COLORS.DEBUG, // Using same as debug
|
|
16
|
+
};
|
|
17
|
+
const RESET_COLOR = ANSI_COLORS.RESET;
|
|
18
|
+
/**
|
|
19
|
+
* No-operation logger for testing - discards all log messages
|
|
20
|
+
*/
|
|
21
|
+
export class NoOpLogger {
|
|
22
|
+
error() { }
|
|
23
|
+
warn() { }
|
|
24
|
+
info() { }
|
|
25
|
+
debug() { }
|
|
26
|
+
trace() { }
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Logger implementation that outputs to stderr
|
|
30
|
+
* Safe for use with STDIO MCP transport as it won't interfere with stdout protocol
|
|
31
|
+
*/
|
|
32
|
+
export class StderrLogger {
|
|
33
|
+
config;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = {
|
|
36
|
+
enableTimestamp: true,
|
|
37
|
+
enableColors: true,
|
|
38
|
+
...config,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
shouldLog(level) {
|
|
42
|
+
return LOG_LEVELS[level] <= LOG_LEVELS[this.config.level];
|
|
43
|
+
}
|
|
44
|
+
formatMessage(level, message, meta) {
|
|
45
|
+
let formatted = '';
|
|
46
|
+
// Add timestamp if enabled
|
|
47
|
+
if (this.config.enableTimestamp) {
|
|
48
|
+
formatted += `[${new Date().toISOString()}] `;
|
|
49
|
+
}
|
|
50
|
+
// Add level with color if enabled
|
|
51
|
+
const levelUpper = level.toUpperCase().padEnd(5);
|
|
52
|
+
if (this.config.enableColors) {
|
|
53
|
+
formatted += `${LOG_COLORS[level]}${levelUpper}${RESET_COLOR} `;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
formatted += `${levelUpper} `;
|
|
57
|
+
}
|
|
58
|
+
// Add prefix if configured
|
|
59
|
+
if (this.config.prefix) {
|
|
60
|
+
formatted += `${this.config.prefix} `;
|
|
61
|
+
}
|
|
62
|
+
// Add message
|
|
63
|
+
formatted += message;
|
|
64
|
+
// Add metadata
|
|
65
|
+
if (meta !== undefined) {
|
|
66
|
+
if (typeof meta === 'object') {
|
|
67
|
+
formatted += ` ${JSON.stringify(meta)}`;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
formatted += ` ${String(meta)}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return formatted;
|
|
74
|
+
}
|
|
75
|
+
writeLog(level, message, meta) {
|
|
76
|
+
if (!this.shouldLog(level))
|
|
77
|
+
return;
|
|
78
|
+
const formatted = this.formatMessage(level, message, meta);
|
|
79
|
+
console.error(formatted);
|
|
80
|
+
}
|
|
81
|
+
error(message, meta) {
|
|
82
|
+
this.writeLog('error', message, meta);
|
|
83
|
+
}
|
|
84
|
+
warn(message, meta) {
|
|
85
|
+
this.writeLog('warn', message, meta);
|
|
86
|
+
}
|
|
87
|
+
info(message, meta) {
|
|
88
|
+
this.writeLog('info', message, meta);
|
|
89
|
+
}
|
|
90
|
+
debug(message, meta) {
|
|
91
|
+
this.writeLog('debug', message, meta);
|
|
92
|
+
}
|
|
93
|
+
trace(message, meta) {
|
|
94
|
+
this.writeLog('trace', message, meta);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* No-op logger for testing or when logging is disabled
|
|
99
|
+
*/
|
|
100
|
+
export class NoopLogger {
|
|
101
|
+
error() { }
|
|
102
|
+
warn() { }
|
|
103
|
+
info() { }
|
|
104
|
+
debug() { }
|
|
105
|
+
trace() { }
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Helper to get log level from environment
|
|
109
|
+
*/
|
|
110
|
+
export function getLogLevel() {
|
|
111
|
+
return process.env.LOG_LEVEL || DEFAULT_LOG_LEVEL;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const ProjectIdSchema: z.ZodString;
|
|
3
|
+
export declare const ScenarioIdSchema: z.ZodString;
|
|
4
|
+
export declare const ActionWordIdSchema: z.ZodString;
|
|
5
|
+
export declare const FolderIdSchema: z.ZodString;
|
|
6
|
+
export declare const TestRunIdSchema: z.ZodString;
|
|
7
|
+
export declare const BuildIdSchema: z.ZodString;
|
|
8
|
+
export declare const PaginationSchema: z.ZodOptional<z.ZodObject<{
|
|
9
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
pageSize: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
page?: number | undefined;
|
|
13
|
+
pageSize?: number | undefined;
|
|
14
|
+
}, {
|
|
15
|
+
page?: number | undefined;
|
|
16
|
+
pageSize?: number | undefined;
|
|
17
|
+
}>>;
|
|
18
|
+
export declare const FilterSchema: z.ZodOptional<z.ZodObject<{
|
|
19
|
+
name: z.ZodOptional<z.ZodString>;
|
|
20
|
+
tags: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
name?: string | undefined;
|
|
23
|
+
tags?: string | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
name?: string | undefined;
|
|
26
|
+
tags?: string | undefined;
|
|
27
|
+
}>>;
|
|
28
|
+
export declare const ListParamsSchema: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
pagination: z.ZodOptional<z.ZodObject<{
|
|
30
|
+
page: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
pageSize: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
page?: number | undefined;
|
|
34
|
+
pageSize?: number | undefined;
|
|
35
|
+
}, {
|
|
36
|
+
page?: number | undefined;
|
|
37
|
+
pageSize?: number | undefined;
|
|
38
|
+
}>>;
|
|
39
|
+
filter: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
name: z.ZodOptional<z.ZodString>;
|
|
41
|
+
tags: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
name?: string | undefined;
|
|
44
|
+
tags?: string | undefined;
|
|
45
|
+
}, {
|
|
46
|
+
name?: string | undefined;
|
|
47
|
+
tags?: string | undefined;
|
|
48
|
+
}>>;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
filter?: {
|
|
51
|
+
name?: string | undefined;
|
|
52
|
+
tags?: string | undefined;
|
|
53
|
+
} | undefined;
|
|
54
|
+
pagination?: {
|
|
55
|
+
page?: number | undefined;
|
|
56
|
+
pageSize?: number | undefined;
|
|
57
|
+
} | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
filter?: {
|
|
60
|
+
name?: string | undefined;
|
|
61
|
+
tags?: string | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
pagination?: {
|
|
64
|
+
page?: number | undefined;
|
|
65
|
+
pageSize?: number | undefined;
|
|
66
|
+
} | undefined;
|
|
67
|
+
}>>;
|
|
68
|
+
/**
|
|
69
|
+
* Convert pagination and filter parameters to API format
|
|
70
|
+
*/
|
|
71
|
+
export declare function convertToApiParams(params?: {
|
|
72
|
+
pagination?: {
|
|
73
|
+
page?: number;
|
|
74
|
+
pageSize?: number;
|
|
75
|
+
};
|
|
76
|
+
filter?: {
|
|
77
|
+
name?: string;
|
|
78
|
+
tags?: string;
|
|
79
|
+
};
|
|
80
|
+
}): Record<string, unknown>;
|
|
81
|
+
/**
|
|
82
|
+
* Validate input against a schema and throw MCP error if invalid
|
|
83
|
+
*/
|
|
84
|
+
export declare function validateInput<T>(schema: z.ZodSchema<T>, input: unknown, context?: string): T;
|
|
85
|
+
/**
|
|
86
|
+
* Validate that required environment variables are present
|
|
87
|
+
*/
|
|
88
|
+
export declare function validateEnvironment(): void;
|
|
89
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,eAAe,aAA8C,CAAA;AAC1E,eAAO,MAAM,gBAAgB,aAA+C,CAAA;AAC5E,eAAO,MAAM,kBAAkB,aAAkD,CAAA;AACjF,eAAO,MAAM,cAAc,aAA6C,CAAA;AACxE,eAAO,MAAM,eAAe,aAA+C,CAAA;AAC3E,eAAO,MAAM,aAAa,aAA4C,CAAA;AAGtE,eAAO,MAAM,gBAAgB;;;;;;;;;GAKhB,CAAA;AAGb,eAAO,MAAM,YAAY;;;;;;;;;GAKZ,CAAA;AAGb,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAKhB,CAAA;AAEb;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE;IAC1C,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACjD,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsB1B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAU5F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAQ1C"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { MAX_PAGE_SIZE } from '../constants.js';
|
|
4
|
+
// Common validation schemas
|
|
5
|
+
export const ProjectIdSchema = z.string().min(1, 'Project ID is required');
|
|
6
|
+
export const ScenarioIdSchema = z.string().min(1, 'Scenario ID is required');
|
|
7
|
+
export const ActionWordIdSchema = z.string().min(1, 'Action Word ID is required');
|
|
8
|
+
export const FolderIdSchema = z.string().min(1, 'Folder ID is required');
|
|
9
|
+
export const TestRunIdSchema = z.string().min(1, 'Test Run ID is required');
|
|
10
|
+
export const BuildIdSchema = z.string().min(1, 'Build ID is required');
|
|
11
|
+
// Pagination schema
|
|
12
|
+
export const PaginationSchema = z
|
|
13
|
+
.object({
|
|
14
|
+
page: z.number().int().min(1).optional(),
|
|
15
|
+
pageSize: z.number().int().min(1).max(MAX_PAGE_SIZE).optional(),
|
|
16
|
+
})
|
|
17
|
+
.optional();
|
|
18
|
+
// Filter schema
|
|
19
|
+
export const FilterSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
name: z.string().optional(),
|
|
22
|
+
tags: z.string().optional(),
|
|
23
|
+
})
|
|
24
|
+
.optional();
|
|
25
|
+
// List parameters schema
|
|
26
|
+
export const ListParamsSchema = z
|
|
27
|
+
.object({
|
|
28
|
+
pagination: PaginationSchema,
|
|
29
|
+
filter: FilterSchema,
|
|
30
|
+
})
|
|
31
|
+
.optional();
|
|
32
|
+
/**
|
|
33
|
+
* Convert pagination and filter parameters to API format
|
|
34
|
+
*/
|
|
35
|
+
export function convertToApiParams(params) {
|
|
36
|
+
if (!params)
|
|
37
|
+
return {};
|
|
38
|
+
const apiParams = {};
|
|
39
|
+
if (params.pagination?.page) {
|
|
40
|
+
apiParams['page[number]'] = params.pagination.page;
|
|
41
|
+
}
|
|
42
|
+
if (params.pagination?.pageSize) {
|
|
43
|
+
apiParams['page[size]'] = params.pagination.pageSize;
|
|
44
|
+
}
|
|
45
|
+
if (params.filter?.name) {
|
|
46
|
+
apiParams['filter[name]'] = params.filter.name;
|
|
47
|
+
}
|
|
48
|
+
if (params.filter?.tags) {
|
|
49
|
+
apiParams['filter[tags]'] = params.filter.tags;
|
|
50
|
+
}
|
|
51
|
+
return apiParams;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate input against a schema and throw MCP error if invalid
|
|
55
|
+
*/
|
|
56
|
+
export function validateInput(schema, input, context) {
|
|
57
|
+
try {
|
|
58
|
+
return schema.parse(input);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof z.ZodError) {
|
|
62
|
+
const issues = error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
63
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid parameters${context ? ` for ${context}` : ''}: ${issues}`);
|
|
64
|
+
}
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Validate that required environment variables are present
|
|
70
|
+
*/
|
|
71
|
+
export function validateEnvironment() {
|
|
72
|
+
const required = ['CUCUMBERSTUDIO_ACCESS_TOKEN', 'CUCUMBERSTUDIO_CLIENT_ID', 'CUCUMBERSTUDIO_UID'];
|
|
73
|
+
const missing = required.filter((envVar) => !process.env[envVar]);
|
|
74
|
+
if (missing.length > 0) {
|
|
75
|
+
throw new McpError(ErrorCode.InvalidRequest, `Missing required environment variables: ${missing.join(', ')}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
cucumberstudio-mcp:
|
|
5
|
+
build: .
|
|
6
|
+
env_file:
|
|
7
|
+
- .env
|
|
8
|
+
restart: unless-stopped
|
|
9
|
+
ports:
|
|
10
|
+
- "${MCP_PORT:-3000}:3000"
|
|
11
|
+
healthcheck:
|
|
12
|
+
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health", "||", "exit", "1"]
|
|
13
|
+
interval: 30s
|
|
14
|
+
timeout: 10s
|
|
15
|
+
retries: 3
|
|
16
|
+
start_period: 40s
|
|
17
|
+
|
|
18
|
+
networks:
|
|
19
|
+
default:
|
|
20
|
+
name: cucumberstudio-mcp-network
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import tseslint from '@typescript-eslint/eslint-plugin'
|
|
2
|
+
import tsparser from '@typescript-eslint/parser'
|
|
3
|
+
import importPlugin from 'eslint-plugin-import'
|
|
4
|
+
|
|
5
|
+
export default [
|
|
6
|
+
{
|
|
7
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
8
|
+
languageOptions: {
|
|
9
|
+
parser: tsparser,
|
|
10
|
+
parserOptions: {
|
|
11
|
+
ecmaVersion: 2022,
|
|
12
|
+
sourceType: 'module',
|
|
13
|
+
project: './tsconfig.json',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
'@typescript-eslint': tseslint,
|
|
18
|
+
import: importPlugin,
|
|
19
|
+
},
|
|
20
|
+
settings: {
|
|
21
|
+
'import/resolver': {
|
|
22
|
+
typescript: {
|
|
23
|
+
alwaysTryTypes: true,
|
|
24
|
+
project: './tsconfig.json',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
rules: {
|
|
29
|
+
// TypeScript-specific rules
|
|
30
|
+
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
|
31
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
32
|
+
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
33
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
34
|
+
'@typescript-eslint/no-non-null-assertion': 'off', // Allow ! in Result pattern
|
|
35
|
+
|
|
36
|
+
// Import organization rules
|
|
37
|
+
'import/order': [
|
|
38
|
+
'error',
|
|
39
|
+
{
|
|
40
|
+
groups: [
|
|
41
|
+
'builtin', // Node.js built-in modules
|
|
42
|
+
'external', // External libraries
|
|
43
|
+
'internal', // Internal modules (using path mapping)
|
|
44
|
+
'parent', // Parent directories
|
|
45
|
+
'sibling', // Same directory
|
|
46
|
+
'index', // Index files
|
|
47
|
+
],
|
|
48
|
+
'newlines-between': 'always',
|
|
49
|
+
alphabetize: {
|
|
50
|
+
order: 'asc',
|
|
51
|
+
caseInsensitive: true,
|
|
52
|
+
},
|
|
53
|
+
pathGroups: [
|
|
54
|
+
{
|
|
55
|
+
pattern: '@/**',
|
|
56
|
+
group: 'internal',
|
|
57
|
+
position: 'before',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
pathGroupsExcludedImportTypes: ['builtin'],
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
'import/newline-after-import': 'error',
|
|
64
|
+
'import/no-duplicates': 'error',
|
|
65
|
+
'import/no-unused-modules': 'off', // Can be enabled for stricter checking
|
|
66
|
+
|
|
67
|
+
// General code quality rules
|
|
68
|
+
'no-console': 'off', // Allow console for this MCP server
|
|
69
|
+
'no-debugger': 'error',
|
|
70
|
+
'no-unused-vars': 'off', // Use TypeScript version instead
|
|
71
|
+
'prefer-const': 'error',
|
|
72
|
+
'no-var': 'error',
|
|
73
|
+
'object-shorthand': 'error',
|
|
74
|
+
'prefer-arrow-callback': 'error',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
files: ['**/*.test.ts', '**/*.spec.ts', 'test/**/*.ts'],
|
|
79
|
+
rules: {
|
|
80
|
+
// Relax some rules for test files
|
|
81
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
82
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
83
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
// Ignore patterns
|
|
88
|
+
ignores: [
|
|
89
|
+
'build/**',
|
|
90
|
+
'node_modules/**',
|
|
91
|
+
'coverage/**',
|
|
92
|
+
'*.js', // Ignore JS files in root (like this config file)
|
|
93
|
+
'vitest.config.ts', // Vitest config not in main tsconfig
|
|
94
|
+
'**/*.d.ts', // Ignore generated TypeScript declaration files
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
]
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cucumberstudio-mcp",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "MCP server for Cucumber Studio API integration",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cucumberstudio-mcp": "./build/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"prepare": "node scripts/generate-version.js",
|
|
12
|
+
"prebuild": "node scripts/generate-version.js",
|
|
13
|
+
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
14
|
+
"start": "node build/index.js",
|
|
15
|
+
"start:http": "MCP_TRANSPORT=http node build/index.js",
|
|
16
|
+
"dev": "tsx --watch -r tsconfig-paths/register src/index.ts",
|
|
17
|
+
"dev:http": "MCP_TRANSPORT=http tsx --watch -r tsconfig-paths/register src/index.ts",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"test:ui": "vitest --ui",
|
|
21
|
+
"test:coverage": "vitest run --coverage",
|
|
22
|
+
"test:ui-coverage": "vitest --ui --coverage",
|
|
23
|
+
"lint": "eslint src test --ext .ts",
|
|
24
|
+
"lint:fix": "eslint src test --ext .ts --fix",
|
|
25
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
26
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"docker:build": "docker build -t cucumberstudio-mcp .",
|
|
29
|
+
"docker:build:dev": "docker build -f Dockerfile.dev -t cucumberstudio-mcp:dev .",
|
|
30
|
+
"docker:run": "docker run --env-file .env cucumberstudio-mcp",
|
|
31
|
+
"docker:run:dev": "docker run --env-file .env -v $(pwd)/src:/app/src cucumberstudio-mcp:dev",
|
|
32
|
+
"docker:compose:up": "docker-compose up",
|
|
33
|
+
"docker:compose:up:dev": "docker-compose --profile dev up cucumberstudio-mcp-dev",
|
|
34
|
+
"docker:compose:down": "docker-compose down",
|
|
35
|
+
"docker:compose:build": "docker-compose build"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"mcp",
|
|
39
|
+
"cucumber",
|
|
40
|
+
"testing",
|
|
41
|
+
"api",
|
|
42
|
+
"automation",
|
|
43
|
+
"model-context-protocol",
|
|
44
|
+
"cucumber-studio",
|
|
45
|
+
"ai",
|
|
46
|
+
"llm"
|
|
47
|
+
],
|
|
48
|
+
"author": "",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/HeroSizy/cucumberstudio-mcp.git"
|
|
53
|
+
},
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/HeroSizy/cucumberstudio-mcp/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://github.com/HeroSizy/cucumberstudio-mcp#readme",
|
|
58
|
+
"preferGlobal": true,
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@modelcontextprotocol/sdk": "^1.12.3",
|
|
61
|
+
"axios": "^1.6.0",
|
|
62
|
+
"cors": "^2.8.5",
|
|
63
|
+
"dotenv": "^16.5.0",
|
|
64
|
+
"express": "^4.18.0",
|
|
65
|
+
"zod": "^3.22.0"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/cors": "^2.8.0",
|
|
69
|
+
"@types/express": "^4.17.0",
|
|
70
|
+
"@types/node": "^22.15.30",
|
|
71
|
+
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
|
72
|
+
"@typescript-eslint/parser": "^8.34.0",
|
|
73
|
+
"@vitest/coverage-v8": "^3.2.2",
|
|
74
|
+
"@vitest/ui": "^3.2.2",
|
|
75
|
+
"eslint": "^9.28.0",
|
|
76
|
+
"eslint-config-prettier": "^9.0.0",
|
|
77
|
+
"eslint-import-resolver-typescript": "^4.4.3",
|
|
78
|
+
"eslint-plugin-import": "^2.31.0",
|
|
79
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
80
|
+
"msw": "^2.10.2",
|
|
81
|
+
"prettier": "^3.5.3",
|
|
82
|
+
"tsc-alias": "^1.8.16",
|
|
83
|
+
"tsconfig-paths": "^4.2.0",
|
|
84
|
+
"tsx": "^4.0.0",
|
|
85
|
+
"typescript": "^5.8.3",
|
|
86
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
87
|
+
"vitest": "^3.2.2"
|
|
88
|
+
},
|
|
89
|
+
"engines": {
|
|
90
|
+
"node": ">=20.0.0"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs'
|
|
4
|
+
import { join, dirname } from 'path'
|
|
5
|
+
import { fileURLToPath } from 'url'
|
|
6
|
+
|
|
7
|
+
// Get current directory for ES modules
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
9
|
+
const __dirname = dirname(__filename)
|
|
10
|
+
|
|
11
|
+
// Read package.json
|
|
12
|
+
const packagePath = join(__dirname, '..', 'package.json')
|
|
13
|
+
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'))
|
|
14
|
+
|
|
15
|
+
// Generate version constants file
|
|
16
|
+
const versionContent = `// Auto-generated version info - DO NOT EDIT
|
|
17
|
+
// Generated at build time from package.json
|
|
18
|
+
|
|
19
|
+
export const PACKAGE_VERSION = '${packageJson.version}'
|
|
20
|
+
export const PACKAGE_NAME = '${packageJson.name}'
|
|
21
|
+
`
|
|
22
|
+
|
|
23
|
+
// Ensure the generated directory exists
|
|
24
|
+
const generatedDir = join(__dirname, '..', 'src', 'generated')
|
|
25
|
+
mkdirSync(generatedDir, { recursive: true })
|
|
26
|
+
|
|
27
|
+
// Write to src/generated/version.ts
|
|
28
|
+
const outputPath = join(generatedDir, 'version.ts')
|
|
29
|
+
writeFileSync(outputPath, versionContent)
|
|
30
|
+
|
|
31
|
+
console.log(`✅ Generated version constants: ${packageJson.name}@${packageJson.version}`)
|