@liangshanli/mcp-server-project-standards 1.0.0 → 1.1.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 CHANGED
@@ -2,6 +2,43 @@
2
2
 
3
3
  A MCP (Model Context Protocol) server for project standards management, designed for AI-assisted development to help teams maintain unified development standards and specifications across multiple machines.
4
4
 
5
+ ## 📋 Version Updates
6
+
7
+ ### v1.1.0 (2024-12-19)
8
+
9
+ #### 🆕 New Features
10
+ - **API Debug Tool Environment Variable Support**:
11
+ - `API_DEBUG_ALLOWED_METHODS` - Control allowed request methods (default: GET)
12
+ - `API_DEBUG_LOGIN_URL` - Set login API URL (default: /api/login)
13
+ - `API_DEBUG_LOGIN_METHOD` - Set login request method (default: POST)
14
+ - `API_DEBUG_LOGIN_BODY` - Set login request body (default: {"username":"","password":""})
15
+ - `API_DEBUG_LOGIN_DESCRIPTION` - Set login API description (default: Save returned token to common headers in debug tool, field name Authorization, field value Bearer token)
16
+
17
+ #### 🔧 Feature Improvements
18
+ - **Smart Login API Recognition**:
19
+ - Support for full URL and relative path matching
20
+ - Automatic login API recognition using environment variable configuration
21
+ - Non-login APIs strictly follow allowed method restrictions
22
+
23
+ - **Error Handling Optimization**:
24
+ - Only request-related errors are saved to api.json
25
+ - Method validation errors don't pollute execution records
26
+ - More precise error classification and handling
27
+
28
+ - **Dynamic Tool Description**:
29
+ - Display login authentication information based on environment variable configuration
30
+ - Real-time display of allowed request methods and usage instructions
31
+
32
+ #### 🛡️ Security Enhancements
33
+ - **Request Method Restrictions**: Default only allows GET requests to prevent accidental operations
34
+ - **Login API Exception**: Login APIs can use methods configured in environment variables
35
+ - **Flexible Configuration**: Can open more request methods as needed
36
+
37
+ #### 📚 Documentation Updates
38
+ - Added environment variable configuration instructions
39
+ - Updated API debug tool usage guide
40
+ - Improved login authentication flow documentation
41
+
5
42
  ## 🚀 Core Advantages
6
43
 
7
44
  ### 🎯 Solving Multi-Machine Development Chaos
@@ -73,9 +110,14 @@ The server uses the `./.setting/` directory to store configuration files by defa
73
110
 
74
111
  ### Environment Variables
75
112
 
76
- | Variable | Default | Description |
77
- |----------|---------|-------------|
78
- | CONFIG_DIR | ./.setting | Configuration file directory (contains config.json and api.json) |
113
+ | Variable | Default | Description | Example |
114
+ |----------|---------|-------------|---------|
115
+ | CONFIG_DIR | ./.setting | Configuration file directory (contains config.json and api.json) | `export CONFIG_DIR="./config"` |
116
+ | API_DEBUG_ALLOWED_METHODS | GET | Control allowed request methods (supports: GET,POST,PUT,DELETE,PATCH, etc.) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
117
+ | API_DEBUG_LOGIN_URL | /api/login | Set login API URL | `export API_DEBUG_LOGIN_URL="/api/auth/login"` |
118
+ | API_DEBUG_LOGIN_METHOD | POST | Set login request method | `export API_DEBUG_LOGIN_METHOD="POST"` |
119
+ | API_DEBUG_LOGIN_BODY | {"username":"","password":""} | Set login request body | `export API_DEBUG_LOGIN_BODY='{"mobile":"","password":""}'` |
120
+ | API_DEBUG_LOGIN_DESCRIPTION | Save returned token to common headers in debug tool, field name Authorization, field value Bearer token | Set login API description | `export API_DEBUG_LOGIN_DESCRIPTION="User Login API"` |
79
121
 
80
122
  ### Configuration Files
81
123
 
@@ -166,7 +208,12 @@ npm run dev
166
208
  "command": "npx",
167
209
  "args": ["@liangshanli/mcp-server-project-standards"],
168
210
  "env": {
169
- "CONFIG_DIR": "./.setting"
211
+ "CONFIG_DIR": "./.setting",
212
+ "API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
213
+ "API_DEBUG_LOGIN_URL": "/api/login",
214
+ "API_DEBUG_LOGIN_METHOD": "POST",
215
+ "API_DEBUG_LOGIN_BODY": "{\"username\":\"\",\"password\":\"\"}",
216
+ "API_DEBUG_LOGIN_DESCRIPTION": "Save returned token to common headers in debug tool, field name Authorization, field value Bearer token"
170
217
  }
171
218
  }
172
219
  }
@@ -185,7 +232,12 @@ npm run dev
185
232
  "command": "npx",
186
233
  "args": ["@liangshanli/mcp-server-project-standards"],
187
234
  "env": {
188
- "CONFIG_DIR": "./.setting"
235
+ "CONFIG_DIR": "./.setting",
236
+ "API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
237
+ "API_DEBUG_LOGIN_URL": "/api/login",
238
+ "API_DEBUG_LOGIN_METHOD": "POST",
239
+ "API_DEBUG_LOGIN_BODY": "{\"username\":\"\",\"password\":\"\"}",
240
+ "API_DEBUG_LOGIN_DESCRIPTION": "Save returned token to common headers in debug tool, field name Authorization, field value Bearer token"
189
241
  }
190
242
  }
191
243
  }
package/README.zh-CN.md CHANGED
@@ -2,6 +2,43 @@
2
2
 
3
3
  一个基于 MCP(Model Context Protocol)协议的项目标准管理工具,专为 AI 辅助开发而设计,帮助团队在多台机器上保持统一的开发标准和规范。
4
4
 
5
+ ## 📋 版本更新说明
6
+
7
+ ### v1.1.0 (2024-12-19)
8
+
9
+ #### 🆕 新增功能
10
+ - **API 调试工具环境变量支持**:
11
+ - `API_DEBUG_ALLOWED_METHODS` - 控制允许的请求方法(默认:GET,支持:GET,POST,PUT,DELETE,PATCH等)
12
+ - `API_DEBUG_LOGIN_URL` - 设置登录接口 URL(默认:/api/login)
13
+ - `API_DEBUG_LOGIN_METHOD` - 设置登录请求方法(默认:POST)
14
+ - `API_DEBUG_LOGIN_BODY` - 设置登录请求体(默认:{"username":"","password":""})
15
+ - `API_DEBUG_LOGIN_DESCRIPTION` - 设置登录接口说明(默认:将返回的token保存到调试工具中的公共header,字段名Authorization,字段值是Bearer token)
16
+
17
+ #### 🔧 功能优化
18
+ - **登录接口智能识别**:
19
+ - 支持完整 URL 和相对路径匹配
20
+ - 自动识别登录接口并使用环境变量配置
21
+ - 非登录接口严格遵循允许的方法限制
22
+
23
+ - **错误处理优化**:
24
+ - 只有请求相关错误才保存到 api.json
25
+ - 方法验证错误不污染执行记录
26
+ - 更精确的错误分类和处理
27
+
28
+ - **工具描述动态显示**:
29
+ - 根据环境变量配置显示登录认证信息
30
+ - 实时显示允许的请求方法和使用说明
31
+
32
+ #### 🛡️ 安全增强
33
+ - **请求方法限制**:默认只允许 GET 请求,防止误操作
34
+ - **登录接口例外**:登录接口可使用环境变量中配置的方法
35
+ - **灵活配置**:可根据需要开放更多请求方法
36
+
37
+ #### 📚 文档更新
38
+ - 添加了环境变量配置说明
39
+ - 更新了 API 调试工具使用指南
40
+ - 完善了登录认证流程文档
41
+
5
42
  ## 🚀 核心优势
6
43
 
7
44
  ### 🎯 解决多机器开发混乱问题
@@ -73,9 +110,14 @@ npm install
73
110
 
74
111
  ### 环境变量
75
112
 
76
- | 变量名 | 默认值 | 描述 |
77
- |--------|--------|------|
78
- | CONFIG_DIR | ./.setting | 配置文件目录(包含 config.json 和 api.json) |
113
+ | 变量名 | 默认值 | 描述 | 示例 |
114
+ |--------|--------|------|------|
115
+ | CONFIG_DIR | ./.setting | 配置文件目录(包含 config.json 和 api.json) | `export CONFIG_DIR="./config"` |
116
+ | API_DEBUG_ALLOWED_METHODS | GET | 控制允许的请求方法(支持:GET,POST,PUT,DELETE,PATCH等) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
117
+ | API_DEBUG_LOGIN_URL | /api/login | 设置登录接口 URL | `export API_DEBUG_LOGIN_URL="/api/auth/login"` |
118
+ | API_DEBUG_LOGIN_METHOD | POST | 设置登录请求方法 | `export API_DEBUG_LOGIN_METHOD="POST"` |
119
+ | API_DEBUG_LOGIN_BODY | {"username":"","password":""} | 设置登录请求体 | `export API_DEBUG_LOGIN_BODY='{"mobile":"","password":""}'` |
120
+ | API_DEBUG_LOGIN_DESCRIPTION | 将返回的token保存到调试工具中的公共header,字段名Authorization,字段值是Bearer token | 设置登录接口说明 | `export API_DEBUG_LOGIN_DESCRIPTION="用户登录接口"` |
79
121
 
80
122
  ### 配置文件
81
123
 
@@ -166,7 +208,12 @@ npm run dev
166
208
  "command": "npx",
167
209
  "args": ["@liangshanli/mcp-server-project-standards"],
168
210
  "env": {
169
- "CONFIG_DIR": "./.setting"
211
+ "CONFIG_DIR": "./.setting",
212
+ "API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
213
+ "API_DEBUG_LOGIN_URL": "/api/login",
214
+ "API_DEBUG_LOGIN_METHOD": "POST",
215
+ "API_DEBUG_LOGIN_BODY": "{\"username\":\"\",\"password\":\"\"}",
216
+ "API_DEBUG_LOGIN_DESCRIPTION": "将返回的token保存到调试工具中的公共header,字段名Authorization,字段值是Bearer token"
170
217
  }
171
218
  }
172
219
  }
@@ -185,7 +232,12 @@ npm run dev
185
232
  "command": "npx",
186
233
  "args": ["@liangshanli/mcp-server-project-standards"],
187
234
  "env": {
188
- "CONFIG_DIR": "./.setting"
235
+ "CONFIG_DIR": "./.setting",
236
+ "API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
237
+ "API_DEBUG_LOGIN_URL": "/api/login",
238
+ "API_DEBUG_LOGIN_METHOD": "POST",
239
+ "API_DEBUG_LOGIN_BODY": "{\"username\":\"\",\"password\":\"\"}",
240
+ "API_DEBUG_LOGIN_DESCRIPTION": "将返回的token保存到调试工具中的公共header,字段名Authorization,字段值是Bearer token"
189
241
  }
190
242
  }
191
243
  }
@@ -348,6 +400,10 @@ npm run dev
348
400
  - **执行记录**:无论成功失败都记录执行历史
349
401
  - **搜索功能**:支持按 URL 或描述搜索 API
350
402
  - **参数管理**:支持查询参数、请求体、自定义请求头等
403
+ - **环境变量控制**:通过环境变量控制允许的请求方法和登录接口配置
404
+ - **请求方法限制**:默认只允许 GET 请求,防止误操作
405
+ - **登录接口智能识别**:自动识别登录接口并使用环境变量配置
406
+ - **动态工具描述**:根据环境变量配置实时显示工具说明
351
407
 
352
408
  **🔐 特别说明 - 登录认证流程:**
353
409
 
package/bin/cli.js CHANGED
@@ -28,9 +28,20 @@ function startServer() {
28
28
  const env = {
29
29
  ...process.env,
30
30
  // Set CONFIG_DIR if specified, otherwise use default
31
- CONFIG_DIR: process.env.CONFIG_DIR || './.setting'
31
+ CONFIG_DIR: process.env.CONFIG_DIR || './.setting',
32
+ // API Debug environment variables
33
+ API_DEBUG_ALLOWED_METHODS: process.env.API_DEBUG_ALLOWED_METHODS || 'GET',
34
+ API_DEBUG_LOGIN_URL: process.env.API_DEBUG_LOGIN_URL || '/api/login',
35
+ API_DEBUG_LOGIN_METHOD: process.env.API_DEBUG_LOGIN_METHOD || 'POST',
36
+ API_DEBUG_LOGIN_BODY: process.env.API_DEBUG_LOGIN_BODY || '{"username":"","password":""}',
37
+ API_DEBUG_LOGIN_DESCRIPTION: process.env.API_DEBUG_LOGIN_DESCRIPTION || 'Save returned token to common headers in debug tool, field name Authorization, field value Bearer token'
32
38
  };
33
39
 
40
+ // Convert allowed methods to uppercase if specified
41
+ if (env.API_DEBUG_ALLOWED_METHODS) {
42
+ env.API_DEBUG_ALLOWED_METHODS = env.API_DEBUG_ALLOWED_METHODS.toUpperCase();
43
+ }
44
+
34
45
  writeLog('INFO', 'Starting MCP Project Standards server');
35
46
 
36
47
  server = spawn('node', [serverPath], {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liangshanli/mcp-server-project-standards",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "MCP Project Standards server with project info, structure, API standards, development standards and custom tools",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {
@@ -498,9 +498,40 @@ class ProjectStandardsMCPServer {
498
498
  }
499
499
  );
500
500
 
501
+ // 构建 API 调试工具描述
502
+ let apiDebugDescription = 'API debugging tool for testing and executing API requests';
503
+
504
+ // 检查是否设置了登录接口环境变量
505
+ const loginUrl = process.env.API_DEBUG_LOGIN_URL;
506
+ const loginMethod = process.env.API_DEBUG_LOGIN_METHOD;
507
+ const loginDescription = process.env.API_DEBUG_LOGIN_DESCRIPTION;
508
+ const allowedMethods = process.env.API_DEBUG_ALLOWED_METHODS;
509
+
510
+ if (loginUrl || loginMethod || allowedMethods) {
511
+ apiDebugDescription += '\n\n🔐 Login Authentication Configuration:';
512
+
513
+ if (loginUrl) {
514
+ apiDebugDescription += `\n- Login URL: ${loginUrl}`;
515
+ }
516
+ if (loginMethod) {
517
+ apiDebugDescription += `\n- Login Method: ${loginMethod}`;
518
+ }
519
+ if (loginDescription) {
520
+ apiDebugDescription += `\n- Login Description: ${loginDescription}`;
521
+ }
522
+ if (allowedMethods) {
523
+ apiDebugDescription += `\n- Allowed Methods: ${allowedMethods}`;
524
+ }
525
+
526
+ apiDebugDescription += '\n\n💡 Usage Instructions:';
527
+ apiDebugDescription += '\n- Login API automatically uses environment variable configuration';
528
+ apiDebugDescription += '\n- Non-login APIs must use allowed methods only';
529
+ apiDebugDescription += '\n- Common request headers are automatically updated after successful login';
530
+ }
531
+
501
532
  tools.push({
502
533
  name: 'api_debug',
503
- description: 'API debugging tool for testing and executing API requests',
534
+ description: apiDebugDescription,
504
535
  inputSchema: {
505
536
  type: 'object',
506
537
  properties: {
@@ -1,6 +1,32 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
 
4
+ // Get allowed methods from environment variable
5
+ const getAllowedMethods = () => {
6
+ const allowedMethods = process.env.API_DEBUG_ALLOWED_METHODS || 'GET';
7
+ return allowedMethods.split(',').map(method => method.trim().toUpperCase());
8
+ };
9
+
10
+ // Get login URL from environment variable
11
+ const getLoginUrl = () => {
12
+ return process.env.API_DEBUG_LOGIN_URL || '/api/login';
13
+ };
14
+
15
+ // Get login method from environment variable
16
+ const getLoginMethod = () => {
17
+ return (process.env.API_DEBUG_LOGIN_METHOD || 'POST').toUpperCase();
18
+ };
19
+
20
+ // Get login body from environment variable
21
+ const getLoginBody = () => {
22
+ return process.env.API_DEBUG_LOGIN_BODY || '{"username":"","password":""}';
23
+ };
24
+
25
+ // Get login description from environment variable
26
+ const getLoginDescription = () => {
27
+ return process.env.API_DEBUG_LOGIN_DESCRIPTION || 'Save returned token to common headers in debug tool, field name Authorization, field value Bearer token';
28
+ };
29
+
4
30
  // Get API debug config file path
5
31
  const getApiConfigPath = () => {
6
32
  const configDir = process.env.CONFIG_DIR || './.setting';
@@ -228,6 +254,43 @@ async function api_debug(params, config, saveConfig) {
228
254
  const baseUrl = apiDebugConfig.baseUrl || '';
229
255
  const commonHeaders = apiDebugConfig.headers || {};
230
256
 
257
+ // 验证请求方法是否被允许
258
+ const allowedMethods = getAllowedMethods();
259
+ const requestMethod = (apiItem.method || 'GET').toUpperCase();
260
+ const loginUrl = getLoginUrl();
261
+
262
+ // 判断是否为登录接口 - 支持完整 URL 和相对路径匹配
263
+ const isLoginRequest = (() => {
264
+ const apiUrl = apiItem.url;
265
+ const loginUrlPattern = loginUrl;
266
+
267
+ // 如果登录 URL 是完整 URL,提取路径部分进行匹配
268
+ if (loginUrlPattern.startsWith('http://') || loginUrlPattern.startsWith('https://')) {
269
+ try {
270
+ const url = new URL(loginUrlPattern);
271
+ const loginPath = url.pathname;
272
+ // 匹配完整路径或去掉前导斜杠的路径
273
+ return apiUrl === loginPath || apiUrl === loginPath.replace(/^\//, '') || apiUrl === loginUrlPattern;
274
+ } catch (e) {
275
+ // 如果 URL 解析失败,回退到字符串匹配
276
+ return apiUrl === loginUrlPattern;
277
+ }
278
+ } else {
279
+ // 相对路径匹配
280
+ return apiUrl === loginUrlPattern ||
281
+ apiUrl === loginUrlPattern.replace(/^\//, '') ||
282
+ apiUrl.endsWith(loginUrlPattern) ||
283
+ apiUrl.endsWith(loginUrlPattern.replace(/^\//, ''));
284
+ }
285
+ })();
286
+
287
+ if (!allowedMethods.includes(requestMethod)) {
288
+ // 如果是登录接口,继续执行;否则返回错误
289
+ if (!isLoginRequest) {
290
+ throw new Error(`Method ${requestMethod} is not allowed. Allowed methods: ${allowedMethods.join(', ')}`);
291
+ }
292
+ }
293
+
231
294
  // 构建完整 URL
232
295
  const fullUrl = baseUrl + apiItem.url;
233
296
 
@@ -291,64 +354,113 @@ async function api_debug(params, config, saveConfig) {
291
354
 
292
355
  const finalUrl = queryString ? `${fullUrl}?${queryString}` : fullUrl;
293
356
 
357
+ let success = true;
294
358
  let response;
295
359
  let responseData;
296
360
  let error = null;
297
- let success = true;
298
361
 
362
+ // 请求处理部分 - 只有这部分出错才会保存到 api.json
299
363
  try {
300
- // 执行请求
301
- response = await fetch(finalUrl, {
302
- method: apiItem.method || 'GET',
303
- headers: headers,
304
- body: body
305
- });
306
364
 
307
- // 获取响应数据
308
- const contentType = response.headers.get('content-type');
365
+ // 如果是登录接口且方法不被允许,使用环境变量中的登录配置
366
+ if (isLoginRequest && !allowedMethods.includes(requestMethod)) {
367
+ const loginMethod = getLoginMethod();
368
+ const loginBody = getLoginBody();
369
+
370
+ // 更新请求方法和请求体
371
+ apiItem.method = loginMethod;
372
+ if (loginBody) {
373
+ apiItem.body = loginBody;
374
+ }
375
+
376
+ // 更新最终 URL 和方法
377
+ const updatedFinalUrl = queryString ? `${fullUrl}?${queryString}` : fullUrl;
378
+
379
+ try {
380
+ response = await fetch(updatedFinalUrl, {
381
+ method: loginMethod,
382
+ headers: headers,
383
+ body: loginBody
384
+ });
385
+ } catch (fetchError) {
386
+ error = fetchError.message;
387
+ success = false;
388
+ response = null;
389
+ }
390
+ } else {
391
+ try {
392
+ // 执行请求
393
+ response = await fetch(finalUrl, {
394
+ method: apiItem.method || 'GET',
395
+ headers: headers,
396
+ body: body
397
+ });
398
+ } catch (fetchError) {
399
+ error = fetchError.message;
400
+ success = false;
401
+ response = null;
402
+ }
403
+ }
309
404
 
310
- if (contentType && contentType.includes('application/json')) {
311
- responseData = await response.json();
405
+ if (response) {
406
+ // 获取响应数据
407
+ const contentType = response.headers.get('content-type');
408
+
409
+ if (contentType && contentType.includes('application/json')) {
410
+ responseData = await response.json();
411
+ } else {
412
+ responseData = await response.text();
413
+ }
414
+
415
+ // 判断请求是否成功(HTTP 状态码 200-299 为成功)
416
+ const isHttpSuccess = response.status >= 200 && response.status < 300;
417
+ success = isHttpSuccess;
418
+
419
+ // 记录响应信息
420
+ apiDebugConfig.list[index].data = responseData;
421
+ apiDebugConfig.list[index].status = response.status;
422
+ apiDebugConfig.list[index].statusText = response.statusText;
423
+ apiDebugConfig.list[index].responseHeaders = Object.fromEntries(response.headers.entries());
424
+ apiDebugConfig.list[index].lastExecuted = new Date().toISOString();
425
+ apiDebugConfig.list[index].success = isHttpSuccess;
426
+ apiDebugConfig.list[index].error = isHttpSuccess ? null : `HTTP ${response.status}: ${response.statusText}`;
312
427
  } else {
313
- responseData = await response.text();
428
+ // 记录失败信息
429
+ success = false;
430
+ apiDebugConfig.list[index].data = null;
431
+ apiDebugConfig.list[index].status = null;
432
+ apiDebugConfig.list[index].statusText = null;
433
+ apiDebugConfig.list[index].responseHeaders = null;
434
+ apiDebugConfig.list[index].lastExecuted = new Date().toISOString();
435
+ apiDebugConfig.list[index].success = false;
436
+ apiDebugConfig.list[index].error = error;
314
437
  }
315
438
 
316
- // 记录成功信息
317
- apiDebugConfig.list[index].data = responseData;
318
- apiDebugConfig.list[index].status = response.status;
319
- apiDebugConfig.list[index].statusText = response.statusText;
320
- apiDebugConfig.list[index].responseHeaders = Object.fromEntries(response.headers.entries());
321
- apiDebugConfig.list[index].lastExecuted = new Date().toISOString();
322
- apiDebugConfig.list[index].success = true;
323
- apiDebugConfig.list[index].error = null;
439
+ // 去重处理:相同的 URL 只保留一份(保留最新的执行结果)
440
+ const urlMap = new Map();
441
+ apiDebugConfig.list.forEach(item => {
442
+ if (item.url) {
443
+ urlMap.set(item.url, item);
444
+ }
445
+ });
446
+ apiDebugConfig.list = Array.from(urlMap.values());
324
447
 
325
- } catch (fetchError) {
326
- // 记录失败信息
327
- error = fetchError.message;
328
- success = false;
448
+ // 无论成功还是失败,都保存配置
449
+ saveApiConfig(apiDebugConfig);
329
450
 
330
- apiDebugConfig.list[index].data = null;
331
- apiDebugConfig.list[index].status = null;
332
- apiDebugConfig.list[index].statusText = null;
333
- apiDebugConfig.list[index].responseHeaders = null;
334
- apiDebugConfig.list[index].lastExecuted = new Date().toISOString();
335
- apiDebugConfig.list[index].success = false;
336
- apiDebugConfig.list[index].error = error;
337
- }
338
-
339
- // 去重处理:相同的 URL 只保留一份(保留最新的执行结果)
340
- const urlMap = new Map();
341
- apiDebugConfig.list.forEach(item => {
342
- if (item.url) {
343
- urlMap.set(item.url, item);
451
+ } catch (requestError) {
452
+ // 只有请求相关的错误才保存到 api.json
453
+ try {
454
+ apiDebugConfig.list[index].lastExecuted = new Date().toISOString();
455
+ apiDebugConfig.list[index].success = false;
456
+ apiDebugConfig.list[index].error = requestError.message;
457
+ saveApiConfig(apiDebugConfig);
458
+ } catch (saveErr) {
459
+ console.error('Failed to save request error information:', saveErr.message);
344
460
  }
345
- });
346
- apiDebugConfig.list = Array.from(urlMap.values());
347
-
348
- // 无论成功还是失败,都保存配置
349
- saveApiConfig(apiDebugConfig);
461
+ }
350
462
 
351
- if (success) {
463
+ if (success && response) {
352
464
  return {
353
465
  success: true,
354
466
  message: `Successfully executed API: ${apiItem.description || apiItem.url}`,
@@ -376,7 +488,7 @@ async function api_debug(params, config, saveConfig) {
376
488
  headers: headers,
377
489
  body: body
378
490
  },
379
- error: error,
491
+ error: error || (response ? `HTTP ${response.status}: ${response.statusText}` : 'Request failed'),
380
492
  timestamp: new Date().toISOString()
381
493
  };
382
494
  }