@task-shepherd/agent 1.0.2

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.
@@ -0,0 +1,916 @@
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, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { ProjectAnalysisSchema, ImplementationPlanSchema } from './types.js';
6
+ import * as net from 'net';
7
+ class AgentMCPServer {
8
+ server;
9
+ analysisResults = new Map();
10
+ agentInteractions = new Map();
11
+ tcpClient = null;
12
+ agentPort;
13
+ constructor() {
14
+ // Agent TCP port from environment variable or default
15
+ this.agentPort = parseInt(process.env.AGENT_TCP_PORT || '8549');
16
+ this.server = new Server({
17
+ name: 'task-shepherd-agent-mcp',
18
+ version: '1.0.0',
19
+ }, {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ });
24
+ this.setupToolHandlers();
25
+ this.setupErrorHandling();
26
+ }
27
+ setupToolHandlers() {
28
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
29
+ tools: [
30
+ {
31
+ name: 'submit_project_analysis',
32
+ description: 'Submit structured project analysis results from Claude',
33
+ inputSchema: {
34
+ type: 'object',
35
+ properties: {
36
+ project_id: {
37
+ type: 'string',
38
+ description: 'Unique identifier for the project being analyzed'
39
+ },
40
+ analysis_type: {
41
+ type: 'string',
42
+ enum: ['project_review', 'development_plan', 'story_implementation'],
43
+ description: 'Type of analysis being performed'
44
+ },
45
+ executive_summary: {
46
+ type: 'string',
47
+ description: 'High-level summary of the analysis findings'
48
+ },
49
+ analysis: {
50
+ type: 'object',
51
+ properties: {
52
+ strengths: {
53
+ type: 'array',
54
+ items: {
55
+ type: 'object',
56
+ properties: {
57
+ title: { type: 'string' },
58
+ description: { type: 'string' },
59
+ impact: { type: 'string', enum: ['low', 'medium', 'high'] },
60
+ evidence: { type: 'array', items: { type: 'string' } }
61
+ },
62
+ required: ['title', 'description', 'impact']
63
+ }
64
+ },
65
+ weaknesses: {
66
+ type: 'array',
67
+ items: {
68
+ type: 'object',
69
+ properties: {
70
+ title: { type: 'string' },
71
+ description: { type: 'string' },
72
+ severity: { type: 'string', enum: ['low', 'medium', 'high'] },
73
+ affected_areas: { type: 'array', items: { type: 'string' } },
74
+ improvement_effort: { type: 'string', enum: ['minimal', 'moderate', 'significant'] }
75
+ },
76
+ required: ['title', 'description', 'severity']
77
+ }
78
+ },
79
+ risks: {
80
+ type: 'array',
81
+ items: {
82
+ type: 'object',
83
+ properties: {
84
+ title: { type: 'string' },
85
+ description: { type: 'string' },
86
+ probability: { type: 'string', enum: ['low', 'medium', 'high'] },
87
+ impact: { type: 'string', enum: ['low', 'medium', 'high'] },
88
+ mitigation_strategy: { type: 'string' }
89
+ },
90
+ required: ['title', 'description', 'probability', 'impact']
91
+ }
92
+ },
93
+ opportunities: {
94
+ type: 'array',
95
+ items: {
96
+ type: 'object',
97
+ properties: {
98
+ title: { type: 'string' },
99
+ description: { type: 'string' },
100
+ potential_value: { type: 'string', enum: ['low', 'medium', 'high'] },
101
+ implementation_complexity: { type: 'string', enum: ['simple', 'moderate', 'complex'] }
102
+ },
103
+ required: ['title', 'description', 'potential_value']
104
+ }
105
+ }
106
+ },
107
+ required: ['strengths', 'weaknesses', 'risks', 'opportunities']
108
+ },
109
+ scores: {
110
+ type: 'object',
111
+ properties: {
112
+ completeness: {
113
+ type: 'object',
114
+ properties: {
115
+ score: { type: 'number', minimum: 0, maximum: 100 },
116
+ reasoning: { type: 'string' }
117
+ },
118
+ required: ['score', 'reasoning']
119
+ },
120
+ clarity: {
121
+ type: 'object',
122
+ properties: {
123
+ score: { type: 'number', minimum: 0, maximum: 100 },
124
+ reasoning: { type: 'string' }
125
+ },
126
+ required: ['score', 'reasoning']
127
+ },
128
+ feasibility: {
129
+ type: 'object',
130
+ properties: {
131
+ score: { type: 'number', minimum: 0, maximum: 100 },
132
+ reasoning: { type: 'string' }
133
+ },
134
+ required: ['score', 'reasoning']
135
+ },
136
+ overall: {
137
+ type: 'object',
138
+ properties: {
139
+ score: { type: 'number', minimum: 0, maximum: 100 },
140
+ reasoning: { type: 'string' }
141
+ },
142
+ required: ['score', 'reasoning']
143
+ }
144
+ },
145
+ required: ['completeness', 'clarity', 'feasibility', 'overall']
146
+ },
147
+ recommendations: {
148
+ type: 'array',
149
+ items: {
150
+ type: 'object',
151
+ properties: {
152
+ id: { type: 'string' },
153
+ category: {
154
+ type: 'string',
155
+ enum: ['requirements', 'architecture', 'security', 'performance', 'maintainability', 'testing']
156
+ },
157
+ title: { type: 'string' },
158
+ description: { type: 'string' },
159
+ implementation_guide: { type: 'string' },
160
+ priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
161
+ estimated_effort: { type: 'string' },
162
+ business_impact: { type: 'string' },
163
+ technical_complexity: { type: 'string', enum: ['simple', 'moderate', 'complex'] }
164
+ },
165
+ required: ['id', 'category', 'title', 'description', 'priority']
166
+ }
167
+ },
168
+ timeline: {
169
+ type: 'object',
170
+ properties: {
171
+ total_duration_weeks: { type: 'number' },
172
+ phases: {
173
+ type: 'array',
174
+ items: {
175
+ type: 'object',
176
+ properties: {
177
+ id: { type: 'string' },
178
+ name: { type: 'string' },
179
+ description: { type: 'string' },
180
+ duration_weeks: { type: 'number' },
181
+ start_week: { type: 'number' },
182
+ dependencies: {
183
+ type: 'array',
184
+ items: { type: 'string' }
185
+ },
186
+ deliverables: {
187
+ type: 'array',
188
+ items: { type: 'string' }
189
+ },
190
+ key_milestones: {
191
+ type: 'array',
192
+ items: { type: 'string' }
193
+ },
194
+ resources_required: {
195
+ type: 'array',
196
+ items: { type: 'string' }
197
+ },
198
+ risks: {
199
+ type: 'array',
200
+ items: { type: 'string' }
201
+ }
202
+ },
203
+ required: ['id', 'name', 'description', 'duration_weeks', 'start_week']
204
+ }
205
+ }
206
+ },
207
+ required: ['total_duration_weeks', 'phases']
208
+ },
209
+ suggested_product_requirements: {
210
+ type: 'object',
211
+ properties: {
212
+ explicit_requirements: {
213
+ type: 'array',
214
+ items: {
215
+ type: 'object',
216
+ properties: {
217
+ requirement: { type: 'string' },
218
+ source_text: { type: 'string' },
219
+ confidence: { type: 'string', enum: ['high', 'medium', 'low'] }
220
+ },
221
+ required: ['requirement', 'source_text', 'confidence']
222
+ }
223
+ },
224
+ inferred_functional_requirements: {
225
+ type: 'array',
226
+ items: {
227
+ type: 'object',
228
+ properties: {
229
+ requirement: { type: 'string' },
230
+ rationale: { type: 'string' },
231
+ domain_pattern: { type: 'string' },
232
+ priority: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] }
233
+ },
234
+ required: ['requirement', 'rationale', 'domain_pattern', 'priority']
235
+ }
236
+ },
237
+ suggested_non_functional_requirements: {
238
+ type: 'array',
239
+ items: {
240
+ type: 'object',
241
+ properties: {
242
+ category: { type: 'string' },
243
+ requirement: { type: 'string' },
244
+ industry_standard: { type: 'boolean' },
245
+ customization_needed: { type: 'boolean' }
246
+ },
247
+ required: ['category', 'requirement', 'industry_standard', 'customization_needed']
248
+ }
249
+ },
250
+ requirements_clarification_questions: {
251
+ type: 'array',
252
+ items: {
253
+ type: 'object',
254
+ properties: {
255
+ category: { type: 'string' },
256
+ question: { type: 'string' },
257
+ impact_if_unclear: { type: 'string' },
258
+ suggested_default: { type: 'string' }
259
+ },
260
+ required: ['category', 'question', 'impact_if_unclear', 'suggested_default']
261
+ }
262
+ }
263
+ },
264
+ required: ['explicit_requirements', 'inferred_functional_requirements', 'suggested_non_functional_requirements', 'requirements_clarification_questions']
265
+ },
266
+ metadata: {
267
+ type: 'object',
268
+ properties: {
269
+ analysis_duration_seconds: { type: 'number' },
270
+ claude_model: { type: 'string' },
271
+ confidence_level: { type: 'number', minimum: 0, maximum: 1 },
272
+ analysis_timestamp: { type: 'string' },
273
+ reviewer_notes: { type: 'string' }
274
+ },
275
+ required: ['analysis_duration_seconds', 'claude_model', 'confidence_level', 'analysis_timestamp']
276
+ }
277
+ },
278
+ required: ['project_id', 'analysis_type', 'executive_summary', 'analysis', 'scores', 'recommendations', 'timeline', 'suggested_product_requirements', 'metadata']
279
+ }
280
+ },
281
+ {
282
+ name: 'get_analysis_result',
283
+ description: 'Retrieve a previously submitted analysis result',
284
+ inputSchema: {
285
+ type: 'object',
286
+ properties: {
287
+ project_id: {
288
+ type: 'string',
289
+ description: 'Unique identifier for the project'
290
+ }
291
+ },
292
+ required: ['project_id']
293
+ }
294
+ },
295
+ {
296
+ name: 'submit_implementation_plan',
297
+ description: 'Submit structured implementation plan analysis results from Claude',
298
+ inputSchema: {
299
+ type: 'object',
300
+ properties: {
301
+ project_id: {
302
+ type: 'string',
303
+ description: 'Unique identifier for the project being analyzed'
304
+ },
305
+ analysis_type: {
306
+ type: 'string',
307
+ enum: ['implementation_plan'],
308
+ description: 'Type of analysis being performed'
309
+ },
310
+ executive_summary: {
311
+ type: 'string',
312
+ description: 'High-level summary of the implementation plan findings'
313
+ },
314
+ analysis: {
315
+ type: 'object',
316
+ properties: {
317
+ strengths: {
318
+ type: 'array',
319
+ items: {
320
+ type: 'object',
321
+ properties: {
322
+ title: { type: 'string' },
323
+ description: { type: 'string' },
324
+ impact: { type: 'string', enum: ['low', 'medium', 'high'] },
325
+ evidence: { type: 'array', items: { type: 'string' } }
326
+ },
327
+ required: ['title', 'description', 'impact']
328
+ }
329
+ },
330
+ weaknesses: {
331
+ type: 'array',
332
+ items: {
333
+ type: 'object',
334
+ properties: {
335
+ title: { type: 'string' },
336
+ description: { type: 'string' },
337
+ severity: { type: 'string', enum: ['low', 'medium', 'high'] },
338
+ affected_areas: { type: 'array', items: { type: 'string' } },
339
+ improvement_effort: { type: 'string', enum: ['minimal', 'moderate', 'significant'] }
340
+ },
341
+ required: ['title', 'description', 'severity']
342
+ }
343
+ },
344
+ risks: {
345
+ type: 'array',
346
+ items: {
347
+ type: 'object',
348
+ properties: {
349
+ title: { type: 'string' },
350
+ description: { type: 'string' },
351
+ probability: { type: 'string', enum: ['low', 'medium', 'high'] },
352
+ impact: { type: 'string', enum: ['low', 'medium', 'high'] },
353
+ mitigation_strategy: { type: 'string' }
354
+ },
355
+ required: ['title', 'description', 'probability', 'impact']
356
+ }
357
+ },
358
+ opportunities: {
359
+ type: 'array',
360
+ items: {
361
+ type: 'object',
362
+ properties: {
363
+ title: { type: 'string' },
364
+ description: { type: 'string' },
365
+ potential_value: { type: 'string', enum: ['low', 'medium', 'high'] },
366
+ implementation_complexity: { type: 'string', enum: ['simple', 'moderate', 'complex'] }
367
+ },
368
+ required: ['title', 'description', 'potential_value']
369
+ }
370
+ }
371
+ },
372
+ required: ['strengths', 'weaknesses', 'risks', 'opportunities']
373
+ },
374
+ scores: {
375
+ type: 'object',
376
+ properties: {
377
+ completeness: {
378
+ type: 'object',
379
+ properties: {
380
+ score: { type: 'number', minimum: 0, maximum: 100 },
381
+ reasoning: { type: 'string' }
382
+ },
383
+ required: ['score', 'reasoning']
384
+ },
385
+ clarity: {
386
+ type: 'object',
387
+ properties: {
388
+ score: { type: 'number', minimum: 0, maximum: 100 },
389
+ reasoning: { type: 'string' }
390
+ },
391
+ required: ['score', 'reasoning']
392
+ },
393
+ feasibility: {
394
+ type: 'object',
395
+ properties: {
396
+ score: { type: 'number', minimum: 0, maximum: 100 },
397
+ reasoning: { type: 'string' }
398
+ },
399
+ required: ['score', 'reasoning']
400
+ },
401
+ overall: {
402
+ type: 'object',
403
+ properties: {
404
+ score: { type: 'number', minimum: 0, maximum: 100 },
405
+ reasoning: { type: 'string' }
406
+ },
407
+ required: ['score', 'reasoning']
408
+ }
409
+ },
410
+ required: ['completeness', 'clarity', 'feasibility', 'overall']
411
+ },
412
+ recommendations: {
413
+ type: 'array',
414
+ items: {
415
+ type: 'object',
416
+ properties: {
417
+ id: { type: 'string' },
418
+ category: { type: 'string', enum: ['requirements', 'architecture', 'security', 'performance', 'maintainability', 'testing'] },
419
+ title: { type: 'string' },
420
+ description: { type: 'string' },
421
+ priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
422
+ implementation_guide: { type: 'string' },
423
+ estimated_effort: { type: 'string' },
424
+ business_impact: { type: 'string' },
425
+ technical_complexity: { type: 'string', enum: ['simple', 'moderate', 'complex'] }
426
+ },
427
+ required: ['id', 'category', 'title', 'description', 'priority']
428
+ }
429
+ },
430
+ timeline: {
431
+ type: 'object',
432
+ properties: {
433
+ total_duration_weeks: { type: 'number' },
434
+ phases: {
435
+ type: 'array',
436
+ items: {
437
+ type: 'object',
438
+ properties: {
439
+ id: { type: 'string' },
440
+ name: { type: 'string' },
441
+ description: { type: 'string' },
442
+ duration_weeks: { type: 'number' },
443
+ start_week: { type: 'number' },
444
+ dependencies: {
445
+ type: 'array',
446
+ items: { type: 'string' }
447
+ },
448
+ deliverables: {
449
+ type: 'array',
450
+ items: { type: 'string' }
451
+ },
452
+ key_milestones: {
453
+ type: 'array',
454
+ items: { type: 'string' }
455
+ },
456
+ resources_required: {
457
+ type: 'array',
458
+ items: { type: 'string' }
459
+ },
460
+ risks: {
461
+ type: 'array',
462
+ items: { type: 'string' }
463
+ }
464
+ },
465
+ required: ['id', 'name', 'description', 'duration_weeks', 'start_week']
466
+ }
467
+ }
468
+ },
469
+ required: ['total_duration_weeks', 'phases']
470
+ },
471
+ suggested_product_requirements: {
472
+ type: 'object',
473
+ properties: {
474
+ explicit_requirements: {
475
+ type: 'array',
476
+ items: {
477
+ type: 'object',
478
+ properties: {
479
+ requirement: { type: 'string' },
480
+ source_text: { type: 'string' },
481
+ confidence: { type: 'string', enum: ['high', 'medium', 'low'] }
482
+ },
483
+ required: ['requirement', 'source_text', 'confidence']
484
+ }
485
+ },
486
+ inferred_functional_requirements: {
487
+ type: 'array',
488
+ items: {
489
+ type: 'object',
490
+ properties: {
491
+ requirement: { type: 'string' },
492
+ rationale: { type: 'string' },
493
+ domain_pattern: { type: 'string' },
494
+ priority: { type: 'string', enum: ['critical', 'high', 'medium', 'low'] }
495
+ },
496
+ required: ['requirement', 'rationale', 'domain_pattern', 'priority']
497
+ }
498
+ },
499
+ suggested_non_functional_requirements: {
500
+ type: 'array',
501
+ items: {
502
+ type: 'object',
503
+ properties: {
504
+ category: { type: 'string' },
505
+ requirement: { type: 'string' },
506
+ industry_standard: { type: 'boolean' },
507
+ customization_needed: { type: 'boolean' }
508
+ },
509
+ required: ['category', 'requirement', 'industry_standard', 'customization_needed']
510
+ }
511
+ },
512
+ requirements_clarification_questions: {
513
+ type: 'array',
514
+ items: {
515
+ type: 'object',
516
+ properties: {
517
+ category: { type: 'string' },
518
+ question: { type: 'string' },
519
+ impact_if_unclear: { type: 'string' },
520
+ suggested_default: { type: 'string' }
521
+ },
522
+ required: ['category', 'question', 'impact_if_unclear', 'suggested_default']
523
+ }
524
+ }
525
+ },
526
+ required: ['explicit_requirements', 'inferred_functional_requirements', 'suggested_non_functional_requirements', 'requirements_clarification_questions']
527
+ },
528
+ metadata: {
529
+ type: 'object',
530
+ properties: {
531
+ analysis_duration_seconds: { type: 'number' },
532
+ claude_model: { type: 'string' },
533
+ confidence_level: { type: 'number', minimum: 0, maximum: 1 },
534
+ analysis_timestamp: { type: 'string' },
535
+ reviewer_notes: { type: 'string' }
536
+ },
537
+ required: ['analysis_duration_seconds', 'claude_model', 'confidence_level', 'analysis_timestamp']
538
+ }
539
+ },
540
+ required: ['project_id', 'analysis_type', 'executive_summary', 'analysis', 'scores', 'recommendations', 'timeline', 'suggested_product_requirements', 'metadata']
541
+ }
542
+ },
543
+ {
544
+ name: 'submit_task_implementation',
545
+ description: 'Submit structured implementation results for a task',
546
+ inputSchema: {
547
+ type: 'object',
548
+ properties: {
549
+ task_id: {
550
+ type: 'string',
551
+ description: 'Unique identifier for the task'
552
+ },
553
+ implementation_summary: {
554
+ type: 'string',
555
+ description: 'Summary of what was implemented'
556
+ },
557
+ files_modified: {
558
+ type: 'array',
559
+ items: {
560
+ type: 'object',
561
+ properties: {
562
+ path: { type: 'string' },
563
+ change_type: { type: 'string', enum: ['created', 'modified', 'deleted'] },
564
+ summary: { type: 'string' }
565
+ },
566
+ required: ['path', 'change_type', 'summary']
567
+ }
568
+ },
569
+ tests_added: {
570
+ type: 'array',
571
+ items: { type: 'string' },
572
+ description: 'List of test files or test descriptions'
573
+ },
574
+ completion_status: {
575
+ type: 'string',
576
+ enum: ['completed', 'partial', 'blocked'],
577
+ description: 'Status of task completion'
578
+ },
579
+ blockers: {
580
+ type: 'array',
581
+ items: { type: 'string' },
582
+ description: 'Any blockers encountered'
583
+ }
584
+ },
585
+ required: ['task_id', 'implementation_summary', 'files_modified', 'completion_status']
586
+ }
587
+ },
588
+ {
589
+ name: 'submit_story_progress',
590
+ description: 'Submit progress update for a story implementation',
591
+ inputSchema: {
592
+ type: 'object',
593
+ properties: {
594
+ story_id: {
595
+ type: 'string',
596
+ description: 'Unique identifier for the story'
597
+ },
598
+ tasks_completed: {
599
+ type: 'array',
600
+ items: { type: 'string' },
601
+ description: 'IDs of completed tasks'
602
+ },
603
+ tasks_remaining: {
604
+ type: 'array',
605
+ items: { type: 'string' },
606
+ description: 'IDs of remaining tasks'
607
+ },
608
+ overall_progress: {
609
+ type: 'number',
610
+ minimum: 0,
611
+ maximum: 100,
612
+ description: 'Overall completion percentage'
613
+ },
614
+ status_summary: {
615
+ type: 'string',
616
+ description: 'Current status summary'
617
+ },
618
+ next_steps: {
619
+ type: 'array',
620
+ items: { type: 'string' },
621
+ description: 'Next steps to be taken'
622
+ }
623
+ },
624
+ required: ['story_id', 'overall_progress', 'status_summary']
625
+ }
626
+ }
627
+ ]
628
+ }));
629
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
630
+ const { name, arguments: args } = request.params;
631
+ console.error(`[MCP] Tool called: ${name}`);
632
+ console.error(`[MCP] Args received:`, JSON.stringify(args, null, 2));
633
+ console.error(`[MCP] Args keys:`, Object.keys(args || {}));
634
+ console.error(`[MCP] Args stringified length:`, JSON.stringify(args).length);
635
+ if (name === 'submit_project_analysis') {
636
+ try {
637
+ console.error(`[MCP] Starting validation of analysis data`);
638
+ // Validate the analysis data
639
+ const validatedAnalysis = ProjectAnalysisSchema.parse(args);
640
+ console.error(`[MCP] Validation successful, storing result`);
641
+ // Store the analysis result
642
+ this.analysisResults.set(validatedAnalysis.project_id, validatedAnalysis);
643
+ console.error(`[MCP] Sending to agent via TCP`);
644
+ // Send to agent via TCP
645
+ await this.sendToAgent({
646
+ type: 'analysis_complete',
647
+ projectId: validatedAnalysis.project_id,
648
+ analysisType: validatedAnalysis.analysis_type,
649
+ data: validatedAnalysis
650
+ });
651
+ console.error(`[MCP] TCP send completed, returning success response`);
652
+ // Return success response with summary
653
+ return {
654
+ content: [
655
+ {
656
+ type: 'text',
657
+ text: JSON.stringify({
658
+ success: true,
659
+ project_id: validatedAnalysis.project_id,
660
+ analysis_type: validatedAnalysis.analysis_type,
661
+ summary: {
662
+ overall_score: validatedAnalysis.scores.overall.score,
663
+ strengths_count: validatedAnalysis.analysis.strengths.length,
664
+ weaknesses_count: validatedAnalysis.analysis.weaknesses.length,
665
+ risks_count: validatedAnalysis.analysis.risks.length,
666
+ recommendations_count: validatedAnalysis.recommendations.length
667
+ },
668
+ message: 'Analysis submitted successfully and validated.'
669
+ }, null, 2)
670
+ }
671
+ ]
672
+ };
673
+ }
674
+ catch (error) {
675
+ console.error(`[MCP] Error in submit_project_analysis:`, error);
676
+ return {
677
+ content: [
678
+ {
679
+ type: 'text',
680
+ text: JSON.stringify({
681
+ success: false,
682
+ error: 'Validation failed',
683
+ details: error instanceof Error ? error.message : 'Unknown error',
684
+ help: 'Please ensure all required fields are provided with correct types and values.'
685
+ }, null, 2)
686
+ }
687
+ ]
688
+ };
689
+ }
690
+ }
691
+ if (name === 'submit_implementation_plan') {
692
+ try {
693
+ console.error(`[MCP] Starting validation of implementation plan data`);
694
+ // Validate the implementation plan data using the specific schema
695
+ const validatedPlan = ImplementationPlanSchema.parse(args);
696
+ console.error(`[MCP] Validation successful, storing implementation plan result`);
697
+ // Store the implementation plan result with a different key pattern
698
+ this.analysisResults.set(`impl_plan_${validatedPlan.project_id}`, validatedPlan);
699
+ console.error(`[MCP] Sending implementation plan to agent via TCP`);
700
+ // Send to agent via TCP
701
+ await this.sendToAgent({
702
+ type: 'implementation_plan_complete',
703
+ projectId: validatedPlan.project_id,
704
+ analysisType: validatedPlan.analysis_type,
705
+ data: validatedPlan
706
+ });
707
+ console.error(`[MCP] TCP send completed, returning success response`);
708
+ // Return success response with summary
709
+ return {
710
+ content: [
711
+ {
712
+ type: 'text',
713
+ text: JSON.stringify({
714
+ success: true,
715
+ project_id: validatedPlan.project_id,
716
+ analysis_type: validatedPlan.analysis_type,
717
+ summary: {
718
+ executive_summary_length: validatedPlan.executive_summary.length,
719
+ strengths_count: validatedPlan.analysis.strengths.length,
720
+ weaknesses_count: validatedPlan.analysis.weaknesses.length,
721
+ risks_count: validatedPlan.analysis.risks.length,
722
+ recommendations_count: validatedPlan.recommendations.length,
723
+ timeline_phases: validatedPlan.timeline.phases.length,
724
+ overall_score: validatedPlan.scores.overall.score
725
+ },
726
+ message: 'Implementation plan submitted successfully and validated.'
727
+ }, null, 2)
728
+ }
729
+ ]
730
+ };
731
+ }
732
+ catch (error) {
733
+ console.error(`[MCP] Error in submit_implementation_plan:`, error);
734
+ return {
735
+ content: [
736
+ {
737
+ type: 'text',
738
+ text: JSON.stringify({
739
+ success: false,
740
+ error: 'Validation failed',
741
+ details: error instanceof Error ? error.message : 'Unknown error',
742
+ help: 'Please ensure all required fields are provided with correct types and values for the implementation plan.'
743
+ }, null, 2)
744
+ }
745
+ ]
746
+ };
747
+ }
748
+ }
749
+ if (name === 'get_analysis_result') {
750
+ const projectId = args?.project_id;
751
+ const analysis = this.analysisResults.get(projectId);
752
+ if (!analysis) {
753
+ return {
754
+ content: [
755
+ {
756
+ type: 'text',
757
+ text: JSON.stringify({
758
+ success: false,
759
+ error: 'Analysis not found',
760
+ project_id: projectId
761
+ }, null, 2)
762
+ }
763
+ ]
764
+ };
765
+ }
766
+ return {
767
+ content: [
768
+ {
769
+ type: 'text',
770
+ text: JSON.stringify({
771
+ success: true,
772
+ analysis: analysis
773
+ }, null, 2)
774
+ }
775
+ ]
776
+ };
777
+ }
778
+ if (name === 'submit_task_implementation') {
779
+ try {
780
+ // Store task implementation data
781
+ this.agentInteractions.set(`task_${args?.task_id}`, args);
782
+ return {
783
+ content: [
784
+ {
785
+ type: 'text',
786
+ text: JSON.stringify({
787
+ success: true,
788
+ task_id: args?.task_id,
789
+ completion_status: args?.completion_status,
790
+ files_modified_count: args?.files_modified?.length || 0,
791
+ message: 'Task implementation details submitted successfully.'
792
+ }, null, 2)
793
+ }
794
+ ]
795
+ };
796
+ }
797
+ catch (error) {
798
+ return {
799
+ content: [
800
+ {
801
+ type: 'text',
802
+ text: JSON.stringify({
803
+ success: false,
804
+ error: 'Failed to submit task implementation',
805
+ details: error instanceof Error ? error.message : 'Unknown error'
806
+ }, null, 2)
807
+ }
808
+ ]
809
+ };
810
+ }
811
+ }
812
+ if (name === 'submit_story_progress') {
813
+ try {
814
+ // Store story progress data
815
+ this.agentInteractions.set(`story_${args?.story_id}`, args);
816
+ return {
817
+ content: [
818
+ {
819
+ type: 'text',
820
+ text: JSON.stringify({
821
+ success: true,
822
+ story_id: args?.story_id,
823
+ overall_progress: args?.overall_progress,
824
+ tasks_completed: args?.tasks_completed?.length || 0,
825
+ tasks_remaining: args?.tasks_remaining?.length || 0,
826
+ message: 'Story progress submitted successfully.'
827
+ }, null, 2)
828
+ }
829
+ ]
830
+ };
831
+ }
832
+ catch (error) {
833
+ return {
834
+ content: [
835
+ {
836
+ type: 'text',
837
+ text: JSON.stringify({
838
+ success: false,
839
+ error: 'Failed to submit story progress',
840
+ details: error instanceof Error ? error.message : 'Unknown error'
841
+ }, null, 2)
842
+ }
843
+ ]
844
+ };
845
+ }
846
+ }
847
+ throw new Error(`Unknown tool: ${name}`);
848
+ });
849
+ }
850
+ async connectToAgent() {
851
+ return new Promise((resolve, reject) => {
852
+ console.error(`Attempting to connect to agent TCP server on localhost:${this.agentPort}`);
853
+ this.tcpClient = net.connect(this.agentPort, 'localhost', () => {
854
+ console.error(`✓ Successfully connected to agent TCP server on port ${this.agentPort}`);
855
+ resolve();
856
+ });
857
+ this.tcpClient.on('error', (error) => {
858
+ console.error(`✗ TCP connection error to localhost:${this.agentPort}:`, error.message);
859
+ this.tcpClient = null;
860
+ reject(error);
861
+ });
862
+ this.tcpClient.on('close', () => {
863
+ console.error(`TCP connection to agent closed`);
864
+ this.tcpClient = null;
865
+ });
866
+ // Add connection timeout
867
+ setTimeout(() => {
868
+ if (this.tcpClient && !this.tcpClient.connecting && !this.tcpClient.readyState) {
869
+ console.error(`TCP connection timeout after 5 seconds`);
870
+ this.tcpClient.destroy();
871
+ reject(new Error('TCP connection timeout'));
872
+ }
873
+ }, 5000);
874
+ });
875
+ }
876
+ async sendToAgent(message) {
877
+ console.error(`Sending message to agent:`, { type: message.type, projectId: message.projectId });
878
+ if (!this.tcpClient) {
879
+ try {
880
+ await this.connectToAgent();
881
+ }
882
+ catch (error) {
883
+ console.error('Failed to connect to agent:', error);
884
+ throw error; // Propagate error instead of silently returning
885
+ }
886
+ }
887
+ if (this.tcpClient) {
888
+ const messageStr = JSON.stringify(message) + '\n';
889
+ console.error(`Writing message to TCP socket: ${messageStr.substring(0, 100)}...`);
890
+ this.tcpClient.write(messageStr);
891
+ console.error(`✓ Message sent to agent successfully`);
892
+ }
893
+ else {
894
+ throw new Error('No TCP connection available to agent');
895
+ }
896
+ }
897
+ setupErrorHandling() {
898
+ this.server.onerror = (error) => {
899
+ console.error('[MCP Error]', error);
900
+ };
901
+ process.on('SIGINT', async () => {
902
+ if (this.tcpClient) {
903
+ this.tcpClient.destroy();
904
+ }
905
+ await this.server.close();
906
+ process.exit(0);
907
+ });
908
+ }
909
+ async run() {
910
+ const transport = new StdioServerTransport();
911
+ await this.server.connect(transport);
912
+ console.error('Task Shepherd Agent MCP Server running on stdio');
913
+ }
914
+ }
915
+ const server = new AgentMCPServer();
916
+ server.run().catch(console.error);