@liangshanli/mcp-server-project-standards 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.
@@ -0,0 +1,874 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('path');
3
+
4
+ // Import tool modules
5
+ const project_info = require('./utils/get_project_info');
6
+ const project_structure = require('./utils/get_project_structure');
7
+ const api_standards = require('./utils/get_api_standards');
8
+ const development_standards = require('./utils/get_development_standards');
9
+ const database_standards = require('./utils/database_standards');
10
+ const api_debug = require('./utils/api_debug');
11
+
12
+ // Get configuration from file or environment
13
+ const getConfig = () => {
14
+ const configDir = process.env.CONFIG_DIR || './.setting';
15
+ const configPath = path.join(configDir, 'config.json');
16
+
17
+ try {
18
+ if (fs.existsSync(configPath)) {
19
+ const configData = fs.readFileSync(configPath, 'utf8');
20
+ return JSON.parse(configData);
21
+ }
22
+ } catch (err) {
23
+ console.error('Failed to read config file:', err.message);
24
+ }
25
+
26
+ // Return null if no config file exists - this will trigger the notification
27
+ return null;
28
+ };
29
+
30
+ // Save configuration to file
31
+ const saveConfig = (config) => {
32
+ const configDir = process.env.CONFIG_DIR || './.setting';
33
+ const configPath = path.join(configDir, 'config.json');
34
+
35
+ try {
36
+ if (!fs.existsSync(configDir)) {
37
+ fs.mkdirSync(configDir, { recursive: true });
38
+ }
39
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
40
+ return true;
41
+ } catch (err) {
42
+ console.error('Failed to save config file:', err.message);
43
+ return false;
44
+ }
45
+ };
46
+
47
+ // 启动日志
48
+ console.error('=== MCP Project Standards Server Starting ===');
49
+ console.error(`Time: ${new Date().toISOString()}`);
50
+ console.error(`Config Dir: ${process.env.CONFIG_DIR || './.setting'}`);
51
+ console.error('==============================================');
52
+
53
+ // Final MCP Server
54
+ class ProjectStandardsMCPServer {
55
+ constructor() {
56
+ this.name = 'project-standards-mcp-server';
57
+ this.version = '1.0.0';
58
+ this.initialized = false;
59
+ this.config = getConfig();
60
+ this.needsProjectFolder = this.config === null;
61
+
62
+ // 如果配置文件不存在,创建默认配置
63
+ if (this.needsProjectFolder) {
64
+ this.createDefaultConfig();
65
+ }
66
+ }
67
+
68
+ // 创建默认配置文件
69
+ createDefaultConfig() {
70
+ const configDir = process.env.CONFIG_DIR || './.setting';
71
+ const configPath = path.join(configDir, 'config.json');
72
+
73
+ try {
74
+ // 创建配置目录
75
+ if (!fs.existsSync(configDir)) {
76
+ fs.mkdirSync(configDir, { recursive: true });
77
+ console.error(`Created config directory: ${configDir}`);
78
+ }
79
+
80
+ // 创建默认配置文件
81
+ const defaultConfig = {
82
+ project_info: {},
83
+ project_structure: [],
84
+ api_standards: {},
85
+ development_standards: [],
86
+ database_standards: []
87
+ };
88
+
89
+ fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf8');
90
+ console.error(`Created default config file: ${configPath}`);
91
+
92
+ // 更新配置和状态
93
+ this.config = defaultConfig;
94
+ this.needsProjectFolder = false;
95
+ } catch (err) {
96
+ console.error('Failed to create default config:', err.message);
97
+ // 保持 needsProjectFolder = true 状态
98
+ }
99
+ }
100
+
101
+
102
+ // Project information tool
103
+ async project_info(params) {
104
+ const result = await project_info(params, this.config, saveConfig);
105
+ // Update local config if action was 'set'
106
+ if (params?.action === 'set') {
107
+ this.config = getConfig();
108
+ }
109
+ return result;
110
+ }
111
+
112
+ // Project structure tool
113
+ async project_structure(params) {
114
+ const result = await project_structure(params, this.config, saveConfig);
115
+ // Update local config if action was 'set'
116
+ if (params?.action === 'set') {
117
+ this.config = getConfig();
118
+ }
119
+ return result;
120
+ }
121
+
122
+ // API standards tool
123
+ async api_standards(params) {
124
+ const result = await api_standards(params, this.config, saveConfig);
125
+ // Update local config if action was 'set'
126
+ if (params?.action === 'set') {
127
+ this.config = getConfig();
128
+ }
129
+ return result;
130
+ }
131
+
132
+ // Development standards tool
133
+ async development_standards(params) {
134
+ const result = await development_standards(params, this.config, saveConfig);
135
+ // Update local config if action was 'set'
136
+ if (params?.action === 'set') {
137
+ this.config = getConfig();
138
+ }
139
+ return result;
140
+ }
141
+
142
+ // Database standards tool
143
+ async database_standards(params) {
144
+ const result = await database_standards(params, this.config, saveConfig);
145
+ // Update local config if action was 'set'
146
+ if (params?.action === 'set') {
147
+ this.config = getConfig();
148
+ }
149
+ return result;
150
+ }
151
+
152
+ // API debug tool
153
+ async api_debug(params) {
154
+ const result = await api_debug(params, this.config, saveConfig);
155
+ // Update local config if action was 'set'
156
+ if (params?.action === 'set') {
157
+ this.config = getConfig();
158
+ }
159
+ return result;
160
+ }
161
+
162
+
163
+
164
+
165
+ // Handle JSON-RPC requests
166
+ async handleRequest(request) {
167
+ try {
168
+ const { jsonrpc, id, method, params } = request;
169
+
170
+ if (jsonrpc !== '2.0') {
171
+ throw new Error('Unsupported JSON-RPC version');
172
+ }
173
+
174
+ let result = null;
175
+ let error = null;
176
+
177
+ try {
178
+ if (method === 'initialize') {
179
+ // If already initialized, return success but don't re-initialize
180
+ if (!this.initialized) {
181
+ this.initialized = true;
182
+ }
183
+
184
+ // Build server capabilities to match client capabilities
185
+ const serverCapabilities = {
186
+ tools: {
187
+ listChanged: false
188
+ }
189
+ };
190
+
191
+ // If client supports prompts, we also support it
192
+ if (params?.capabilities?.prompts) {
193
+ serverCapabilities.prompts = {
194
+ listChanged: false
195
+ };
196
+ }
197
+
198
+ // If client supports resources, we also support it
199
+ if (params?.capabilities?.resources) {
200
+ serverCapabilities.resources = {
201
+ listChanged: false
202
+ };
203
+ }
204
+
205
+ // If client supports logging, we also support it
206
+ if (params?.capabilities?.logging) {
207
+ serverCapabilities.logging = {
208
+ listChanged: false
209
+ };
210
+ }
211
+
212
+ // If client supports roots, we also support it
213
+ if (params?.capabilities?.roots) {
214
+ serverCapabilities.roots = {
215
+ listChanged: false
216
+ };
217
+ }
218
+
219
+ result = {
220
+ protocolVersion: params?.protocolVersion || '2025-06-18',
221
+ capabilities: serverCapabilities,
222
+ serverInfo: {
223
+ name: this.name,
224
+ version: this.version
225
+ }
226
+ };
227
+ } else if (method === 'tools/list') {
228
+ const tools = [];
229
+
230
+ // Add all tools since config is always available now
231
+ tools.push({
232
+ name: 'project_info',
233
+ description: 'Get or set project information in configuration file',
234
+ inputSchema: {
235
+ type: 'object',
236
+ properties: {
237
+ action: {
238
+ type: 'string',
239
+ enum: ['get', 'set'],
240
+ description: 'Action to perform: "get" to retrieve info, "set" to update info'
241
+ },
242
+ key: {
243
+ type: 'string',
244
+ enum: ['projectName', 'developmentLanguage', 'basicInfo'],
245
+ description: 'Key to update when action is "set" (projectName|developmentLanguage|basicInfo)'
246
+ },
247
+ value: {
248
+ description: 'Value to set when action is "set"'
249
+ }
250
+ },
251
+ required: ['action'],
252
+ anyOf: [
253
+ {
254
+ properties: {
255
+ action: { const: 'get' }
256
+ }
257
+ },
258
+ {
259
+ properties: {
260
+ action: { const: 'set' },
261
+ key: { type: 'string' },
262
+ value: {}
263
+ },
264
+ required: ['key', 'value']
265
+ }
266
+ ]
267
+ }
268
+ });
269
+
270
+ tools.push( {
271
+ name: 'project_structure',
272
+ description: 'Get, set or delete project structure in configuration',
273
+ inputSchema: {
274
+ type: 'object',
275
+ properties: {
276
+ action: {
277
+ type: 'string',
278
+ enum: ['get', 'set', 'delete'],
279
+ description: 'Action to perform: "get" to retrieve structure, "set" to update structure, "delete" to delete structure item'
280
+ },
281
+ structure: {
282
+ type: 'array',
283
+ description: 'Array of structure items with path and description (required for "set" action)',
284
+ items: {
285
+ type: 'object',
286
+ properties: {
287
+ path: {
288
+ type: 'string',
289
+ description: 'Path of the structure item'
290
+ },
291
+ description: {
292
+ type: 'string',
293
+ description: 'Description of the structure item'
294
+ }
295
+ },
296
+ required: ['path', 'description']
297
+ }
298
+ },
299
+ path: {
300
+ type: 'string',
301
+ description: 'Path to delete when action is "delete"'
302
+ }
303
+ },
304
+ required: ['action'],
305
+ anyOf: [
306
+ {
307
+ properties: {
308
+ action: { const: 'get' }
309
+ }
310
+ },
311
+ {
312
+ properties: {
313
+ action: { const: 'set' },
314
+ structure: { type: 'array' }
315
+ },
316
+ required: ['structure']
317
+ },
318
+ {
319
+ properties: {
320
+ action: { const: 'delete' },
321
+ path: { type: 'string' }
322
+ },
323
+ required: ['path']
324
+ }
325
+ ]
326
+ }
327
+ });
328
+
329
+ tools.push( {
330
+ name: 'api_standards',
331
+ description: 'Get, set or delete API interface standards and best practices',
332
+ inputSchema: {
333
+ type: 'object',
334
+ properties: {
335
+ action: {
336
+ type: 'string',
337
+ enum: ['get', 'set', 'delete'],
338
+ description: 'Action to perform: "get" to retrieve standards, "set" to update standards, "delete" to delete header'
339
+ },
340
+ key: {
341
+ type: 'string',
342
+ enum: ['interfaceType', 'successStructure', 'errorStructure', 'basicHeaders', 'requirements'],
343
+ description: 'Key to update when action is "set" (interfaceType|successStructure|errorStructure|basicHeaders|requirements)'
344
+ },
345
+ value: {
346
+ oneOf: [
347
+ { type: 'string' },
348
+ { type: 'array' }
349
+ ],
350
+ description: 'Value to set when action is "set" (must be string or array)'
351
+ },
352
+ forceOverwrite: {
353
+ type: 'boolean',
354
+ description: 'Force overwrite array values when action is "set" and value is array (default: false)'
355
+ },
356
+ headerName: {
357
+ type: 'string',
358
+ description: 'Header name to delete when action is "delete"'
359
+ },
360
+ requirement: {
361
+ type: 'string',
362
+ description: 'Requirement content to delete when action is "delete"'
363
+ }
364
+ },
365
+ required: ['action'],
366
+ anyOf: [
367
+ {
368
+ properties: {
369
+ action: { const: 'get' }
370
+ }
371
+ },
372
+ {
373
+ properties: {
374
+ action: { const: 'set' },
375
+ key: { type: 'string' },
376
+ value: {}
377
+ },
378
+ required: ['key', 'value']
379
+ },
380
+ {
381
+ properties: {
382
+ action: { const: 'delete' },
383
+ headerName: { type: 'string' }
384
+ },
385
+ required: ['headerName']
386
+ },
387
+ {
388
+ properties: {
389
+ action: { const: 'delete' },
390
+ requirement: { type: 'string' }
391
+ },
392
+ required: ['requirement']
393
+ }
394
+ ]
395
+ }
396
+ },
397
+ {
398
+ name: 'development_standards',
399
+ description: 'Get, set or delete development standards',
400
+ inputSchema: {
401
+ type: 'object',
402
+ properties: {
403
+ action: {
404
+ type: 'string',
405
+ enum: ['get', 'set', 'delete'],
406
+ description: 'Action to perform: "get" to retrieve standards, "set" to update standards, "delete" to delete standard'
407
+ },
408
+ standards: {
409
+ type: 'array',
410
+ description: 'Array of development standards (required for "set" action)',
411
+ items: {
412
+ type: 'string'
413
+ }
414
+ },
415
+ forceOverwrite: {
416
+ type: 'boolean',
417
+ description: 'Force overwrite array values when action is "set" and value is array (default: false)'
418
+ },
419
+ standard: {
420
+ type: 'string',
421
+ description: 'Standard content to delete when action is "delete"'
422
+ }
423
+ },
424
+ required: ['action'],
425
+ anyOf: [
426
+ {
427
+ properties: {
428
+ action: { const: 'get' }
429
+ }
430
+ },
431
+ {
432
+ properties: {
433
+ action: { const: 'set' },
434
+ standards: { type: 'array' }
435
+ },
436
+ required: ['standards']
437
+ },
438
+ {
439
+ properties: {
440
+ action: { const: 'delete' },
441
+ standard: { type: 'string' }
442
+ },
443
+ required: ['standard']
444
+ }
445
+ ]
446
+ }
447
+ },
448
+ {
449
+ name: 'database_standards',
450
+ description: 'Get, set or delete database standards',
451
+ inputSchema: {
452
+ type: 'object',
453
+ properties: {
454
+ action: {
455
+ type: 'string',
456
+ enum: ['get', 'set', 'delete'],
457
+ description: 'Action to perform: "get" to retrieve standards, "set" to update standards, "delete" to delete standard'
458
+ },
459
+ standards: {
460
+ type: 'array',
461
+ description: 'Array of database standards (required for "set" action)',
462
+ items: {
463
+ type: 'string'
464
+ }
465
+ },
466
+ forceOverwrite: {
467
+ type: 'boolean',
468
+ description: 'Force overwrite array values when action is "set" and value is array (default: false)'
469
+ },
470
+ standard: {
471
+ type: 'string',
472
+ description: 'Standard content to delete when action is "delete"'
473
+ }
474
+ },
475
+ required: ['action'],
476
+ anyOf: [
477
+ {
478
+ properties: {
479
+ action: { const: 'get' }
480
+ }
481
+ },
482
+ {
483
+ properties: {
484
+ action: { const: 'set' },
485
+ standards: { type: 'array' }
486
+ },
487
+ required: ['standards']
488
+ },
489
+ {
490
+ properties: {
491
+ action: { const: 'delete' },
492
+ standard: { type: 'string' }
493
+ },
494
+ required: ['standard']
495
+ }
496
+ ]
497
+ }
498
+ }
499
+ );
500
+
501
+ tools.push({
502
+ name: 'api_debug',
503
+ description: 'API debugging tool for testing and executing API requests',
504
+ inputSchema: {
505
+ type: 'object',
506
+ properties: {
507
+ action: {
508
+ type: 'string',
509
+ enum: ['get', 'set', 'delete', 'execute', 'updateBaseUrl', 'updateHeaders', 'deleteHeader', 'search'],
510
+ description: 'Action to perform: "get" to retrieve config, "set" to update config, "delete" to delete API, "execute" to execute API, "updateBaseUrl" to update base URL, "updateHeaders" to update headers, "deleteHeader" to delete specific header, "search" to search APIs by URL or description'
511
+ },
512
+ config: {
513
+ type: 'object',
514
+ description: 'API debug configuration (required for "set" action)',
515
+ properties: {
516
+ baseUrl: {
517
+ type: 'string',
518
+ description: 'Base URL for API requests'
519
+ },
520
+ headers: {
521
+ type: 'object',
522
+ description: 'Common headers for all requests'
523
+ },
524
+ list: {
525
+ type: 'array',
526
+ description: 'List of API endpoints to test',
527
+ items: {
528
+ type: 'object',
529
+ properties: {
530
+ description: {
531
+ type: 'string',
532
+ description: 'API description'
533
+ },
534
+ url: {
535
+ type: 'string',
536
+ description: 'API endpoint URL'
537
+ },
538
+ method: {
539
+ type: 'string',
540
+ enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
541
+ description: 'HTTP method'
542
+ },
543
+ query: {
544
+ type: 'object',
545
+ description: 'Query parameters for GET requests'
546
+ },
547
+ body: {
548
+ description: 'Request body for POST/PUT requests'
549
+ },
550
+ contentType: {
551
+ type: 'string',
552
+ description: 'Content-Type for request body (optional, will auto-detect if not specified)'
553
+ },
554
+ header: {
555
+ type: 'object',
556
+ description: 'Additional headers for this specific request'
557
+ }
558
+ },
559
+ required: ['url', 'method']
560
+ }
561
+ }
562
+ }
563
+ },
564
+ index: {
565
+ type: 'number',
566
+ description: 'Index of API to delete or execute (required for "delete" and "execute" actions)'
567
+ },
568
+ baseUrl: {
569
+ type: 'string',
570
+ description: 'New base URL (required for "updateBaseUrl" action)'
571
+ },
572
+ headers: {
573
+ type: 'object',
574
+ description: 'New headers to add or update (required for "updateHeaders" action)'
575
+ },
576
+ headerName: {
577
+ type: 'string',
578
+ description: 'Name of header to delete (required for "deleteHeader" action)'
579
+ },
580
+ keyword: {
581
+ type: 'string',
582
+ description: 'Search keyword to match against URL or description (required for "search" action)'
583
+ }
584
+ },
585
+ required: ['action'],
586
+ anyOf: [
587
+ {
588
+ properties: {
589
+ action: { const: 'get' }
590
+ }
591
+ },
592
+ {
593
+ properties: {
594
+ action: { const: 'set' },
595
+ config: { type: 'object' }
596
+ },
597
+ required: ['config']
598
+ },
599
+ {
600
+ properties: {
601
+ action: { const: 'delete' },
602
+ index: { type: 'number' }
603
+ },
604
+ required: ['index']
605
+ },
606
+ {
607
+ properties: {
608
+ action: { const: 'execute' },
609
+ index: { type: 'number' }
610
+ },
611
+ required: ['index']
612
+ },
613
+ {
614
+ properties: {
615
+ action: { const: 'updateBaseUrl' },
616
+ baseUrl: { type: 'string' }
617
+ },
618
+ required: ['baseUrl']
619
+ },
620
+ {
621
+ properties: {
622
+ action: { const: 'updateHeaders' },
623
+ headers: { type: 'object' }
624
+ },
625
+ required: ['headers']
626
+ },
627
+ {
628
+ properties: {
629
+ action: { const: 'deleteHeader' },
630
+ headerName: { type: 'string' }
631
+ },
632
+ required: ['headerName']
633
+ },
634
+ {
635
+ properties: {
636
+ action: { const: 'search' },
637
+ keyword: { type: 'string' }
638
+ },
639
+ required: ['keyword']
640
+ }
641
+ ]
642
+ }
643
+ });
644
+
645
+ result = {
646
+ tools: tools,
647
+ environment: {
648
+ CONFIG_DIR: process.env.CONFIG_DIR || './.setting',
649
+ serverInfo: {
650
+ name: this.name,
651
+ version: this.version
652
+ }
653
+ }
654
+ };
655
+ } else if (method === 'prompts/list') {
656
+ result = {
657
+ prompts: []
658
+ };
659
+ } else if (method === 'prompts/call') {
660
+ result = {
661
+ messages: [
662
+ {
663
+ role: 'assistant',
664
+ content: [
665
+ {
666
+ type: 'text',
667
+ text: 'Unsupported prompts call'
668
+ }
669
+ ]
670
+ }
671
+ ]
672
+ };
673
+ } else if (method === 'resources/list') {
674
+ result = {
675
+ resources: []
676
+ };
677
+ } else if (method === 'resources/read') {
678
+ result = {
679
+ contents: [
680
+ {
681
+ uri: 'error://unsupported',
682
+ text: 'Unsupported resources read'
683
+ }
684
+ ]
685
+ };
686
+ } else if (method === 'logging/list') {
687
+ result = {
688
+ logs: []
689
+ };
690
+ } else if (method === 'logging/read') {
691
+ result = {
692
+ contents: [
693
+ {
694
+ uri: 'error://unsupported',
695
+ text: 'Unsupported logging read'
696
+ }
697
+ ]
698
+ };
699
+ } else if (method === 'roots/list') {
700
+ result = {
701
+ roots: []
702
+ };
703
+ } else if (method === 'roots/read') {
704
+ result = {
705
+ contents: [
706
+ {
707
+ uri: 'error://unsupported',
708
+ text: 'Unsupported roots read'
709
+ }
710
+ ]
711
+ };
712
+ } else if (method === 'tools/call') {
713
+ const { name, arguments: args } = params || {};
714
+
715
+ if (!name) {
716
+ throw new Error('Missing tool name');
717
+ }
718
+
719
+ // Check if method exists
720
+ if (!this[name]) {
721
+ throw new Error(`Unknown tool: ${name}`);
722
+ }
723
+
724
+ result = await this[name](args || {});
725
+
726
+ // Tool call results need to be wrapped in content
727
+ result = {
728
+ content: [
729
+ {
730
+ type: 'text',
731
+ text: JSON.stringify(result, null, 2)
732
+ }
733
+ ]
734
+ };
735
+ } else if (method === 'ping') {
736
+ result = { pong: true };
737
+ } else if (method === 'shutdown') {
738
+ result = null;
739
+ setTimeout(() => {
740
+ process.exit(0);
741
+ }, 100);
742
+ } else if (method === 'notifications/initialized') {
743
+ // Load configuration on initialization
744
+ this.config = getConfig();
745
+ console.error('Project Standards MCP server initialized');
746
+ } else if (method === 'notifications/exit') {
747
+ result = null;
748
+ process.exit(0);
749
+ } else {
750
+ throw new Error(`Unknown method: ${method}`);
751
+ }
752
+ } catch (err) {
753
+ error = err.message;
754
+ throw err;
755
+ } finally {
756
+ // No logging
757
+ }
758
+
759
+ // For notification methods, no response is needed
760
+ if (method === 'notifications/initialized' || method === 'notifications/exit') {
761
+ return null;
762
+ }
763
+
764
+ // shutdown method needs to return response
765
+ if (method === 'shutdown') {
766
+ return {
767
+ jsonrpc: '2.0',
768
+ id,
769
+ result: null
770
+ };
771
+ }
772
+
773
+ return {
774
+ jsonrpc: '2.0',
775
+ id,
776
+ result
777
+ };
778
+ } catch (error) {
779
+ // Use standard MCP error codes
780
+ let errorCode = -32603; // Internal error
781
+ let errorMessage = error.message;
782
+
783
+ if (error.message.includes('Server not initialized')) {
784
+ errorCode = -32002; // Server not initialized
785
+ } else if (error.message.includes('Unknown method')) {
786
+ errorCode = -32601; // Method not found
787
+ } else if (error.message.includes('Unsupported JSON-RPC version')) {
788
+ errorCode = -32600; // Invalid Request
789
+ }
790
+ return {
791
+ jsonrpc: '2.0',
792
+ id: request.id,
793
+ error: {
794
+ code: errorCode,
795
+ message: errorMessage
796
+ }
797
+ };
798
+ }
799
+ }
800
+
801
+ // Start server
802
+ async start() {
803
+ console.error('MCP Project Standards server started');
804
+
805
+ // Listen to stdin
806
+ process.stdin.setEncoding('utf8');
807
+
808
+ process.stdin.on('data', async (data) => {
809
+ try {
810
+ const lines = data.toString().trim().split('\n');
811
+
812
+ for (const line of lines) {
813
+ if (line.trim()) {
814
+ try {
815
+ const request = JSON.parse(line);
816
+ const response = await this.handleRequest(request);
817
+ if (response) {
818
+ console.log(JSON.stringify(response));
819
+ }
820
+ } catch (requestError) {
821
+ console.error('Error processing individual request:', requestError.message);
822
+ const errorResponse = {
823
+ jsonrpc: '2.0',
824
+ id: null,
825
+ error: {
826
+ code: -32603,
827
+ message: `Internal error: ${requestError.message}`
828
+ }
829
+ };
830
+ console.log(JSON.stringify(errorResponse));
831
+ }
832
+ }
833
+ }
834
+ } catch (error) {
835
+ console.error('Error processing data:', error.message);
836
+ }
837
+ });
838
+
839
+ // Handle process signals
840
+ process.on('SIGTERM', async () => {
841
+ console.error('Received SIGTERM signal, shutting down server...');
842
+ process.exit(0);
843
+ });
844
+
845
+ process.on('SIGINT', async () => {
846
+ console.error('Received SIGINT signal, shutting down server...');
847
+ process.exit(0);
848
+ });
849
+
850
+ // Handle uncaught exceptions
851
+ process.on('uncaughtException', (error) => {
852
+ console.error('Uncaught exception:', error);
853
+ process.exit(1);
854
+ });
855
+
856
+ process.on('unhandledRejection', (reason, promise) => {
857
+ console.error('Unhandled Promise rejection:', reason);
858
+ process.exit(1);
859
+ });
860
+ }
861
+ }
862
+
863
+ // Start server
864
+ async function main() {
865
+ console.error('Starting MCP Project Standards server...');
866
+ const server = new ProjectStandardsMCPServer();
867
+ await server.start();
868
+ console.error('MCP Project Standards server started successfully');
869
+ }
870
+
871
+ main().catch(error => {
872
+ console.error(error);
873
+ process.exit(1);
874
+ });