@programinglive/dev-workflow-mcp-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # Development Workflow MCP Server
2
+
3
+ An MCP (Model Context Protocol) server that helps enforce development discipline and workflow best practices. This server acts as your coding conscience, reminding you to follow proper development workflows.
4
+
5
+ ## 🎯 Purpose
6
+
7
+ This MCP server guides you through a disciplined development workflow:
8
+
9
+ 1. **Start Conscious** - Be clear about what you're coding
10
+ 2. **Fix/Implement** - Write your code
11
+ 3. **Create Tests** - Always test your changes
12
+ 4. **Run Tests** - Tests must pass (GREEN)
13
+ 5. **Document** - Update documentation
14
+ 6. **Commit & Push** - Only when all steps are complete
15
+
16
+ ## 🚀 Installation
17
+
18
+ ### 1. Install Dependencies
19
+
20
+ ```bash
21
+ npm install
22
+ ```
23
+
24
+ ### 2. Configure in Windsurf/Claude Desktop
25
+
26
+ Add to your MCP settings file:
27
+
28
+ **For Windsurf** (`~/Library/Application Support/Windsurf/config.json`):
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "dev-workflow": {
34
+ "command": "node",
35
+ "args": ["/Users/mahardhika/code/project/mine/app/CascadeProjects/windsurf-project/index.js"]
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ **For Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
42
+
43
+ ```json
44
+ {
45
+ "mcpServers": {
46
+ "dev-workflow": {
47
+ "command": "node",
48
+ "args": ["/Users/mahardhika/code/project/mine/app/CascadeProjects/windsurf-project/index.js"]
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### 3. Restart Windsurf/Claude Desktop
55
+
56
+ After adding the configuration, restart the application to load the MCP server.
57
+
58
+ ## 🛠️ Available Tools
59
+
60
+ ### `start_task`
61
+ Start a new coding task. This is your first step - be conscious about what you're coding.
62
+
63
+ **Parameters:**
64
+ - `description` (string, required): Clear description of what you're going to code
65
+ - `type` (enum, required): Type of task - "feature", "bugfix", "refactor", or "other"
66
+
67
+ **Example:**
68
+ ```
69
+ Use the start_task tool with:
70
+ - description: "Add user authentication to the login page"
71
+ - type: "feature"
72
+ ```
73
+
74
+ ### `mark_bug_fixed`
75
+ Mark that the bug/feature is fixed. **Reminder: Now you MUST create tests!**
76
+
77
+ **Parameters:**
78
+ - `summary` (string, required): Brief summary of what was fixed/implemented
79
+
80
+ ### `run_tests`
81
+ Record test results. **NEVER commit if tests fail!** Only proceed if all tests are green.
82
+
83
+ **Parameters:**
84
+ - `passed` (boolean, required): Did all tests pass?
85
+ - `testCommand` (string, required): The test command that was run
86
+ - `details` (string, optional): Test results details
87
+
88
+ **Example:**
89
+ ```
90
+ Use run_tests with:
91
+ - passed: true
92
+ - testCommand: "npm test"
93
+ - details: "All 15 tests passed"
94
+ ```
95
+
96
+ ### `create_documentation`
97
+ Mark that documentation has been created/updated. This is required before committing.
98
+
99
+ **Parameters:**
100
+ - `documentationType` (enum, required): "README", "inline-comments", "API-docs", "changelog", or "other"
101
+ - `summary` (string, required): What was documented
102
+
103
+ ### `check_ready_to_commit`
104
+ Check if all workflow steps are completed and you're ready to commit & push.
105
+
106
+ ### `complete_task`
107
+ Mark the task as complete after successful commit & push. Resets workflow for next task.
108
+
109
+ **Parameters:**
110
+ - `commitMessage` (string, required): The commit message used
111
+
112
+ ### `get_workflow_status`
113
+ Get current workflow status and what needs to be done next.
114
+
115
+ ### `view_history`
116
+ View workflow history of completed tasks.
117
+
118
+ **Parameters:**
119
+ - `limit` (number, optional): Number of recent tasks to show (default: 10)
120
+
121
+ ## 📋 Available Prompts
122
+
123
+ ### `workflow_reminder`
124
+ Get a complete reminder of the development workflow discipline.
125
+
126
+ ### `pre_commit_checklist`
127
+ Get a pre-commit checklist to ensure nothing is missed before committing.
128
+
129
+ ## 🔄 Typical Workflow
130
+
131
+ Here's how you'd use this MCP server in a typical coding session:
132
+
133
+ 1. **Start your task:**
134
+ ```
135
+ Ask Cascade to use start_task:
136
+ "Start a new task: implementing user profile page, type: feature"
137
+ ```
138
+
139
+ 2. **Code your feature/fix**
140
+ - Write your code as usual
141
+
142
+ 3. **Mark as fixed:**
143
+ ```
144
+ "Mark the feature as fixed: User profile page with avatar and bio completed"
145
+ ```
146
+
147
+ 4. **Create tests:**
148
+ - Write your tests
149
+ - The server will remind you this is mandatory!
150
+
151
+ 5. **Run tests:**
152
+ ```
153
+ "Record test results: passed=true, command='npm test'"
154
+ ```
155
+ - If tests fail, the server will **block** you from proceeding!
156
+
157
+ 6. **Document:**
158
+ ```
159
+ "Create documentation: type=README, summary='Added user profile section to docs'"
160
+ ```
161
+
162
+ 7. **Check readiness:**
163
+ ```
164
+ "Check if I'm ready to commit"
165
+ ```
166
+
167
+ 8. **Commit & Push:**
168
+ ```bash
169
+ git add .
170
+ git commit -m "feat: add user profile page with tests and docs"
171
+ git push
172
+ ```
173
+
174
+ 9. **Complete:**
175
+ ```
176
+ "Complete the task with commit message: 'feat: add user profile page'"
177
+ ```
178
+
179
+ ## 🎯 Key Features
180
+
181
+ - **Enforces discipline**: Won't let you skip steps
182
+ - **Test-driven**: Blocks commits if tests fail
183
+ - **Documentation reminder**: Ensures you document your work
184
+ - **State tracking**: Remembers where you are in the workflow
185
+ - **History**: Keeps track of completed tasks
186
+ - **Prompts**: Quick reminders of best practices
187
+
188
+ ## 🚫 What This Server Prevents
189
+
190
+ - ❌ Committing without tests
191
+ - ❌ Committing with failing tests
192
+ - ❌ Committing without documentation
193
+ - ❌ Losing track of what you're working on
194
+ - ❌ Skipping important workflow steps
195
+
196
+ ## 💡 Tips
197
+
198
+ 1. **Always start with `start_task`** - This sets your intention
199
+ 2. **Never skip tests** - The server will remind you!
200
+ 3. **Use `get_workflow_status`** - Check where you are anytime
201
+ 4. **Review history** - Learn from your past tasks
202
+ 5. **Follow the prompts** - They contain best practices
203
+
204
+ ## 🔧 Customization
205
+
206
+ You can modify the workflow in `index.js`:
207
+ - Add more workflow phases
208
+ - Customize reminders
209
+ - Add integration with your test runner
210
+ - Add custom validation rules
211
+
212
+ ## 📝 State Management
213
+
214
+ The server maintains state in `.workflow-state.json`:
215
+ - Current phase
216
+ - Task description
217
+ - Completion status of each step
218
+ - History of completed tasks
219
+
220
+ This file is automatically created and managed by the server.
221
+
222
+ ## 🤝 Integration with Your Rules
223
+
224
+ This MCP server aligns with your existing development rules:
225
+ - ✅ Enforces test-first discipline
226
+ - ✅ Prevents commits with failing tests
227
+ - ✅ Reminds about documentation
228
+ - ✅ Tracks workflow state
229
+ - ✅ Maintains history
230
+
231
+ ## 📄 License
232
+
233
+ MIT
234
+
235
+ ## 🙏 Contributing
236
+
237
+ Feel free to customize this server to match your specific workflow needs!
package/index.js ADDED
@@ -0,0 +1,588 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import {
6
+ CallToolRequestSchema,
7
+ ListToolsRequestSchema,
8
+ ListPromptsRequestSchema,
9
+ GetPromptRequestSchema,
10
+ } from "@modelcontextprotocol/sdk/types.js";
11
+ import fs from "fs/promises";
12
+ import path from "path";
13
+ import { fileURLToPath } from "url";
14
+
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = path.dirname(__filename);
17
+
18
+ // Workflow state management
19
+ export class WorkflowState {
20
+ constructor(stateFilePath = path.join(__dirname, ".workflow-state.json")) {
21
+ this.stateFile = stateFilePath;
22
+ this.state = {
23
+ currentPhase: "idle",
24
+ taskDescription: "",
25
+ bugFixed: false,
26
+ testsPassed: false,
27
+ documentationCreated: false,
28
+ readyToCommit: false,
29
+ history: [],
30
+ };
31
+ }
32
+
33
+ async load() {
34
+ try {
35
+ const data = await fs.readFile(this.stateFile, "utf-8");
36
+ this.state = JSON.parse(data);
37
+ } catch (error) {
38
+ // File doesn't exist yet, use default state
39
+ }
40
+ }
41
+
42
+ async save() {
43
+ await fs.writeFile(this.stateFile, JSON.stringify(this.state, null, 2));
44
+ }
45
+
46
+ reset() {
47
+ this.state = {
48
+ currentPhase: "idle",
49
+ taskDescription: "",
50
+ bugFixed: false,
51
+ testsPassed: false,
52
+ documentationCreated: false,
53
+ readyToCommit: false,
54
+ history: this.state.history,
55
+ };
56
+ }
57
+
58
+ addToHistory(entry) {
59
+ this.state.history.push({
60
+ ...entry,
61
+ timestamp: new Date().toISOString(),
62
+ });
63
+ }
64
+ }
65
+
66
+ export const workflowState = new WorkflowState();
67
+ await workflowState.load();
68
+
69
+ // Create MCP server
70
+ export const server = new Server(
71
+ {
72
+ name: "@programinglive/dev-workflow-mcp-server",
73
+ version: "1.0.0",
74
+ },
75
+ {
76
+ capabilities: {
77
+ tools: {},
78
+ prompts: {},
79
+ },
80
+ }
81
+ );
82
+
83
+ // Define tools
84
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
85
+ return {
86
+ tools: [
87
+ {
88
+ name: "start_task",
89
+ description:
90
+ "Start a new coding task. This is the first step - be conscious about what you're coding.",
91
+ inputSchema: {
92
+ type: "object",
93
+ properties: {
94
+ description: {
95
+ type: "string",
96
+ description: "Clear description of what you're going to code",
97
+ },
98
+ type: {
99
+ type: "string",
100
+ enum: ["feature", "bugfix", "refactor", "other"],
101
+ description: "Type of task",
102
+ },
103
+ },
104
+ required: ["description", "type"],
105
+ },
106
+ },
107
+ {
108
+ name: "mark_bug_fixed",
109
+ description:
110
+ "Mark that the bug/feature is fixed. Reminder: Now you MUST create tests!",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ summary: {
115
+ type: "string",
116
+ description: "Brief summary of what was fixed/implemented",
117
+ },
118
+ },
119
+ required: ["summary"],
120
+ },
121
+ },
122
+ {
123
+ name: "run_tests",
124
+ description:
125
+ "Record test results. NEVER commit if tests fail! Only proceed if all tests are green.",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ passed: {
130
+ type: "boolean",
131
+ description: "Did all tests pass?",
132
+ },
133
+ testCommand: {
134
+ type: "string",
135
+ description: "The test command that was run",
136
+ },
137
+ details: {
138
+ type: "string",
139
+ description: "Test results details",
140
+ },
141
+ },
142
+ required: ["passed", "testCommand"],
143
+ },
144
+ },
145
+ {
146
+ name: "create_documentation",
147
+ description:
148
+ "Mark that documentation has been created/updated. This is required before committing.",
149
+ inputSchema: {
150
+ type: "object",
151
+ properties: {
152
+ documentationType: {
153
+ type: "string",
154
+ enum: ["README", "inline-comments", "API-docs", "changelog", "other"],
155
+ description: "Type of documentation created",
156
+ },
157
+ summary: {
158
+ type: "string",
159
+ description: "What was documented",
160
+ },
161
+ },
162
+ required: ["documentationType", "summary"],
163
+ },
164
+ },
165
+ {
166
+ name: "check_ready_to_commit",
167
+ description:
168
+ "Check if all workflow steps are completed and you're ready to commit & push.",
169
+ inputSchema: {
170
+ type: "object",
171
+ properties: {},
172
+ },
173
+ },
174
+ {
175
+ name: "complete_task",
176
+ description:
177
+ "Mark the task as complete after successful commit & push. Resets workflow for next task.",
178
+ inputSchema: {
179
+ type: "object",
180
+ properties: {
181
+ commitMessage: {
182
+ type: "string",
183
+ description: "The commit message used",
184
+ },
185
+ },
186
+ required: ["commitMessage"],
187
+ },
188
+ },
189
+ {
190
+ name: "get_workflow_status",
191
+ description: "Get current workflow status and what needs to be done next.",
192
+ inputSchema: {
193
+ type: "object",
194
+ properties: {},
195
+ },
196
+ },
197
+ {
198
+ name: "view_history",
199
+ description: "View workflow history of completed tasks.",
200
+ inputSchema: {
201
+ type: "object",
202
+ properties: {
203
+ limit: {
204
+ type: "number",
205
+ description: "Number of recent tasks to show (default: 10)",
206
+ },
207
+ },
208
+ },
209
+ },
210
+ ],
211
+ };
212
+ });
213
+
214
+ // Handle tool calls
215
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
216
+ const { name, arguments: args } = request.params;
217
+
218
+ switch (name) {
219
+ case "start_task": {
220
+ workflowState.reset();
221
+ workflowState.state.currentPhase = "coding";
222
+ workflowState.state.taskDescription = args.description;
223
+ workflowState.state.taskType = args.type;
224
+ await workflowState.save();
225
+
226
+ return {
227
+ content: [
228
+ {
229
+ type: "text",
230
+ text: `✅ Task Started: ${args.description}\n\n🎯 Be conscious about what you're coding!\n\nWorkflow Steps:\n1. ✓ Start task (current)\n2. ⏳ Fix/implement the feature\n3. ⏳ Create tests\n4. ⏳ Run tests (must pass!)\n5. ⏳ Create documentation\n6. ⏳ Commit & push\n\nReminder: Focus on writing clean, maintainable code!`,
231
+ },
232
+ ],
233
+ };
234
+ }
235
+
236
+ case "mark_bug_fixed": {
237
+ if (workflowState.state.currentPhase === "idle") {
238
+ return {
239
+ content: [
240
+ {
241
+ type: "text",
242
+ text: "⚠️ Please start a task first using 'start_task'!",
243
+ },
244
+ ],
245
+ };
246
+ }
247
+
248
+ workflowState.state.bugFixed = true;
249
+ workflowState.state.currentPhase = "testing";
250
+ workflowState.state.fixSummary = args.summary;
251
+ await workflowState.save();
252
+
253
+ return {
254
+ content: [
255
+ {
256
+ type: "text",
257
+ text: `✅ Feature/Bug marked as fixed!\n\n⚠️ CRITICAL REMINDER: You MUST create tests now!\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ⏳ Create tests for: ${args.summary}\n3. ⏳ Run tests (must be green!)\n4. ⏳ Create documentation\n5. ⏳ Commit & push\n\n🚫 DO NOT SKIP TESTING!`,
258
+ },
259
+ ],
260
+ };
261
+ }
262
+
263
+ case "run_tests": {
264
+ if (!workflowState.state.bugFixed) {
265
+ return {
266
+ content: [
267
+ {
268
+ type: "text",
269
+ text: "⚠️ Please mark your feature/bug as fixed first using 'mark_bug_fixed'!",
270
+ },
271
+ ],
272
+ };
273
+ }
274
+
275
+ workflowState.state.testsPassed = args.passed;
276
+ workflowState.state.testCommand = args.testCommand;
277
+ workflowState.state.testDetails = args.details || "";
278
+
279
+ if (!args.passed) {
280
+ workflowState.state.currentPhase = "testing";
281
+ await workflowState.save();
282
+
283
+ return {
284
+ content: [
285
+ {
286
+ type: "text",
287
+ text: `❌ TESTS FAILED!\n\n🚫 STOP! DO NOT COMMIT OR PUSH!\n\nYou must:\n1. Fix the failing tests\n2. Run tests again until they pass\n\nTest command: ${args.testCommand}\n\nNever skip or ignore failing tests!`,
288
+ },
289
+ ],
290
+ };
291
+ }
292
+
293
+ workflowState.state.currentPhase = "documentation";
294
+ await workflowState.save();
295
+
296
+ return {
297
+ content: [
298
+ {
299
+ type: "text",
300
+ text: `✅ All tests passed! 🎉\n\nTest command: ${args.testCommand}\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ⏳ Create/update documentation\n5. ⏳ Commit & push\n\nReminder: Document what you did before committing!`,
301
+ },
302
+ ],
303
+ };
304
+ }
305
+
306
+ case "create_documentation": {
307
+ if (!workflowState.state.testsPassed) {
308
+ return {
309
+ content: [
310
+ {
311
+ type: "text",
312
+ text: "⚠️ Please ensure tests are passing first! Run 'run_tests' with passed=true.",
313
+ },
314
+ ],
315
+ };
316
+ }
317
+
318
+ workflowState.state.documentationCreated = true;
319
+ workflowState.state.documentationType = args.documentationType;
320
+ workflowState.state.documentationSummary = args.summary;
321
+ workflowState.state.currentPhase = "ready";
322
+ workflowState.state.readyToCommit = true;
323
+ await workflowState.save();
324
+
325
+ return {
326
+ content: [
327
+ {
328
+ type: "text",
329
+ text: `✅ Documentation created!\n\nType: ${args.documentationType}\nSummary: ${args.summary}\n\n🎉 You're ready to commit!\n\nNext Steps:\n1. ✓ Fix/implement feature\n2. ✓ Create tests\n3. ✓ Run tests (GREEN!)\n4. ✓ Create documentation\n5. ⏳ Run 'check_ready_to_commit' to verify\n6. ⏳ Commit & push\n7. ⏳ Mark as complete with 'complete_task'\n\nRemember: git add . && git commit && git push`,
330
+ },
331
+ ],
332
+ };
333
+ }
334
+
335
+ case "check_ready_to_commit": {
336
+ const status = workflowState.state;
337
+ const checks = [
338
+ { name: "Task started", done: status.currentPhase !== "idle" },
339
+ { name: "Feature/bug fixed", done: status.bugFixed },
340
+ { name: "Tests created and passed", done: status.testsPassed },
341
+ { name: "Documentation created", done: status.documentationCreated },
342
+ ];
343
+
344
+ const allDone = checks.every((c) => c.done);
345
+ const checkList = checks
346
+ .map((c) => `${c.done ? "✅" : "❌"} ${c.name}`)
347
+ .join("\n");
348
+
349
+ if (allDone) {
350
+ return {
351
+ content: [
352
+ {
353
+ type: "text",
354
+ text: `🎉 ALL CHECKS PASSED! You're ready to commit!\n\n${checkList}\n\n✅ You can now:\n1. git add .\n2. git commit -m "your message"\n3. git push\n4. Run 'complete_task' to finish\n\nTask: ${status.taskDescription}`,
355
+ },
356
+ ],
357
+ };
358
+ } else {
359
+ return {
360
+ content: [
361
+ {
362
+ type: "text",
363
+ text: `⚠️ NOT READY TO COMMIT!\n\n${checkList}\n\nPlease complete all steps before committing.`,
364
+ },
365
+ ],
366
+ };
367
+ }
368
+ }
369
+
370
+ case "complete_task": {
371
+ if (!workflowState.state.readyToCommit) {
372
+ return {
373
+ content: [
374
+ {
375
+ type: "text",
376
+ text: "⚠️ Not ready to complete! Run 'check_ready_to_commit' first.",
377
+ },
378
+ ],
379
+ };
380
+ }
381
+
382
+ workflowState.addToHistory({
383
+ taskDescription: workflowState.state.taskDescription,
384
+ taskType: workflowState.state.taskType,
385
+ fixSummary: workflowState.state.fixSummary,
386
+ testCommand: workflowState.state.testCommand,
387
+ documentationType: workflowState.state.documentationType,
388
+ commitMessage: args.commitMessage,
389
+ });
390
+
391
+ const completedTask = workflowState.state.taskDescription;
392
+ workflowState.reset();
393
+ workflowState.state.currentPhase = "idle";
394
+ await workflowState.save();
395
+
396
+ return {
397
+ content: [
398
+ {
399
+ type: "text",
400
+ text: `🎉 Task completed successfully!\n\nCompleted: ${completedTask}\nCommit: ${args.commitMessage}\n\n✅ Workflow reset. Ready for next task!\n\nUse 'start_task' when you begin your next coding session.`,
401
+ },
402
+ ],
403
+ };
404
+ }
405
+
406
+ case "get_workflow_status": {
407
+ const status = workflowState.state;
408
+
409
+ if (status.currentPhase === "idle") {
410
+ return {
411
+ content: [
412
+ {
413
+ type: "text",
414
+ text: "📋 No active task.\n\nUse 'start_task' to begin a new coding session.",
415
+ },
416
+ ],
417
+ };
418
+ }
419
+
420
+ const phaseMessages = {
421
+ coding: "🔨 Currently coding",
422
+ testing: "🧪 Ready for testing",
423
+ documentation: "📝 Ready for documentation",
424
+ ready: "✅ Ready to commit",
425
+ };
426
+
427
+ return {
428
+ content: [
429
+ {
430
+ type: "text",
431
+ text: `📋 Current Workflow Status\n\nTask: ${status.taskDescription}\nPhase: ${phaseMessages[status.currentPhase]}\n\nProgress:\n${status.bugFixed ? "✅" : "⏳"} Feature/bug fixed\n${status.testsPassed ? "✅" : "⏳"} Tests passed\n${status.documentationCreated ? "✅" : "⏳"} Documentation created\n${status.readyToCommit ? "✅" : "⏳"} Ready to commit\n\nNext: ${getNextStep(status)}`,
432
+ },
433
+ ],
434
+ };
435
+ }
436
+
437
+ case "view_history": {
438
+ const limit = args.limit || 10;
439
+ const history = workflowState.state.history.slice(-limit).reverse();
440
+
441
+ if (history.length === 0) {
442
+ return {
443
+ content: [
444
+ {
445
+ type: "text",
446
+ text: "📜 No workflow history yet.",
447
+ },
448
+ ],
449
+ };
450
+ }
451
+
452
+ const historyText = history
453
+ .map(
454
+ (entry, index) =>
455
+ `${index + 1}. [${new Date(entry.timestamp).toLocaleString()}]\n Task: ${entry.taskDescription}\n Type: ${entry.taskType}\n Commit: ${entry.commitMessage}\n`
456
+ )
457
+ .join("\n");
458
+
459
+ return {
460
+ content: [
461
+ {
462
+ type: "text",
463
+ text: `📜 Workflow History (last ${history.length} tasks)\n\n${historyText}`,
464
+ },
465
+ ],
466
+ };
467
+ }
468
+
469
+ default:
470
+ throw new Error(`Unknown tool: ${name}`);
471
+ }
472
+ });
473
+
474
+ // Helper function
475
+ export function getNextStep(status) {
476
+ if (!status.bugFixed) return "Mark feature/bug as fixed";
477
+ if (!status.testsPassed) return "Create and run tests";
478
+ if (!status.documentationCreated) return "Create documentation";
479
+ if (!status.readyToCommit) return "Check if ready to commit";
480
+ return "Commit and push!";
481
+ }
482
+
483
+ // Define prompts
484
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
485
+ return {
486
+ prompts: [
487
+ {
488
+ name: "workflow_reminder",
489
+ description: "Get a reminder of the complete development workflow",
490
+ },
491
+ {
492
+ name: "pre_commit_checklist",
493
+ description: "Pre-commit checklist to ensure nothing is missed",
494
+ },
495
+ ],
496
+ };
497
+ });
498
+
499
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
500
+ const { name } = request.params;
501
+
502
+ if (name === "workflow_reminder") {
503
+ return {
504
+ messages: [
505
+ {
506
+ role: "user",
507
+ content: {
508
+ type: "text",
509
+ text: `Development Workflow Discipline:
510
+
511
+ 1. 🎯 START CONSCIOUS
512
+ - Use 'start_task' to declare what you're coding
513
+ - Be clear about your intention
514
+
515
+ 2. 🔨 CODE WITH PURPOSE
516
+ - Implement your feature or fix
517
+ - Follow best practices
518
+
519
+ 3. 🧪 ALWAYS CREATE TESTS
520
+ - After fixing/implementing, create tests
521
+ - Use 'mark_bug_fixed' when done
522
+
523
+ 4. ✅ TESTS MUST PASS
524
+ - Run your tests with 'run_tests'
525
+ - If tests fail: FIX THEM, never skip!
526
+ - Only proceed when all tests are GREEN
527
+
528
+ 5. 📝 DOCUMENT YOUR WORK
529
+ - Update README, comments, or docs
530
+ - Use 'create_documentation' when done
531
+
532
+ 6. 🚀 COMMIT & PUSH
533
+ - Use 'check_ready_to_commit' to verify
534
+ - git add . && git commit && git push
535
+ - Use 'complete_task' to finish
536
+
537
+ Remember: No shortcuts! Each step is important for code quality.`,
538
+ },
539
+ },
540
+ ],
541
+ };
542
+ }
543
+
544
+ if (name === "pre_commit_checklist") {
545
+ return {
546
+ messages: [
547
+ {
548
+ role: "user",
549
+ content: {
550
+ type: "text",
551
+ text: `Pre-Commit Checklist:
552
+
553
+ Before you commit and push, verify:
554
+
555
+ □ Feature/bug is fully implemented
556
+ □ Tests are created for the changes
557
+ □ All tests pass (GREEN) - run 'run_tests'
558
+ □ Documentation is updated
559
+ □ Code is clean (no console.logs, unused imports)
560
+ □ No TypeScript 'any' types
561
+ □ Followed project coding standards
562
+
563
+ Use 'check_ready_to_commit' to verify workflow completion.
564
+
565
+ 🚫 NEVER commit if tests are failing!
566
+ ✅ Only commit when everything is green!`,
567
+ },
568
+ },
569
+ ],
570
+ };
571
+ }
572
+
573
+ throw new Error(`Unknown prompt: ${name}`);
574
+ });
575
+
576
+ // Start server
577
+ export async function main() {
578
+ const transport = new StdioServerTransport();
579
+ await server.connect(transport);
580
+ console.error("Dev Workflow MCP Server running on stdio");
581
+ }
582
+
583
+ if (process.argv[1] === __filename) {
584
+ main().catch((error) => {
585
+ console.error("Server error:", error);
586
+ process.exit(1);
587
+ });
588
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@programinglive/dev-workflow-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server to enforce development workflow discipline",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "bin": {
8
+ "dev-workflow-mcp": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "test": "node --test",
12
+ "check": "node --check index.js",
13
+ "start": "node index.js",
14
+ "dev": "node --watch index.js"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "workflow",
19
+ "development",
20
+ "discipline"
21
+ ],
22
+ "author": "",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.0.4"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ }
30
+ }
@@ -0,0 +1,87 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, rm } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+ import { WorkflowState, getNextStep } from "../index.js";
7
+
8
+ async function withWorkflowState(callback) {
9
+ const tempDir = await mkdtemp(path.join(tmpdir(), "workflow-state-"));
10
+ const stateFile = path.join(tempDir, "state.json");
11
+ const state = new WorkflowState(stateFile);
12
+ await state.load();
13
+
14
+ try {
15
+ await callback(state);
16
+ } finally {
17
+ await rm(tempDir, { recursive: true, force: true });
18
+ }
19
+ }
20
+
21
+ test("WorkflowState persists data across save/load", async () => {
22
+ await withWorkflowState(async (state) => {
23
+ state.state.currentPhase = "testing";
24
+ state.state.taskDescription = "Test persistence";
25
+ state.state.bugFixed = true;
26
+ await state.save();
27
+
28
+ const reloaded = new WorkflowState(state.stateFile);
29
+ await reloaded.load();
30
+
31
+ assert.equal(reloaded.state.currentPhase, "testing");
32
+ assert.equal(reloaded.state.taskDescription, "Test persistence");
33
+ assert.equal(reloaded.state.bugFixed, true);
34
+ });
35
+ });
36
+
37
+ test("WorkflowState reset keeps history but clears progress", async () => {
38
+ await withWorkflowState(async (state) => {
39
+ state.state.currentPhase = "ready";
40
+ state.state.testsPassed = true;
41
+ state.state.documentationCreated = true;
42
+ state.addToHistory({ taskDescription: "Sample task" });
43
+
44
+ state.reset();
45
+
46
+ assert.equal(state.state.currentPhase, "idle");
47
+ assert.equal(state.state.testsPassed, false);
48
+ assert.equal(state.state.documentationCreated, false);
49
+ assert.equal(state.state.history.length, 1);
50
+ assert.equal(state.state.history[0].taskDescription, "Sample task");
51
+ });
52
+ });
53
+
54
+ test("getNextStep guides workflow progression", () => {
55
+ const baseState = {
56
+ bugFixed: false,
57
+ testsPassed: false,
58
+ documentationCreated: false,
59
+ readyToCommit: false,
60
+ };
61
+
62
+ assert.equal(
63
+ getNextStep(baseState),
64
+ "Mark feature/bug as fixed"
65
+ );
66
+
67
+ const afterFix = { ...baseState, bugFixed: true };
68
+ assert.equal(
69
+ getNextStep(afterFix),
70
+ "Create and run tests"
71
+ );
72
+
73
+ const afterTests = { ...afterFix, testsPassed: true };
74
+ assert.equal(
75
+ getNextStep(afterTests),
76
+ "Create documentation"
77
+ );
78
+
79
+ const afterDocs = { ...afterTests, documentationCreated: true };
80
+ assert.equal(
81
+ getNextStep(afterDocs),
82
+ "Check if ready to commit"
83
+ );
84
+
85
+ const ready = { ...afterDocs, readyToCommit: true };
86
+ assert.equal(getNextStep(ready), "Commit and push!");
87
+ });