sdd-mcp-server 1.1.22 → 1.2.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/mcp-server.js ADDED
@@ -0,0 +1,1501 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ import fs from 'fs/promises';
6
+ import path from 'path';
7
+
8
+ const server = new McpServer({
9
+ name: 'sdd-mcp-server',
10
+ version: '1.1.21'
11
+ }, {
12
+ instructions: 'Use this server for spec-driven development workflows'
13
+ });
14
+
15
+ // Helper functions for file operations
16
+ async function createKiroDirectory(projectPath) {
17
+ const kiroPath = path.join(projectPath, '.kiro');
18
+ const specsPath = path.join(kiroPath, 'specs');
19
+ const steeringPath = path.join(kiroPath, 'steering');
20
+
21
+ await fs.mkdir(kiroPath, { recursive: true });
22
+ await fs.mkdir(specsPath, { recursive: true });
23
+ await fs.mkdir(steeringPath, { recursive: true });
24
+
25
+ return { kiroPath, specsPath, steeringPath };
26
+ }
27
+
28
+ async function generateFeatureName(description) {
29
+ // Simple feature name generation from description
30
+ return description.toLowerCase()
31
+ .replace(/[^a-z0-9\s]/g, '')
32
+ .replace(/\s+/g, '-')
33
+ .substring(0, 50);
34
+ }
35
+
36
+ async function getCurrentTimestamp() {
37
+ return new Date().toISOString();
38
+ }
39
+
40
+ // Register all SDD tools matching README and kiro command templates
41
+
42
+ // 1. sdd-init - Initialize new SDD project
43
+ server.registerTool("sdd-init", {
44
+ title: "Initialize SDD Project",
45
+ description: "Initialize a new SDD project",
46
+ inputSchema: {
47
+ projectName: z.string().describe('The name of the project to initialize'),
48
+ description: z.string().optional().describe('Optional project description')
49
+ },
50
+ }, async ({ projectName, description = '' }) => {
51
+ try {
52
+ const currentPath = process.cwd();
53
+
54
+ // Create .kiro directory structure in current directory (not in a subdirectory)
55
+ const { specsPath, steeringPath } = await createKiroDirectory(currentPath);
56
+
57
+ // Generate feature name from description
58
+ const featureName = await generateFeatureName(description || projectName);
59
+ const featurePath = path.join(specsPath, featureName);
60
+ await fs.mkdir(featurePath, { recursive: true });
61
+
62
+ // Create spec.json
63
+ const specJson = {
64
+ "feature_name": featureName,
65
+ "created_at": await getCurrentTimestamp(),
66
+ "updated_at": await getCurrentTimestamp(),
67
+ "language": "en",
68
+ "phase": "initialized",
69
+ "approvals": {
70
+ "requirements": {
71
+ "generated": false,
72
+ "approved": false
73
+ },
74
+ "design": {
75
+ "generated": false,
76
+ "approved": false
77
+ },
78
+ "tasks": {
79
+ "generated": false,
80
+ "approved": false
81
+ }
82
+ },
83
+ "ready_for_implementation": false
84
+ };
85
+
86
+ await fs.writeFile(path.join(featurePath, 'spec.json'), JSON.stringify(specJson, null, 2));
87
+
88
+ // Create requirements.md template
89
+ const requirementsTemplate = `# Requirements Document\n\n## Project Description (Input)\n${description}\n\n## Requirements\n<!-- Will be generated in /kiro:spec-requirements phase -->`;
90
+ await fs.writeFile(path.join(featurePath, 'requirements.md'), requirementsTemplate);
91
+
92
+ return {
93
+ content: [{
94
+ type: 'text',
95
+ text: `## Spec Initialization Complete\n\n**Generated Feature Name**: ${featureName}\n**Project Name**: ${projectName}\n**Project Description**: ${description}\n\n**Created Files**:\n- \`.kiro/specs/${featureName}/spec.json\` - Metadata and approval tracking\n- \`.kiro/specs/${featureName}/requirements.md\` - Requirements template\n\n**Next Step**: Use \`sdd-requirements ${featureName}\` to generate comprehensive requirements\n\nThe spec has been initialized following stage-by-stage development principles.`
96
+ }]
97
+ };
98
+ } catch (error) {
99
+ return {
100
+ content: [{
101
+ type: 'text',
102
+ text: `Error initializing SDD project: ${error.message}`
103
+ }]
104
+ };
105
+ }
106
+ });
107
+
108
+ // 2. sdd-requirements - Generate requirements doc
109
+ server.registerTool("sdd-requirements", {
110
+ title: "Generate Requirements Document",
111
+ description: "Generate requirements doc",
112
+ inputSchema: {
113
+ featureName: z.string().describe('Feature name from spec initialization')
114
+ },
115
+ }, async ({ featureName }) => {
116
+ try {
117
+ const currentPath = process.cwd();
118
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
119
+
120
+ // Check if spec exists
121
+ const specPath = path.join(featurePath, 'spec.json');
122
+ const specExists = await fs.access(specPath).then(() => true).catch(() => false);
123
+ if (!specExists) {
124
+ return {
125
+ content: [{
126
+ type: 'text',
127
+ text: `Error: Spec not found for feature "${featureName}". Use sdd-init first.`
128
+ }]
129
+ };
130
+ }
131
+
132
+ // Read existing spec
133
+ const specContent = await fs.readFile(specPath, 'utf8');
134
+ const spec = JSON.parse(specContent);
135
+
136
+ // Generate EARS-format requirements
137
+ const requirementsContent = `# Requirements Document\n\n## Introduction\nThis feature delivers comprehensive spec-driven development workflow capabilities to AI development teams.\n\n## Requirements\n\n### Requirement 1: Project Initialization\n**Objective:** As a developer, I want to initialize SDD projects with proper structure, so that I can follow structured development workflows\n\n#### Acceptance Criteria\n1. WHEN a user runs sdd-init THEN the system SHALL create .kiro directory structure\n2. WHEN initialization occurs THEN the system SHALL generate spec.json with metadata\n3. WHEN project is created THEN the system SHALL create requirements.md template\n4. WHERE .kiro directory exists THE system SHALL track project state and approvals\n\n### Requirement 2: Requirements Generation\n**Objective:** As a developer, I want to generate comprehensive requirements, so that I can clearly define project scope\n\n1. WHEN requirements are requested THEN the system SHALL generate EARS-format acceptance criteria\n2. IF project description exists THEN the system SHALL incorporate it into requirements\n3. WHILE requirements are being generated THE system SHALL follow structured documentation patterns\n\n### Requirement 3: Workflow Phase Management\n**Objective:** As a developer, I want phase-based workflow control, so that I can ensure proper development progression\n\n1. WHEN each phase completes THEN the system SHALL require approval before proceeding\n2. IF approvals are missing THEN the system SHALL block phase transitions\n3. WHERE workflow violations occur THE system SHALL provide clear guidance`;
138
+
139
+ await fs.writeFile(path.join(featurePath, 'requirements.md'), requirementsContent);
140
+
141
+ // Update spec.json
142
+ spec.phase = "requirements-generated";
143
+ spec.approvals.requirements.generated = true;
144
+ spec.updated_at = await getCurrentTimestamp();
145
+
146
+ await fs.writeFile(specPath, JSON.stringify(spec, null, 2));
147
+
148
+ return {
149
+ content: [{
150
+ type: 'text',
151
+ text: `## Requirements Generated\n\nRequirements document generated for feature: **${featureName}**\n\n**Generated**: .kiro/specs/${featureName}/requirements.md\n**Status**: Requirements phase completed\n\n**Next Step**: Review the requirements, then use \`sdd-design\` to proceed to design phase`
152
+ }]
153
+ };
154
+ } catch (error) {
155
+ return {
156
+ content: [{
157
+ type: 'text',
158
+ text: `Error generating requirements: ${error.message}`
159
+ }]
160
+ };
161
+ }
162
+ });
163
+
164
+ // 3. sdd-design - Create design specifications
165
+ server.registerTool("sdd-design", {
166
+ title: "Create Design Specifications",
167
+ description: "Create design specifications",
168
+ inputSchema: {
169
+ featureName: z.string().describe('Feature name from spec initialization')
170
+ },
171
+ }, async ({ featureName }) => {
172
+ try {
173
+ const currentPath = process.cwd();
174
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
175
+ const specPath = path.join(featurePath, 'spec.json');
176
+
177
+ // Read and validate spec
178
+ const specContent = await fs.readFile(specPath, 'utf8');
179
+ const spec = JSON.parse(specContent);
180
+
181
+ if (!spec.approvals.requirements.generated) {
182
+ return {
183
+ content: [{
184
+ type: 'text',
185
+ text: `Error: Requirements must be generated before design. Run \`sdd-requirements ${featureName}\` first.`
186
+ }]
187
+ };
188
+ }
189
+
190
+ // Generate design document
191
+ const designContent = `# Technical Design Document\n\n## Overview\n\n**Purpose**: This feature delivers comprehensive MCP server capabilities for spec-driven development workflows to AI development teams.\n\n**Users**: AI developers and development teams will utilize this for structured project development.\n\n**Impact**: Transforms ad-hoc development into systematic, phase-based workflows with quality gates.\n\n### Goals\n- Provide complete SDD workflow automation\n- Ensure quality through Linus-style code review\n- Enable multi-language development support\n- Integrate seamlessly with AI development tools\n\n### Non-Goals\n- Real-time collaboration features\n- Deployment automation\n- Version control integration\n\n## Architecture\n\n### High-Level Architecture\n\n\`\`\`mermaid\ngraph TB\n A[AI Client] --> B[MCP Server]\n B --> C[SDD Workflow Engine]\n C --> D[Project Management]\n C --> E[Template System]\n C --> F[Quality Analysis]\n D --> G[File System]\n E --> G\n F --> G\n\`\`\`\n\n### Technology Stack\n\n**Runtime**: Node.js with ES modules\n**Protocol**: Model Context Protocol (MCP)\n**Templates**: Handlebars-based generation\n**Quality**: AST-based code analysis\n**Storage**: File-based project persistence\n\n### Key Design Decisions\n\n**Decision**: Use MCP protocol for AI tool integration\n**Context**: Need seamless integration with Claude Code and other AI development tools\n**Alternatives**: REST API, GraphQL, custom protocol\n**Selected Approach**: MCP provides standardized AI tool integration\n**Rationale**: Direct integration with AI development workflows\n**Trade-offs**: Protocol-specific but optimized for AI use cases\n\n## Components and Interfaces\n\n### SDD Workflow Engine\n\n**Responsibility**: Manages 5-phase workflow state transitions\n**Domain Boundary**: Workflow orchestration and validation\n**Data Ownership**: Phase state, approval tracking, transition rules\n\n**Contract Definition**:\n\`\`\`typescript\ninterface SDDWorkflowEngine {\n initializeProject(name: string, description: string): ProjectSpec;\n generateRequirements(featureName: string): RequirementsDoc;\n generateDesign(featureName: string): DesignDoc;\n generateTasks(featureName: string): TasksDoc;\n checkQuality(code: string): QualityReport;\n}\n\`\`\`\n\n### Template System\n\n**Responsibility**: Generate structured documents from templates\n**Domain Boundary**: Document generation and formatting\n**Data Ownership**: Template definitions, generated content\n\n### Quality Analysis Engine\n\n**Responsibility**: Perform Linus-style 5-layer code review\n**Domain Boundary**: Code quality assessment\n**Data Ownership**: Quality metrics, review reports\n\n## Data Models\n\n### Project Specification\n\`\`\`json\n{\n "feature_name": "string",\n "created_at": "ISO8601",\n "updated_at": "ISO8601",\n "language": "en",\n "phase": "initialized|requirements-generated|design-generated|tasks-generated|implementation",\n "approvals": {\n "requirements": { "generated": boolean, "approved": boolean },\n "design": { "generated": boolean, "approved": boolean },\n "tasks": { "generated": boolean, "approved": boolean }\n },\n "ready_for_implementation": boolean\n}\n\`\`\`\n\n## Error Handling\n\n### Error Strategy\n- Phase validation with clear error messages\n- Graceful degradation for missing dependencies\n- Detailed logging for debugging\n\n### Error Categories\n**User Errors**: Invalid phase transitions → workflow guidance\n**System Errors**: File system failures → graceful error handling\n**Business Logic Errors**: Missing approvals → phase requirement messages\n\n## Testing Strategy\n\n- Unit Tests: SDD workflow engine methods\n- Integration Tests: MCP protocol communication\n- E2E Tests: Complete workflow execution\n- Performance Tests: Large project handling`;
192
+
193
+ await fs.writeFile(path.join(featurePath, 'design.md'), designContent);
194
+
195
+ // Update spec.json
196
+ spec.phase = "design-generated";
197
+ spec.approvals.design.generated = true;
198
+ spec.updated_at = await getCurrentTimestamp();
199
+
200
+ await fs.writeFile(specPath, JSON.stringify(spec, null, 2));
201
+
202
+ return {
203
+ content: [{
204
+ type: 'text',
205
+ text: `## Design Generated\n\nTechnical design document generated for feature: **${featureName}**\n\n**Generated**: .kiro/specs/${featureName}/design.md\n**Status**: Design phase completed\n\n**Next Step**: Review the design document, then use \`sdd-tasks\` to proceed to task planning phase`
206
+ }]
207
+ };
208
+ } catch (error) {
209
+ return {
210
+ content: [{
211
+ type: 'text',
212
+ text: `Error generating design: ${error.message}`
213
+ }]
214
+ };
215
+ }
216
+ });
217
+
218
+ // 4. sdd-tasks - Generate task breakdown
219
+ server.registerTool("sdd-tasks", {
220
+ title: "Generate Task Breakdown",
221
+ description: "Generate task breakdown",
222
+ inputSchema: {
223
+ featureName: z.string().describe('Feature name from spec initialization')
224
+ },
225
+ }, async ({ featureName }) => {
226
+ try {
227
+ const currentPath = process.cwd();
228
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
229
+ const specPath = path.join(featurePath, 'spec.json');
230
+
231
+ // Read and validate spec
232
+ const specContent = await fs.readFile(specPath, 'utf8');
233
+ const spec = JSON.parse(specContent);
234
+
235
+ if (!spec.approvals.design.generated) {
236
+ return {
237
+ content: [{
238
+ type: 'text',
239
+ text: `Error: Design must be generated before tasks. Run \`sdd-design ${featureName}\` first.`
240
+ }]
241
+ };
242
+ }
243
+
244
+ // Generate tasks document
245
+ const tasksContent = `# Implementation Plan\n\n- [ ] 1. Set up MCP server foundation and infrastructure\n - Initialize Node.js project with MCP SDK dependencies\n - Configure server infrastructure and request handling\n - Establish project directory structure and file operations\n - Set up configuration and environment management\n - _Requirements: All requirements need foundational setup_\n\n- [ ] 2. Build core SDD workflow engine\n- [ ] 2.1 Implement project initialization functionality\n - Set up .kiro directory structure creation\n - Implement spec.json metadata generation\n - Build requirements template creation logic\n - Add project state tracking mechanisms\n - _Requirements: 1.1, 1.2, 1.3_\n\n- [ ] 2.2 Enable workflow phase management\n - Implement phase transition validation logic\n - Build approval tracking system\n - Create workflow state persistence\n - Develop phase progression controls\n - _Requirements: 3.1, 3.2, 3.3_\n\n- [ ] 3. Implement document generation system\n- [ ] 3.1 Build requirements generation capabilities\n - Implement EARS-format requirements generation\n - Build project description integration\n - Create structured documentation patterns\n - Add requirements validation logic\n - _Requirements: 2.1, 2.2, 2.3_\n\n- [ ] 3.2 Create design document generation\n - Implement technical design template generation\n - Build architecture diagram integration\n - Create component specification logic\n - Add design validation and approval tracking\n - _Requirements: Design workflow requirements_\n\n- [ ] 3.3 Develop task breakdown functionality\n - Implement task generation from design specifications\n - Build sequential task numbering system\n - Create requirements traceability mapping\n - Add task completion tracking\n - _Requirements: Task management requirements_\n\n- [ ] 4. Integrate quality analysis and review system\n- [ ] 4.1 Implement Linus-style code review engine\n - Build 5-layer code analysis framework\n - Implement AST-based code quality assessment\n - Create quality report generation\n - Add review criteria and scoring system\n - _Requirements: Quality management requirements_\n\n- [ ] 5. Build MCP protocol integration\n- [ ] 5.1 Implement complete MCP tool registration\n - Register all 10 SDD tools with proper schemas\n - Implement tool execution handlers\n - Build error handling and validation\n - Add protocol compliance and communication\n - _Requirements: All tool integration requirements_\n\n- [ ] 6. Add testing and validation\n- [ ] 6.1 Create comprehensive test suite\n - Build unit tests for workflow engine\n - Implement integration tests for MCP communication\n - Create end-to-end workflow validation tests\n - Add performance and reliability testing\n - _Requirements: Testing and validation requirements_`;
246
+
247
+ await fs.writeFile(path.join(featurePath, 'tasks.md'), tasksContent);
248
+
249
+ // Update spec.json
250
+ spec.phase = "tasks-generated";
251
+ spec.approvals.tasks.generated = true;
252
+ spec.ready_for_implementation = true;
253
+ spec.updated_at = await getCurrentTimestamp();
254
+
255
+ await fs.writeFile(specPath, JSON.stringify(spec, null, 2));
256
+
257
+ return {
258
+ content: [{
259
+ type: 'text',
260
+ text: `## Implementation Tasks Generated\n\nImplementation tasks document generated for feature: **${featureName}**\n\n**Generated**: .kiro/specs/${featureName}/tasks.md\n**Status**: Tasks phase completed\n**Ready for Implementation**: Yes\n\n**Next Step**: Review tasks, then use \`sdd-implement\` to begin implementation or \`sdd-status\` to check progress`
261
+ }]
262
+ };
263
+ } catch (error) {
264
+ return {
265
+ content: [{
266
+ type: 'text',
267
+ text: `Error generating tasks: ${error.message}`
268
+ }]
269
+ };
270
+ }
271
+ });
272
+
273
+ // 5. sdd-implement - Implementation guidelines
274
+ server.registerTool("sdd-implement", {
275
+ title: "Implementation Guidelines",
276
+ description: "Implementation guidelines",
277
+ inputSchema: {
278
+ featureName: z.string().describe('Feature name from spec initialization')
279
+ },
280
+ }, async ({ featureName }) => {
281
+ try {
282
+ const currentPath = process.cwd();
283
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
284
+ const specPath = path.join(featurePath, 'spec.json');
285
+
286
+ // Read spec
287
+ const specContent = await fs.readFile(specPath, 'utf8');
288
+ const spec = JSON.parse(specContent);
289
+
290
+ if (!spec.ready_for_implementation) {
291
+ return {
292
+ content: [{
293
+ type: 'text',
294
+ text: `Error: Project not ready for implementation. Complete requirements, design, and tasks phases first.`
295
+ }]
296
+ };
297
+ }
298
+
299
+ return {
300
+ content: [{
301
+ type: 'text',
302
+ text: `## Implementation Guidelines for ${featureName}\n\n**Project Status**: Ready for implementation\n**Current Phase**: ${spec.phase}\n\n**Implementation Instructions**:\n1. Work through tasks sequentially as defined in tasks.md\n2. Follow the technical design specifications in design.md\n3. Ensure all requirements from requirements.md are satisfied\n4. Use \`sdd-quality-check\` to validate code quality\n5. Mark tasks as completed in tasks.md as you progress\n\n**Key Principles**:\n- Follow established coding patterns and conventions\n- Implement comprehensive error handling\n- Add appropriate logging and monitoring\n- Write tests for each component\n- Validate against requirements at each step\n\n**Next Steps**:\n- Begin with Task 1: Set up MCP server foundation\n- Use the design document as your implementation guide\n- Run quality checks regularly during development`
303
+ }]
304
+ };
305
+ } catch (error) {
306
+ return {
307
+ content: [{
308
+ type: 'text',
309
+ text: `Error getting implementation guidelines: ${error.message}`
310
+ }]
311
+ };
312
+ }
313
+ });
314
+
315
+ // 6. sdd-status - Check workflow progress
316
+ server.registerTool("sdd-status", {
317
+ title: "Check Workflow Progress",
318
+ description: "Check workflow progress",
319
+ inputSchema: {
320
+ featureName: z.string().optional().describe('Feature name (optional - shows all if not provided)')
321
+ },
322
+ }, async ({ featureName }) => {
323
+ try {
324
+ const currentPath = process.cwd();
325
+ const kiroPath = path.join(currentPath, '.kiro');
326
+
327
+ // Check if .kiro directory exists
328
+ const kiroExists = await fs.access(kiroPath).then(() => true).catch(() => false);
329
+ if (!kiroExists) {
330
+ return {
331
+ content: [{
332
+ type: 'text',
333
+ text: 'SDD project status: No active project found. Use sdd-init to create a new project.'
334
+ }]
335
+ };
336
+ }
337
+
338
+ const specsPath = path.join(kiroPath, 'specs');
339
+
340
+ if (featureName) {
341
+ // Show status for specific feature
342
+ const featurePath = path.join(specsPath, featureName);
343
+ const specPath = path.join(featurePath, 'spec.json');
344
+
345
+ const specExists = await fs.access(specPath).then(() => true).catch(() => false);
346
+ if (!specExists) {
347
+ return {
348
+ content: [{
349
+ type: 'text',
350
+ text: `Feature "${featureName}" not found. Use sdd-init to create it.`
351
+ }]
352
+ };
353
+ }
354
+
355
+ const specContent = await fs.readFile(specPath, 'utf8');
356
+ const spec = JSON.parse(specContent);
357
+
358
+ let status = `## SDD Project Status: ${spec.feature_name}\n\n`;
359
+ status += `**Current Phase**: ${spec.phase}\n`;
360
+ status += `**Language**: ${spec.language}\n`;
361
+ status += `**Created**: ${spec.created_at}\n`;
362
+ status += `**Updated**: ${spec.updated_at}\n\n`;
363
+
364
+ status += `**Phase Progress**:\n`;
365
+ status += `- Requirements: ${spec.approvals.requirements.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.requirements.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n`;
366
+ status += `- Design: ${spec.approvals.design.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.design.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n`;
367
+ status += `- Tasks: ${spec.approvals.tasks.generated ? '✅ Generated' : '❌ Not Generated'}${spec.approvals.tasks.approved ? ', ✅ Approved' : ', ❌ Not Approved'}\n\n`;
368
+
369
+ status += `**Ready for Implementation**: ${spec.ready_for_implementation ? '✅ Yes' : '❌ No'}\n\n`;
370
+
371
+ // Suggest next steps
372
+ if (!spec.approvals.requirements.generated) {
373
+ status += `**Next Step**: Run \`sdd-requirements ${featureName}\``;
374
+ } else if (!spec.approvals.design.generated) {
375
+ status += `**Next Step**: Run \`sdd-design ${featureName}\``;
376
+ } else if (!spec.approvals.tasks.generated) {
377
+ status += `**Next Step**: Run \`sdd-tasks ${featureName}\``;
378
+ } else {
379
+ status += `**Next Step**: Run \`sdd-implement ${featureName}\` to begin implementation`;
380
+ }
381
+
382
+ return {
383
+ content: [{
384
+ type: 'text',
385
+ text: status
386
+ }]
387
+ };
388
+ } else {
389
+ // Show all features
390
+ const features = await fs.readdir(specsPath).catch(() => []);
391
+
392
+ if (features.length === 0) {
393
+ return {
394
+ content: [{
395
+ type: 'text',
396
+ text: 'No SDD features found. Use sdd-init to create a new project.'
397
+ }]
398
+ };
399
+ }
400
+
401
+ let status = `## SDD Project Status - All Features\n\n`;
402
+
403
+ for (const feature of features) {
404
+ const specPath = path.join(specsPath, feature, 'spec.json');
405
+ const specExists = await fs.access(specPath).then(() => true).catch(() => false);
406
+
407
+ if (specExists) {
408
+ const specContent = await fs.readFile(specPath, 'utf8');
409
+ const spec = JSON.parse(specContent);
410
+
411
+ status += `**${spec.feature_name}**:\n`;
412
+ status += `- Phase: ${spec.phase}\n`;
413
+ status += `- Requirements: ${spec.approvals.requirements.generated ? '✅' : '❌'}\n`;
414
+ status += `- Design: ${spec.approvals.design.generated ? '✅' : '❌'}\n`;
415
+ status += `- Tasks: ${spec.approvals.tasks.generated ? '✅' : '❌'}\n`;
416
+ status += `- Ready: ${spec.ready_for_implementation ? '✅' : '❌'}\n\n`;
417
+ }
418
+ }
419
+
420
+ return {
421
+ content: [{
422
+ type: 'text',
423
+ text: status
424
+ }]
425
+ };
426
+ }
427
+ } catch (error) {
428
+ return {
429
+ content: [{
430
+ type: 'text',
431
+ text: `Error checking status: ${error.message}`
432
+ }]
433
+ };
434
+ }
435
+ });
436
+
437
+ // 7. sdd-approve - Approve workflow phases
438
+ server.registerTool("sdd-approve", {
439
+ title: "Approve Workflow Phases",
440
+ description: "Approve workflow phases",
441
+ inputSchema: {
442
+ featureName: z.string().describe('Feature name from spec initialization'),
443
+ phase: z.enum(['requirements', 'design', 'tasks']).describe('Phase to approve')
444
+ },
445
+ }, async ({ featureName, phase }) => {
446
+ try {
447
+ const currentPath = process.cwd();
448
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
449
+ const specPath = path.join(featurePath, 'spec.json');
450
+
451
+ // Read spec
452
+ const specContent = await fs.readFile(specPath, 'utf8');
453
+ const spec = JSON.parse(specContent);
454
+
455
+ if (!spec.approvals[phase].generated) {
456
+ return {
457
+ content: [{
458
+ type: 'text',
459
+ text: `Error: ${phase} must be generated before approval. Run sdd-${phase} ${featureName} first.`
460
+ }]
461
+ };
462
+ }
463
+
464
+ // Approve the phase
465
+ spec.approvals[phase].approved = true;
466
+ spec.updated_at = await getCurrentTimestamp();
467
+
468
+ await fs.writeFile(specPath, JSON.stringify(spec, null, 2));
469
+
470
+ return {
471
+ content: [{
472
+ type: 'text',
473
+ text: `## Phase Approved\n\n**Feature**: ${featureName}\n**Phase**: ${phase}\n**Status**: ✅ Approved\n\nPhase has been marked as approved and workflow can proceed to the next phase.`
474
+ }]
475
+ };
476
+ } catch (error) {
477
+ return {
478
+ content: [{
479
+ type: 'text',
480
+ text: `Error approving phase: ${error.message}`
481
+ }]
482
+ };
483
+ }
484
+ });
485
+
486
+ // 8. sdd-quality-check - Code quality analysis
487
+ server.registerTool("sdd-quality-check", {
488
+ title: "Code Quality Analysis",
489
+ description: "Code quality analysis",
490
+ inputSchema: {
491
+ code: z.string().describe('Code to analyze'),
492
+ language: z.string().optional().describe('Programming language (default: javascript)')
493
+ },
494
+ }, async ({ code, language = 'javascript' }) => {
495
+ try {
496
+ // Simple quality analysis (Linus-style 5-layer approach)
497
+ const lines = code.split('\n');
498
+ const issues = [];
499
+
500
+ // Layer 1: Syntax and Basic Structure
501
+ if (code.includes('console.log')) {
502
+ issues.push('L1: Remove debug console.log statements');
503
+ }
504
+ if (code.includes('var ')) {
505
+ issues.push('L1: Use let/const instead of var');
506
+ }
507
+
508
+ // Layer 2: Code Style and Conventions
509
+ if (!/^[a-z]/.test(code.split('function ')[1]?.split('(')[0] || '')) {
510
+ if (code.includes('function ')) {
511
+ issues.push('L2: Function names should start with lowercase');
512
+ }
513
+ }
514
+
515
+ // Layer 3: Logic and Algorithm
516
+ if (code.includes('for') && !code.includes('const')) {
517
+ issues.push('L3: Consider using const in for loops for immutable iteration variables');
518
+ }
519
+
520
+ // Layer 4: Architecture and Design
521
+ if (lines.length > 50) {
522
+ issues.push('L4: Function/module is too long, consider breaking into smaller parts');
523
+ }
524
+
525
+ // Layer 5: Business Logic and Requirements
526
+ if (!code.includes('error') && code.includes('try')) {
527
+ issues.push('L5: Missing proper error handling in try block');
528
+ }
529
+
530
+ const qualityScore = Math.max(0, 100 - (issues.length * 15));
531
+
532
+ let report = `## Linus-Style Code Quality Analysis\n\n`;
533
+ report += `**Language**: ${language}\n`;
534
+ report += `**Lines of Code**: ${lines.length}\n`;
535
+ report += `**Quality Score**: ${qualityScore}/100\n\n`;
536
+
537
+ if (issues.length === 0) {
538
+ report += `**Status**: ✅ Code quality is excellent\n\n`;
539
+ report += `**Analysis**: No significant issues found. Code follows good practices.`;
540
+ } else {
541
+ report += `**Issues Found**: ${issues.length}\n\n`;
542
+ report += `**Quality Issues**:\n`;
543
+ for (const issue of issues) {
544
+ report += `- ${issue}\n`;
545
+ }
546
+ report += `\n**Recommendation**: Address the identified issues to improve code quality.`;
547
+ }
548
+
549
+ return {
550
+ content: [{
551
+ type: 'text',
552
+ text: report
553
+ }]
554
+ };
555
+ } catch (error) {
556
+ return {
557
+ content: [{
558
+ type: 'text',
559
+ text: `Error analyzing code quality: ${error.message}`
560
+ }]
561
+ };
562
+ }
563
+ });
564
+
565
+ // 9. sdd-context-load - Load project context
566
+ server.registerTool("sdd-context-load", {
567
+ title: "Load Project Context",
568
+ description: "Load project context",
569
+ inputSchema: {
570
+ featureName: z.string().describe('Feature name to load context for')
571
+ },
572
+ }, async ({ featureName }) => {
573
+ try {
574
+ const currentPath = process.cwd();
575
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
576
+
577
+ // Load all context files
578
+ const files = ['spec.json', 'requirements.md', 'design.md', 'tasks.md'];
579
+ const context = {};
580
+
581
+ for (const file of files) {
582
+ const filePath = path.join(featurePath, file);
583
+ const fileExists = await fs.access(filePath).then(() => true).catch(() => false);
584
+
585
+ if (fileExists) {
586
+ const content = await fs.readFile(filePath, 'utf8');
587
+ context[file] = file.endsWith('.json') ? JSON.parse(content) : content;
588
+ }
589
+ }
590
+
591
+ let contextReport = `## Project Context Loaded: ${featureName}\n\n`;
592
+
593
+ if (context['spec.json']) {
594
+ const spec = context['spec.json'];
595
+ contextReport += `**Project Metadata**:\n`;
596
+ contextReport += `- Feature: ${spec.feature_name}\n`;
597
+ contextReport += `- Phase: ${spec.phase}\n`;
598
+ contextReport += `- Language: ${spec.language}\n`;
599
+ contextReport += `- Ready for Implementation: ${spec.ready_for_implementation ? 'Yes' : 'No'}\n\n`;
600
+ }
601
+
602
+ contextReport += `**Available Documents**:\n`;
603
+ for (const [file, content] of Object.entries(context)) {
604
+ if (file !== 'spec.json') {
605
+ const preview = typeof content === 'string' ? content.substring(0, 100) + '...' : 'JSON data';
606
+ contextReport += `- **${file}**: ${preview}\n`;
607
+ }
608
+ }
609
+
610
+ contextReport += `\n**Context Status**: Project memory restored successfully\n`;
611
+ contextReport += `**Total Files Loaded**: ${Object.keys(context).length}`;
612
+
613
+ return {
614
+ content: [{
615
+ type: 'text',
616
+ text: contextReport
617
+ }]
618
+ };
619
+ } catch (error) {
620
+ return {
621
+ content: [{
622
+ type: 'text',
623
+ text: `Error loading project context: ${error.message}`
624
+ }]
625
+ };
626
+ }
627
+ });
628
+
629
+ // 10. sdd-template-render - Render templates
630
+ server.registerTool("sdd-template-render", {
631
+ title: "Render Templates",
632
+ description: "Render templates",
633
+ inputSchema: {
634
+ templateType: z.enum(['requirements', 'design', 'tasks', 'custom']).describe('Type of template to render'),
635
+ featureName: z.string().describe('Feature name for template context'),
636
+ customTemplate: z.string().optional().describe('Custom template content (if templateType is custom)')
637
+ },
638
+ }, async ({ templateType, featureName, customTemplate }) => {
639
+ try {
640
+ const currentPath = process.cwd();
641
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
642
+ const specPath = path.join(featurePath, 'spec.json');
643
+
644
+ // Load spec for context
645
+ const specExists = await fs.access(specPath).then(() => true).catch(() => false);
646
+ let spec = {};
647
+ if (specExists) {
648
+ const specContent = await fs.readFile(specPath, 'utf8');
649
+ spec = JSON.parse(specContent);
650
+ }
651
+
652
+ let renderedContent = '';
653
+
654
+ switch (templateType) {
655
+ case 'requirements':
656
+ renderedContent = `# Requirements Template for ${featureName}\n\n## Project Context\n- Feature: ${spec.feature_name || featureName}\n- Language: ${spec.language || 'en'}\n\n## Requirements Sections\n1. Functional Requirements\n2. Non-Functional Requirements\n3. Business Rules\n4. Acceptance Criteria (EARS format)`;
657
+ break;
658
+
659
+ case 'design':
660
+ renderedContent = `# Design Template for ${featureName}\n\n## Architecture Overview\n- System Architecture\n- Component Design\n- Data Models\n- Interface Specifications\n\n## Technology Decisions\n- Stack Selection\n- Framework Choices\n- Integration Patterns`;
661
+ break;
662
+
663
+ case 'tasks':
664
+ renderedContent = `# Tasks Template for ${featureName}\n\n## Implementation Tasks\n\n- [ ] 1. Foundation Setup\n - Project initialization\n - Dependencies setup\n - Basic structure\n\n- [ ] 2. Core Implementation\n - Main functionality\n - Business logic\n - Data handling\n\n- [ ] 3. Integration & Testing\n - System integration\n - Testing implementation\n - Quality validation`;
665
+ break;
666
+
667
+ case 'custom':
668
+ if (!customTemplate) {
669
+ throw new Error('Custom template content is required for custom template type');
670
+ }
671
+ // Simple template variable replacement
672
+ renderedContent = customTemplate
673
+ .replace(/\{\{featureName\}\}/g, featureName)
674
+ .replace(/\{\{language\}\}/g, spec.language || 'en')
675
+ .replace(/\{\{phase\}\}/g, spec.phase || 'initialized')
676
+ .replace(/\{\{timestamp\}\}/g, new Date().toISOString());
677
+ break;
678
+ }
679
+
680
+ return {
681
+ content: [{
682
+ type: 'text',
683
+ text: `## Template Rendered: ${templateType}\n\n**Feature**: ${featureName}\n**Template Type**: ${templateType}\n\n**Rendered Content**:\n\`\`\`markdown\n${renderedContent}\n\`\`\`\n\n**Usage**: Copy the rendered content to create your ${templateType} document`
684
+ }]
685
+ };
686
+ } catch (error) {
687
+ return {
688
+ content: [{
689
+ type: 'text',
690
+ text: `Error rendering template: ${error.message}`
691
+ }]
692
+ };
693
+ }
694
+ });
695
+
696
+ // 11. sdd-steering - Create/update steering documents
697
+ server.registerTool("sdd-steering", {
698
+ title: "Create/Update Steering Documents",
699
+ description: "Create or update steering documents",
700
+ inputSchema: {
701
+ updateMode: z.enum(['create', 'update']).optional().describe('Whether to create new or update existing documents (auto-detected if not specified)')
702
+ },
703
+ }, async ({ updateMode }) => {
704
+ try {
705
+ const currentPath = process.cwd();
706
+ const steeringPath = path.join(currentPath, '.kiro', 'steering');
707
+
708
+ // Create steering directory if it doesn't exist
709
+ await fs.mkdir(steeringPath, { recursive: true });
710
+
711
+ // Analyze existing files
712
+ const productExists = await fs.access(path.join(steeringPath, 'product.md')).then(() => true).catch(() => false);
713
+ const techExists = await fs.access(path.join(steeringPath, 'tech.md')).then(() => true).catch(() => false);
714
+ const structureExists = await fs.access(path.join(steeringPath, 'structure.md')).then(() => true).catch(() => false);
715
+
716
+ // Auto-detect mode if not specified
717
+ if (!updateMode) {
718
+ updateMode = (productExists || techExists || structureExists) ? 'update' : 'create';
719
+ }
720
+
721
+ // Analyze project structure
722
+ const packageJsonExists = await fs.access('package.json').then(() => true).catch(() => false);
723
+ let projectInfo = {
724
+ name: 'Unknown Project',
725
+ description: 'No description available',
726
+ techStack: [],
727
+ structure: {}
728
+ };
729
+
730
+ if (packageJsonExists) {
731
+ const packageContent = await fs.readFile('package.json', 'utf8');
732
+ const packageJson = JSON.parse(packageContent);
733
+ projectInfo.name = packageJson.name || 'Unknown Project';
734
+ projectInfo.description = packageJson.description || 'No description available';
735
+ projectInfo.techStack = Object.keys(packageJson.dependencies || {}).slice(0, 10);
736
+ }
737
+
738
+ // Generate product.md
739
+ const productContent = `# Product Overview
740
+
741
+ ## Product Description
742
+ ${projectInfo.description}
743
+
744
+ ## Core Features
745
+ - Spec-driven development workflow automation
746
+ - AI-agent integration via Model Context Protocol (MCP)
747
+ - Phase-based development with quality gates
748
+ - Template-based document generation
749
+ - Multi-language support and localization
750
+
751
+ ## Target Use Case
752
+ This product is designed for AI-powered development teams who want to follow structured, spec-driven development workflows. It provides systematic guidance through requirements, design, tasks, and implementation phases.
753
+
754
+ ## Key Value Proposition
755
+ - **Structured Development**: Enforces proven development methodologies
756
+ - **AI Integration**: Seamless integration with AI development tools
757
+ - **Quality Assurance**: Built-in quality gates and code review processes
758
+ - **Template System**: Consistent document generation and project structure
759
+ - **Flexibility**: Configurable workflows and customizable steering documents
760
+
761
+ ## Target Users
762
+ - AI development teams
763
+ - Software engineers using Claude Code, Cursor, and similar tools
764
+ - Development teams implementing spec-driven development practices
765
+ - Projects requiring structured documentation and workflow management`;
766
+
767
+ await fs.writeFile(path.join(steeringPath, 'product.md'), productContent);
768
+
769
+ // Generate tech.md
770
+ const techContent = `# Technology Stack
771
+
772
+ ## Architecture
773
+ - **Type**: ${packageJsonExists ? 'Node.js Application' : 'Unknown Architecture'}
774
+ - **Runtime**: Node.js with ES modules
775
+ - **Protocol**: Model Context Protocol (MCP) for AI integration
776
+ - **Package Manager**: npm
777
+
778
+ ## Technology Stack
779
+ ${projectInfo.techStack.length > 0 ?
780
+ projectInfo.techStack.map(dep => `- **${dep}**: ${dep.includes('mcp') ? 'Model Context Protocol SDK' : 'Runtime dependency'}`).join('\n') :
781
+ '- No major dependencies detected'}
782
+
783
+ ## Development Environment
784
+ - **Node Version**: >= 18.0.0
785
+ - **Package Manager**: npm
786
+ - **Module System**: ES modules (type: "module")
787
+
788
+ ## Common Commands
789
+ \`\`\`bash
790
+ # Development
791
+ npm install # Install dependencies
792
+ npm run build # Build the project
793
+ npm test # Run tests
794
+ npm start # Start the application
795
+
796
+ # MCP Server
797
+ node mcp-server.js # Run simple MCP server
798
+ \`\`\`
799
+
800
+ ## Environment Variables
801
+ - \`LOG_LEVEL\`: Logging level (debug, info, warn, error)
802
+ - \`DEFAULT_LANG\`: Default language for generated documents (en, es, fr, etc.)
803
+
804
+ ## Port Configuration
805
+ - MCP Server: Uses stdio transport (no ports)
806
+ - Application ports: Defined by implementation requirements`;
807
+
808
+ await fs.writeFile(path.join(steeringPath, 'tech.md'), techContent);
809
+
810
+ // Generate structure.md
811
+ const structureContent = `# Project Structure
812
+
813
+ ## Root Directory Organization
814
+ \`\`\`
815
+ ├── .kiro/ # SDD workflow files
816
+ │ ├── steering/ # Project steering documents
817
+ │ └── specs/ # Feature specifications
818
+ ├── dist/ # Compiled output (if applicable)
819
+ ├── src/ # Source code (if applicable)
820
+ ├── node_modules/ # npm dependencies
821
+ ├── package.json # Project configuration
822
+ ├── mcp-server.js # Simple MCP server implementation
823
+ └── README.md # Project documentation
824
+ \`\`\`
825
+
826
+ ## SDD Directory Structure (\`.kiro/\`)
827
+ - **steering/**: Always-loaded project context documents
828
+ - \`product.md\`: Product overview and business context
829
+ - \`tech.md\`: Technology stack and development environment
830
+ - \`structure.md\`: Project organization and architectural decisions
831
+ - Custom steering files for specialized contexts
832
+ - **specs/**: Feature-specific specifications
833
+ - \`{feature-name}/\`: Individual feature directories
834
+ - \`spec.json\`: Metadata and approval tracking
835
+ - \`requirements.md\`: EARS-format requirements
836
+ - \`design.md\`: Technical design document
837
+ - \`tasks.md\`: Implementation task breakdown
838
+
839
+ ## Code Organization Patterns
840
+ - **Modular Structure**: Clear separation between different functional areas
841
+ - **Configuration First**: Centralized configuration management
842
+ - **Documentation Co-location**: Specs and steering documents alongside code
843
+
844
+ ## File Naming Conventions
845
+ - **Steering files**: \`kebab-case.md\` (e.g., \`api-standards.md\`)
846
+ - **Spec files**: Standard names (\`requirements.md\`, \`design.md\`, \`tasks.md\`)
847
+ - **Feature names**: Auto-generated from descriptions using kebab-case
848
+
849
+ ## Key Architectural Principles
850
+ - **Spec-Driven Development**: All features start with requirements and design
851
+ - **Phase-Based Workflow**: Structured progression through development phases
852
+ - **Quality Gates**: Approval requirements between phases
853
+ - **Template-Based Generation**: Consistent document structure and formatting
854
+ - **AI-First Design**: Optimized for AI development tool integration`;
855
+
856
+ await fs.writeFile(path.join(steeringPath, 'structure.md'), structureContent);
857
+
858
+ const mode = updateMode === 'update' ? 'Updated' : 'Created';
859
+
860
+ return {
861
+ content: [{
862
+ type: 'text',
863
+ text: `## Steering Documents ${mode}
864
+
865
+ **Project**: ${projectInfo.name}
866
+ **Mode**: ${updateMode}
867
+
868
+ **${mode} Files**:
869
+ - \`.kiro/steering/product.md\` - Product overview and business context
870
+ - \`.kiro/steering/tech.md\` - Technology stack and development environment
871
+ - \`.kiro/steering/structure.md\` - Project organization and architectural decisions
872
+
873
+ **Analysis**:
874
+ - Technology stack: ${projectInfo.techStack.length} dependencies detected
875
+ - Project type: ${packageJsonExists ? 'Node.js application' : 'Unknown project type'}
876
+ - Existing steering: ${productExists || techExists || structureExists ? 'Updated preserving customizations' : 'Created from scratch'}
877
+
878
+ These steering documents provide consistent project context for all AI interactions and spec-driven development workflows.`
879
+ }]
880
+ };
881
+ } catch (error) {
882
+ return {
883
+ content: [{
884
+ type: 'text',
885
+ text: `Error creating/updating steering documents: ${error.message}`
886
+ }]
887
+ };
888
+ }
889
+ });
890
+
891
+ // 12. sdd-steering-custom - Create custom steering documents
892
+ server.registerTool("sdd-steering-custom", {
893
+ title: "Create Custom Steering Document",
894
+ description: "Create custom steering documents",
895
+ inputSchema: {
896
+ fileName: z.string().describe('Filename for the custom steering document (e.g., "api-standards.md")'),
897
+ topic: z.string().describe('Topic/purpose of the custom steering document'),
898
+ inclusionMode: z.enum(['always', 'conditional', 'manual']).describe('How this steering document should be included'),
899
+ filePattern: z.string().optional().describe('File pattern for conditional inclusion (e.g., "*.test.js", "src/api/**/*")')
900
+ },
901
+ }, async ({ fileName, topic, inclusionMode, filePattern }) => {
902
+ try {
903
+ const currentPath = process.cwd();
904
+ const steeringPath = path.join(currentPath, '.kiro', 'steering');
905
+
906
+ // Create steering directory if it doesn't exist
907
+ await fs.mkdir(steeringPath, { recursive: true });
908
+
909
+ // Ensure filename ends with .md
910
+ if (!fileName.endsWith('.md')) {
911
+ fileName += '.md';
912
+ }
913
+
914
+ // Generate inclusion mode comment
915
+ let inclusionComment = '<!-- Inclusion Mode: ';
916
+ if (inclusionMode === 'always') {
917
+ inclusionComment += 'Always -->';
918
+ } else if (inclusionMode === 'conditional') {
919
+ inclusionComment += `Conditional: "${filePattern || '**/*'}" -->`;
920
+ } else {
921
+ inclusionComment += 'Manual -->';
922
+ }
923
+
924
+ // Generate content based on topic
925
+ let content = `${inclusionComment}
926
+
927
+ # ${topic}
928
+
929
+ ## Purpose
930
+ This document provides specialized guidance for ${topic.toLowerCase()} within the project context.
931
+
932
+ ## When This Document Applies
933
+ ${inclusionMode === 'conditional' ?
934
+ `This guidance applies when working with files matching: \`${filePattern || '**/*'}\`` :
935
+ inclusionMode === 'always' ?
936
+ 'This guidance applies to all development work in this project.' :
937
+ 'Reference this document manually using @${fileName} when needed.'}
938
+
939
+ ## Guidelines
940
+
941
+ ### Key Principles
942
+ - [Add specific principles for ${topic.toLowerCase()}]
943
+ - [Include concrete rules and patterns]
944
+ - [Provide rationale for important decisions]
945
+
946
+ ### Implementation Patterns
947
+ \`\`\`
948
+ // Example code patterns for ${topic.toLowerCase()}
949
+ // Include specific examples relevant to your project
950
+ \`\`\`
951
+
952
+ ### Best Practices
953
+ 1. **Practice 1**: Description and rationale
954
+ 2. **Practice 2**: Description and rationale
955
+ 3. **Practice 3**: Description and rationale
956
+
957
+ ## Integration Points
958
+ - Related to core steering: product.md, tech.md, structure.md
959
+ - Dependencies: [List any prerequisites or related documents]
960
+ - Conflicts: [Note any potential conflicts with other guidance]
961
+
962
+ ## Examples
963
+ \`\`\`
964
+ // Concrete examples of correct implementation
965
+ // Show both correct patterns and counter-examples if helpful
966
+ \`\`\`
967
+
968
+ ## Quality Standards
969
+ - [Specific quality criteria for ${topic.toLowerCase()}]
970
+ - [Testing requirements]
971
+ - [Review checklist items]`;
972
+
973
+ const filePath = path.join(steeringPath, fileName);
974
+ await fs.writeFile(filePath, content);
975
+
976
+ return {
977
+ content: [{
978
+ type: 'text',
979
+ text: `## Custom Steering Document Created
980
+
981
+ **File**: .kiro/steering/${fileName}
982
+ **Topic**: ${topic}
983
+ **Inclusion Mode**: ${inclusionMode}${inclusionMode === 'conditional' ? ` (Pattern: "${filePattern}")` : ''}
984
+
985
+ **Created**: Custom steering document with template structure
986
+ **Usage**: ${
987
+ inclusionMode === 'always' ? 'Will be loaded in all AI interactions' :
988
+ inclusionMode === 'conditional' ? `Will be loaded when working with files matching "${filePattern}"` :
989
+ `Reference manually with @${fileName} when needed`
990
+ }
991
+
992
+ The document has been created with a standard template structure. Edit the file to add your specific guidelines, examples, and best practices for ${topic.toLowerCase()}.`
993
+ }]
994
+ };
995
+ } catch (error) {
996
+ return {
997
+ content: [{
998
+ type: 'text',
999
+ text: `Error creating custom steering document: ${error.message}`
1000
+ }]
1001
+ };
1002
+ }
1003
+ });
1004
+
1005
+ // 13. sdd-validate-design - Interactive design quality review
1006
+ server.registerTool("sdd-validate-design", {
1007
+ title: "Validate Design Quality",
1008
+ description: "Interactive design quality review and validation",
1009
+ inputSchema: {
1010
+ featureName: z.string().describe('Feature name to validate design for')
1011
+ },
1012
+ }, async ({ featureName }) => {
1013
+ try {
1014
+ const currentPath = process.cwd();
1015
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
1016
+ const designPath = path.join(featurePath, 'design.md');
1017
+ const specPath = path.join(featurePath, 'spec.json');
1018
+
1019
+ // Check if design document exists
1020
+ const designExists = await fs.access(designPath).then(() => true).catch(() => false);
1021
+ if (!designExists) {
1022
+ return {
1023
+ content: [{
1024
+ type: 'text',
1025
+ text: `Error: Design document not found. Run \`sdd-design ${featureName}\` first to generate design document.`
1026
+ }]
1027
+ };
1028
+ }
1029
+
1030
+ // Load design and spec
1031
+ const designContent = await fs.readFile(designPath, 'utf8');
1032
+ const specContent = await fs.readFile(specPath, 'utf8');
1033
+ const spec = JSON.parse(specContent);
1034
+
1035
+ // Analyze design for critical issues
1036
+ const issues = [];
1037
+
1038
+ // Check for type safety (if TypeScript patterns detected)
1039
+ if (designContent.includes('any') || designContent.includes(': any')) {
1040
+ issues.push({
1041
+ title: "Type Safety Concern",
1042
+ concern: "Design mentions 'any' types which compromises type safety",
1043
+ impact: "Reduces code reliability and IDE support",
1044
+ suggestion: "Define explicit interfaces and types for all data structures"
1045
+ });
1046
+ }
1047
+
1048
+ // Check for architectural patterns
1049
+ if (!designContent.includes('Component') && !designContent.includes('Service') && !designContent.includes('Module')) {
1050
+ issues.push({
1051
+ title: "Architecture Clarity",
1052
+ concern: "Design lacks clear component or service boundaries",
1053
+ impact: "May lead to monolithic or poorly organized code",
1054
+ suggestion: "Define clear components, services, or modules with specific responsibilities"
1055
+ });
1056
+ }
1057
+
1058
+ // Check for error handling
1059
+ if (!designContent.includes('error') && !designContent.includes('Error')) {
1060
+ issues.push({
1061
+ title: "Error Handling Strategy",
1062
+ concern: "Design doesn't address error handling patterns",
1063
+ impact: "Runtime errors may not be properly managed",
1064
+ suggestion: "Add comprehensive error handling strategy and exception management"
1065
+ });
1066
+ }
1067
+
1068
+ // Limit to 3 most critical issues
1069
+ const criticalIssues = issues.slice(0, 3);
1070
+
1071
+ // Identify design strengths
1072
+ const strengths = [];
1073
+ if (designContent.includes('mermaid') || designContent.includes('```')) {
1074
+ strengths.push("Visual documentation with diagrams and code examples");
1075
+ }
1076
+ if (designContent.includes('interface') || designContent.includes('Interface')) {
1077
+ strengths.push("Clear interface definitions and contracts");
1078
+ }
1079
+
1080
+ // Make GO/NO-GO decision
1081
+ const hasBlockingIssues = criticalIssues.length > 2 ||
1082
+ criticalIssues.some(issue => issue.title.includes('Architecture') || issue.title.includes('Type Safety'));
1083
+
1084
+ const decision = hasBlockingIssues ? 'NO-GO' : 'GO';
1085
+ const nextStep = decision === 'GO' ?
1086
+ `Run \`sdd-tasks ${featureName}\` to generate implementation tasks` :
1087
+ `Address critical issues in design document before proceeding`;
1088
+
1089
+ let report = `## Design Validation Review: ${featureName}\n\n`;
1090
+ report += `**Overall Assessment**: ${decision === 'GO' ? '✅ Design ready for implementation' : '❌ Design needs revision'}\n\n`;
1091
+
1092
+ if (criticalIssues.length > 0) {
1093
+ report += `### Critical Issues (${criticalIssues.length})\n\n`;
1094
+ criticalIssues.forEach((issue, index) => {
1095
+ report += `🔴 **Critical Issue ${index + 1}**: ${issue.title}\n`;
1096
+ report += `**Concern**: ${issue.concern}\n`;
1097
+ report += `**Impact**: ${issue.impact}\n`;
1098
+ report += `**Suggestion**: ${issue.suggestion}\n\n`;
1099
+ });
1100
+ }
1101
+
1102
+ if (strengths.length > 0) {
1103
+ report += `### Design Strengths\n\n`;
1104
+ strengths.forEach(strength => {
1105
+ report += `✅ ${strength}\n`;
1106
+ });
1107
+ report += `\n`;
1108
+ }
1109
+
1110
+ report += `### Final Assessment\n`;
1111
+ report += `**Decision**: ${decision}\n`;
1112
+ report += `**Rationale**: ${
1113
+ decision === 'GO' ?
1114
+ 'Design addresses core requirements with acceptable architectural approach and manageable risks.' :
1115
+ 'Critical architectural or technical issues need resolution before implementation can proceed safely.'
1116
+ }\n`;
1117
+ report += `**Next Steps**: ${nextStep}\n\n`;
1118
+
1119
+ report += `### Interactive Discussion\n`;
1120
+ report += `Questions for design review:\n`;
1121
+ report += `1. Do you agree with the identified issues and their severity?\n`;
1122
+ report += `2. Are there alternative approaches to address the concerns?\n`;
1123
+ report += `3. What are your thoughts on the overall design complexity?\n`;
1124
+ report += `4. Are there any design decisions that need clarification?\n`;
1125
+
1126
+ return {
1127
+ content: [{
1128
+ type: 'text',
1129
+ text: report
1130
+ }]
1131
+ };
1132
+ } catch (error) {
1133
+ return {
1134
+ content: [{
1135
+ type: 'text',
1136
+ text: `Error validating design: ${error.message}`
1137
+ }]
1138
+ };
1139
+ }
1140
+ });
1141
+
1142
+ // 14. sdd-validate-gap - Analyze implementation gap
1143
+ server.registerTool("sdd-validate-gap", {
1144
+ title: "Validate Implementation Gap",
1145
+ description: "Analyze implementation gap between requirements and codebase",
1146
+ inputSchema: {
1147
+ featureName: z.string().describe('Feature name to analyze implementation gap for')
1148
+ },
1149
+ }, async ({ featureName }) => {
1150
+ try {
1151
+ const currentPath = process.cwd();
1152
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
1153
+ const requirementsPath = path.join(featurePath, 'requirements.md');
1154
+ const specPath = path.join(featurePath, 'spec.json');
1155
+
1156
+ // Check if requirements exist
1157
+ const requirementsExist = await fs.access(requirementsPath).then(() => true).catch(() => false);
1158
+ if (!requirementsExist) {
1159
+ return {
1160
+ content: [{
1161
+ type: 'text',
1162
+ text: `Error: Requirements document not found. Run \`sdd-requirements ${featureName}\` first to generate requirements.`
1163
+ }]
1164
+ };
1165
+ }
1166
+
1167
+ // Load requirements and spec
1168
+ const requirementsContent = await fs.readFile(requirementsPath, 'utf8');
1169
+ const specContent = await fs.readFile(specPath, 'utf8');
1170
+ const spec = JSON.parse(specContent);
1171
+
1172
+ // Analyze current codebase
1173
+ const codebaseAnalysis = {
1174
+ hasPackageJson: await fs.access('package.json').then(() => true).catch(() => false),
1175
+ hasSourceCode: false,
1176
+ techStack: [],
1177
+ architecture: 'Unknown'
1178
+ };
1179
+
1180
+ if (codebaseAnalysis.hasPackageJson) {
1181
+ const packageContent = await fs.readFile('package.json', 'utf8');
1182
+ const packageJson = JSON.parse(packageContent);
1183
+ codebaseAnalysis.techStack = Object.keys(packageJson.dependencies || {});
1184
+ codebaseAnalysis.architecture = 'Node.js Application';
1185
+ }
1186
+
1187
+ // Check for source directories
1188
+ const srcExists = await fs.access('src').then(() => true).catch(() => false);
1189
+ const libExists = await fs.access('lib').then(() => true).catch(() => false);
1190
+ codebaseAnalysis.hasSourceCode = srcExists || libExists;
1191
+
1192
+ // Extract requirements complexity
1193
+ const requirements = requirementsContent.match(/WHEN|IF|WHILE|WHERE/g) || [];
1194
+ const complexity = requirements.length > 10 ? 'XL' :
1195
+ requirements.length > 6 ? 'L' :
1196
+ requirements.length > 3 ? 'M' : 'S';
1197
+
1198
+ // Identify gaps and implementation approaches
1199
+ const gaps = [];
1200
+ if (!codebaseAnalysis.hasSourceCode) {
1201
+ gaps.push("No existing source code structure - requires full implementation from scratch");
1202
+ }
1203
+ if (!codebaseAnalysis.techStack.includes('@modelcontextprotocol/sdk')) {
1204
+ gaps.push("MCP SDK integration required for AI tool compatibility");
1205
+ }
1206
+ if (requirementsContent.includes('database') || requirementsContent.includes('storage')) {
1207
+ gaps.push("Data storage layer needs to be designed and implemented");
1208
+ }
1209
+
1210
+ // Implementation strategy options
1211
+ const strategies = [
1212
+ {
1213
+ approach: "Extension",
1214
+ rationale: codebaseAnalysis.hasSourceCode ?
1215
+ "Extend existing codebase with new functionality" :
1216
+ "Not applicable - no existing codebase to extend",
1217
+ applicable: codebaseAnalysis.hasSourceCode,
1218
+ complexity: codebaseAnalysis.hasSourceCode ? 'M' : 'N/A',
1219
+ tradeoffs: codebaseAnalysis.hasSourceCode ?
1220
+ "Pros: Maintains consistency, faster development. Cons: May introduce technical debt" :
1221
+ "N/A"
1222
+ },
1223
+ {
1224
+ approach: "New Implementation",
1225
+ rationale: "Create new components following established patterns",
1226
+ applicable: true,
1227
+ complexity: complexity,
1228
+ tradeoffs: "Pros: Clean architecture, full control. Cons: More development time, integration complexity"
1229
+ },
1230
+ {
1231
+ approach: "Hybrid",
1232
+ rationale: "Combine extension of existing components with new development where needed",
1233
+ applicable: codebaseAnalysis.hasSourceCode,
1234
+ complexity: codebaseAnalysis.hasSourceCode ? 'L' : 'M',
1235
+ tradeoffs: "Pros: Balanced approach, optimal resource usage. Cons: Requires careful integration planning"
1236
+ }
1237
+ ];
1238
+
1239
+ const applicableStrategies = strategies.filter(s => s.applicable);
1240
+ const recommendedStrategy = applicableStrategies.find(s => s.approach === 'Hybrid') ||
1241
+ applicableStrategies.find(s => s.approach === 'New Implementation');
1242
+
1243
+ let report = `## Implementation Gap Analysis: ${featureName}\n\n`;
1244
+
1245
+ report += `### Analysis Summary\n`;
1246
+ report += `- **Feature Complexity**: ${complexity} (based on ${requirements.length} requirements)\n`;
1247
+ report += `- **Existing Codebase**: ${codebaseAnalysis.hasSourceCode ? 'Source code detected' : 'No source code structure'}\n`;
1248
+ report += `- **Technology Stack**: ${codebaseAnalysis.techStack.length} dependencies\n`;
1249
+ report += `- **Architecture Type**: ${codebaseAnalysis.architecture}\n\n`;
1250
+
1251
+ report += `### Existing Codebase Insights\n`;
1252
+ report += `- **Package Management**: ${codebaseAnalysis.hasPackageJson ? 'npm/package.json configured' : 'No package.json found'}\n`;
1253
+ report += `- **Source Structure**: ${codebaseAnalysis.hasSourceCode ? 'Established source directories' : 'No conventional source structure'}\n`;
1254
+ report += `- **Key Dependencies**: ${codebaseAnalysis.techStack.slice(0, 5).join(', ') || 'None detected'}\n\n`;
1255
+
1256
+ if (gaps.length > 0) {
1257
+ report += `### Implementation Gaps Identified\n`;
1258
+ gaps.forEach(gap => report += `- ${gap}\n`);
1259
+ report += `\n`;
1260
+ }
1261
+
1262
+ report += `### Implementation Strategy Options\n\n`;
1263
+ applicableStrategies.forEach(strategy => {
1264
+ report += `**${strategy.approach} Approach**:\n`;
1265
+ report += `- **Rationale**: ${strategy.rationale}\n`;
1266
+ report += `- **Complexity**: ${strategy.complexity}\n`;
1267
+ report += `- **Trade-offs**: ${strategy.tradeoffs}\n\n`;
1268
+ });
1269
+
1270
+ report += `### Technical Research Needs\n`;
1271
+ const researchNeeds = [];
1272
+ if (!codebaseAnalysis.techStack.includes('@modelcontextprotocol/sdk')) {
1273
+ researchNeeds.push("MCP SDK integration patterns and best practices");
1274
+ }
1275
+ if (requirementsContent.includes('template') || requirementsContent.includes('generation')) {
1276
+ researchNeeds.push("Template engine selection and implementation");
1277
+ }
1278
+ if (requirementsContent.includes('workflow') || requirementsContent.includes('state')) {
1279
+ researchNeeds.push("State machine or workflow engine patterns");
1280
+ }
1281
+
1282
+ if (researchNeeds.length > 0) {
1283
+ researchNeeds.forEach(need => report += `- ${need}\n`);
1284
+ } else {
1285
+ report += `- No significant research dependencies identified\n`;
1286
+ }
1287
+ report += `\n`;
1288
+
1289
+ report += `### Recommendations for Design Phase\n`;
1290
+ report += `- **Preferred Approach**: ${recommendedStrategy.approach} (${recommendedStrategy.complexity} complexity)\n`;
1291
+ report += `- **Key Decisions**: Architecture patterns, technology integration, component boundaries\n`;
1292
+ report += `- **Risk Mitigation**: ${complexity === 'XL' || complexity === 'L' ? 'Consider phased implementation approach' : 'Standard development approach acceptable'}\n`;
1293
+ report += `- **Next Step**: Use this analysis to inform technical design decisions\n`;
1294
+
1295
+ return {
1296
+ content: [{
1297
+ type: 'text',
1298
+ text: report
1299
+ }]
1300
+ };
1301
+ } catch (error) {
1302
+ return {
1303
+ content: [{
1304
+ type: 'text',
1305
+ text: `Error analyzing implementation gap: ${error.message}`
1306
+ }]
1307
+ };
1308
+ }
1309
+ });
1310
+
1311
+ // 15. sdd-spec-impl - Execute spec tasks using TDD
1312
+ server.registerTool("sdd-spec-impl", {
1313
+ title: "Execute Spec Tasks with TDD",
1314
+ description: "Execute spec tasks using TDD methodology",
1315
+ inputSchema: {
1316
+ featureName: z.string().describe('Feature name to execute tasks for'),
1317
+ taskNumbers: z.string().optional().describe('Specific task numbers to execute (e.g., "1.1,2.3" or leave empty for all pending)')
1318
+ },
1319
+ }, async ({ featureName, taskNumbers }) => {
1320
+ try {
1321
+ const currentPath = process.cwd();
1322
+ const featurePath = path.join(currentPath, '.kiro', 'specs', featureName);
1323
+ const tasksPath = path.join(featurePath, 'tasks.md');
1324
+ const requirementsPath = path.join(featurePath, 'requirements.md');
1325
+ const designPath = path.join(featurePath, 'design.md');
1326
+ const specPath = path.join(featurePath, 'spec.json');
1327
+
1328
+ // Validate required files exist
1329
+ const requiredFiles = [
1330
+ { path: requirementsPath, name: 'requirements.md' },
1331
+ { path: designPath, name: 'design.md' },
1332
+ { path: tasksPath, name: 'tasks.md' },
1333
+ { path: specPath, name: 'spec.json' }
1334
+ ];
1335
+
1336
+ for (const file of requiredFiles) {
1337
+ const exists = await fs.access(file.path).then(() => true).catch(() => false);
1338
+ if (!exists) {
1339
+ return {
1340
+ content: [{
1341
+ type: 'text',
1342
+ text: `Error: Required file ${file.name} not found. Complete the full spec workflow first:\n1. sdd-requirements ${featureName}\n2. sdd-design ${featureName}\n3. sdd-tasks ${featureName}`
1343
+ }]
1344
+ };
1345
+ }
1346
+ }
1347
+
1348
+ // Load all context documents
1349
+ const tasksContent = await fs.readFile(tasksPath, 'utf8');
1350
+ const specContent = await fs.readFile(specPath, 'utf8');
1351
+ const spec = JSON.parse(specContent);
1352
+
1353
+ // Parse tasks to find pending ones
1354
+ const taskLines = tasksContent.split('\n');
1355
+ const tasks = [];
1356
+ let currentMajorTask = null;
1357
+
1358
+ for (let i = 0; i < taskLines.length; i++) {
1359
+ const line = taskLines[i].trim();
1360
+
1361
+ // Match major tasks (- [ ] 1. Task name)
1362
+ const majorMatch = line.match(/^- \[([ x])\] (\d+)\. (.+)$/);
1363
+ if (majorMatch) {
1364
+ currentMajorTask = {
1365
+ number: majorMatch[2],
1366
+ description: majorMatch[3],
1367
+ completed: majorMatch[1] === 'x',
1368
+ subtasks: []
1369
+ };
1370
+ tasks.push(currentMajorTask);
1371
+ continue;
1372
+ }
1373
+
1374
+ // Match sub-tasks (- [ ] 1.1 Subtask name)
1375
+ const subMatch = line.match(/^- \[([ x])\] (\d+\.\d+) (.+)$/);
1376
+ if (subMatch && currentMajorTask) {
1377
+ currentMajorTask.subtasks.push({
1378
+ number: subMatch[2],
1379
+ description: subMatch[3],
1380
+ completed: subMatch[1] === 'x'
1381
+ });
1382
+ }
1383
+ }
1384
+
1385
+ // Filter tasks based on taskNumbers parameter
1386
+ let tasksToExecute = [];
1387
+ if (taskNumbers) {
1388
+ const requestedNumbers = taskNumbers.split(',').map(n => n.trim());
1389
+ for (const task of tasks) {
1390
+ if (requestedNumbers.includes(task.number) && !task.completed) {
1391
+ tasksToExecute.push({ type: 'major', task });
1392
+ }
1393
+ for (const subtask of task.subtasks) {
1394
+ if (requestedNumbers.includes(subtask.number) && !subtask.completed) {
1395
+ tasksToExecute.push({ type: 'subtask', task: subtask, parent: task });
1396
+ }
1397
+ }
1398
+ }
1399
+ } else {
1400
+ // Get all pending tasks
1401
+ for (const task of tasks) {
1402
+ if (!task.completed) {
1403
+ tasksToExecute.push({ type: 'major', task });
1404
+ }
1405
+ for (const subtask of task.subtasks) {
1406
+ if (!subtask.completed) {
1407
+ tasksToExecute.push({ type: 'subtask', task: subtask, parent: task });
1408
+ }
1409
+ }
1410
+ }
1411
+ }
1412
+
1413
+ if (tasksToExecute.length === 0) {
1414
+ return {
1415
+ content: [{
1416
+ type: 'text',
1417
+ text: `## No Pending Tasks Found\n\n**Feature**: ${featureName}\n**Status**: ${taskNumbers ? 'Specified tasks already completed or not found' : 'All tasks already completed'}\n\n${taskNumbers ? `**Requested**: ${taskNumbers}` : '**All tasks**: ✅ Completed'}\n\nUse \`sdd-status ${featureName}\` to check current progress.`
1418
+ }]
1419
+ };
1420
+ }
1421
+
1422
+ // Generate TDD implementation guidance for the tasks
1423
+ let report = `## TDD Implementation Execution: ${featureName}\n\n`;
1424
+ report += `**Tasks to Execute**: ${tasksToExecute.length} pending tasks\n`;
1425
+ report += `**TDD Methodology**: Kent Beck's Red → Green → Refactor cycle\n\n`;
1426
+
1427
+ report += `### Context Loaded\n`;
1428
+ report += `- ✅ Requirements: .kiro/specs/${featureName}/requirements.md\n`;
1429
+ report += `- ✅ Design: .kiro/specs/${featureName}/design.md\n`;
1430
+ report += `- ✅ Tasks: .kiro/specs/${featureName}/tasks.md\n`;
1431
+ report += `- ✅ Metadata: .kiro/specs/${featureName}/spec.json\n\n`;
1432
+
1433
+ report += `### TDD Implementation Plan\n\n`;
1434
+
1435
+ tasksToExecute.slice(0, 5).forEach((item, index) => {
1436
+ const task = item.task;
1437
+ const taskNumber = item.type === 'subtask' ? task.number : task.number;
1438
+ const taskDesc = task.description;
1439
+
1440
+ report += `**Task ${taskNumber}**: ${taskDesc}\n\n`;
1441
+ report += `**TDD Cycle for this task**:\n`;
1442
+ report += `1. 🔴 **RED**: Write failing tests for "${taskDesc}"\n`;
1443
+ report += ` - Define test cases that specify expected behavior\n`;
1444
+ report += ` - Ensure tests fail initially (no implementation yet)\n`;
1445
+ report += ` - Verify test framework and setup is working\n\n`;
1446
+
1447
+ report += `2. 🟢 **GREEN**: Write minimal code to pass tests\n`;
1448
+ report += ` - Implement only what's needed to make tests pass\n`;
1449
+ report += ` - Focus on making it work, not making it perfect\n`;
1450
+ report += ` - Avoid over-engineering at this stage\n\n`;
1451
+
1452
+ report += `3. 🔵 **REFACTOR**: Clean up and improve code structure\n`;
1453
+ report += ` - Improve code quality while keeping tests green\n`;
1454
+ report += ` - Remove duplication and improve naming\n`;
1455
+ report += ` - Ensure code follows project conventions\n\n`;
1456
+
1457
+ report += `4. ✅ **VERIFY**: Complete task verification\n`;
1458
+ report += ` - All tests pass (new and existing)\n`;
1459
+ report += ` - Code quality meets standards\n`;
1460
+ report += ` - No regressions in existing functionality\n`;
1461
+ report += ` - Mark task as completed: \`- [x] ${taskNumber} ${taskDesc}\`\n\n`;
1462
+ });
1463
+
1464
+ if (tasksToExecute.length > 5) {
1465
+ report += `... and ${tasksToExecute.length - 5} more tasks\n\n`;
1466
+ }
1467
+
1468
+ report += `### Implementation Guidelines\n`;
1469
+ report += `- **Follow design specifications**: Implement exactly what's specified in design.md\n`;
1470
+ report += `- **Test-first approach**: Always write tests before implementation code\n`;
1471
+ report += `- **Incremental progress**: Complete one task fully before moving to next\n`;
1472
+ report += `- **Update task status**: Mark checkboxes as completed in tasks.md\n`;
1473
+ report += `- **Quality focus**: Maintain code quality and test coverage\n\n`;
1474
+
1475
+ report += `### Next Steps\n`;
1476
+ report += `1. Start with the first pending task: "${tasksToExecute[0].task.description}"\n`;
1477
+ report += `2. Follow the TDD cycle: Red → Green → Refactor → Verify\n`;
1478
+ report += `3. Update tasks.md to mark completed tasks with [x]\n`;
1479
+ report += `4. Run \`sdd-quality-check\` to validate code quality\n`;
1480
+ report += `5. Continue with remaining tasks sequentially\n\n`;
1481
+
1482
+ report += `**Remember**: TDD is about building confidence through tests. Write tests that clearly specify the expected behavior, then implement the simplest solution that makes those tests pass.`;
1483
+
1484
+ return {
1485
+ content: [{
1486
+ type: 'text',
1487
+ text: report
1488
+ }]
1489
+ };
1490
+ } catch (error) {
1491
+ return {
1492
+ content: [{
1493
+ type: 'text',
1494
+ text: `Error executing spec implementation: ${error.message}`
1495
+ }]
1496
+ };
1497
+ }
1498
+ });
1499
+
1500
+ const transport = new StdioServerTransport();
1501
+ await server.connect(transport);