@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.
- package/README.md +588 -0
- package/README.zh-CN.md +607 -0
- package/bin/cli.js +196 -0
- package/package.json +38 -0
- package/src/server-final.js +874 -0
- package/src/utils/api_debug.js +514 -0
- package/src/utils/create_custom_tool.js +54 -0
- package/src/utils/database_standards.js +147 -0
- package/src/utils/execute_custom_tool.js +51 -0
- package/src/utils/get_api_standards.js +203 -0
- package/src/utils/get_development_standards.js +139 -0
- package/src/utils/get_project_info.js +87 -0
- package/src/utils/get_project_structure.js +139 -0
- package/src/utils/list_custom_tools.js +15 -0
- package/src/utils/update_config.js +36 -0
- package/start-server.js +108 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Project structure tool - get, set or delete project structure
|
|
6
|
+
* @param {Object} params - Parameters
|
|
7
|
+
* @param {string} params.action - Action to perform ('get', 'set', or 'delete')
|
|
8
|
+
* @param {Array} params.structure - Array of structure items with path and description (required for 'set' action)
|
|
9
|
+
* @param {string} params.path - Path to delete when action is 'delete'
|
|
10
|
+
* @param {Object} config - Server configuration
|
|
11
|
+
* @param {Function} saveConfig - Function to save configuration (required for 'set' and 'delete' actions)
|
|
12
|
+
* @returns {Array|Object} Project structure array or update result
|
|
13
|
+
*/
|
|
14
|
+
async function project_structure(params, config, saveConfig) {
|
|
15
|
+
const { action, structure, path: deletePath } = params || {};
|
|
16
|
+
|
|
17
|
+
if (!action) {
|
|
18
|
+
throw new Error('Missing action parameter. Must be "get", "set", or "delete"');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (action === 'get') {
|
|
22
|
+
try {
|
|
23
|
+
// 从配置文件的 project_structure 字段中获取结构,如果没有则使用默认值
|
|
24
|
+
const projectStructure = config?.project_structure || [];
|
|
25
|
+
|
|
26
|
+
return projectStructure;
|
|
27
|
+
} catch (err) {
|
|
28
|
+
throw new Error(`Failed to get project structure: ${err.message}`);
|
|
29
|
+
}
|
|
30
|
+
} else if (action === 'set') {
|
|
31
|
+
if (!Array.isArray(structure)) {
|
|
32
|
+
throw new Error('Structure must be an array for set action');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!saveConfig) {
|
|
36
|
+
throw new Error('saveConfig function is required for set action');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// 获取当前结构
|
|
41
|
+
let currentStructure = config?.project_structure || [];
|
|
42
|
+
|
|
43
|
+
// 创建新结构数组
|
|
44
|
+
const newStructure = [];
|
|
45
|
+
|
|
46
|
+
// 循环处理每个新结构项
|
|
47
|
+
for (const item of structure) {
|
|
48
|
+
if (!item.path || !item.description) {
|
|
49
|
+
throw new Error('Each structure item must have "path" and "description" properties');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 检查路径是否已存在
|
|
53
|
+
const existingIndex = currentStructure.findIndex(existing => existing.path === item.path);
|
|
54
|
+
|
|
55
|
+
if (existingIndex !== -1) {
|
|
56
|
+
// 路径存在,替换
|
|
57
|
+
currentStructure[existingIndex] = {
|
|
58
|
+
path: item.path,
|
|
59
|
+
description: item.description
|
|
60
|
+
};
|
|
61
|
+
} else {
|
|
62
|
+
// 路径不存在,添加到新结构
|
|
63
|
+
newStructure.push({
|
|
64
|
+
path: item.path,
|
|
65
|
+
description: item.description
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 将新结构附加到现有结构
|
|
71
|
+
const updatedStructure = [...currentStructure, ...newStructure];
|
|
72
|
+
|
|
73
|
+
// 更新配置
|
|
74
|
+
if (!config.project_structure) {
|
|
75
|
+
config.project_structure = [];
|
|
76
|
+
}
|
|
77
|
+
config.project_structure = updatedStructure;
|
|
78
|
+
|
|
79
|
+
// 保存配置
|
|
80
|
+
const saved = saveConfig(config);
|
|
81
|
+
if (!saved) {
|
|
82
|
+
throw new Error('Failed to save configuration');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
success: true,
|
|
87
|
+
message: `Successfully updated project structure`,
|
|
88
|
+
updatedCount: structure.length,
|
|
89
|
+
newItemsCount: newStructure.length,
|
|
90
|
+
totalItems: updatedStructure.length,
|
|
91
|
+
timestamp: new Date().toISOString()
|
|
92
|
+
};
|
|
93
|
+
} catch (err) {
|
|
94
|
+
throw new Error(`Failed to update project structure: ${err.message}`);
|
|
95
|
+
}
|
|
96
|
+
} else if (action === 'delete') {
|
|
97
|
+
if (!deletePath) {
|
|
98
|
+
throw new Error('Missing path parameter for delete action');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!saveConfig) {
|
|
102
|
+
throw new Error('saveConfig function is required for delete action');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
// 确保 config.project_structure 存在
|
|
107
|
+
if (!config.project_structure) {
|
|
108
|
+
config.project_structure = [];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 查找并删除指定的路径
|
|
112
|
+
const pathIndex = config.project_structure.findIndex(item => item.path === deletePath);
|
|
113
|
+
if (pathIndex !== -1) {
|
|
114
|
+
const deletedItem = config.project_structure.splice(pathIndex, 1)[0];
|
|
115
|
+
|
|
116
|
+
// 保存配置
|
|
117
|
+
const saved = saveConfig(config);
|
|
118
|
+
if (!saved) {
|
|
119
|
+
throw new Error('Failed to save configuration');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
success: true,
|
|
124
|
+
message: `Successfully deleted structure item: ${deletePath}`,
|
|
125
|
+
deletedItem: deletedItem,
|
|
126
|
+
timestamp: new Date().toISOString()
|
|
127
|
+
};
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error(`Path '${deletePath}' not found`);
|
|
130
|
+
}
|
|
131
|
+
} catch (err) {
|
|
132
|
+
throw new Error(`Failed to delete structure item: ${err.message}`);
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
throw new Error('Invalid action. Must be "get", "set", or "delete"');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = project_structure;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* List all custom tools
|
|
3
|
+
* @param {Object} params - Parameters
|
|
4
|
+
* @param {Object} config - Server configuration
|
|
5
|
+
* @returns {Object} List of custom tools
|
|
6
|
+
*/
|
|
7
|
+
async function list_custom_tools(params, config) {
|
|
8
|
+
return {
|
|
9
|
+
tools: config.customTools || [],
|
|
10
|
+
count: (config.customTools || []).length,
|
|
11
|
+
timestamp: new Date().toISOString()
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = list_custom_tools;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update server configuration
|
|
3
|
+
* @param {Object} params - Parameters
|
|
4
|
+
* @param {Object} params.config - Configuration object to update
|
|
5
|
+
* @param {Object} currentConfig - Current server configuration
|
|
6
|
+
* @param {Function} saveConfig - Function to save configuration
|
|
7
|
+
* @returns {Object} Result of configuration update
|
|
8
|
+
*/
|
|
9
|
+
async function update_config(params, currentConfig, saveConfig) {
|
|
10
|
+
const { config } = params || {};
|
|
11
|
+
|
|
12
|
+
if (!config || typeof config !== 'object') {
|
|
13
|
+
throw new Error('Invalid config parameter');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
// Merge with existing config
|
|
18
|
+
const updatedConfig = { ...currentConfig, ...config };
|
|
19
|
+
|
|
20
|
+
// Save to file
|
|
21
|
+
const saved = saveConfig(updatedConfig);
|
|
22
|
+
if (!saved) {
|
|
23
|
+
throw new Error('Failed to save configuration');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
success: true,
|
|
28
|
+
config: updatedConfig,
|
|
29
|
+
message: 'Configuration updated successfully'
|
|
30
|
+
};
|
|
31
|
+
} catch (err) {
|
|
32
|
+
throw new Error(`Failed to update configuration: ${err.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = update_config;
|
package/start-server.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
|
|
7
|
+
class ServerManager {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.serverProcess = null;
|
|
10
|
+
this.restartCount = 0;
|
|
11
|
+
this.maxRestarts = 10;
|
|
12
|
+
this.restartDelay = 5000; // 5 seconds
|
|
13
|
+
this.serverPath = path.resolve(__dirname, 'src/server-final.js');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
start() {
|
|
17
|
+
console.log('Starting MCP Project Standards server...');
|
|
18
|
+
this.spawnServer();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
spawnServer() {
|
|
22
|
+
// Set environment variables
|
|
23
|
+
const env = {
|
|
24
|
+
...process.env,
|
|
25
|
+
// Only pass CONFIG_PATH if specified
|
|
26
|
+
...(process.env.CONFIG_PATH && { CONFIG_PATH: process.env.CONFIG_PATH })
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
this.serverProcess = spawn('node', [this.serverPath], {
|
|
30
|
+
stdio: ['inherit', 'inherit', 'inherit'],
|
|
31
|
+
env: env
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
console.log(`Server process started, PID: ${this.serverProcess.pid}`);
|
|
35
|
+
|
|
36
|
+
this.serverProcess.on('close', (code) => {
|
|
37
|
+
console.log(`Server process exited, exit code: ${code}`);
|
|
38
|
+
this.handleServerExit(code);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.serverProcess.on('error', (err) => {
|
|
42
|
+
console.error('Server process error:', err.message);
|
|
43
|
+
this.handleServerError(err);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Handle process signals
|
|
47
|
+
process.on('SIGTERM', () => {
|
|
48
|
+
console.log('Received SIGTERM signal, shutting down server...');
|
|
49
|
+
this.shutdown();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
process.on('SIGINT', () => {
|
|
53
|
+
console.log('Received SIGINT signal, shutting down server...');
|
|
54
|
+
this.shutdown();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
handleServerExit(code) {
|
|
59
|
+
if (code === 0) {
|
|
60
|
+
console.log('Server exited normally');
|
|
61
|
+
process.exit(0);
|
|
62
|
+
} else {
|
|
63
|
+
console.error(`Server exited abnormally, exit code: ${code}`);
|
|
64
|
+
this.restartServer();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
handleServerError(err) {
|
|
69
|
+
console.error('Server process error:', err.message);
|
|
70
|
+
this.restartServer();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
restartServer() {
|
|
74
|
+
if (this.restartCount < this.maxRestarts) {
|
|
75
|
+
this.restartCount++;
|
|
76
|
+
console.log(`Restarting server... (${this.restartCount}/${this.maxRestarts})`);
|
|
77
|
+
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
this.spawnServer();
|
|
80
|
+
}, this.restartDelay);
|
|
81
|
+
} else {
|
|
82
|
+
console.error(`Reached maximum restart count (${this.maxRestarts}), stopping restarts`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
shutdown() {
|
|
88
|
+
if (this.serverProcess) {
|
|
89
|
+
console.log('Sending SIGTERM signal to server process...');
|
|
90
|
+
this.serverProcess.kill('SIGTERM');
|
|
91
|
+
|
|
92
|
+
// Wait 5 seconds then force exit
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
if (this.serverProcess) {
|
|
95
|
+
console.log('Force killing server process...');
|
|
96
|
+
this.serverProcess.kill('SIGKILL');
|
|
97
|
+
}
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}, 5000);
|
|
100
|
+
} else {
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Start server manager
|
|
107
|
+
const manager = new ServerManager();
|
|
108
|
+
manager.start();
|