@codemcp/workflows 3.1.21

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