zephyr-enterprise-tools 1.0.5 → 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.
Files changed (4) hide show
  1. package/README.md +27 -43
  2. package/cli.js +12 -1
  3. package/mcp-server.js +345 -0
  4. package/package.json +10 -3
package/README.md CHANGED
@@ -46,18 +46,32 @@ Set environment variables:
46
46
 
47
47
  ```bash
48
48
  export ZEPHYR_BASE_URL="https://your-zephyr.com/flex/services/rest/latest"
49
- export ZEPHYR_USERNAME="your-username"
50
- export ZEPHYR_PASSWORD="your-password"
51
-
52
- # Or use a bearer token instead:
53
- export ZEPHYR_TOKEN="your-token"
49
+ export ZEPHYR_TOKEN="your-api-token"
54
50
  ```
55
51
 
56
52
  ---
57
53
 
58
54
  ## 🤖 MCP Integration
59
55
 
60
- Use zephyr-enterprise-tools as an MCP (Model Context Protocol) server with your AI assistant.
56
+ Use zephyr-enterprise-tools as an MCP (Model Context Protocol) server with your AI assistant. The server only requires `ZEPHYR_BASE_URL` and `ZEPHYR_TOKEN` at startup - **Project ID and Release ID are passed as parameters when calling each tool**.
57
+
58
+ ### Available MCP Tools
59
+
60
+ | Tool | Description |
61
+ |------|-------------|
62
+ | `list_projects` | List all Zephyr projects (no parameters needed) |
63
+ | `list_releases` | List releases for a project (requires projectId) |
64
+ | `release_readiness` | Run all 4 quality gates |
65
+ | `requirement_coverage` | Check requirement coverage |
66
+ | `test_plan_analysis` | Analyze test planning status |
67
+ | `test_execution` | Check test execution progress |
68
+ | `defect_quality` | Analyze defect status |
69
+ | `project_health` | Get project health score |
70
+ | `test_coverage` | Get test coverage details |
71
+ | `failed_tests` | List failed tests |
72
+ | `test_trends` | Get execution trends over time |
73
+ | `search_test_cases` | Search test cases by query |
74
+ | `user_activity` | Get user activity metrics |
61
75
 
62
76
  ### VS Code with GitHub Copilot
63
77
 
@@ -69,14 +83,9 @@ Create or edit `.vscode/mcp.json` in your workspace:
69
83
  "zephyr-enterprise": {
70
84
  "type": "stdio",
71
85
  "command": "npx",
72
- "args": [
73
- "-y",
74
- "zephyr-enterprise-tools@latest"
75
- ],
86
+ "args": ["-y", "zephyr-enterprise-tools@latest", "mcp"],
76
87
  "env": {
77
88
  "ZEPHYR_BASE_URL": "${input:zephyr_base_url}",
78
- "ZEPHYR_USERNAME": "${input:zephyr_username}",
79
- "ZEPHYR_PASSWORD": "${input:zephyr_password}",
80
89
  "ZEPHYR_TOKEN": "${input:zephyr_token}"
81
90
  }
82
91
  }
@@ -88,22 +97,10 @@ Create or edit `.vscode/mcp.json` in your workspace:
88
97
  "description": "Zephyr Enterprise API Base URL (e.g. https://your-zephyr.com/flex/services/rest/latest)",
89
98
  "password": false
90
99
  },
91
- {
92
- "id": "zephyr_username",
93
- "type": "promptString",
94
- "description": "Zephyr Enterprise Username (for Basic Auth)",
95
- "password": false
96
- },
97
- {
98
- "id": "zephyr_password",
99
- "type": "promptString",
100
- "description": "Zephyr Enterprise Password (for Basic Auth)",
101
- "password": true
102
- },
103
100
  {
104
101
  "id": "zephyr_token",
105
102
  "type": "promptString",
106
- "description": "Zephyr Enterprise Bearer Token (alternative to username/password)",
103
+ "description": "Zephyr Enterprise API Token",
107
104
  "password": true
108
105
  }
109
106
  ]
@@ -119,15 +116,10 @@ Add to your `mcp.json` configuration:
119
116
  "mcpServers": {
120
117
  "zephyr-enterprise": {
121
118
  "command": "npx",
122
- "args": [
123
- "-y",
124
- "zephyr-enterprise-tools@latest"
125
- ],
119
+ "args": ["-y", "zephyr-enterprise-tools@latest", "mcp"],
126
120
  "env": {
127
121
  "ZEPHYR_BASE_URL": "https://your-zephyr.com/flex/services/rest/latest",
128
- "ZEPHYR_USERNAME": "your-username",
129
- "ZEPHYR_PASSWORD": "your-password",
130
- "ZEPHYR_TOKEN": "your-token"
122
+ "ZEPHYR_TOKEN": "your-api-token"
131
123
  }
132
124
  }
133
125
  }
@@ -143,23 +135,16 @@ Edit your `claude_desktop_config.json` file:
143
135
  "mcpServers": {
144
136
  "zephyr-enterprise": {
145
137
  "command": "npx",
146
- "args": [
147
- "-y",
148
- "zephyr-enterprise-tools@latest"
149
- ],
138
+ "args": ["-y", "zephyr-enterprise-tools@latest", "mcp"],
150
139
  "env": {
151
140
  "ZEPHYR_BASE_URL": "https://your-zephyr.com/flex/services/rest/latest",
152
- "ZEPHYR_USERNAME": "your-username",
153
- "ZEPHYR_PASSWORD": "your-password",
154
- "ZEPHYR_TOKEN": "your-token"
141
+ "ZEPHYR_TOKEN": "your-api-token"
155
142
  }
156
143
  }
157
144
  }
158
145
  }
159
146
  ```
160
147
 
161
- > **Note:** Use either `ZEPHYR_USERNAME` + `ZEPHYR_PASSWORD` for Basic Auth, or `ZEPHYR_TOKEN` for Bearer token authentication.
162
-
163
148
  ---
164
149
 
165
150
  ## 🖥️ CLI Usage
@@ -215,8 +200,7 @@ import QualityGates from 'zephyr-quality-gates';
215
200
 
216
201
  const tools = new QualityGates({
217
202
  baseUrl: 'https://your-zephyr.com/flex/services/rest/latest',
218
- username: 'user',
219
- password: 'pass',
203
+ token: 'your-api-token',
220
204
  });
221
205
 
222
206
  // ── Release Readiness ──────────────────────────────────────
package/cli.js CHANGED
@@ -12,9 +12,19 @@
12
12
  * zephyr-tools --project 364 --release 4312
13
13
  * zephyr-tools -p 364 -r 4312 -t project-health
14
14
  * zephyr-tools -p 364 -r 4312 -t search-tests -q "login"
15
+ * zephyr-tools mcp # Start MCP server
15
16
  */
16
17
 
17
- import QualityGates from './zephyr-enterprise-tools.js';
18
+ // Check if MCP server mode
19
+ if (process.argv[2] === 'mcp') {
20
+ import('./mcp-server.js');
21
+ } else {
22
+ // Normal CLI mode
23
+ runCLI();
24
+ }
25
+
26
+ async function runCLI() {
27
+ const { default: QualityGates } = await import('./zephyr-enterprise-tools.js');
18
28
 
19
29
  // ─── Parse Arguments ──────────────────────────────────────────────────────────
20
30
 
@@ -537,3 +547,4 @@ async function main() {
537
547
  }
538
548
 
539
549
  main();
550
+ } // end runCLI
package/mcp-server.js ADDED
@@ -0,0 +1,345 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Zephyr Enterprise MCP Server
5
+ *
6
+ * Model Context Protocol server for Zephyr Enterprise Tools.
7
+ * Exposes all tools with projectId and releaseId as runtime parameters.
8
+ */
9
+
10
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
11
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
12
+ import {
13
+ CallToolRequestSchema,
14
+ ListToolsRequestSchema,
15
+ } from '@modelcontextprotocol/sdk/types.js';
16
+ import QualityGates from './zephyr-enterprise-tools.js';
17
+
18
+ // ─── Tool Definitions ─────────────────────────────────────────────────────────
19
+
20
+ const TOOLS = [
21
+ {
22
+ name: 'release_readiness',
23
+ description: 'Run all 4 quality gates to assess release readiness. Returns GO, CONDITIONAL GO, or NO GO status.',
24
+ inputSchema: {
25
+ type: 'object',
26
+ properties: {
27
+ projectId: { type: 'number', description: 'Zephyr project ID' },
28
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
29
+ },
30
+ required: ['projectId', 'releaseId'],
31
+ },
32
+ },
33
+ {
34
+ name: 'requirement_coverage',
35
+ description: 'Check if requirements are covered by test cases. Threshold: ≥70% = GO.',
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ projectId: { type: 'number', description: 'Zephyr project ID' },
40
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
41
+ },
42
+ required: ['projectId', 'releaseId'],
43
+ },
44
+ },
45
+ {
46
+ name: 'test_plan_analysis',
47
+ description: 'Analyze test planning status. Threshold: <80% = NO GO, 80-90% = CONDITIONAL, ≥90% = GO.',
48
+ inputSchema: {
49
+ type: 'object',
50
+ properties: {
51
+ projectId: { type: 'number', description: 'Zephyr project ID' },
52
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
53
+ },
54
+ required: ['projectId', 'releaseId'],
55
+ },
56
+ },
57
+ {
58
+ name: 'test_execution',
59
+ description: 'Check test execution progress. Threshold: <90% = NO GO, 90-97% = CONDITIONAL, ≥97% = GO.',
60
+ inputSchema: {
61
+ type: 'object',
62
+ properties: {
63
+ projectId: { type: 'number', description: 'Zephyr project ID' },
64
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
65
+ },
66
+ required: ['projectId', 'releaseId'],
67
+ },
68
+ },
69
+ {
70
+ name: 'defect_quality',
71
+ description: 'Analyze defect status. Threshold: Blocker >0 = NO GO, High-risk >10 = NO GO.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ projectId: { type: 'number', description: 'Zephyr project ID' },
76
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
77
+ },
78
+ required: ['projectId', 'releaseId'],
79
+ },
80
+ },
81
+ {
82
+ name: 'project_health',
83
+ description: 'Get overall project health score (0-100) with metrics, team info, releases, and recommendations.',
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: {
87
+ projectId: { type: 'number', description: 'Zephyr project ID' },
88
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
89
+ },
90
+ required: ['projectId', 'releaseId'],
91
+ },
92
+ },
93
+ {
94
+ name: 'test_coverage',
95
+ description: 'Get detailed test coverage analysis including requirements and test case coverage.',
96
+ inputSchema: {
97
+ type: 'object',
98
+ properties: {
99
+ projectId: { type: 'number', description: 'Zephyr project ID' },
100
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
101
+ },
102
+ required: ['projectId', 'releaseId'],
103
+ },
104
+ },
105
+ {
106
+ name: 'failed_tests',
107
+ description: 'List and analyze failed test cases with details.',
108
+ inputSchema: {
109
+ type: 'object',
110
+ properties: {
111
+ projectId: { type: 'number', description: 'Zephyr project ID' },
112
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
113
+ limit: { type: 'number', description: 'Maximum number of failed tests to return (default: 50)' },
114
+ },
115
+ required: ['projectId', 'releaseId'],
116
+ },
117
+ },
118
+ {
119
+ name: 'requirement_coverage_details',
120
+ description: 'Get requirements with and without test coverage.',
121
+ inputSchema: {
122
+ type: 'object',
123
+ properties: {
124
+ projectId: { type: 'number', description: 'Zephyr project ID' },
125
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
126
+ },
127
+ required: ['projectId', 'releaseId'],
128
+ },
129
+ },
130
+ {
131
+ name: 'test_trends',
132
+ description: 'Get test execution trends over time (daily breakdown).',
133
+ inputSchema: {
134
+ type: 'object',
135
+ properties: {
136
+ projectId: { type: 'number', description: 'Zephyr project ID' },
137
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
138
+ days: { type: 'number', description: 'Number of days to analyze (default: 30)' },
139
+ },
140
+ required: ['projectId', 'releaseId'],
141
+ },
142
+ },
143
+ {
144
+ name: 'search_test_cases',
145
+ description: 'Search test cases by query string.',
146
+ inputSchema: {
147
+ type: 'object',
148
+ properties: {
149
+ projectId: { type: 'number', description: 'Zephyr project ID' },
150
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
151
+ query: { type: 'string', description: 'Search query string' },
152
+ limit: { type: 'number', description: 'Maximum results (default: 50)' },
153
+ },
154
+ required: ['projectId', 'releaseId'],
155
+ },
156
+ },
157
+ {
158
+ name: 'user_activity',
159
+ description: 'Get user activity and productivity metrics showing who is assigned and who executed tests.',
160
+ inputSchema: {
161
+ type: 'object',
162
+ properties: {
163
+ projectId: { type: 'number', description: 'Zephyr project ID' },
164
+ releaseId: { type: 'number', description: 'Zephyr release ID' },
165
+ days: { type: 'number', description: 'Number of days to analyze (default: 30)' },
166
+ },
167
+ required: ['projectId', 'releaseId'],
168
+ },
169
+ },
170
+ {
171
+ name: 'list_projects',
172
+ description: 'List all available Zephyr projects.',
173
+ inputSchema: {
174
+ type: 'object',
175
+ properties: {},
176
+ required: [],
177
+ },
178
+ },
179
+ {
180
+ name: 'list_releases',
181
+ description: 'List all releases for a project.',
182
+ inputSchema: {
183
+ type: 'object',
184
+ properties: {
185
+ projectId: { type: 'number', description: 'Zephyr project ID' },
186
+ },
187
+ required: ['projectId'],
188
+ },
189
+ },
190
+ ];
191
+
192
+ // ─── MCP Server ───────────────────────────────────────────────────────────────
193
+
194
+ const server = new Server(
195
+ {
196
+ name: 'zephyr-enterprise-tools',
197
+ version: '1.0.6',
198
+ },
199
+ {
200
+ capabilities: {
201
+ tools: {},
202
+ },
203
+ }
204
+ );
205
+
206
+ // Create QualityGates instance
207
+ let tools;
208
+ try {
209
+ tools = new QualityGates({
210
+ baseUrl: process.env.ZEPHYR_BASE_URL,
211
+ token: process.env.ZEPHYR_TOKEN,
212
+ });
213
+ } catch (err) {
214
+ console.error(`Configuration error: ${err.message}`);
215
+ process.exit(1);
216
+ }
217
+
218
+ // ─── List Tools Handler ───────────────────────────────────────────────────────
219
+
220
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
221
+ return { tools: TOOLS };
222
+ });
223
+
224
+ // ─── Call Tool Handler ────────────────────────────────────────────────────────
225
+
226
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
227
+ const { name, arguments: args } = request.params;
228
+
229
+ try {
230
+ let result;
231
+ const projectId = args.projectId;
232
+ const releaseId = args.releaseId;
233
+
234
+ switch (name) {
235
+ case 'release_readiness':
236
+ result = await tools.runAllGates(projectId, releaseId);
237
+ break;
238
+
239
+ case 'requirement_coverage':
240
+ result = await tools.requirementCoverageGate(projectId, releaseId);
241
+ break;
242
+
243
+ case 'test_plan_analysis':
244
+ result = await tools.testPlanAnalysisGate(projectId, releaseId);
245
+ break;
246
+
247
+ case 'test_execution':
248
+ result = await tools.testExecutionGate(projectId, releaseId);
249
+ break;
250
+
251
+ case 'defect_quality':
252
+ result = await tools.defectQualityGate(projectId, releaseId);
253
+ break;
254
+
255
+ case 'project_health':
256
+ result = await tools.getProjectHealth(projectId, releaseId);
257
+ break;
258
+
259
+ case 'test_coverage':
260
+ result = await tools.getTestCoverage(projectId, releaseId);
261
+ break;
262
+
263
+ case 'failed_tests':
264
+ result = await tools.getFailedTests(projectId, releaseId, { limit: args.limit || 50 });
265
+ break;
266
+
267
+ case 'requirement_coverage_details':
268
+ result = await tools.getRequirementCoverage(projectId, releaseId);
269
+ break;
270
+
271
+ case 'test_trends':
272
+ result = await tools.getTestCaseTrends(projectId, releaseId, { days: args.days || 30 });
273
+ break;
274
+
275
+ case 'search_test_cases':
276
+ result = await tools.searchTestCases(projectId, releaseId, {
277
+ query: args.query || '',
278
+ limit: args.limit || 50
279
+ });
280
+ break;
281
+
282
+ case 'user_activity':
283
+ result = await tools.getUserActivity(projectId, releaseId, { days: args.days || 30 });
284
+ break;
285
+
286
+ case 'list_projects':
287
+ const projects = await tools.GET('/project');
288
+ result = {
289
+ total: projects.length,
290
+ projects: projects.map(p => ({
291
+ id: p.id,
292
+ name: p.name,
293
+ description: p.description,
294
+ startDate: p.projectStartDate,
295
+ endDate: p.projectEndDate,
296
+ })),
297
+ };
298
+ break;
299
+
300
+ case 'list_releases':
301
+ const releases = await tools.GET('/release', { projectid: projectId, isaliasallowed: false });
302
+ const filtered = releases.filter(r => !r.projectRelease);
303
+ result = {
304
+ projectId,
305
+ total: filtered.length,
306
+ releases: filtered.map(r => ({
307
+ id: r.id,
308
+ name: r.name,
309
+ startDate: r.releaseStartDate,
310
+ endDate: r.releaseEndDate,
311
+ })),
312
+ };
313
+ break;
314
+
315
+ default:
316
+ return {
317
+ content: [{ type: 'text', text: `Unknown tool: ${name}` }],
318
+ isError: true,
319
+ };
320
+ }
321
+
322
+ return {
323
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
324
+ };
325
+
326
+ } catch (error) {
327
+ return {
328
+ content: [{ type: 'text', text: `Error: ${error.message}` }],
329
+ isError: true,
330
+ };
331
+ }
332
+ });
333
+
334
+ // ─── Start Server ─────────────────────────────────────────────────────────────
335
+
336
+ async function main() {
337
+ const transport = new StdioServerTransport();
338
+ await server.connect(transport);
339
+ console.error('Zephyr Enterprise MCP Server running on stdio');
340
+ }
341
+
342
+ main().catch((error) => {
343
+ console.error('Fatal error:', error);
344
+ process.exit(1);
345
+ });
package/package.json CHANGED
@@ -1,21 +1,27 @@
1
1
  {
2
2
  "name": "zephyr-enterprise-tools",
3
- "version": "1.0.5",
3
+ "version": "1.1.0",
4
4
  "description": "Comprehensive Zephyr Enterprise Tools - Release Readiness, Project Health, Test Analytics & More",
5
5
  "main": "zephyr-enterprise-tools.js",
6
6
  "exports": {
7
7
  ".": "./zephyr-enterprise-tools.js",
8
- "./cli": "./cli.js"
8
+ "./cli": "./cli.js",
9
+ "./mcp": "./mcp-server.js"
9
10
  },
10
11
  "bin": {
11
12
  "zephyr-gates": "cli.js",
12
- "zephyr-tools": "cli.js"
13
+ "zephyr-tools": "cli.js",
14
+ "zephyr-mcp": "mcp-server.js"
13
15
  },
14
16
  "type": "module",
15
17
  "scripts": {
16
18
  "start": "node cli.js",
19
+ "mcp": "node mcp-server.js",
17
20
  "test": "node cli.js --help"
18
21
  },
22
+ "dependencies": {
23
+ "@modelcontextprotocol/sdk": "^1.0.0"
24
+ },
19
25
  "keywords": [
20
26
  "zephyr",
21
27
  "zephyr-enterprise",
@@ -47,6 +53,7 @@
47
53
  "files": [
48
54
  "zephyr-enterprise-tools.js",
49
55
  "cli.js",
56
+ "mcp-server.js",
50
57
  "README.md",
51
58
  "LICENSE"
52
59
  ]