@liangshanli/mcp-server-project-standards 3.0.1 → 5.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 +62 -1
- package/README.zh-CN.md +62 -1
- package/bin/cli.js +1 -1
- package/package.json +1 -1
- package/src/server-final.js +102 -9
- package/src/utils/api_common.js +3 -3
- package/src/utils/api_config.js +22 -22
- package/src/utils/api_debug.js +51 -44
- package/src/utils/api_execute.js +56 -36
- package/src/utils/api_login.js +24 -24
- package/src/utils/database_standards.js +9 -9
- package/src/utils/generate_cursorrules.js +172 -0
- package/src/utils/get_api_standards.js +17 -17
- package/src/utils/get_development_standards.js +9 -9
- package/src/utils/get_project_info.js +7 -7
- package/src/utils/get_project_structure.js +13 -13
- package/src/utils/list_directory.js +85 -0
package/README.md
CHANGED
|
@@ -4,6 +4,13 @@ A MCP (Model Context Protocol) server for project standards management, designed
|
|
|
4
4
|
|
|
5
5
|
## 📋 Version Updates
|
|
6
6
|
|
|
7
|
+
### v5.0.0 (2025-12-19) - Major Release
|
|
8
|
+
- **Project Path Support**: Added `PROJECT_PATH` environment variable for resolving relative paths.
|
|
9
|
+
- **Cursor Detection**: Automatic identification of Cursor IDE for enhanced features.
|
|
10
|
+
- **New Tools**: Added `list_directory`, `generate_cursorrules`, and `generate_rules`.
|
|
11
|
+
- **AI Guidance**: Integrated AI Enforcement Rules into rule generation templates.
|
|
12
|
+
- **Security**: Added path validation for directory listing.
|
|
13
|
+
|
|
7
14
|
### v3.0.0 (2025-10-31) - Major Release
|
|
8
15
|
|
|
9
16
|
#### 🚀 Breaking Changes
|
|
@@ -78,6 +85,10 @@ A MCP (Model Context Protocol) server for project standards management, designed
|
|
|
78
85
|
|
|
79
86
|
## 🚀 Core Advantages
|
|
80
87
|
|
|
88
|
+
### 💰 Token Cost Optimization
|
|
89
|
+
- **Efficient Context Caching**: By using MCP tools to retrieve short, structured standard data instead of reading long documents, it triggers model Context Caching more effectively (e.g., Gemini 3 Flash), significantly reducing input costs (down to $0.05/1M).
|
|
90
|
+
- **Incremental Output**: Enforces minimal code diffs and precise tool responses, minimizing high-cost output token consumption.
|
|
91
|
+
|
|
81
92
|
### 🎯 Solving Multi-Machine Development Chaos
|
|
82
93
|
- **Unified Standards**: AI assistants on multiple machines use the same project standards, avoiding inconsistent development styles
|
|
83
94
|
- **Team Collaboration**: Eliminates code style differences caused by different developers using different AI configurations
|
|
@@ -149,7 +160,8 @@ The server uses the `./.setting/` directory to store configuration files by defa
|
|
|
149
160
|
|
|
150
161
|
| Variable | Default | Description | Example |
|
|
151
162
|
|----------|---------|-------------|---------|
|
|
152
|
-
|
|
|
163
|
+
| PROJECT_PATH | . | Root path of the project. Supports both absolute (e.g., `/` or `C:\`) and relative paths. Used to resolve all relative paths. | `export PROJECT_PATH="/path/to/project"` |
|
|
164
|
+
| CONFIG_DIR | ./.setting or ./.setting.<TOOL_PREFIX> | Configuration directory. Resolved relative to PROJECT_PATH. | `export CONFIG_DIR="./config"` |
|
|
153
165
|
| TOOL_PREFIX | | Optional tool prefix for tool names and config isolation | `export TOOL_PREFIX="projA"` |
|
|
154
166
|
| PROJECT_NAME | | Optional project branding for tool descriptions | `export PROJECT_NAME="MyProject"` |
|
|
155
167
|
| API_DEBUG_ALLOWED_METHODS | GET | Control allowed request methods (supports: GET,POST,PUT,DELETE,PATCH, etc.) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
|
|
@@ -247,6 +259,7 @@ npm run dev
|
|
|
247
259
|
"command": "npx",
|
|
248
260
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
249
261
|
"env": {
|
|
262
|
+
"PROJECT_PATH": ".",
|
|
250
263
|
"CONFIG_DIR": "./.setting",
|
|
251
264
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
252
265
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
@@ -268,6 +281,7 @@ npm run dev
|
|
|
268
281
|
"command": "npx",
|
|
269
282
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
270
283
|
"env": {
|
|
284
|
+
"PROJECT_PATH": ".",
|
|
271
285
|
"TOOL_PREFIX": "projA",
|
|
272
286
|
"PROJECT_NAME": "Project A",
|
|
273
287
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -280,6 +294,7 @@ npm run dev
|
|
|
280
294
|
"command": "npx",
|
|
281
295
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
282
296
|
"env": {
|
|
297
|
+
"PROJECT_PATH": ".",
|
|
283
298
|
"TOOL_PREFIX": "projB",
|
|
284
299
|
"PROJECT_NAME": "Project B",
|
|
285
300
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -303,6 +318,7 @@ npm run dev
|
|
|
303
318
|
"command": "npx",
|
|
304
319
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
305
320
|
"env": {
|
|
321
|
+
"PROJECT_PATH": ".",
|
|
306
322
|
"CONFIG_DIR": "./.setting",
|
|
307
323
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
308
324
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
@@ -323,6 +339,7 @@ npm run dev
|
|
|
323
339
|
"command": "npx",
|
|
324
340
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
325
341
|
"env": {
|
|
342
|
+
"PROJECT_PATH": ".",
|
|
326
343
|
"TOOL_PREFIX": "projA",
|
|
327
344
|
"PROJECT_NAME": "Project A",
|
|
328
345
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -335,6 +352,7 @@ npm run dev
|
|
|
335
352
|
"command": "npx",
|
|
336
353
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
337
354
|
"env": {
|
|
355
|
+
"PROJECT_PATH": ".",
|
|
338
356
|
"TOOL_PREFIX": "projB",
|
|
339
357
|
"PROJECT_NAME": "Project B",
|
|
340
358
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -544,6 +562,49 @@ The API debugging tool supports a complete login authentication flow, making it
|
|
|
544
562
|
|
|
545
563
|
This design eliminates the need for manual authentication state management, as the tool automatically handles login and token updates, greatly simplifying the API debugging process!
|
|
546
564
|
|
|
565
|
+
### 7. Directory Listing (list_directory)
|
|
566
|
+
Recursively explores the directory structure relative to the project root.
|
|
567
|
+
|
|
568
|
+
**Parameters:**
|
|
569
|
+
- `path` (optional): Subdirectory path to list.
|
|
570
|
+
- `depth` (optional): Max recursion depth (default: 2).
|
|
571
|
+
|
|
572
|
+
**Example:**
|
|
573
|
+
```json
|
|
574
|
+
{
|
|
575
|
+
"jsonrpc": "2.0",
|
|
576
|
+
"id": 10,
|
|
577
|
+
"method": "tools/call",
|
|
578
|
+
"params": {
|
|
579
|
+
"name": "list_directory",
|
|
580
|
+
"arguments": {
|
|
581
|
+
"depth": 3
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### 8. Rule Generation (generate_cursorrules / generate_rules)
|
|
588
|
+
Generates AI project guidance files (`.cursorrules` for Cursor, `PROJECT_RULES.md` for others) based on your standards.
|
|
589
|
+
|
|
590
|
+
**Parameters:**
|
|
591
|
+
- `save` (optional): Whether to save content to disk (default: false).
|
|
592
|
+
|
|
593
|
+
**Example:**
|
|
594
|
+
```json
|
|
595
|
+
{
|
|
596
|
+
"jsonrpc": "2.0",
|
|
597
|
+
"id": 11,
|
|
598
|
+
"method": "tools/call",
|
|
599
|
+
"params": {
|
|
600
|
+
"name": "generate_cursorrules",
|
|
601
|
+
"arguments": {
|
|
602
|
+
"save": true
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
```
|
|
607
|
+
|
|
547
608
|
## 🔗 Related Tools for Collaborative Use
|
|
548
609
|
|
|
549
610
|
To provide a more complete development experience, we recommend using the following MCP tools in collaboration:
|
package/README.zh-CN.md
CHANGED
|
@@ -4,6 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## 📋 版本更新说明
|
|
6
6
|
|
|
7
|
+
### v5.0.0 (2025-12-19) - 重大更新
|
|
8
|
+
- **项目路径支持**:新增 `PROJECT_PATH` 环境变量,支持相对于项目根目录解析路径。
|
|
9
|
+
- **Cursor 自动识别**:初始化时自动识别 Cursor 编辑器,开启环境特有的增强模式。
|
|
10
|
+
- **新增工具**:新增 `list_directory`、`generate_cursorrules` 及 `generate_rules` 工具。
|
|
11
|
+
- **AI 行为准则**:在规则生成模板中集成了完善的 AI 行为准则与强制执行逻辑。
|
|
12
|
+
- **安全性增强**:为目录扫描工具增加了路径越界校验。
|
|
13
|
+
|
|
7
14
|
### v3.0.0 (2025-10-31) - 重大更新
|
|
8
15
|
|
|
9
16
|
#### 🚀 破坏性变更
|
|
@@ -62,6 +69,10 @@
|
|
|
62
69
|
|
|
63
70
|
## 🚀 核心优势
|
|
64
71
|
|
|
72
|
+
### 💰 Token 成本优化
|
|
73
|
+
- **高效 Context Caching**:通过 MCP 工具获取短小、结构化的标准数据而非读取冗长文档,能更有效地触发模型的 Context Caching(上下文缓存,如 Gemini 3 Flash),将输入成本降低至极低水平(约 $0.05/1M)。
|
|
74
|
+
- **增量式输出**:强制执行最小化代码 Diff 和精简的工具响应,最大限度减少高昂的输出 Token 消耗。
|
|
75
|
+
|
|
65
76
|
### 🎯 解决多机器开发混乱问题
|
|
66
77
|
- **统一标准**:多台机器上的 AI 助手使用相同的项目标准,避免开发风格不一致
|
|
67
78
|
- **团队协作**:消除因不同开发者使用不同 AI 配置导致的代码风格差异
|
|
@@ -133,7 +144,8 @@ npm install
|
|
|
133
144
|
|
|
134
145
|
| 变量名 | 默认值 | 描述 | 示例 |
|
|
135
146
|
|--------|--------|------|------|
|
|
136
|
-
|
|
|
147
|
+
| PROJECT_PATH | . | 项目根路径。支持绝对路径(如 `/` 或 `C:\`)和相对路径。用于解析所有相对路径。 | `export PROJECT_PATH="/path/to/project"` |
|
|
148
|
+
| CONFIG_DIR | ./.setting 或 ./.setting.<TOOL_PREFIX> | 配置目录。相对于 PROJECT_PATH 解析。 | `export CONFIG_DIR="./config"` |
|
|
137
149
|
| TOOL_PREFIX | | 工具名前缀,同时用于多项目配置隔离 | `export TOOL_PREFIX="projA"` |
|
|
138
150
|
| PROJECT_NAME | | 工具描述前添加项目名称用于标识 | `export PROJECT_NAME="MyProject"` |
|
|
139
151
|
| API_DEBUG_ALLOWED_METHODS | GET | 控制允许的请求方法(支持:GET,POST,PUT,DELETE,PATCH等) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
|
|
@@ -231,6 +243,7 @@ npm run dev
|
|
|
231
243
|
"command": "npx",
|
|
232
244
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
233
245
|
"env": {
|
|
246
|
+
"PROJECT_PATH": ".",
|
|
234
247
|
"CONFIG_DIR": "./.setting",
|
|
235
248
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
236
249
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
@@ -252,6 +265,7 @@ npm run dev
|
|
|
252
265
|
"command": "npx",
|
|
253
266
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
254
267
|
"env": {
|
|
268
|
+
"PROJECT_PATH": ".",
|
|
255
269
|
"TOOL_PREFIX": "projA",
|
|
256
270
|
"PROJECT_NAME": "项目A",
|
|
257
271
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -264,6 +278,7 @@ npm run dev
|
|
|
264
278
|
"command": "npx",
|
|
265
279
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
266
280
|
"env": {
|
|
281
|
+
"PROJECT_PATH": ".",
|
|
267
282
|
"TOOL_PREFIX": "projB",
|
|
268
283
|
"PROJECT_NAME": "项目B",
|
|
269
284
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -287,6 +302,7 @@ npm run dev
|
|
|
287
302
|
"command": "npx",
|
|
288
303
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
289
304
|
"env": {
|
|
305
|
+
"PROJECT_PATH": ".",
|
|
290
306
|
"CONFIG_DIR": "./.setting",
|
|
291
307
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
292
308
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
@@ -307,6 +323,7 @@ npm run dev
|
|
|
307
323
|
"command": "npx",
|
|
308
324
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
309
325
|
"env": {
|
|
326
|
+
"PROJECT_PATH": ".",
|
|
310
327
|
"TOOL_PREFIX": "projA",
|
|
311
328
|
"PROJECT_NAME": "项目A",
|
|
312
329
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -319,6 +336,7 @@ npm run dev
|
|
|
319
336
|
"command": "npx",
|
|
320
337
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
321
338
|
"env": {
|
|
339
|
+
"PROJECT_PATH": ".",
|
|
322
340
|
"TOOL_PREFIX": "projB",
|
|
323
341
|
"PROJECT_NAME": "项目B",
|
|
324
342
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
@@ -532,6 +550,49 @@ API 调试工具支持完整的登录认证流程,让您轻松管理 API 访
|
|
|
532
550
|
|
|
533
551
|
这样设计让您无需手动管理认证状态,工具会自动处理登录和 token 更新,大大简化了 API 调试流程!
|
|
534
552
|
|
|
553
|
+
### 7. 目录列表工具 (list_directory)
|
|
554
|
+
递归地探索相对于项目根目录的目录结构。
|
|
555
|
+
|
|
556
|
+
**参数:**
|
|
557
|
+
- `path` (可选): 要列出的子目录路径。
|
|
558
|
+
- `depth` (可选): 最大递归深度(默认:2)。
|
|
559
|
+
|
|
560
|
+
**使用示例:**
|
|
561
|
+
```json
|
|
562
|
+
{
|
|
563
|
+
"jsonrpc": "2.0",
|
|
564
|
+
"id": 10,
|
|
565
|
+
"method": "tools/call",
|
|
566
|
+
"params": {
|
|
567
|
+
"name": "list_directory",
|
|
568
|
+
"arguments": {
|
|
569
|
+
"depth": 3
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### 8. 规则生成工具 (generate_cursorrules / generate_rules)
|
|
576
|
+
根据您的标准生成 AI 项目指导文件(Cursor 使用 `.cursorrules`,其他客户端使用 `PROJECT_RULES.md`)。
|
|
577
|
+
|
|
578
|
+
**参数:**
|
|
579
|
+
- `save` (可选): 是否将内容保存到磁盘(默认:false)。
|
|
580
|
+
|
|
581
|
+
**使用示例:**
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"jsonrpc": "2.0",
|
|
585
|
+
"id": 11,
|
|
586
|
+
"method": "tools/call",
|
|
587
|
+
"params": {
|
|
588
|
+
"name": "generate_cursorrules",
|
|
589
|
+
"arguments": {
|
|
590
|
+
"save": true
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
```
|
|
595
|
+
|
|
535
596
|
## 🔗 相关工具协同使用
|
|
536
597
|
|
|
537
598
|
为了提供更完整的开发体验,推荐与以下 MCP 工具协同使用:
|
package/bin/cli.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liangshanli/mcp-server-project-standards",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "MCP Project Standards server with project info, structure, API standards, development standards, API debugging, login authentication and configuration management tools",
|
|
5
5
|
"main": "bin/cli.js",
|
|
6
6
|
"bin": {
|
package/src/server-final.js
CHANGED
|
@@ -12,16 +12,28 @@ const api_debug = require('./utils/api_debug');
|
|
|
12
12
|
const api_config = require('./utils/api_config');
|
|
13
13
|
const api_help = require('./utils/api_help');
|
|
14
14
|
const api_execute = require('./utils/api_execute');
|
|
15
|
+
const list_directory = require('./utils/list_directory');
|
|
16
|
+
const generate_cursorrules = require('./utils/generate_cursorrules');
|
|
15
17
|
|
|
16
18
|
// Get config directory based on CONFIG_DIR and TOOL_PREFIX
|
|
17
19
|
const getConfigDir = () => {
|
|
18
20
|
let configDir = process.env.CONFIG_DIR;
|
|
21
|
+
// If PROJECT_PATH is null and client is Cursor, default to '.', otherwise null
|
|
22
|
+
const projectPath = process.env.PROJECT_PATH || (global.isCursor ? '.' : null);
|
|
23
|
+
|
|
19
24
|
if (!configDir) {
|
|
20
25
|
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
26
|
+
// Configuration location: under project path if available, otherwise current directory
|
|
27
|
+
const baseDir = projectPath || '.';
|
|
21
28
|
if (toolPrefix) {
|
|
22
|
-
configDir =
|
|
29
|
+
configDir = path.resolve(baseDir, `.setting.${toolPrefix}`);
|
|
23
30
|
} else {
|
|
24
|
-
configDir = '
|
|
31
|
+
configDir = path.resolve(baseDir, '.setting');
|
|
32
|
+
}
|
|
33
|
+
} else if (projectPath) {
|
|
34
|
+
// If CONFIG_DIR is set, make it absolute or relative to projectPath if not already absolute
|
|
35
|
+
if (!path.isAbsolute(configDir)) {
|
|
36
|
+
configDir = path.resolve(projectPath, configDir);
|
|
25
37
|
}
|
|
26
38
|
}
|
|
27
39
|
return configDir;
|
|
@@ -62,12 +74,16 @@ const saveConfig = (config) => {
|
|
|
62
74
|
}
|
|
63
75
|
};
|
|
64
76
|
|
|
65
|
-
//
|
|
77
|
+
// Startup logs
|
|
66
78
|
console.error('=== MCP Project Standards Server Starting ===');
|
|
67
79
|
console.error(`Time: ${new Date().toISOString()}`);
|
|
80
|
+
console.error(`Project Path: ${process.env.PROJECT_PATH || '.'}`);
|
|
68
81
|
console.error(`Config Dir: ${getConfigDir()}`);
|
|
69
82
|
console.error('==============================================');
|
|
70
83
|
|
|
84
|
+
// Global state
|
|
85
|
+
global.isCursor = false;
|
|
86
|
+
|
|
71
87
|
// Final MCP Server
|
|
72
88
|
class ProjectStandardsMCPServer {
|
|
73
89
|
constructor() {
|
|
@@ -77,25 +93,25 @@ class ProjectStandardsMCPServer {
|
|
|
77
93
|
this.config = getConfig();
|
|
78
94
|
this.needsProjectFolder = this.config === null;
|
|
79
95
|
|
|
80
|
-
//
|
|
96
|
+
// Create default config if config file doesn't exist
|
|
81
97
|
if (this.needsProjectFolder) {
|
|
82
98
|
this.createDefaultConfig();
|
|
83
99
|
}
|
|
84
100
|
}
|
|
85
101
|
|
|
86
|
-
//
|
|
102
|
+
// Create default config file
|
|
87
103
|
createDefaultConfig() {
|
|
88
104
|
const configDir = getConfigDir();
|
|
89
105
|
const configPath = path.join(configDir, 'config.json');
|
|
90
106
|
|
|
91
107
|
try {
|
|
92
|
-
//
|
|
108
|
+
// Create config directory
|
|
93
109
|
if (!fs.existsSync(configDir)) {
|
|
94
110
|
fs.mkdirSync(configDir, { recursive: true });
|
|
95
111
|
console.error(`Created config directory: ${configDir}`);
|
|
96
112
|
}
|
|
97
113
|
|
|
98
|
-
//
|
|
114
|
+
// Create default config file
|
|
99
115
|
const defaultConfig = {
|
|
100
116
|
project_info: {},
|
|
101
117
|
project_structure: [],
|
|
@@ -107,12 +123,12 @@ class ProjectStandardsMCPServer {
|
|
|
107
123
|
fs.writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2), 'utf8');
|
|
108
124
|
console.error(`Created default config file: ${configPath}`);
|
|
109
125
|
|
|
110
|
-
//
|
|
126
|
+
// Update config and state
|
|
111
127
|
this.config = defaultConfig;
|
|
112
128
|
this.needsProjectFolder = false;
|
|
113
129
|
} catch (err) {
|
|
114
130
|
console.error('Failed to create default config:', err.message);
|
|
115
|
-
//
|
|
131
|
+
// Keep needsProjectFolder = true state
|
|
116
132
|
}
|
|
117
133
|
}
|
|
118
134
|
|
|
@@ -197,8 +213,23 @@ class ProjectStandardsMCPServer {
|
|
|
197
213
|
return result;
|
|
198
214
|
}
|
|
199
215
|
|
|
216
|
+
// List directory tool
|
|
217
|
+
async list_directory(params) {
|
|
218
|
+
const result = await list_directory(params);
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
200
221
|
|
|
222
|
+
// Generate cursorrules tool
|
|
223
|
+
async generate_cursorrules(params) {
|
|
224
|
+
const result = await generate_cursorrules(params, this.config);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
201
227
|
|
|
228
|
+
// Generate rules tool (for non-cursor)
|
|
229
|
+
async generate_rules(params) {
|
|
230
|
+
const result = await generate_cursorrules(params, this.config);
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
202
233
|
|
|
203
234
|
// Handle JSON-RPC requests
|
|
204
235
|
async handleRequest(request) {
|
|
@@ -214,6 +245,11 @@ class ProjectStandardsMCPServer {
|
|
|
214
245
|
|
|
215
246
|
try {
|
|
216
247
|
if (method === 'initialize') {
|
|
248
|
+
// Detect Cursor client
|
|
249
|
+
const clientName = params?.clientInfo?.name || '';
|
|
250
|
+
global.isCursor = clientName.toLowerCase().includes('cursor');
|
|
251
|
+
console.error(`Client identified: ${clientName} (isCursor: ${global.isCursor})`);
|
|
252
|
+
|
|
217
253
|
// If already initialized, return success but don't re-initialize
|
|
218
254
|
if (!this.initialized) {
|
|
219
255
|
this.initialized = true;
|
|
@@ -878,6 +914,63 @@ class ProjectStandardsMCPServer {
|
|
|
878
914
|
}
|
|
879
915
|
});
|
|
880
916
|
|
|
917
|
+
// Check whether to show project structure related tools
|
|
918
|
+
const projectPath = process.env.PROJECT_PATH || (global.isCursor ? '.' : null);
|
|
919
|
+
const showStructureTools = !!projectPath;
|
|
920
|
+
|
|
921
|
+
if (showStructureTools) {
|
|
922
|
+
// List Directory Tool
|
|
923
|
+
tools.push({
|
|
924
|
+
name: 'list_directory',
|
|
925
|
+
description: 'List directory structure relative to the project path. Returns a tree of files and directories.',
|
|
926
|
+
inputSchema: {
|
|
927
|
+
type: 'object',
|
|
928
|
+
properties: {
|
|
929
|
+
path: {
|
|
930
|
+
type: 'string',
|
|
931
|
+
description: 'Subdirectory path to list (relative to project path, optional)'
|
|
932
|
+
},
|
|
933
|
+
depth: {
|
|
934
|
+
type: 'number',
|
|
935
|
+
description: 'Max depth to traverse (default: 2, optional)'
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
if (global.isCursor) {
|
|
942
|
+
// Generate Cursor Rules Tool
|
|
943
|
+
tools.push({
|
|
944
|
+
name: 'generate_cursorrules',
|
|
945
|
+
description: 'Generate .cursorrules content based on project standards. Returns content and save path for user confirmation.',
|
|
946
|
+
inputSchema: {
|
|
947
|
+
type: 'object',
|
|
948
|
+
properties: {
|
|
949
|
+
save: {
|
|
950
|
+
type: 'boolean',
|
|
951
|
+
description: 'Whether to save to .cursorrules file (default: false)'
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
} else {
|
|
957
|
+
// Generate General Rules Tool
|
|
958
|
+
tools.push({
|
|
959
|
+
name: 'generate_rules',
|
|
960
|
+
description: 'Generate project rules content based on standards. Returns content and suggested save path for user confirmation.',
|
|
961
|
+
inputSchema: {
|
|
962
|
+
type: 'object',
|
|
963
|
+
properties: {
|
|
964
|
+
save: {
|
|
965
|
+
type: 'boolean',
|
|
966
|
+
description: 'Whether to save to rules file (default: false)'
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
881
974
|
// Apply tool prefix and project name if both provided
|
|
882
975
|
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
883
976
|
const projectName = process.env.PROJECT_NAME || '';
|
package/src/utils/api_common.js
CHANGED
|
@@ -79,16 +79,16 @@ const getLoginMethod = () => {
|
|
|
79
79
|
const getLoginBody = () => {
|
|
80
80
|
const envBody = process.env.API_DEBUG_LOGIN_BODY || '{"username":"","password":""}';
|
|
81
81
|
|
|
82
|
-
//
|
|
82
|
+
// If it is a string format, return it directly
|
|
83
83
|
if (typeof envBody === 'string' && !envBody.startsWith('{')) {
|
|
84
84
|
return envBody;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// If it is JSON format, parse and return it
|
|
88
88
|
try {
|
|
89
89
|
return JSON.parse(envBody);
|
|
90
90
|
} catch {
|
|
91
|
-
//
|
|
91
|
+
// If parsing fails, return the original string
|
|
92
92
|
return envBody;
|
|
93
93
|
}
|
|
94
94
|
};
|
package/src/utils/api_config.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
const { loadApiConfig, saveApiConfig } = require('./api_common');
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* API
|
|
5
|
-
* @param {Object} params -
|
|
6
|
-
* @param {string} params.action -
|
|
7
|
-
* @param {Object} params.config - API
|
|
8
|
-
* @param {string} params.baseUrl -
|
|
9
|
-
* @param {Object} params.headers -
|
|
10
|
-
* @param {string} params.headerName -
|
|
11
|
-
* @param {Object} params.api - API
|
|
12
|
-
* @param {string} params.keyword -
|
|
13
|
-
* @param {Object} config -
|
|
14
|
-
* @param {Function} saveConfig -
|
|
15
|
-
* @returns {Object} API
|
|
4
|
+
* API Configuration Tool - Handles API configuration management
|
|
5
|
+
* @param {Object} params - Parameters
|
|
6
|
+
* @param {string} params.action - Action type ('get', 'set', 'updateBaseUrl', 'updateHeaders', 'deleteHeader', 'addApi', 'search', 'list')
|
|
7
|
+
* @param {Object} params.config - API configuration (required for 'set')
|
|
8
|
+
* @param {string} params.baseUrl - Base URL (required for 'updateBaseUrl')
|
|
9
|
+
* @param {Object} params.headers - Request headers (required for 'updateHeaders')
|
|
10
|
+
* @param {string} params.headerName - Header name to delete (required for 'deleteHeader')
|
|
11
|
+
* @param {Object} params.api - API configuration (required for 'addApi')
|
|
12
|
+
* @param {string} params.keyword - Search keyword (required for 'search')
|
|
13
|
+
* @param {Object} config - Server configuration
|
|
14
|
+
* @param {Function} saveConfig - Save configuration function
|
|
15
|
+
* @returns {Object} API configuration result
|
|
16
16
|
*/
|
|
17
17
|
async function api_config(params, config, saveConfig) {
|
|
18
18
|
const { action, config: apiConfig, baseUrl, headers, headerName, api, keyword } = params || {};
|
|
@@ -38,20 +38,20 @@ async function api_config(params, config, saveConfig) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
try {
|
|
41
|
-
//
|
|
41
|
+
// Load existing configuration
|
|
42
42
|
const existingConfig = loadApiConfig();
|
|
43
43
|
|
|
44
|
-
//
|
|
44
|
+
// Merge configuration
|
|
45
45
|
const mergedConfig = {
|
|
46
46
|
baseUrl: apiConfig.baseUrl !== undefined ? apiConfig.baseUrl : existingConfig.baseUrl || '',
|
|
47
47
|
headers: { ...existingConfig.headers, ...apiConfig.headers },
|
|
48
48
|
list: []
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
//
|
|
51
|
+
// De-duplication: Keep only one entry for the same URL
|
|
52
52
|
const urlMap = new Map();
|
|
53
53
|
|
|
54
|
-
//
|
|
54
|
+
// Add items from the existing list first
|
|
55
55
|
if (existingConfig.list && Array.isArray(existingConfig.list)) {
|
|
56
56
|
existingConfig.list.forEach(item => {
|
|
57
57
|
if (item.url) {
|
|
@@ -60,7 +60,7 @@ async function api_config(params, config, saveConfig) {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// Then add items from the new configuration (overwriting items with the same URL)
|
|
64
64
|
if (apiConfig.list && Array.isArray(apiConfig.list)) {
|
|
65
65
|
apiConfig.list.forEach(item => {
|
|
66
66
|
if (item.url) {
|
|
@@ -69,10 +69,10 @@ async function api_config(params, config, saveConfig) {
|
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
//
|
|
72
|
+
// Convert to array
|
|
73
73
|
mergedConfig.list = Array.from(urlMap.values());
|
|
74
74
|
|
|
75
|
-
//
|
|
75
|
+
// Save configuration
|
|
76
76
|
const saved = saveApiConfig(mergedConfig);
|
|
77
77
|
if (!saved) {
|
|
78
78
|
throw new Error('Failed to save API configuration');
|
|
@@ -175,11 +175,11 @@ async function api_config(params, config, saveConfig) {
|
|
|
175
175
|
apiDebugConfig.list = [];
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
//
|
|
178
|
+
// Check if an API with the same URL already exists
|
|
179
179
|
const existingIndex = apiDebugConfig.list.findIndex(item => item.url === api.url);
|
|
180
180
|
|
|
181
181
|
if (existingIndex >= 0) {
|
|
182
|
-
//
|
|
182
|
+
// Update existing API
|
|
183
183
|
apiDebugConfig.list[existingIndex] = { ...apiDebugConfig.list[existingIndex], ...api };
|
|
184
184
|
const saved = saveApiConfig(apiDebugConfig);
|
|
185
185
|
if (!saved) {
|
|
@@ -194,7 +194,7 @@ async function api_config(params, config, saveConfig) {
|
|
|
194
194
|
timestamp: new Date().toISOString()
|
|
195
195
|
};
|
|
196
196
|
} else {
|
|
197
|
-
//
|
|
197
|
+
// Add new API
|
|
198
198
|
apiDebugConfig.list.push(api);
|
|
199
199
|
const saved = saveApiConfig(apiDebugConfig);
|
|
200
200
|
if (!saved) {
|