@alternative-path/qa-path-mcp 1.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 +23 -0
- package/QUICK_INSTALL.md +133 -0
- package/README.md +226 -0
- package/TOOLS_DOCUMENTATION.md +675 -0
- package/dist/__tests__/tools/module-tools.test.d.ts +2 -0
- package/dist/__tests__/tools/module-tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools/module-tools.test.js +145 -0
- package/dist/__tests__/tools/module-tools.test.js.map +1 -0
- package/dist/__tests__/tools/project-tools.test.d.ts +2 -0
- package/dist/__tests__/tools/project-tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools/project-tools.test.js +674 -0
- package/dist/__tests__/tools/project-tools.test.js.map +1 -0
- package/dist/__tests__/tools/query-tools.test.d.ts +2 -0
- package/dist/__tests__/tools/query-tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools/query-tools.test.js +225 -0
- package/dist/__tests__/tools/query-tools.test.js.map +1 -0
- package/dist/__tests__/tools/testgroup-launch-tools.test.d.ts +2 -0
- package/dist/__tests__/tools/testgroup-launch-tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools/testgroup-launch-tools.test.js +553 -0
- package/dist/__tests__/tools/testgroup-launch-tools.test.js.map +1 -0
- package/dist/__tests__/utils/mcp-error-mapper.test.d.ts +2 -0
- package/dist/__tests__/utils/mcp-error-mapper.test.d.ts.map +1 -0
- package/dist/__tests__/utils/mcp-error-mapper.test.js +240 -0
- package/dist/__tests__/utils/mcp-error-mapper.test.js.map +1 -0
- package/dist/__tests__/utils/mcp-response.test.d.ts +2 -0
- package/dist/__tests__/utils/mcp-response.test.d.ts.map +1 -0
- package/dist/__tests__/utils/mcp-response.test.js +72 -0
- package/dist/__tests__/utils/mcp-response.test.js.map +1 -0
- package/dist/agents/test-planner-context.d.ts +7 -0
- package/dist/agents/test-planner-context.d.ts.map +1 -0
- package/dist/agents/test-planner-context.js +283 -0
- package/dist/agents/test-planner-context.js.map +1 -0
- package/dist/agents/test-planner-prompt.d.ts +34 -0
- package/dist/agents/test-planner-prompt.d.ts.map +1 -0
- package/dist/agents/test-planner-prompt.js +82 -0
- package/dist/agents/test-planner-prompt.js.map +1 -0
- package/dist/api-client.d.ts +52 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +285 -0
- package/dist/api-client.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +175 -0
- package/dist/index.js.map +1 -0
- package/dist/services/project-context-service.d.ts +15 -0
- package/dist/services/project-context-service.d.ts.map +1 -0
- package/dist/services/project-context-service.js +36 -0
- package/dist/services/project-context-service.js.map +1 -0
- package/dist/tools/auth-tools.d.ts +16 -0
- package/dist/tools/auth-tools.d.ts.map +1 -0
- package/dist/tools/auth-tools.js +66 -0
- package/dist/tools/auth-tools.js.map +1 -0
- package/dist/tools/automation-tools.d.ts +28 -0
- package/dist/tools/automation-tools.d.ts.map +1 -0
- package/dist/tools/automation-tools.js +541 -0
- package/dist/tools/automation-tools.js.map +1 -0
- package/dist/tools/export-import-tools.d.ts +18 -0
- package/dist/tools/export-import-tools.d.ts.map +1 -0
- package/dist/tools/export-import-tools.js +61 -0
- package/dist/tools/export-import-tools.js.map +1 -0
- package/dist/tools/module-tools.d.ts +43 -0
- package/dist/tools/module-tools.d.ts.map +1 -0
- package/dist/tools/module-tools.js +289 -0
- package/dist/tools/module-tools.js.map +1 -0
- package/dist/tools/project-context-tools.d.ts +19 -0
- package/dist/tools/project-context-tools.d.ts.map +1 -0
- package/dist/tools/project-context-tools.js +133 -0
- package/dist/tools/project-context-tools.js.map +1 -0
- package/dist/tools/project-tools.d.ts +47 -0
- package/dist/tools/project-tools.d.ts.map +1 -0
- package/dist/tools/project-tools.js +362 -0
- package/dist/tools/project-tools.js.map +1 -0
- package/dist/tools/query-tools.d.ts +22 -0
- package/dist/tools/query-tools.d.ts.map +1 -0
- package/dist/tools/query-tools.js +127 -0
- package/dist/tools/query-tools.js.map +1 -0
- package/dist/tools/testcase-tools.d.ts +135 -0
- package/dist/tools/testcase-tools.d.ts.map +1 -0
- package/dist/tools/testcase-tools.js +845 -0
- package/dist/tools/testcase-tools.js.map +1 -0
- package/dist/tools/testgroup-launch-tools.d.ts +37 -0
- package/dist/tools/testgroup-launch-tools.d.ts.map +1 -0
- package/dist/tools/testgroup-launch-tools.js +727 -0
- package/dist/tools/testgroup-launch-tools.js.map +1 -0
- package/dist/utils/mcp-error-mapper.d.ts +27 -0
- package/dist/utils/mcp-error-mapper.d.ts.map +1 -0
- package/dist/utils/mcp-error-mapper.js +79 -0
- package/dist/utils/mcp-error-mapper.js.map +1 -0
- package/dist/utils/mcp-response.d.ts +26 -0
- package/dist/utils/mcp-response.d.ts.map +1 -0
- package/dist/utils/mcp-response.js +34 -0
- package/dist/utils/mcp-response.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { ApiClient } from "../api-client.js";
|
|
3
|
+
export interface Project {
|
|
4
|
+
id: string;
|
|
5
|
+
org_id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
created_at: string;
|
|
9
|
+
updated_at: string;
|
|
10
|
+
context: string;
|
|
11
|
+
created_by: string | null;
|
|
12
|
+
updated_by: string | null;
|
|
13
|
+
prefix: string;
|
|
14
|
+
deletedAt: string | null;
|
|
15
|
+
createdByUser: {
|
|
16
|
+
id: string;
|
|
17
|
+
username: string;
|
|
18
|
+
} | null;
|
|
19
|
+
updatedByUser: {
|
|
20
|
+
id: string;
|
|
21
|
+
username: string;
|
|
22
|
+
} | null;
|
|
23
|
+
testCaseCount: number;
|
|
24
|
+
moduleCount: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ProjectsResponse {
|
|
27
|
+
success: boolean;
|
|
28
|
+
message: string;
|
|
29
|
+
data: Project[];
|
|
30
|
+
}
|
|
31
|
+
export declare class ProjectTools {
|
|
32
|
+
private apiClient;
|
|
33
|
+
constructor(apiClient: ApiClient);
|
|
34
|
+
getTools(): Tool[];
|
|
35
|
+
handles(name: string): boolean;
|
|
36
|
+
handle(name: string, args: unknown): Promise<{
|
|
37
|
+
content: {
|
|
38
|
+
type: "text";
|
|
39
|
+
text: string;
|
|
40
|
+
}[];
|
|
41
|
+
}>;
|
|
42
|
+
private suggestProjectPrefix;
|
|
43
|
+
private listProjects;
|
|
44
|
+
private createProject;
|
|
45
|
+
private updateProject;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=project-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-tools.d.ts","sourceRoot":"","sources":["../../src/tools/project-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,aAAa,EAAE;QACb,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,IAAI,CAAC;IACT,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AA0CD,qBAAa,YAAY;IACX,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC,QAAQ,IAAI,IAAI,EAAE;IAsHlB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;;;;;;YAe1B,oBAAoB;YA6CpB,YAAY;YA2EZ,aAAa;YAkFb,aAAa;CAkF5B"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { jsonResponse } from "../utils/mcp-response.js";
|
|
2
|
+
import { mapApiErrorToMcpResponse, mapApiResponseToMcpError } from "../utils/mcp-error-mapper.js";
|
|
3
|
+
// Allowed sort fields - matches backend schema
|
|
4
|
+
const ALLOWED_SORT_FIELDS = ["name", "description", "created_at", "createdByUser"];
|
|
5
|
+
export class ProjectTools {
|
|
6
|
+
apiClient;
|
|
7
|
+
constructor(apiClient) {
|
|
8
|
+
this.apiClient = apiClient;
|
|
9
|
+
}
|
|
10
|
+
getTools() {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
name: "list_projects",
|
|
14
|
+
description: "List projects accessible to the authenticated user with filtering and sorting. Returns projects with their details including test case counts and module counts. Supports text-based queries in canonical format for efficient filtering (e.g., \"name contains 'API' AND createdByUser = 'user-id'\"). IMPORTANT: Always call get_query_schema with entity='project' first to understand available fields, operators, and valid values. Use field names (not labels) in queries, and use IDs for association fields like createdByUser and updatedByUser.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
query: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Text query in canonical format for filtering projects (e.g., \"name = 'MyProject'\", \"name contains 'API'\", \"createdByUser = 'user-id' AND updated_at > '2024-01-01'\"). IMPORTANT: Always call get_query_schema with entity='project' first to understand available fields, operators, and valid values. Use field names (not labels) in queries. Use IDs for association fields like createdByUser and updatedByUser. Leave empty or omit only if you need ALL projects. For finding a specific project, use a query filter instead of fetching all projects. Max length: 5000 characters.",
|
|
21
|
+
maxLength: 5000,
|
|
22
|
+
},
|
|
23
|
+
sortField: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "Optional field to sort by. Allowed values: 'name', 'description', 'created_at', 'createdByUser'.",
|
|
26
|
+
enum: ALLOWED_SORT_FIELDS,
|
|
27
|
+
},
|
|
28
|
+
sortOrder: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "Optional sort order: 'ASC' or 'DESC'. Defaults to 'ASC'.",
|
|
31
|
+
enum: ["ASC", "DESC"],
|
|
32
|
+
},
|
|
33
|
+
page: {
|
|
34
|
+
type: "number",
|
|
35
|
+
description: "Page number (required, minimum: 1).",
|
|
36
|
+
minimum: 1,
|
|
37
|
+
},
|
|
38
|
+
pageSize: {
|
|
39
|
+
type: "number",
|
|
40
|
+
description: "Number of results per page (required, minimum: 1, maximum: 10000).",
|
|
41
|
+
minimum: 1,
|
|
42
|
+
maximum: 10000,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
required: ["page", "pageSize"],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "suggest_project_prefix",
|
|
50
|
+
description: "Generate a unique project prefix suggestion based on the project name. " +
|
|
51
|
+
"This checks existing prefixes in the organization and suggests an available prefix. " +
|
|
52
|
+
"Use this before creating a project if you're unsure about prefix availability. " +
|
|
53
|
+
"The prefix will be 2-4 characters long, derived from the project name (e.g., 'Test Project' → 'TP', 'API Testing' → 'AT').",
|
|
54
|
+
inputSchema: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
projectName: {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "Project name to generate prefix from (required, non-empty string).",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
required: ["projectName"],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "create_project",
|
|
67
|
+
description: "Create a new project in the organization. The project name and prefix must be unique within the organization. " +
|
|
68
|
+
"If you're unsure about prefix availability, use 'suggest_project_prefix' first to get a unique prefix suggestion.",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
name: {
|
|
73
|
+
type: "string",
|
|
74
|
+
description: "Project name (required, non-empty string).",
|
|
75
|
+
},
|
|
76
|
+
prefix: {
|
|
77
|
+
type: "string",
|
|
78
|
+
description: "Project key prefix (required, non-empty string, 2-4 characters). Must be unique within the organization.",
|
|
79
|
+
},
|
|
80
|
+
description: {
|
|
81
|
+
type: "string",
|
|
82
|
+
description: "Optional project description (must be string if provided).",
|
|
83
|
+
},
|
|
84
|
+
context: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "Optional project context (must be string if provided).",
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
required: ["name", "prefix"],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "update_project",
|
|
94
|
+
description: "Update an existing project. Only projects in the authenticated user's organization can be updated. The project name must be unique within the organization.",
|
|
95
|
+
inputSchema: {
|
|
96
|
+
type: "object",
|
|
97
|
+
properties: {
|
|
98
|
+
projectId: {
|
|
99
|
+
type: "string",
|
|
100
|
+
description: "Project ID (UUID) to update (required).",
|
|
101
|
+
},
|
|
102
|
+
name: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "Updated project name (required, non-empty string).",
|
|
105
|
+
},
|
|
106
|
+
description: {
|
|
107
|
+
type: "string",
|
|
108
|
+
description: "Optional updated project description.",
|
|
109
|
+
},
|
|
110
|
+
context: {
|
|
111
|
+
type: "string",
|
|
112
|
+
description: "Optional updated project context.",
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
required: ["projectId", "name"],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
handles(name) {
|
|
121
|
+
return ["list_projects", "suggest_project_prefix", "create_project", "update_project"].includes(name);
|
|
122
|
+
}
|
|
123
|
+
async handle(name, args) {
|
|
124
|
+
switch (name) {
|
|
125
|
+
case "list_projects":
|
|
126
|
+
return await this.listProjects(args);
|
|
127
|
+
case "suggest_project_prefix":
|
|
128
|
+
return await this.suggestProjectPrefix(args);
|
|
129
|
+
case "create_project":
|
|
130
|
+
return await this.createProject(args);
|
|
131
|
+
case "update_project":
|
|
132
|
+
return await this.updateProject(args);
|
|
133
|
+
default:
|
|
134
|
+
throw new Error(`Unknown project tool: ${name}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async suggestProjectPrefix(args) {
|
|
138
|
+
const { projectName } = args;
|
|
139
|
+
if (!projectName || typeof projectName !== "string" || projectName.trim().length === 0) {
|
|
140
|
+
return jsonResponse({
|
|
141
|
+
success: false,
|
|
142
|
+
error_code: "INVALID_PROJECT_NAME",
|
|
143
|
+
message: "projectName (string) is required and must be non-empty.",
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const apiResult = await this.apiClient.get(`/project/generateUniquePrefixForProject`, { params: { projectName: projectName.trim() } });
|
|
148
|
+
if (apiResult.success !== true) {
|
|
149
|
+
return jsonResponse({
|
|
150
|
+
success: false,
|
|
151
|
+
error_code: "PREFIX_GENERATION_FAILED",
|
|
152
|
+
message: apiResult.message ?? "Failed to generate prefix suggestion.",
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return jsonResponse({
|
|
156
|
+
success: true,
|
|
157
|
+
message: apiResult.message ?? "Prefix suggestion generated successfully.",
|
|
158
|
+
data: {
|
|
159
|
+
prefix: apiResult.data,
|
|
160
|
+
projectName: projectName.trim(),
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const mappedError = mapApiErrorToMcpResponse(err, "PREFIX_GENERATION_FAILED");
|
|
166
|
+
if (mappedError) {
|
|
167
|
+
return mappedError;
|
|
168
|
+
}
|
|
169
|
+
// Infrastructure/system failure - throw
|
|
170
|
+
throw new Error(err?.message ?? "Failed to generate prefix suggestion due to system error.");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async listProjects(args) {
|
|
174
|
+
const { sortField, sortOrder, query, page, pageSize } = args;
|
|
175
|
+
// Validate required pagination parameters
|
|
176
|
+
if (!page || typeof page !== "number" || page < 1) {
|
|
177
|
+
return jsonResponse({
|
|
178
|
+
success: false,
|
|
179
|
+
error_code: "INVALID_PAGE",
|
|
180
|
+
message: "page (number) is required and must be >= 1.",
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (!pageSize || typeof pageSize !== "number" || pageSize < 1 || pageSize > 10000) {
|
|
184
|
+
return jsonResponse({
|
|
185
|
+
success: false,
|
|
186
|
+
error_code: "INVALID_PAGE_SIZE",
|
|
187
|
+
message: "pageSize (number) is required and must be between 1 and 10000.",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (sortField && !ALLOWED_SORT_FIELDS.includes(sortField)) {
|
|
191
|
+
return jsonResponse({
|
|
192
|
+
success: false,
|
|
193
|
+
error_code: "INVALID_SORT_FIELD",
|
|
194
|
+
message: `sortField must be one of: ${ALLOWED_SORT_FIELDS.join(", ")}.`,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
if (query && typeof query === "string" && query.length > 5000) {
|
|
198
|
+
return jsonResponse({
|
|
199
|
+
success: false,
|
|
200
|
+
error_code: "INVALID_QUERY",
|
|
201
|
+
message: "query string must not exceed 5000 characters.",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const body = {
|
|
205
|
+
page,
|
|
206
|
+
pageSize,
|
|
207
|
+
};
|
|
208
|
+
if (sortField)
|
|
209
|
+
body.sortField = sortField;
|
|
210
|
+
if (sortOrder)
|
|
211
|
+
body.sortOrder = sortOrder;
|
|
212
|
+
if (query && query.trim().length > 0)
|
|
213
|
+
body.query = query.trim();
|
|
214
|
+
// Note: getProjects endpoint doesn't require x-project-id header
|
|
215
|
+
// It returns all projects for the authenticated user based on session
|
|
216
|
+
// XSRF-TOKEN cookie is automatically sent via cookie jar (set during login)
|
|
217
|
+
// We must explicitly remove x-project-id header to avoid permission checks
|
|
218
|
+
try {
|
|
219
|
+
const apiResult = await this.apiClient.post(`/project/getProjects`, body);
|
|
220
|
+
if (apiResult.success !== true) {
|
|
221
|
+
return jsonResponse({
|
|
222
|
+
success: false,
|
|
223
|
+
error_code: "LIST_FAILED",
|
|
224
|
+
message: apiResult.message ?? "Failed to retrieve projects.",
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return jsonResponse({
|
|
228
|
+
success: true,
|
|
229
|
+
message: apiResult.message ?? "Projects retrieved successfully.",
|
|
230
|
+
data: apiResult.data ?? [],
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
// Infrastructure/system failure - throw
|
|
235
|
+
throw new Error(err?.message ?? "Failed to retrieve projects due to system error.");
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async createProject(args) {
|
|
239
|
+
const { name, prefix, description, context } = args;
|
|
240
|
+
// Contract-level validation: required fields, types, structural sanity
|
|
241
|
+
if (!name || typeof name !== "string" || name.trim().length === 0) {
|
|
242
|
+
return jsonResponse({
|
|
243
|
+
success: false,
|
|
244
|
+
error_code: "INVALID_NAME",
|
|
245
|
+
message: "name (string) is required and must be non-empty.",
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
if (!prefix || typeof prefix !== "string" || prefix.trim().length === 0) {
|
|
249
|
+
return jsonResponse({
|
|
250
|
+
success: false,
|
|
251
|
+
error_code: "INVALID_PREFIX",
|
|
252
|
+
message: "prefix (string) is required and must be 2-4 characters long.",
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (description != null && typeof description !== "string") {
|
|
256
|
+
return jsonResponse({
|
|
257
|
+
success: false,
|
|
258
|
+
error_code: "INVALID_DESCRIPTION_TYPE",
|
|
259
|
+
message: "description must be a string if provided.",
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (context != null && typeof context !== "string") {
|
|
263
|
+
return jsonResponse({
|
|
264
|
+
success: false,
|
|
265
|
+
error_code: "INVALID_CONTEXT_TYPE",
|
|
266
|
+
message: "context must be a string if provided.",
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const body = {
|
|
270
|
+
name: name.trim(),
|
|
271
|
+
prefix: prefix.trim(),
|
|
272
|
+
};
|
|
273
|
+
if (description != null) {
|
|
274
|
+
body.description = description.trim();
|
|
275
|
+
}
|
|
276
|
+
if (context != null) {
|
|
277
|
+
body.context = context.trim();
|
|
278
|
+
}
|
|
279
|
+
let apiResult;
|
|
280
|
+
try {
|
|
281
|
+
apiResult = await this.apiClient.post(`/project/createProject`, body);
|
|
282
|
+
}
|
|
283
|
+
catch (err) {
|
|
284
|
+
const mappedError = mapApiErrorToMcpResponse(err, "CREATE_FAILED");
|
|
285
|
+
if (mappedError) {
|
|
286
|
+
return mappedError;
|
|
287
|
+
}
|
|
288
|
+
throw new Error(err?.message ?? "Project creation failed due to system error.");
|
|
289
|
+
}
|
|
290
|
+
const mappedFailure = mapApiResponseToMcpError(apiResult, "CREATE_FAILED");
|
|
291
|
+
if (mappedFailure) {
|
|
292
|
+
return mappedFailure;
|
|
293
|
+
}
|
|
294
|
+
return jsonResponse({
|
|
295
|
+
success: true,
|
|
296
|
+
message: apiResult.message ?? "Project created successfully.",
|
|
297
|
+
data: apiResult.data,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
async updateProject(args) {
|
|
301
|
+
const { projectId, name, description, context } = args;
|
|
302
|
+
if (!projectId || typeof projectId !== "string") {
|
|
303
|
+
return jsonResponse({
|
|
304
|
+
success: false,
|
|
305
|
+
error_code: "INVALID_PROJECT_ID",
|
|
306
|
+
message: "projectId (string UUID) is required.",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
if (!name || typeof name !== "string" || name.trim().length === 0) {
|
|
310
|
+
return jsonResponse({
|
|
311
|
+
success: false,
|
|
312
|
+
error_code: "INVALID_NAME",
|
|
313
|
+
message: "name (string) is required and must be non-empty.",
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
if (description != null && typeof description !== "string") {
|
|
317
|
+
return jsonResponse({
|
|
318
|
+
success: false,
|
|
319
|
+
error_code: "INVALID_DESCRIPTION_TYPE",
|
|
320
|
+
message: "description must be a string if provided.",
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
if (context != null && typeof context !== "string") {
|
|
324
|
+
return jsonResponse({
|
|
325
|
+
success: false,
|
|
326
|
+
error_code: "INVALID_CONTEXT_TYPE",
|
|
327
|
+
message: "context must be a string if provided.",
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
const body = {
|
|
331
|
+
id: projectId,
|
|
332
|
+
name: name.trim(),
|
|
333
|
+
};
|
|
334
|
+
if (description != null) {
|
|
335
|
+
body.description = description.trim();
|
|
336
|
+
}
|
|
337
|
+
if (context != null) {
|
|
338
|
+
body.context = context.trim();
|
|
339
|
+
}
|
|
340
|
+
let apiResult;
|
|
341
|
+
try {
|
|
342
|
+
apiResult = await this.apiClient.put(`/project/update`, body);
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
const mappedError = mapApiErrorToMcpResponse(err, "UPDATE_FAILED");
|
|
346
|
+
if (mappedError) {
|
|
347
|
+
return mappedError;
|
|
348
|
+
}
|
|
349
|
+
throw new Error(err?.message ?? "Project update failed due to system error.");
|
|
350
|
+
}
|
|
351
|
+
const mappedFailure = mapApiResponseToMcpError(apiResult, "UPDATE_FAILED");
|
|
352
|
+
if (mappedFailure) {
|
|
353
|
+
return mappedFailure;
|
|
354
|
+
}
|
|
355
|
+
return jsonResponse({
|
|
356
|
+
success: true,
|
|
357
|
+
message: apiResult.message ?? "Project updated successfully.",
|
|
358
|
+
data: apiResult.data,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=project-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-tools.js","sourceRoot":"","sources":["../../src/tools/project-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { ApiClient } from "../api-client.js";
|
|
3
|
+
import { ProjectContextService } from "../services/project-context-service.js";
|
|
4
|
+
/**
|
|
5
|
+
* MCP tools for query system operations.
|
|
6
|
+
* Provides generic query schema tool that works for all entities (testcase, testgroup, project).
|
|
7
|
+
*/
|
|
8
|
+
export declare class QueryTools {
|
|
9
|
+
private apiClient;
|
|
10
|
+
private projectContext;
|
|
11
|
+
constructor(apiClient: ApiClient, projectContext: ProjectContextService);
|
|
12
|
+
getTools(): Tool[];
|
|
13
|
+
handles(name: string): boolean;
|
|
14
|
+
handle(name: string, args: any): Promise<{
|
|
15
|
+
content: {
|
|
16
|
+
type: "text";
|
|
17
|
+
text: string;
|
|
18
|
+
}[];
|
|
19
|
+
}>;
|
|
20
|
+
private getQuerySchema;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=query-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-tools.d.ts","sourceRoot":"","sources":["../../src/tools/query-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAG/E;;;GAGG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,cAAc;gBADd,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,qBAAqB;IAG/C,QAAQ,IAAI,IAAI,EAAE;IA6BlB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;;;;;;YAStB,cAAc;CAgG7B"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { jsonResponse } from "../utils/mcp-response.js";
|
|
2
|
+
/**
|
|
3
|
+
* MCP tools for query system operations.
|
|
4
|
+
* Provides generic query schema tool that works for all entities (testcase, testgroup, project).
|
|
5
|
+
*/
|
|
6
|
+
export class QueryTools {
|
|
7
|
+
apiClient;
|
|
8
|
+
projectContext;
|
|
9
|
+
constructor(apiClient, projectContext) {
|
|
10
|
+
this.apiClient = apiClient;
|
|
11
|
+
this.projectContext = projectContext;
|
|
12
|
+
}
|
|
13
|
+
getTools() {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
name: "get_query_schema",
|
|
17
|
+
description: "Get the query schema for any entity (testcase, testgroup, or project). This provides all filterable fields, their supported operators, and valid values (including IDs for user/module fields). IMPORTANT: Always call this tool first before using list operations with queries to understand what fields and values are available. Use field names (not labels) in queries, and use IDs for association fields. Supported entities: 'testcase', 'testgroup', 'project'.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
entity: {
|
|
22
|
+
type: "string",
|
|
23
|
+
enum: ["testcase", "testgroup", "project"],
|
|
24
|
+
description: "Entity type to get query schema for. Supported: 'testcase', 'testgroup', 'project'.",
|
|
25
|
+
},
|
|
26
|
+
projectId: {
|
|
27
|
+
type: "string",
|
|
28
|
+
description: "Optional project ID (UUID). If not provided, uses the active project set via 'set_active_project'. " +
|
|
29
|
+
"If no active project is set, the tool will return an error with instructions on how to set one. " +
|
|
30
|
+
"Note: For project entity queries, any projectId from your accessible projects will work since projects are organization-scoped.",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
required: ["entity"],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
handles(name) {
|
|
39
|
+
return ["get_query_schema"].includes(name);
|
|
40
|
+
}
|
|
41
|
+
async handle(name, args) {
|
|
42
|
+
switch (name) {
|
|
43
|
+
case "get_query_schema":
|
|
44
|
+
return await this.getQuerySchema(args);
|
|
45
|
+
default:
|
|
46
|
+
throw new Error(`Unknown query tool: ${name}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async getQuerySchema(args) {
|
|
50
|
+
const { entity } = args;
|
|
51
|
+
if (!entity) {
|
|
52
|
+
throw new Error("entity is required. Supported entities: 'testcase', 'testgroup', 'project'");
|
|
53
|
+
}
|
|
54
|
+
const supportedEntities = ["testcase", "testgroup", "project"];
|
|
55
|
+
if (!supportedEntities.includes(entity)) {
|
|
56
|
+
throw new Error(`Unsupported entity: '${entity}'. Supported entities: ${supportedEntities.join(", ")}`);
|
|
57
|
+
}
|
|
58
|
+
const projectId = this.projectContext.resolveProjectId(args, "get_query_schema");
|
|
59
|
+
try {
|
|
60
|
+
const response = await this.apiClient.get(`${projectId}/query/query-schema`, {
|
|
61
|
+
params: { entity },
|
|
62
|
+
});
|
|
63
|
+
// Entity-specific instruction templates
|
|
64
|
+
const instructionTemplates = {
|
|
65
|
+
testcase: {
|
|
66
|
+
usage: "Use this schema to understand available fields, operators, and valid values when querying test cases.",
|
|
67
|
+
important: [
|
|
68
|
+
"Always use field names (e.g., 'status', 'generated_by_user') NOT labels (e.g., 'Status', 'Created By') in queries.",
|
|
69
|
+
"For association fields (generated_by_user, updated_by_user, module, last_executed_by), use the 'id' from the values array.",
|
|
70
|
+
"For enum fields (status, priority, type, label, automation_status, execution_mode), use the exact string values from the values array.",
|
|
71
|
+
"For user fields, you can match by username, email, or label, but must use the corresponding 'id' in the query.",
|
|
72
|
+
"For module fields, you can match by name or path, but must use the corresponding 'id' in the query.",
|
|
73
|
+
"For multiple values, use the in operator and pass the values in an array",
|
|
74
|
+
"For in operator make use of [] these brackets to pass the values",
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
testgroup: {
|
|
78
|
+
usage: "Use this schema to understand available fields, operators, and valid values when querying test groups.",
|
|
79
|
+
important: [
|
|
80
|
+
"Always use field names (e.g., 'name', 'createdByUser') NOT labels (e.g., 'Name', 'Created By') in queries.",
|
|
81
|
+
"For association fields (createdByUser), use the 'id' from the values array.",
|
|
82
|
+
"For string fields (name, description, key), use string operators like 'contains', 'equals', 'startsWith', etc.",
|
|
83
|
+
"For date fields (created_at, updated_at, next_scheduled_run), use date operators like 'equals', 'before', 'after', 'between', etc.",
|
|
84
|
+
"For enum fields (group_type), use enum operators like 'equals', 'in', etc. Valid values are: 'Static', 'Dynamic'.",
|
|
85
|
+
"For user fields, you can match by username, email, or label, but must use the corresponding 'id' in the query.",
|
|
86
|
+
"For multiple values, use the in operator and pass the values in an array",
|
|
87
|
+
"For in operator make use of [] these brackets to pass the values",
|
|
88
|
+
"Test groups are project-scoped, so queries automatically filter by the specified project.",
|
|
89
|
+
"Example queries: \"name = 'API Test Group'\", \"name contains 'API'\", \"createdByUser = 'user-id' AND created_at > '2024-01-01'\", \"group_type = 'Static'\"",
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
project: {
|
|
93
|
+
usage: "Use this schema to understand available fields, operators, and valid values when querying projects.",
|
|
94
|
+
important: [
|
|
95
|
+
"Always use field names (e.g., 'name', 'createdByUser') NOT labels (e.g., 'Name', 'Created By') in queries.",
|
|
96
|
+
"For association fields (createdByUser, updatedByUser), use the 'id' from the values array.",
|
|
97
|
+
"For string fields (name, description, prefix, context), use string operators like 'contains', 'equals', 'startsWith', etc.",
|
|
98
|
+
"For date fields (created_at, updated_at), use date operators like 'equals', 'before', 'after', 'between', etc.",
|
|
99
|
+
"For user fields, you can match by username, email, or label, but must use the corresponding 'id' in the query.",
|
|
100
|
+
"For multiple values, use the in operator and pass the values in an array",
|
|
101
|
+
"For in operator make use of [] these brackets to pass the values",
|
|
102
|
+
"Projects are organization-scoped, so queries automatically filter by your organization.",
|
|
103
|
+
"Example queries: \"name = 'MyProject'\", \"name contains 'API'\", \"createdByUser = 'user-id' AND updated_at > '2024-01-01'\"",
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const instructions = instructionTemplates[entity] || {
|
|
108
|
+
usage: `Use this schema to understand available fields, operators, and valid values when querying ${entity}.`,
|
|
109
|
+
important: [
|
|
110
|
+
"Always use field names (not labels) in queries.",
|
|
111
|
+
"For association fields, use the 'id' from the values array.",
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
return jsonResponse({
|
|
115
|
+
success: response.success,
|
|
116
|
+
message: response.message,
|
|
117
|
+
data: response.data,
|
|
118
|
+
instructions,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const errorMessage = error.message || "Unknown error";
|
|
123
|
+
throw new Error(`Failed to fetch query schema: ${errorMessage}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=query-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-tools.js","sourceRoot":"","sources":["../../src/tools/query-tools.ts"],"names":[],"mappings":"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"}
|