@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.
Files changed (97) hide show
  1. package/LICENSE +23 -0
  2. package/QUICK_INSTALL.md +133 -0
  3. package/README.md +226 -0
  4. package/TOOLS_DOCUMENTATION.md +675 -0
  5. package/dist/__tests__/tools/module-tools.test.d.ts +2 -0
  6. package/dist/__tests__/tools/module-tools.test.d.ts.map +1 -0
  7. package/dist/__tests__/tools/module-tools.test.js +145 -0
  8. package/dist/__tests__/tools/module-tools.test.js.map +1 -0
  9. package/dist/__tests__/tools/project-tools.test.d.ts +2 -0
  10. package/dist/__tests__/tools/project-tools.test.d.ts.map +1 -0
  11. package/dist/__tests__/tools/project-tools.test.js +674 -0
  12. package/dist/__tests__/tools/project-tools.test.js.map +1 -0
  13. package/dist/__tests__/tools/query-tools.test.d.ts +2 -0
  14. package/dist/__tests__/tools/query-tools.test.d.ts.map +1 -0
  15. package/dist/__tests__/tools/query-tools.test.js +225 -0
  16. package/dist/__tests__/tools/query-tools.test.js.map +1 -0
  17. package/dist/__tests__/tools/testgroup-launch-tools.test.d.ts +2 -0
  18. package/dist/__tests__/tools/testgroup-launch-tools.test.d.ts.map +1 -0
  19. package/dist/__tests__/tools/testgroup-launch-tools.test.js +553 -0
  20. package/dist/__tests__/tools/testgroup-launch-tools.test.js.map +1 -0
  21. package/dist/__tests__/utils/mcp-error-mapper.test.d.ts +2 -0
  22. package/dist/__tests__/utils/mcp-error-mapper.test.d.ts.map +1 -0
  23. package/dist/__tests__/utils/mcp-error-mapper.test.js +240 -0
  24. package/dist/__tests__/utils/mcp-error-mapper.test.js.map +1 -0
  25. package/dist/__tests__/utils/mcp-response.test.d.ts +2 -0
  26. package/dist/__tests__/utils/mcp-response.test.d.ts.map +1 -0
  27. package/dist/__tests__/utils/mcp-response.test.js +72 -0
  28. package/dist/__tests__/utils/mcp-response.test.js.map +1 -0
  29. package/dist/agents/test-planner-context.d.ts +7 -0
  30. package/dist/agents/test-planner-context.d.ts.map +1 -0
  31. package/dist/agents/test-planner-context.js +283 -0
  32. package/dist/agents/test-planner-context.js.map +1 -0
  33. package/dist/agents/test-planner-prompt.d.ts +34 -0
  34. package/dist/agents/test-planner-prompt.d.ts.map +1 -0
  35. package/dist/agents/test-planner-prompt.js +82 -0
  36. package/dist/agents/test-planner-prompt.js.map +1 -0
  37. package/dist/api-client.d.ts +52 -0
  38. package/dist/api-client.d.ts.map +1 -0
  39. package/dist/api-client.js +285 -0
  40. package/dist/api-client.js.map +1 -0
  41. package/dist/constants.d.ts +7 -0
  42. package/dist/constants.d.ts.map +1 -0
  43. package/dist/constants.js +7 -0
  44. package/dist/constants.js.map +1 -0
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +175 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/services/project-context-service.d.ts +15 -0
  50. package/dist/services/project-context-service.d.ts.map +1 -0
  51. package/dist/services/project-context-service.js +36 -0
  52. package/dist/services/project-context-service.js.map +1 -0
  53. package/dist/tools/auth-tools.d.ts +16 -0
  54. package/dist/tools/auth-tools.d.ts.map +1 -0
  55. package/dist/tools/auth-tools.js +66 -0
  56. package/dist/tools/auth-tools.js.map +1 -0
  57. package/dist/tools/automation-tools.d.ts +28 -0
  58. package/dist/tools/automation-tools.d.ts.map +1 -0
  59. package/dist/tools/automation-tools.js +541 -0
  60. package/dist/tools/automation-tools.js.map +1 -0
  61. package/dist/tools/export-import-tools.d.ts +18 -0
  62. package/dist/tools/export-import-tools.d.ts.map +1 -0
  63. package/dist/tools/export-import-tools.js +61 -0
  64. package/dist/tools/export-import-tools.js.map +1 -0
  65. package/dist/tools/module-tools.d.ts +43 -0
  66. package/dist/tools/module-tools.d.ts.map +1 -0
  67. package/dist/tools/module-tools.js +289 -0
  68. package/dist/tools/module-tools.js.map +1 -0
  69. package/dist/tools/project-context-tools.d.ts +19 -0
  70. package/dist/tools/project-context-tools.d.ts.map +1 -0
  71. package/dist/tools/project-context-tools.js +133 -0
  72. package/dist/tools/project-context-tools.js.map +1 -0
  73. package/dist/tools/project-tools.d.ts +47 -0
  74. package/dist/tools/project-tools.d.ts.map +1 -0
  75. package/dist/tools/project-tools.js +362 -0
  76. package/dist/tools/project-tools.js.map +1 -0
  77. package/dist/tools/query-tools.d.ts +22 -0
  78. package/dist/tools/query-tools.d.ts.map +1 -0
  79. package/dist/tools/query-tools.js +127 -0
  80. package/dist/tools/query-tools.js.map +1 -0
  81. package/dist/tools/testcase-tools.d.ts +135 -0
  82. package/dist/tools/testcase-tools.d.ts.map +1 -0
  83. package/dist/tools/testcase-tools.js +845 -0
  84. package/dist/tools/testcase-tools.js.map +1 -0
  85. package/dist/tools/testgroup-launch-tools.d.ts +37 -0
  86. package/dist/tools/testgroup-launch-tools.d.ts.map +1 -0
  87. package/dist/tools/testgroup-launch-tools.js +727 -0
  88. package/dist/tools/testgroup-launch-tools.js.map +1 -0
  89. package/dist/utils/mcp-error-mapper.d.ts +27 -0
  90. package/dist/utils/mcp-error-mapper.d.ts.map +1 -0
  91. package/dist/utils/mcp-error-mapper.js +79 -0
  92. package/dist/utils/mcp-error-mapper.js.map +1 -0
  93. package/dist/utils/mcp-response.d.ts +26 -0
  94. package/dist/utils/mcp-response.d.ts.map +1 -0
  95. package/dist/utils/mcp-response.js +34 -0
  96. package/dist/utils/mcp-response.js.map +1 -0
  97. package/package.json +60 -0
@@ -0,0 +1,285 @@
1
+ import axios from "axios";
2
+ import { CookieJar } from "tough-cookie";
3
+ import { wrapper } from "axios-cookiejar-support";
4
+ import { API_URL, API_KEY } from "./constants.js";
5
+ export class ApiClient {
6
+ client;
7
+ loginClient; // Separate client for login to bypass interceptor
8
+ projectId;
9
+ cookieJar;
10
+ isAuthenticated = false;
11
+ userId; // Store user ID after login
12
+ /** When set, 401 responses trigger one retry via apiTokenLogin then re-request */
13
+ apiToken;
14
+ constructor(baseUrl, apiKey) {
15
+ this.apiToken = apiKey; // API token for api-token-login
16
+ this.cookieJar = new CookieJar();
17
+ // Use API root for all requests so paths like /project/getProjects resolve to /api/project/getProjects.
18
+ // If baseUrl is the auth path (e.g. .../api/auth), normalize to .../api.
19
+ const baseURL = baseUrl.replace(/\/auth\/?$/, "") || baseUrl;
20
+ // Create axios instance with cookie jar support (session cookies set by apiTokenLogin)
21
+ const baseAxiosConfig = {
22
+ baseURL,
23
+ timeout: 30000,
24
+ jar: this.cookieJar,
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ },
28
+ withCredentials: true, // Important for session-based auth
29
+ };
30
+ this.client = wrapper(axios.create(baseAxiosConfig));
31
+ // Create a separate client for login that doesn't have the error interceptor
32
+ // Login returns 403 for invalid credentials, which the interceptor would convert to "Permission denied"
33
+ this.loginClient = wrapper(axios.create(baseAxiosConfig));
34
+ // Helper function to get XSRF-TOKEN from cookie jar
35
+ const getXSRFToken = async (requestUrl) => {
36
+ try {
37
+ // Try multiple URL formats to find the cookie
38
+ const urlsToTry = [];
39
+ if (requestUrl) {
40
+ urlsToTry.push(requestUrl);
41
+ }
42
+ // Add base URL variations
43
+ urlsToTry.push(baseURL);
44
+ // Try protocol + host only
45
+ try {
46
+ const urlObj = new URL(baseURL);
47
+ urlsToTry.push(`${urlObj.protocol}//${urlObj.host}`);
48
+ urlsToTry.push(`${urlObj.protocol}//${urlObj.host}/`);
49
+ }
50
+ catch (e) {
51
+ // Ignore URL parsing errors
52
+ }
53
+ // Try each URL until we find the cookie
54
+ for (const url of urlsToTry) {
55
+ try {
56
+ const cookies = await this.cookieJar.getCookies(url);
57
+ const xsrfCookie = cookies.find((cookie) => cookie.key.toLowerCase() === "xsrf-token");
58
+ if (xsrfCookie) {
59
+ return xsrfCookie.value;
60
+ }
61
+ }
62
+ catch (e) {
63
+ // Continue to next URL
64
+ continue;
65
+ }
66
+ }
67
+ return undefined;
68
+ }
69
+ catch (error) {
70
+ return undefined;
71
+ }
72
+ };
73
+ // Request interceptor to add XSRF-TOKEN header and handle project ID
74
+ const requestInterceptor = async (config) => {
75
+ // Ensure headers object exists
76
+ if (!config.headers) {
77
+ config.headers = {};
78
+ }
79
+ // For POST/PUT/DELETE/PATCH requests, ensure CSRF token is available
80
+ const method = config.method?.toLowerCase();
81
+ if (method && !['get', 'head', 'options'].includes(method)) {
82
+ const requestUrl = config.url ? `${config.baseURL || baseURL}${config.url}` : baseURL;
83
+ let xsrfToken = await getXSRFToken(requestUrl);
84
+ if (!xsrfToken) {
85
+ try {
86
+ await this.client.get("/healthcheck");
87
+ await new Promise(resolve => setTimeout(resolve, 100));
88
+ xsrfToken = await getXSRFToken(requestUrl);
89
+ if (!xsrfToken) {
90
+ xsrfToken = await getXSRFToken(baseURL);
91
+ }
92
+ }
93
+ catch (e) {
94
+ // Ignore healthcheck errors
95
+ }
96
+ }
97
+ if (xsrfToken) {
98
+ config.headers["X-CSRF-Token"] = xsrfToken;
99
+ }
100
+ else {
101
+ console.warn(`[ApiClient] CSRF token not found for ${method.toUpperCase()} ${config.url}. Request may fail with CSRF_TOKEN_MISSING error.`);
102
+ }
103
+ }
104
+ else {
105
+ // For GET requests, try to get token but don't require it
106
+ const requestUrl = config.url ? `${config.baseURL || baseURL}${config.url}` : baseURL;
107
+ const xsrfToken = await getXSRFToken(requestUrl);
108
+ if (xsrfToken) {
109
+ config.headers["X-CSRF-Token"] = xsrfToken;
110
+ }
111
+ }
112
+ // Check if x-project-id was explicitly set to null/undefined to remove it
113
+ if (config.headers["x-project-id"] === null || config.headers["x-project-id"] === undefined) {
114
+ delete config.headers["x-project-id"];
115
+ }
116
+ else if (this.projectId && !config.headers["x-project-id"]) {
117
+ // Only add project ID if it's not already set and projectId is configured
118
+ config.headers["x-project-id"] = this.projectId;
119
+ }
120
+ return config;
121
+ };
122
+ // Add request interceptor to both clients
123
+ this.client.interceptors.request.use(requestInterceptor);
124
+ this.loginClient.interceptors.request.use(requestInterceptor);
125
+ // Add response interceptor for error handling
126
+ this.client.interceptors.response.use((response) => response, (error) => {
127
+ if (error.response) {
128
+ const status = error.response.status;
129
+ const data = error.response.data;
130
+ let errorMessage;
131
+ if (status === 401) {
132
+ // One-time retry via api-token-login when API token is configured
133
+ const config = error.config;
134
+ if (this.apiToken && config && !config._401Retried) {
135
+ config._401Retried = true;
136
+ return this.apiTokenLogin(this.apiToken)
137
+ .then(() => this.client.request(config))
138
+ .catch(() => {
139
+ throw new Error("Authentication failed. Please check your API key (QA_PATH_API_KEY).");
140
+ });
141
+ }
142
+ throw new Error("Authentication failed. Please check your API key (QA_PATH_API_KEY).");
143
+ }
144
+ if (status === 403) {
145
+ errorMessage = `Permission denied: ${data?.message || "You don't have permission to perform this action"}`;
146
+ }
147
+ else if (status === 404) {
148
+ errorMessage = `Resource not found: ${data?.message || "The requested resource does not exist"}`;
149
+ }
150
+ else if (status >= 500) {
151
+ errorMessage = `Server error: ${data?.error || data?.message || "An internal server error occurred"}`;
152
+ }
153
+ else {
154
+ errorMessage = data?.error || data?.message || `Request failed with status ${status}`;
155
+ }
156
+ // Create error and attach original axios error structure
157
+ // This allows error mappers to extract status code and response data
158
+ const customError = new Error(errorMessage);
159
+ customError.response = error.response;
160
+ customError.status = status;
161
+ throw customError;
162
+ }
163
+ if (error.request) {
164
+ throw new Error(`Network error: Unable to connect to the API server. Please check your ${API_URL} and check.`);
165
+ }
166
+ throw error;
167
+ });
168
+ }
169
+ setProjectId(projectId) {
170
+ this.projectId = projectId;
171
+ this.client.defaults.headers["x-project-id"] = projectId;
172
+ }
173
+ getProjectId() {
174
+ return this.projectId;
175
+ }
176
+ /**
177
+ * Log in using an API token (POST /api/auth/api-token-login).
178
+ * Session cookies are stored in the cookie jar; subsequent requests use them.
179
+ */
180
+ async apiTokenLogin(token) {
181
+ const t = token?.trim();
182
+ if (!t) {
183
+ this.isAuthenticated = false;
184
+ throw new Error("API token is required for api-token-login.");
185
+ }
186
+ try {
187
+ const baseURL = this.loginClient.defaults.baseURL;
188
+ const origin = new URL(baseURL).origin;
189
+ await this.loginClient.get(`${origin}/api/healthcheck`);
190
+ const response = await this.loginClient.post("auth/api-token-login", undefined, {
191
+ headers: {
192
+ Authorization: `Bearer ${t}`,
193
+ },
194
+ });
195
+ this.isAuthenticated = true;
196
+ this.userId = response.data.data?.user?.id;
197
+ return response.data;
198
+ }
199
+ catch (error) {
200
+ this.isAuthenticated = false;
201
+ if (error.response) {
202
+ const status = error.response.status;
203
+ const data = error.response.data;
204
+ if (status === 401) {
205
+ throw new Error(data?.message || `Invalid or expired token. Please check ${API_KEY}.`);
206
+ }
207
+ throw new Error(data?.message || data?.error || `api-token-login failed with status ${status}`);
208
+ }
209
+ throw error;
210
+ }
211
+ }
212
+ getIsAuthenticated() {
213
+ return this.isAuthenticated;
214
+ }
215
+ /**
216
+ * Get cookie header string for a given URL (and optionally the API base URL).
217
+ * Used to forward session cookies to the automation agent WebSocket.
218
+ */
219
+ async getCookieStringForUrl(url) {
220
+ const urlsToTry = [url];
221
+ const baseUrl = this.client.defaults.baseURL;
222
+ if (baseUrl && !urlsToTry.includes(baseUrl)) {
223
+ urlsToTry.push(baseUrl);
224
+ try {
225
+ const u = new URL(baseUrl);
226
+ urlsToTry.push(`${u.protocol}//${u.host}`);
227
+ }
228
+ catch (_) { }
229
+ }
230
+ const seen = new Set();
231
+ const parts = [];
232
+ for (const u of urlsToTry) {
233
+ try {
234
+ const cookies = await this.cookieJar.getCookies(u);
235
+ if (Array.isArray(cookies)) {
236
+ for (const c of cookies) {
237
+ if (c && typeof c.key === "string" && !seen.has(c.key)) {
238
+ seen.add(c.key);
239
+ parts.push(`${c.key}=${c.value || ""}`);
240
+ }
241
+ }
242
+ }
243
+ }
244
+ catch (_) {
245
+ continue;
246
+ }
247
+ }
248
+ return parts.join("; ");
249
+ }
250
+ getUserId() {
251
+ return this.userId;
252
+ }
253
+ async get(url, config) {
254
+ const response = await this.client.get(url, config);
255
+ return response.data;
256
+ }
257
+ async post(url, data, config) {
258
+ const response = await this.client.post(url, data, config);
259
+ return response.data;
260
+ }
261
+ async put(url, data, config) {
262
+ const response = await this.client.put(url, data, config);
263
+ return response.data;
264
+ }
265
+ async patch(url, data, config) {
266
+ const response = await this.client.patch(url, data, config);
267
+ return response.data;
268
+ }
269
+ async delete(url, config) {
270
+ const response = await this.client.delete(url, config);
271
+ return response.data;
272
+ }
273
+ // Helper for file uploads
274
+ async postFormData(url, formData, config) {
275
+ const response = await this.client.post(url, formData, {
276
+ ...config,
277
+ headers: {
278
+ ...config?.headers,
279
+ "Content-Type": "multipart/form-data",
280
+ },
281
+ });
282
+ return response.data;
283
+ }
284
+ }
285
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Environment variable names for QA Path MCP server.
3
+ * Only the required/primary vars are centralized; optional ones are inlined where used.
4
+ */
5
+ export declare const API_URL: string;
6
+ export declare const API_KEY: string | undefined;
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,OAAO,QAAkE,CAAC;AAEvF,eAAO,MAAM,OAAO,oBAA8B,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Environment variable names for QA Path MCP server.
3
+ * Only the required/primary vars are centralized; optional ones are inlined where used.
4
+ */
5
+ export const API_URL = process.env.QA_PATH_API_URL || "http://localhost:3000/api/auth";
6
+ export const API_KEY = process.env.QA_PATH_API_KEY;
7
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gCAAgC,CAAC;AAEvF,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import { ApiClient } from "./api-client.js";
6
+ import { getTestPlannerPromptDefinition, getTestPlannerMessages, X_TEST_PLANNER_NAME, } from "./agents/test-planner-prompt.js";
7
+ import { ModuleTools } from "./tools/module-tools.js";
8
+ import { TestCaseTools } from "./tools/testcase-tools.js";
9
+ import { ExportImportTools } from "./tools/export-import-tools.js";
10
+ import { ProjectTools } from "./tools/project-tools.js";
11
+ import { AuthTools } from "./tools/auth-tools.js";
12
+ import { AutomationTools } from "./tools/automation-tools.js";
13
+ import { TestGroupLaunchTools } from "./tools/testgroup-launch-tools.js";
14
+ import { QueryTools } from "./tools/query-tools.js";
15
+ import { ProjectContextTools } from "./tools/project-context-tools.js";
16
+ import { ProjectContextService } from "./services/project-context-service.js";
17
+ import { API_URL, API_KEY } from "./constants.js";
18
+ class QAPathServer {
19
+ server;
20
+ apiClient;
21
+ projectContext;
22
+ moduleTools;
23
+ testCaseTools;
24
+ exportImportTools;
25
+ projectTools;
26
+ authTools;
27
+ automationTools;
28
+ testGroupLaunchTools;
29
+ queryTools;
30
+ projectContextTools;
31
+ apiKey;
32
+ constructor() {
33
+ this.server = new Server({
34
+ name: "qa-path",
35
+ version: "1.0.0",
36
+ }, {
37
+ capabilities: {
38
+ tools: {},
39
+ resources: {},
40
+ prompts: {},
41
+ },
42
+ });
43
+ const apiBaseUrl = API_URL;
44
+ this.apiKey = API_KEY;
45
+ if (!apiBaseUrl) {
46
+ throw new Error(`${API_URL} environment variable is required`);
47
+ }
48
+ // Initialize API client (project will be set via set_active_project or QA_PATH_PROJECT_ID)
49
+ this.apiClient = new ApiClient(apiBaseUrl, this.apiKey);
50
+ // Initialize project context service
51
+ this.projectContext = new ProjectContextService();
52
+ // Initialize tools (pass projectContext to tools that need it)
53
+ this.projectContextTools = new ProjectContextTools(this.apiClient, this.projectContext);
54
+ this.moduleTools = new ModuleTools(this.apiClient, this.projectContext);
55
+ this.testCaseTools = new TestCaseTools(this.apiClient, this.projectContext);
56
+ this.exportImportTools = new ExportImportTools(this.apiClient, this.projectContext);
57
+ this.projectTools = new ProjectTools(this.apiClient);
58
+ this.authTools = new AuthTools(this.apiClient);
59
+ this.automationTools = new AutomationTools(this.apiClient, this.projectContext);
60
+ this.testGroupLaunchTools = new TestGroupLaunchTools(this.apiClient, this.projectContext);
61
+ this.queryTools = new QueryTools(this.apiClient, this.projectContext);
62
+ this.setupHandlers();
63
+ }
64
+ setupHandlers() {
65
+ // List available tools
66
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
67
+ return {
68
+ tools: [
69
+ ...this.authTools.getTools(),
70
+ ...this.projectContextTools.getTools(),
71
+ ...this.moduleTools.getTools(),
72
+ ...this.testCaseTools.getTools(),
73
+ // ...this.exportImportTools.getTools(), // export tool commented out
74
+ ...this.projectTools.getTools(),
75
+ ...this.automationTools.getTools(),
76
+ ...this.testGroupLaunchTools.getTools(),
77
+ ...this.queryTools.getTools(),
78
+ ],
79
+ };
80
+ });
81
+ // Handle tool calls
82
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
83
+ const { name, arguments: args } = request.params;
84
+ try {
85
+ // Route to appropriate tool handler
86
+ if (this.authTools.handles(name)) {
87
+ return await this.authTools.handle(name, args);
88
+ }
89
+ if (this.projectContextTools.handles(name)) {
90
+ return await this.projectContextTools.handle(name, args);
91
+ }
92
+ if (this.moduleTools.handles(name)) {
93
+ return await this.moduleTools.handle(name, args);
94
+ }
95
+ if (this.testCaseTools.handles(name)) {
96
+ return await this.testCaseTools.handle(name, args);
97
+ }
98
+ // if (this.exportImportTools.handles(name)) {
99
+ // return await this.exportImportTools.handle(name, args);
100
+ // }
101
+ if (this.projectTools.handles(name)) {
102
+ return await this.projectTools.handle(name, args);
103
+ }
104
+ if (this.automationTools.handles(name)) {
105
+ return await this.automationTools.handle(name, args);
106
+ }
107
+ if (this.testGroupLaunchTools.handles(name)) {
108
+ return await this.testGroupLaunchTools.handle(name, args);
109
+ }
110
+ if (this.queryTools.handles(name)) {
111
+ return await this.queryTools.handle(name, args);
112
+ }
113
+ throw new Error(`Unknown tool: ${name}`);
114
+ }
115
+ catch (error) {
116
+ // Format error message to be more actionable for AI
117
+ const errorMessage = error.message || String(error);
118
+ // If error contains ACTION_REQUIRED or WORKFLOW markers, preserve them
119
+ // These help the AI understand what steps to take
120
+ const formattedError = errorMessage.includes("ACTION_REQUIRED") || errorMessage.includes("WORKFLOW")
121
+ ? errorMessage
122
+ : `Error: ${errorMessage}`;
123
+ return {
124
+ content: [
125
+ {
126
+ type: "text",
127
+ text: formattedError,
128
+ },
129
+ ],
130
+ isError: true,
131
+ };
132
+ }
133
+ });
134
+ // List resources (optional - for future use)
135
+ this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
136
+ return {
137
+ resources: [],
138
+ };
139
+ });
140
+ // List prompts (x-test-planner agent)
141
+ this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
142
+ return {
143
+ prompts: [getTestPlannerPromptDefinition()],
144
+ };
145
+ });
146
+ // Get prompt (x-test-planner agent)
147
+ this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
148
+ const { name, arguments: args } = request.params;
149
+ if (name !== X_TEST_PLANNER_NAME) {
150
+ throw new Error(`Unknown prompt: ${name}`);
151
+ }
152
+ return getTestPlannerMessages(args);
153
+ });
154
+ }
155
+ async ensureAuth() {
156
+ if (!this.apiKey?.trim()) {
157
+ throw new Error(`${API_KEY} is required.`);
158
+ }
159
+ await this.apiClient.apiTokenLogin(this.apiKey);
160
+ console.error("QA-Path: API token login successful");
161
+ }
162
+ async run() {
163
+ await this.ensureAuth();
164
+ const transport = new StdioServerTransport();
165
+ await this.server.connect(transport);
166
+ console.error("QA-Path server running on stdio");
167
+ }
168
+ }
169
+ // Start the server
170
+ const server = new QAPathServer();
171
+ server.run().catch((error) => {
172
+ console.error("Fatal error in QA-Path server:", error);
173
+ process.exit(1);
174
+ });
175
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Service for managing active project context
3
+ * Maintains the active project ID that persists for the lifetime of the MCP server process
4
+ */
5
+ export declare class ProjectContextService {
6
+ private activeProjectId?;
7
+ setActiveProjectId(projectId: string): void;
8
+ getActiveProjectId(): string | undefined;
9
+ /**
10
+ * Resolve project ID from args or active project
11
+ * Throws error if neither is available with actionable guidance for the AI
12
+ */
13
+ resolveProjectId(args: any, toolName: string): string;
14
+ }
15
+ //# sourceMappingURL=project-context-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-service.d.ts","sourceRoot":"","sources":["../../src/services/project-context-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,eAAe,CAAC,CAAS;IAEjC,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI3C,kBAAkB,IAAI,MAAM,GAAG,SAAS;IAIxC;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAuBtD"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Service for managing active project context
3
+ * Maintains the active project ID that persists for the lifetime of the MCP server process
4
+ */
5
+ export class ProjectContextService {
6
+ activeProjectId;
7
+ setActiveProjectId(projectId) {
8
+ this.activeProjectId = projectId;
9
+ }
10
+ getActiveProjectId() {
11
+ return this.activeProjectId;
12
+ }
13
+ /**
14
+ * Resolve project ID from args or active project
15
+ * Throws error if neither is available with actionable guidance for the AI
16
+ */
17
+ resolveProjectId(args, toolName) {
18
+ const argProjectId = args?.projectId;
19
+ const activeProjectId = this.activeProjectId;
20
+ if (argProjectId) {
21
+ return argProjectId; // Explicit projectId takes precedence
22
+ }
23
+ if (activeProjectId) {
24
+ return activeProjectId; // Use active project
25
+ }
26
+ // Enhanced error message that guides the AI to ask the user
27
+ throw new Error(`PROJECT_ID_REQUIRED: A project ID is required to use ${toolName}. ` +
28
+ `ACTION_REQUIRED: You need to either:\n` +
29
+ `1. Ask the user which project they want to use, then call 'list_projects' to show available projects, ` +
30
+ ` and once the user selects a project (by name), extract the projectId (UUID) from the list_projects response ` +
31
+ ` and call 'set_active_project' with that projectId, OR\n` +
32
+ `2. If the user provides a projectId (UUID) directly, use it as the 'projectId' parameter in this tool call.\n` +
33
+ `WORKFLOW: The recommended flow is: list_projects → ask user to select (by name) → extract projectId from response → set_active_project → retry original operation.`);
34
+ }
35
+ }
36
+ //# sourceMappingURL=project-context-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-service.js","sourceRoot":"","sources":["../../src/services/project-context-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IACxB,eAAe,CAAU;IAEjC,kBAAkB,CAAC,SAAiB;QAClC,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;IACnC,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,gBAAgB,CAAC,IAAS,EAAE,QAAgB;QAC1C,MAAM,YAAY,GAAG,IAAI,EAAE,SAAS,CAAC;QACrC,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QAE7C,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,YAAY,CAAC,CAAC,sCAAsC;QAC7D,CAAC;QAED,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC,CAAC,qBAAqB;QAC/C,CAAC;QAED,4DAA4D;QAC5D,MAAM,IAAI,KAAK,CACb,wDAAwD,QAAQ,IAAI;YACpE,wCAAwC;YACxC,wGAAwG;YACxG,iHAAiH;YACjH,4DAA4D;YAC5D,+GAA+G;YAC/G,oKAAoK,CACrK,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import { Tool } from "@modelcontextprotocol/sdk/types.js";
2
+ import { ApiClient } from "../api-client.js";
3
+ export declare class AuthTools {
4
+ private apiClient;
5
+ constructor(apiClient: ApiClient);
6
+ getTools(): Tool[];
7
+ handles(name: string): boolean;
8
+ handle(name: string, args: any): Promise<{
9
+ content: {
10
+ type: "text";
11
+ text: string;
12
+ }[];
13
+ }>;
14
+ private checkAuthStatus;
15
+ }
16
+ //# sourceMappingURL=auth-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-tools.d.ts","sourceRoot":"","sources":["../../src/tools/auth-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAI7C,qBAAa,SAAS;IACR,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC,QAAQ,IAAI,IAAI,EAAE;IAclB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG;;;;;;YAOtB,eAAe;CAoD9B"}