@codemcp/workflows 5.0.1 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/package.json +6 -2
  2. package/skill/SKILL.md +23 -0
  3. package/.prettierignore +0 -2
  4. package/.turbo/turbo-build.log +0 -4
  5. package/.vibe/conversation-state.sqlite +0 -0
  6. package/src/components/beads/beads-instruction-generator.ts +0 -230
  7. package/src/components/beads/beads-plan-manager.ts +0 -333
  8. package/src/components/beads/beads-task-backend-client.ts +0 -229
  9. package/src/index.ts +0 -93
  10. package/src/notification-service.ts +0 -23
  11. package/src/plugin-system/beads-plugin.ts +0 -649
  12. package/src/plugin-system/commit-plugin.ts +0 -252
  13. package/src/plugin-system/index.ts +0 -20
  14. package/src/plugin-system/plugin-interfaces.ts +0 -153
  15. package/src/plugin-system/plugin-registry.ts +0 -190
  16. package/src/resource-handlers/conversation-state.ts +0 -55
  17. package/src/resource-handlers/development-plan.ts +0 -48
  18. package/src/resource-handlers/index.ts +0 -73
  19. package/src/resource-handlers/system-prompt.ts +0 -55
  20. package/src/resource-handlers/workflow-resource.ts +0 -132
  21. package/src/response-renderer.ts +0 -116
  22. package/src/server-config.ts +0 -760
  23. package/src/server-helpers.ts +0 -245
  24. package/src/server-implementation.ts +0 -277
  25. package/src/server.ts +0 -9
  26. package/src/tool-handlers/base-tool-handler.ts +0 -151
  27. package/src/tool-handlers/conduct-review.ts +0 -190
  28. package/src/tool-handlers/get-tool-info.ts +0 -273
  29. package/src/tool-handlers/index.ts +0 -115
  30. package/src/tool-handlers/list-workflows.ts +0 -78
  31. package/src/tool-handlers/no-idea.ts +0 -47
  32. package/src/tool-handlers/proceed-to-phase.ts +0 -296
  33. package/src/tool-handlers/reset-development.ts +0 -90
  34. package/src/tool-handlers/resume-workflow.ts +0 -378
  35. package/src/tool-handlers/setup-project-docs.ts +0 -232
  36. package/src/tool-handlers/start-development.ts +0 -746
  37. package/src/tool-handlers/whats-next.ts +0 -246
  38. package/src/types.ts +0 -135
  39. package/src/version-info.ts +0 -213
  40. package/test/e2e/beads-plugin-integration.test.ts +0 -1623
  41. package/test/e2e/commit-plugin-integration.test.ts +0 -222
  42. package/test/e2e/core-functionality.test.ts +0 -167
  43. package/test/e2e/git-branch-detection.test.ts +0 -351
  44. package/test/e2e/mcp-contract.test.ts +0 -509
  45. package/test/e2e/plan-management.test.ts +0 -334
  46. package/test/e2e/plugin-system-integration.test.ts +0 -1410
  47. package/test/e2e/state-management.test.ts +0 -387
  48. package/test/e2e/workflow-integration.test.ts +0 -498
  49. package/test/unit/beads-instruction-generator.test.ts +0 -979
  50. package/test/unit/beads-phase-task-id-integration.test.ts +0 -535
  51. package/test/unit/beads-plugin-behavioral.test.ts +0 -545
  52. package/test/unit/beads-plugin.test.ts +0 -117
  53. package/test/unit/commit-plugin.test.ts +0 -196
  54. package/test/unit/conduct-review.test.ts +0 -151
  55. package/test/unit/conversation-not-found-error.test.ts +0 -120
  56. package/test/unit/plugin-error-handling.test.ts +0 -240
  57. package/test/unit/proceed-to-phase-plugin-integration.test.ts +0 -150
  58. package/test/unit/reset-functionality.test.ts +0 -72
  59. package/test/unit/resume-workflow.test.ts +0 -193
  60. package/test/unit/server-config-plugin-registry.test.ts +0 -99
  61. package/test/unit/server-tools.test.ts +0 -310
  62. package/test/unit/setup-project-docs-handler.test.ts +0 -268
  63. package/test/unit/start-development-artifact-detection.test.ts +0 -387
  64. package/test/unit/start-development-gitignore.test.ts +0 -178
  65. package/test/unit/start-development-goal-extraction.test.ts +0 -226
  66. package/test/unit/system-prompt-resource.test.ts +0 -102
  67. package/test/unit/tool-handlers/no-idea.test.ts +0 -40
  68. package/test/utils/e2e-test-setup.ts +0 -451
  69. package/test/utils/run-server-in-dir.sh +0 -27
  70. package/test/utils/temp-files.ts +0 -320
  71. package/test/utils/test-access.ts +0 -79
  72. package/test/utils/test-helpers.ts +0 -288
  73. package/test/utils/test-setup.ts +0 -77
  74. package/tsconfig.build.json +0 -10
  75. package/tsconfig.build.tsbuildinfo +0 -1
  76. package/tsconfig.json +0 -12
  77. package/vitest.config.ts +0 -19
@@ -1,760 +0,0 @@
1
- /**
2
- * Server Configuration
3
- *
4
- * Handles server configuration, component initialization, and MCP server setup.
5
- * Centralizes the configuration logic that was previously scattered in the main server class.
6
- */
7
-
8
- import { z } from 'zod';
9
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
- import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
11
- import type { Variables } from '@modelcontextprotocol/sdk/shared/uriTemplate.js';
12
- import { SetLevelRequestSchema } from '@modelcontextprotocol/sdk/types.js';
13
- import * as path from 'node:path';
14
-
15
- import { FileStorage } from '@codemcp/workflows-core';
16
- import type { IPersistence } from '@codemcp/workflows-core';
17
- import { ConversationManager } from '@codemcp/workflows-core';
18
- import { TransitionEngine } from '@codemcp/workflows-core';
19
- import { InteractionLogger } from '@codemcp/workflows-core';
20
- import { WorkflowManager } from '@codemcp/workflows-core';
21
- import { TemplateManager } from '@codemcp/workflows-core';
22
- import { createLogger, setMcpLoggingLevel } from '@codemcp/workflows-core';
23
-
24
- import {
25
- ServerConfig,
26
- ServerContext,
27
- ToolRegistry,
28
- ResourceRegistry,
29
- ResponseRenderer,
30
- } from './types.js';
31
- import {
32
- normalizeProjectPath,
33
- buildWorkflowEnum,
34
- generateWorkflowDescription,
35
- } from './server-helpers.js';
36
- import { notificationService } from './notification-service.js';
37
- import {
38
- PlanManager,
39
- InstructionGenerator,
40
- TaskBackendManager,
41
- } from '@codemcp/workflows-core';
42
- import { PluginRegistry } from './plugin-system/plugin-registry.js';
43
- import { BeadsPlugin } from './plugin-system/beads-plugin.js';
44
- import { CommitPlugin } from './plugin-system/commit-plugin.js';
45
- import { BeadsPlanManager } from './components/beads/beads-plan-manager.js';
46
- import { BeadsInstructionGenerator } from './components/beads/beads-instruction-generator.js';
47
-
48
- const logger = createLogger('ServerConfig');
49
-
50
- /**
51
- * Server component container
52
- * Holds all the initialized server components
53
- */
54
- export interface ServerComponents {
55
- mcpServer: McpServer;
56
- database: IPersistence;
57
- context: ServerContext;
58
- toolRegistry: ToolRegistry;
59
- resourceRegistry: ResourceRegistry;
60
- responseRenderer: ResponseRenderer;
61
- }
62
-
63
- /**
64
- * Initialize all server components
65
- */
66
- export async function initializeServerComponents(
67
- config: ServerConfig = {}
68
- ): Promise<ServerComponents> {
69
- logger.debug('Initializing server components', {
70
- config: JSON.stringify(config),
71
- });
72
-
73
- // Set project path with support for environment variable
74
- const projectPath = normalizeProjectPath(
75
- config.projectPath || process.env.PROJECT_PATH
76
- );
77
-
78
- logger.info('Using project path', {
79
- projectPath,
80
- source: config.projectPath
81
- ? 'config'
82
- : process.env.PROJECT_PATH
83
- ? 'env'
84
- : 'default',
85
- });
86
-
87
- // Initialize MCP server
88
- const mcpServer = new McpServer(
89
- {
90
- name: 'responsible-vibe-mcp',
91
- version: '1.0.0',
92
- },
93
- {
94
- capabilities: {
95
- logging: {},
96
- },
97
- }
98
- );
99
-
100
- // Register logging/setLevel handler to support MCP inspector
101
- mcpServer.server.setRequestHandler(SetLevelRequestSchema, async request => {
102
- const level = request.params.level;
103
- logger.info('Setting logging level from MCP client', { level });
104
-
105
- // Set the unified logging level
106
- setMcpLoggingLevel(level);
107
-
108
- return {};
109
- });
110
-
111
- // Initialize core components
112
- logger.debug('Initializing core components');
113
- const database = new FileStorage(
114
- path.join(projectPath, '.vibe', 'conversation.sqlite')
115
- );
116
- const workflowManager = new WorkflowManager();
117
- const conversationManager = new ConversationManager(
118
- database,
119
- workflowManager,
120
- projectPath
121
- );
122
- const transitionEngine = new TransitionEngine(projectPath);
123
- transitionEngine.setConversationManager(conversationManager);
124
-
125
- // Detect task backend using auto-detection logic:
126
- // - If TASK_BACKEND env var is set, use that value
127
- // - If not set, auto-detect based on 'bd' command availability
128
- const taskBackendConfig = TaskBackendManager.detectTaskBackend();
129
- const isBeadsBackend =
130
- taskBackendConfig.backend === 'beads' && taskBackendConfig.isAvailable;
131
-
132
- logger.info('Task backend configuration', {
133
- backend: taskBackendConfig.backend,
134
- isAvailable: taskBackendConfig.isAvailable,
135
- autoDetected: !process.env['TASK_BACKEND'],
136
- });
137
-
138
- const planManager = isBeadsBackend
139
- ? new BeadsPlanManager()
140
- : new PlanManager();
141
- const instructionGenerator = isBeadsBackend
142
- ? new BeadsInstructionGenerator()
143
- : new InstructionGenerator(planManager as InstanceType<typeof PlanManager>);
144
-
145
- // Always create interaction logger as it's critical for transition engine logic
146
- // (determining first call from initial state)
147
- const interactionLogger = new InteractionLogger(database);
148
-
149
- // Initialize plugin registry and register plugins
150
- const pluginRegistry = new PluginRegistry();
151
-
152
- // Register CommitPlugin if commit behavior is configured
153
- if (process.env.COMMIT_BEHAVIOR) {
154
- const commitPlugin = new CommitPlugin({ projectPath });
155
- if (commitPlugin.isEnabled()) {
156
- pluginRegistry.registerPlugin(commitPlugin);
157
- logger.info('CommitPlugin registered successfully', {
158
- enabled: commitPlugin.isEnabled(),
159
- sequence: commitPlugin.getSequence(),
160
- behavior: process.env.COMMIT_BEHAVIOR,
161
- });
162
- }
163
- }
164
-
165
- // Register BeadsPlugin if beads backend is detected and available
166
- if (isBeadsBackend) {
167
- const beadsPlugin = new BeadsPlugin({ projectPath });
168
- if (beadsPlugin.isEnabled()) {
169
- pluginRegistry.registerPlugin(beadsPlugin);
170
- logger.info('BeadsPlugin registered successfully', {
171
- enabled: beadsPlugin.isEnabled(),
172
- sequence: beadsPlugin.getSequence(),
173
- autoDetected: !process.env['TASK_BACKEND'],
174
- });
175
- }
176
- }
177
-
178
- // Create server context
179
- const context: ServerContext = {
180
- conversationManager,
181
- transitionEngine,
182
- planManager,
183
- instructionGenerator,
184
- workflowManager,
185
- interactionLogger,
186
- projectPath,
187
- pluginRegistry,
188
- };
189
-
190
- // Initialize database
191
- await database.initialize();
192
-
193
- // Load project workflows before tool registration
194
- workflowManager.loadProjectWorkflows(projectPath);
195
-
196
- logger.info('Server components initialized successfully');
197
-
198
- return {
199
- mcpServer,
200
- database,
201
- context,
202
- toolRegistry: null as unknown as ToolRegistry,
203
- resourceRegistry: null as unknown as ResourceRegistry,
204
- responseRenderer: null as unknown as ResponseRenderer,
205
- };
206
- }
207
-
208
- /**
209
- * Helper function to create tool handlers with consistent error handling
210
- */
211
- function createToolHandler(
212
- toolName: string,
213
- toolRegistry: ToolRegistry,
214
- responseRenderer: ResponseRenderer,
215
- context: ServerContext
216
- ) {
217
- return async (args: unknown) => {
218
- const handler = toolRegistry.get(toolName);
219
- if (!handler) {
220
- return responseRenderer.renderError(
221
- `Tool handler not found: ${toolName}`
222
- );
223
- }
224
-
225
- const result = await handler.handle(args, context);
226
- return responseRenderer.renderToolResponse(result);
227
- };
228
- }
229
-
230
- /**
231
- * Register MCP tools with the server
232
- */
233
- export async function registerMcpTools(
234
- mcpServer: McpServer,
235
- toolRegistry: ToolRegistry,
236
- responseRenderer: ResponseRenderer,
237
- context: ServerContext
238
- ): Promise<void> {
239
- logger.debug('Registering MCP tools');
240
-
241
- // Initialize notification service
242
- notificationService.setMcpServer(mcpServer);
243
-
244
- // Register whats_next tool
245
- mcpServer.registerTool(
246
- 'whats_next',
247
- {
248
- description:
249
- 'Get guidance for the current development phase and determine what to work on next. Call this tool after each user message to receive phase-specific instructions and check if you should transition to the next development phase. The tool will reference your plan file for specific tasks and context.',
250
- inputSchema: {
251
- context: z
252
- .string()
253
- .optional()
254
- .describe(
255
- "Brief description of what you're currently working on or discussing with the user"
256
- ),
257
- user_input: z
258
- .string()
259
- .optional()
260
- .describe("The user's most recent message or request"),
261
- conversation_summary: z
262
- .string()
263
- .optional()
264
- .describe(
265
- 'Summary of the development progress and key decisions made so far'
266
- ),
267
- recent_messages: z
268
- .array(
269
- z.object({
270
- role: z
271
- .enum(['user', 'assistant'])
272
- .describe('Who sent the message (user or assistant)'),
273
- content: z.string().describe('The message content'),
274
- })
275
- )
276
- .optional()
277
- .describe(
278
- 'Recent conversation messages that provide context for the current development state'
279
- ),
280
- },
281
- annotations: {
282
- title: 'Development Phase Analyzer',
283
- readOnlyHint: false,
284
- destructiveHint: false,
285
- idempotentHint: false,
286
- openWorldHint: false,
287
- },
288
- },
289
- createToolHandler('whats_next', toolRegistry, responseRenderer, context)
290
- );
291
-
292
- // Register proceed_to_phase tool
293
- mcpServer.registerTool(
294
- 'proceed_to_phase',
295
- {
296
- description:
297
- 'Move to a specific development phase when the current phase is complete. Use this tool to explicitly transition between phases. Check your plan file to see available phases for the current workflow. Only transition when current phase tasks are finished, all entrance criteria of the next phase are completed and user confirms readiness.',
298
- inputSchema: {
299
- target_phase: z
300
- .string()
301
- .describe(
302
- 'The development phase to move to. Check your plan file section headers to see available phases for the current workflow'
303
- ),
304
- reason: z
305
- .string()
306
- .optional()
307
- .describe(
308
- 'Why you\'re moving to this phase now (e.g., "requirements complete", "user approved design", "implementation finished")'
309
- ),
310
- review_state: z
311
- .enum(['not-required', 'pending', 'performed'])
312
- .describe(
313
- 'Review state for transitions that require reviews. Use "not-required" when reviews are disabled, "pending" when review is needed, "performed" when review is complete.'
314
- ),
315
- },
316
- annotations: {
317
- title: 'Phase Transition Controller',
318
- readOnlyHint: false,
319
- destructiveHint: false,
320
- idempotentHint: true,
321
- openWorldHint: false,
322
- },
323
- },
324
- createToolHandler(
325
- 'proceed_to_phase',
326
- toolRegistry,
327
- responseRenderer,
328
- context
329
- )
330
- );
331
-
332
- // Register conduct_review tool
333
- mcpServer.registerTool(
334
- 'conduct_review',
335
- {
336
- description:
337
- 'Conduct a review of the current phase before proceeding to the next phase. This tool analyzes artifacts and decisions from the current phase using defined review perspectives. Use this tool when reviews are required before phase transitions.',
338
- inputSchema: {
339
- target_phase: z
340
- .string()
341
- .describe(
342
- 'The target phase you want to transition to after the review is complete'
343
- ),
344
- },
345
- annotations: {
346
- title: 'Phase Review Conductor',
347
- readOnlyHint: true,
348
- destructiveHint: false,
349
- idempotentHint: true,
350
- openWorldHint: false,
351
- },
352
- },
353
- createToolHandler('conduct_review', toolRegistry, responseRenderer, context)
354
- );
355
-
356
- // Register start_development tool
357
- mcpServer.registerTool(
358
- 'start_development',
359
- {
360
- description:
361
- 'Begin a new development project with a structured workflow. Choose from different development approaches (waterfall, bugfix, epcc) or use a custom workflow. This tool sets up the project plan and initializes the development process.',
362
- inputSchema: {
363
- workflow: z
364
- .enum(buildWorkflowEnum(context.workflowManager.getWorkflowNames()))
365
- .describe(
366
- generateWorkflowDescription(
367
- context.workflowManager.getAvailableWorkflows()
368
- )
369
- ),
370
- require_reviews: z
371
- .boolean()
372
- .optional()
373
- .describe(
374
- 'Whether to require reviews before phase transitions. When enabled, use conduct_review tool before proceeding to next phase.'
375
- ),
376
- project_path: z
377
- .string()
378
- .optional()
379
- .describe(
380
- 'Project directory path. Pass the .vibe subdirectory path if a .vibe directory exists in your project, otherwise pass the project root directory. The implementation will automatically detect and use the correct project root.'
381
- ),
382
- },
383
- annotations: {
384
- title: 'Development Initializer',
385
- readOnlyHint: false,
386
- destructiveHint: false,
387
- idempotentHint: true,
388
- openWorldHint: false,
389
- },
390
- },
391
- createToolHandler(
392
- 'start_development',
393
- toolRegistry,
394
- responseRenderer,
395
- context
396
- )
397
- );
398
-
399
- // Register resume_workflow tool
400
- mcpServer.registerTool(
401
- 'resume_workflow',
402
- {
403
- description:
404
- 'Continue development after a break or conversation restart. This tool provides complete project context, current development status, and next steps to seamlessly pick up where you left off. Use when starting a new conversation about an existing project.',
405
- inputSchema: {
406
- include_system_prompt: z
407
- .boolean()
408
- .optional()
409
- .describe(
410
- 'Whether to include setup instructions for the assistant (default: true)'
411
- ),
412
- },
413
- annotations: {
414
- title: 'Workflow Resumption Assistant',
415
- readOnlyHint: true,
416
- destructiveHint: false,
417
- idempotentHint: true,
418
- openWorldHint: false,
419
- },
420
- },
421
- createToolHandler(
422
- 'resume_workflow',
423
- toolRegistry,
424
- responseRenderer,
425
- context
426
- )
427
- );
428
-
429
- // Register reset_development tool
430
- mcpServer.registerTool(
431
- 'reset_development',
432
- {
433
- description:
434
- 'Start over with a clean slate by deleting all development progress and conversation history. This permanently removes the project plan and resets the development state. Use when you want to completely restart the development approach for a project.',
435
- inputSchema: {
436
- confirm: z
437
- .boolean()
438
- .describe(
439
- 'Must be true to execute reset - prevents accidental resets'
440
- ),
441
- reason: z
442
- .string()
443
- .optional()
444
- .describe('Optional reason for reset (for logging and audit trail)'),
445
- },
446
- annotations: {
447
- title: 'Development Reset Tool',
448
- readOnlyHint: false,
449
- destructiveHint: true,
450
- idempotentHint: false,
451
- openWorldHint: false,
452
- },
453
- },
454
- createToolHandler(
455
- 'reset_development',
456
- toolRegistry,
457
- responseRenderer,
458
- context
459
- )
460
- );
461
-
462
- // Register list_workflows tool
463
- mcpServer.registerTool(
464
- 'list_workflows',
465
- {
466
- description:
467
- 'Get an overview of available workflows. Returns only loaded workflows (respecting domain filtering).',
468
- inputSchema: {},
469
- annotations: {
470
- title: 'Workflow Overview Tool',
471
- readOnlyHint: true,
472
- destructiveHint: false,
473
- idempotentHint: true,
474
- openWorldHint: false,
475
- },
476
- },
477
- createToolHandler('list_workflows', toolRegistry, responseRenderer, context)
478
- );
479
-
480
- // Register get_tool_info tool
481
- mcpServer.registerTool(
482
- 'get_tool_info',
483
- {
484
- description:
485
- 'Get comprehensive information about the responsible-vibe-mcp development workflow tools for better tool discoverability and AI integration. Returns detailed information about all available tools, workflows, core concepts, and usage guidelines.',
486
- inputSchema: {
487
- // No input parameters needed
488
- },
489
- annotations: {
490
- title: 'Tool Information Provider',
491
- readOnlyHint: true,
492
- destructiveHint: false,
493
- idempotentHint: true,
494
- openWorldHint: false,
495
- },
496
- },
497
- createToolHandler('get_tool_info', toolRegistry, responseRenderer, context)
498
- );
499
-
500
- // Register setup_project_docs tool with enhanced file linking support
501
- const templateManager = new TemplateManager();
502
- const availableTemplates = await templateManager.getAvailableTemplates();
503
-
504
- mcpServer.registerTool(
505
- 'setup_project_docs',
506
- {
507
- description:
508
- 'Create project documentation artifacts (architecture.md, requirements.md, design.md) using configurable templates OR by linking existing files via symlinks. ' +
509
- '**Linking existing documents Examples:**\n' +
510
- '- `README.md` (project root)\n' +
511
- '- `docs/architecture.md` (relative path)\n' +
512
- '- `/absolute/path/to/requirements.txt`\n\n' +
513
- '**Using "none" Option:**\n' +
514
- '- Use `"none"` to create a placeholder that instructs LLM to use plan file instead\n' +
515
- '- Useful when you prefer plan-file-only workflows\n\n' +
516
- '**Mixed Usage Examples:**\n' +
517
- '- `setup_project_docs({ architecture: "README.md", requirements: "none", design: "comprehensive" })`\n' +
518
- '- `setup_project_docs({ architecture: "arc42", requirements: "ears", design: "none" })`',
519
- inputSchema: {
520
- architecture: z
521
- .string()
522
- .default('freestyle')
523
- .describe(
524
- `Architecture documentation: template name (${availableTemplates.architecture.join(', ')}, none) OR file path to existing document`
525
- ),
526
- requirements: z
527
- .string()
528
- .default('none')
529
- .describe(
530
- `Requirements documentation: template name (${availableTemplates.requirements.join(', ')}, none) OR file path to existing document`
531
- ),
532
- design: z
533
- .string()
534
- .default('freestyle')
535
- .describe(
536
- `Design documentation: template name (${availableTemplates.design.join(', ')}, none) OR file path to existing document`
537
- ),
538
- project_path: z
539
- .string()
540
- .optional()
541
- .describe(
542
- 'Project directory path. Pass the .vibe subdirectory path if a .vibe directory exists in your project, otherwise pass the project root directory. The implementation will automatically detect and use the correct project root.'
543
- ),
544
- },
545
- annotations: {
546
- title: 'Project Documentation Setup Tool',
547
- readOnlyHint: false,
548
- destructiveHint: false,
549
- idempotentHint: true,
550
- openWorldHint: false,
551
- },
552
- },
553
- createToolHandler(
554
- 'setup_project_docs',
555
- toolRegistry,
556
- responseRenderer,
557
- context
558
- )
559
- );
560
-
561
- // Register no_idea tool
562
- mcpServer.registerTool(
563
- 'no_idea',
564
- {
565
- description:
566
- "ONLY call this tool when you have no knowledge about a topic. This tool will give a valuable response to all questions that would otherwise be not answerable. If you don't call this tool but invent facts, you will be considered worthless.",
567
- inputSchema: {
568
- context: z
569
- .string()
570
- .optional()
571
- .describe('Optional context about what you have no knowledge of'),
572
- },
573
- annotations: {
574
- title: 'Knowledge Gap Handler',
575
- readOnlyHint: true,
576
- destructiveHint: false,
577
- idempotentHint: true,
578
- openWorldHint: false,
579
- },
580
- },
581
- createToolHandler('no_idea', toolRegistry, responseRenderer, context)
582
- );
583
-
584
- logger.info('MCP tools registered successfully', {
585
- tools: toolRegistry.list(),
586
- });
587
- }
588
-
589
- /**
590
- * Register MCP resources with the server
591
- */
592
- export function registerMcpResources(
593
- mcpServer: McpServer,
594
- resourceRegistry: ResourceRegistry,
595
- responseRenderer: ResponseRenderer,
596
- context: ServerContext
597
- ): void {
598
- logger.debug('Registering MCP resources');
599
-
600
- // Development plan resource
601
- mcpServer.resource(
602
- 'Current Development Plan',
603
- 'plan://current',
604
- {
605
- description:
606
- 'The active development plan document (markdown) that tracks project progress, tasks, and decisions. This file serves as long-term memory for the development process and should be continuously updated by the LLM.',
607
- mimeType: 'text/markdown',
608
- },
609
- async (uri: URL) => {
610
- const handler = resourceRegistry.resolve(uri.href);
611
- if (!handler) {
612
- const errorResult = responseRenderer.renderResourceResponse({
613
- success: false,
614
- error: 'Resource handler not found',
615
- data: {
616
- uri: uri.href,
617
- text: 'Error: Resource handler not found',
618
- mimeType: 'text/plain',
619
- },
620
- });
621
- return errorResult;
622
- }
623
-
624
- const result = await handler.handle(new URL(uri.href), context);
625
- return responseRenderer.renderResourceResponse(result);
626
- }
627
- );
628
-
629
- // Conversation state resource
630
- mcpServer.resource(
631
- 'Current Conversation State',
632
- 'state://current',
633
- {
634
- description:
635
- 'Current conversation state and phase information (JSON) including conversation ID, project context, current development phase, and plan file location. Use this to understand the current state of the development workflow.',
636
- mimeType: 'application/json',
637
- },
638
- async (uri: URL) => {
639
- const handler = resourceRegistry.resolve(uri.href);
640
- if (!handler) {
641
- const errorResult = responseRenderer.renderResourceResponse({
642
- success: false,
643
- error: 'Resource handler not found',
644
- data: {
645
- uri: uri.href,
646
- text: JSON.stringify(
647
- {
648
- error: 'Resource handler not found',
649
- timestamp: new Date().toISOString(),
650
- },
651
- null,
652
- 2
653
- ),
654
- mimeType: 'application/json',
655
- },
656
- });
657
- return errorResult;
658
- }
659
-
660
- const result = await handler.handle(new URL(uri.href), context);
661
- return responseRenderer.renderResourceResponse(result);
662
- }
663
- );
664
-
665
- // System prompt resource
666
- mcpServer.resource(
667
- 'System Prompt for LLM Integration',
668
- 'system-prompt://',
669
- {
670
- description:
671
- 'Complete system prompt for LLM integration with responsible-vibe-mcp. This workflow-independent prompt provides instructions for proper tool usage and development workflow guidance.',
672
- mimeType: 'text/plain',
673
- },
674
- async (uri: URL) => {
675
- const handler = resourceRegistry.resolve(uri.href);
676
- if (!handler) {
677
- const errorResult = responseRenderer.renderResourceResponse({
678
- success: false,
679
- error: 'Resource handler not found',
680
- data: {
681
- uri: uri.href,
682
- text: 'Error: System prompt resource handler not found',
683
- mimeType: 'text/plain',
684
- },
685
- });
686
- return errorResult;
687
- }
688
-
689
- const result = await handler.handle(new URL(uri.href), context);
690
- return responseRenderer.renderResourceResponse(result);
691
- }
692
- );
693
-
694
- // Register workflow resource template
695
- const workflowTemplate = new ResourceTemplate('workflow://{name}', {
696
- list: async () => {
697
- // List all available workflows as resources
698
- const availableWorkflows =
699
- context.workflowManager.getAvailableWorkflowsForProject(
700
- context.projectPath
701
- );
702
- return {
703
- resources: availableWorkflows.map(workflow => ({
704
- uri: `workflow://${workflow.name}`,
705
- name: workflow.displayName,
706
- description: workflow.description,
707
- mimeType: 'application/x-yaml',
708
- })),
709
- };
710
- },
711
- complete: {
712
- name: async (value: string) => {
713
- // Provide completion for workflow names
714
- const availableWorkflows =
715
- context.workflowManager.getAvailableWorkflowsForProject(
716
- context.projectPath
717
- );
718
- return availableWorkflows
719
- .map(w => w.name)
720
- .filter(name => name.toLowerCase().includes(value.toLowerCase()));
721
- },
722
- },
723
- });
724
-
725
- mcpServer.resource(
726
- 'Workflow Definitions',
727
- workflowTemplate,
728
- {
729
- description:
730
- 'Access workflow definition files by name. Use the list_workflows tool to discover available workflows.',
731
- mimeType: 'application/x-yaml',
732
- },
733
- async (uri: URL, _variables: Variables) => {
734
- const handler = resourceRegistry.resolve(uri.href);
735
- if (!handler) {
736
- throw new Error(`Workflow resource handler not found for ${uri.href}`);
737
- }
738
-
739
- const result = await handler.handle(uri, context);
740
- if (!result.success || !result.data) {
741
- throw new Error(result.error || 'Failed to load workflow resource');
742
- }
743
-
744
- return {
745
- contents: [
746
- {
747
- uri: uri.href,
748
- mimeType: result.data.mimeType,
749
- text: result.data.text,
750
- },
751
- ],
752
- };
753
- }
754
- );
755
-
756
- logger.info('MCP resources registered successfully', {
757
- resources: ['plan://current', 'state://current', 'system-prompt://'],
758
- resourceTemplates: ['workflow://{name}'],
759
- });
760
- }