@liangshanli/mcp-server-project-standards 2.1.8 → 3.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 +31 -3
- package/README.zh-CN.md +28 -1
- package/bin/cli.js +18 -3
- package/package.json +2 -2
- package/src/server-final.js +42 -18
- package/src/utils/api_common.js +17 -2
- package/src/utils/api_debug.js +132 -60
- package/src/utils/api_execute.js +6 -0
- package/src/utils/api_login.js +15 -2
package/README.md
CHANGED
|
@@ -4,6 +4,28 @@ A MCP (Model Context Protocol) server for project standards management, designed
|
|
|
4
4
|
|
|
5
5
|
## 📋 Version Updates
|
|
6
6
|
|
|
7
|
+
### v3.0.0 (2025-10-31) - Major Release
|
|
8
|
+
|
|
9
|
+
#### 🚀 Breaking Changes
|
|
10
|
+
- Config directory resolution now depends on both `CONFIG_DIR` and `TOOL_PREFIX`:
|
|
11
|
+
- If `CONFIG_DIR` is set, it is used as-is
|
|
12
|
+
- If `CONFIG_DIR` is not set and `TOOL_PREFIX` is set, use `./.setting.<TOOL_PREFIX>`
|
|
13
|
+
- Otherwise default to `./.setting`
|
|
14
|
+
- `tools/call` now strips the `TOOL_PREFIX` from tool names before method dispatch. If you call `xxx_api_debug` (with `TOOL_PREFIX=xxx`), the server routes the call to `api_debug` internally.
|
|
15
|
+
|
|
16
|
+
#### ✨ New/Improved
|
|
17
|
+
- Unified `getConfigDir()` used by both `server-final.js` and `api_common.js`
|
|
18
|
+
- `tools/list` shows environment with resolved `CONFIG_DIR`
|
|
19
|
+
- Prefixed tool names and project-branded descriptions when both `TOOL_PREFIX` and `PROJECT_NAME` are provided
|
|
20
|
+
|
|
21
|
+
#### 🧹 Cleanup
|
|
22
|
+
- Removed duplicate legacy `api_debug` method definition
|
|
23
|
+
|
|
24
|
+
#### 💡 Benefits
|
|
25
|
+
- Multi-project isolation: simple per-project segregation via `TOOL_PREFIX` without code changes
|
|
26
|
+
- Zero-friction switching: swap project context by environment only
|
|
27
|
+
- Smoother tool calling: clients can call prefixed names, server auto-routes
|
|
28
|
+
|
|
7
29
|
### v2.0.0 (2024-12-19) - Major Release
|
|
8
30
|
|
|
9
31
|
#### 🚀 New Tools & Features
|
|
@@ -127,7 +149,9 @@ The server uses the `./.setting/` directory to store configuration files by defa
|
|
|
127
149
|
|
|
128
150
|
| Variable | Default | Description | Example |
|
|
129
151
|
|----------|---------|-------------|---------|
|
|
130
|
-
| CONFIG_DIR | ./.setting | Configuration
|
|
152
|
+
| CONFIG_DIR | ./.setting or ./.setting.<TOOL_PREFIX> | Configuration directory. If set, used as-is; else if TOOL_PREFIX set, uses ./.setting.<TOOL_PREFIX>; else ./.setting | `export CONFIG_DIR="./config"` |
|
|
153
|
+
| TOOL_PREFIX | | Optional tool prefix for tool names and config isolation | `export TOOL_PREFIX="projA"` |
|
|
154
|
+
| PROJECT_NAME | | Optional project branding for tool descriptions | `export PROJECT_NAME="MyProject"` |
|
|
131
155
|
| API_DEBUG_ALLOWED_METHODS | GET | Control allowed request methods (supports: GET,POST,PUT,DELETE,PATCH, etc.) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
|
|
132
156
|
| API_DEBUG_LOGIN_URL | /api/login | Set login API URL | `export API_DEBUG_LOGIN_URL="/api/auth/login"` |
|
|
133
157
|
| API_DEBUG_LOGIN_METHOD | POST | Set login request method | `export API_DEBUG_LOGIN_METHOD="POST"` |
|
|
@@ -223,7 +247,9 @@ npm run dev
|
|
|
223
247
|
"command": "npx",
|
|
224
248
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
225
249
|
"env": {
|
|
226
|
-
"
|
|
250
|
+
"TOOL_PREFIX": "projA",
|
|
251
|
+
"PROJECT_NAME": "MyProject",
|
|
252
|
+
"CONFIG_DIR": "./.setting",
|
|
227
253
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
228
254
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
229
255
|
"API_DEBUG_LOGIN_METHOD": "POST",
|
|
@@ -247,7 +273,9 @@ npm run dev
|
|
|
247
273
|
"command": "npx",
|
|
248
274
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
249
275
|
"env": {
|
|
250
|
-
"
|
|
276
|
+
"TOOL_PREFIX": "projA",
|
|
277
|
+
"PROJECT_NAME": "MyProject",
|
|
278
|
+
"CONFIG_DIR": "./.setting",
|
|
251
279
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
252
280
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
253
281
|
"API_DEBUG_LOGIN_METHOD": "POST",
|
package/README.zh-CN.md
CHANGED
|
@@ -4,6 +4,27 @@
|
|
|
4
4
|
|
|
5
5
|
## 📋 版本更新说明
|
|
6
6
|
|
|
7
|
+
### v3.0.0 (2025-10-31) - 重大更新
|
|
8
|
+
|
|
9
|
+
#### 🚀 破坏性变更
|
|
10
|
+
- 配置目录解析新增 `TOOL_PREFIX` 参与:
|
|
11
|
+
- 若设置了 `CONFIG_DIR`,优先使用该值
|
|
12
|
+
- 若未设置 `CONFIG_DIR` 且设置了 `TOOL_PREFIX`,使用 `./.setting.<TOOL_PREFIX>`
|
|
13
|
+
- 否则默认 `./.setting`
|
|
14
|
+
- 在 `tools/call` 中,若工具名带有前缀(如 `xxx_api_debug` 且 `TOOL_PREFIX=xxx`),调用时会自动去除前缀,路由到真实方法(`api_debug`)。
|
|
15
|
+
|
|
16
|
+
#### ✨ 新增 / 改进
|
|
17
|
+
- 在 `server-final.js` 与 `api_common.js` 中统一使用 `getConfigDir()`
|
|
18
|
+
- `tools/list` 环境信息展示最终生效的 `CONFIG_DIR`
|
|
19
|
+
- 同时存在 `TOOL_PREFIX` 和 `PROJECT_NAME` 时,工具名自动加前缀、描述自动加项目名
|
|
20
|
+
|
|
21
|
+
#### 🧹 清理
|
|
22
|
+
- 移除了重复的旧版 `api_debug` 方法定义
|
|
23
|
+
|
|
24
|
+
#### 💡 优势
|
|
25
|
+
- 多项目隔离更简单:通过 `TOOL_PREFIX` 即可实现每项目独立配置,无需改代码
|
|
26
|
+
- 切换零侵入:仅改环境变量即可切换项目上下文
|
|
27
|
+
- 调用更顺滑:客户端可使用带前缀名,服务端自动剥前缀并精准路由
|
|
7
28
|
### v1.1.0 (2024-12-19)
|
|
8
29
|
|
|
9
30
|
#### 🆕 新增功能
|
|
@@ -112,7 +133,9 @@ npm install
|
|
|
112
133
|
|
|
113
134
|
| 变量名 | 默认值 | 描述 | 示例 |
|
|
114
135
|
|--------|--------|------|------|
|
|
115
|
-
| CONFIG_DIR | ./.setting |
|
|
136
|
+
| CONFIG_DIR | ./.setting 或 ./.setting.<TOOL_PREFIX> | 配置目录。若设置则直接使用;否则若设置了 TOOL_PREFIX 则使用 ./.setting.<TOOL_PREFIX>;否则 ./.setting | `export CONFIG_DIR="./config"` |
|
|
137
|
+
| TOOL_PREFIX | | 工具名前缀,同时用于多项目配置隔离 | `export TOOL_PREFIX="projA"` |
|
|
138
|
+
| PROJECT_NAME | | 工具描述前添加项目名称用于标识 | `export PROJECT_NAME="MyProject"` |
|
|
116
139
|
| API_DEBUG_ALLOWED_METHODS | GET | 控制允许的请求方法(支持:GET,POST,PUT,DELETE,PATCH等) | `export API_DEBUG_ALLOWED_METHODS="GET,POST"` |
|
|
117
140
|
| API_DEBUG_LOGIN_URL | /api/login | 设置登录接口 URL | `export API_DEBUG_LOGIN_URL="/api/auth/login"` |
|
|
118
141
|
| API_DEBUG_LOGIN_METHOD | POST | 设置登录请求方法 | `export API_DEBUG_LOGIN_METHOD="POST"` |
|
|
@@ -208,6 +231,8 @@ npm run dev
|
|
|
208
231
|
"command": "npx",
|
|
209
232
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
210
233
|
"env": {
|
|
234
|
+
"TOOL_PREFIX": "projA",
|
|
235
|
+
"PROJECT_NAME": "MyProject",
|
|
211
236
|
"CONFIG_DIR": "./.setting",
|
|
212
237
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
213
238
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
|
@@ -232,6 +257,8 @@ npm run dev
|
|
|
232
257
|
"command": "npx",
|
|
233
258
|
"args": ["@liangshanli/mcp-server-project-standards"],
|
|
234
259
|
"env": {
|
|
260
|
+
"TOOL_PREFIX": "projA",
|
|
261
|
+
"PROJECT_NAME": "MyProject",
|
|
235
262
|
"CONFIG_DIR": "./.setting",
|
|
236
263
|
"API_DEBUG_ALLOWED_METHODS": "GET,POST,PUT,DELETE",
|
|
237
264
|
"API_DEBUG_LOGIN_URL": "/api/login",
|
package/bin/cli.js
CHANGED
|
@@ -27,16 +27,31 @@ let server = null;
|
|
|
27
27
|
// Function to start server
|
|
28
28
|
function startServer() {
|
|
29
29
|
// Create environment object
|
|
30
|
+
// Determine CONFIG_DIR: use env var if set, otherwise use .setting with TOOL_PREFIX if available
|
|
31
|
+
let configDir = process.env.CONFIG_DIR;
|
|
32
|
+
if (!configDir) {
|
|
33
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
34
|
+
if (toolPrefix) {
|
|
35
|
+
configDir = `./.setting.${toolPrefix}`;
|
|
36
|
+
} else {
|
|
37
|
+
configDir = './.setting';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
const env = {
|
|
31
42
|
...process.env,
|
|
32
|
-
// Set CONFIG_DIR
|
|
33
|
-
CONFIG_DIR:
|
|
43
|
+
// Set CONFIG_DIR based on logic above
|
|
44
|
+
CONFIG_DIR: configDir,
|
|
34
45
|
// API Debug environment variables
|
|
35
46
|
API_DEBUG_ALLOWED_METHODS: process.env.API_DEBUG_ALLOWED_METHODS || 'GET',
|
|
36
47
|
API_DEBUG_LOGIN_URL: process.env.API_DEBUG_LOGIN_URL || '/api/login',
|
|
37
48
|
API_DEBUG_LOGIN_METHOD: process.env.API_DEBUG_LOGIN_METHOD || 'POST',
|
|
38
49
|
API_DEBUG_LOGIN_BODY: process.env.API_DEBUG_LOGIN_BODY || '{"username":"","password":""}',
|
|
39
|
-
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'
|
|
50
|
+
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',
|
|
51
|
+
// Tool prefix for naming/identification
|
|
52
|
+
TOOL_PREFIX: process.env.TOOL_PREFIX || '',
|
|
53
|
+
// Project name for display/metadata
|
|
54
|
+
PROJECT_NAME: process.env.PROJECT_NAME || ''
|
|
40
55
|
};
|
|
41
56
|
|
|
42
57
|
// Convert allowed methods to uppercase if specified
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liangshanli/mcp-server-project-standards",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.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": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"repository": {
|
|
32
32
|
"type": "git",
|
|
33
|
-
"url": "https://github.com/liliangshan/mcp-server-project-standards"
|
|
33
|
+
"url": "git+https://github.com/liliangshan/mcp-server-project-standards.git"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"fs-extra": "^11.2.0",
|
package/src/server-final.js
CHANGED
|
@@ -13,9 +13,23 @@ 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
15
|
|
|
16
|
+
// Get config directory based on CONFIG_DIR and TOOL_PREFIX
|
|
17
|
+
const getConfigDir = () => {
|
|
18
|
+
let configDir = process.env.CONFIG_DIR;
|
|
19
|
+
if (!configDir) {
|
|
20
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
21
|
+
if (toolPrefix) {
|
|
22
|
+
configDir = `./.setting.${toolPrefix}`;
|
|
23
|
+
} else {
|
|
24
|
+
configDir = './.setting';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return configDir;
|
|
28
|
+
};
|
|
29
|
+
|
|
16
30
|
// Get configuration from file or environment
|
|
17
31
|
const getConfig = () => {
|
|
18
|
-
const configDir =
|
|
32
|
+
const configDir = getConfigDir();
|
|
19
33
|
const configPath = path.join(configDir, 'config.json');
|
|
20
34
|
|
|
21
35
|
try {
|
|
@@ -33,7 +47,7 @@ const getConfig = () => {
|
|
|
33
47
|
|
|
34
48
|
// Save configuration to file
|
|
35
49
|
const saveConfig = (config) => {
|
|
36
|
-
const configDir =
|
|
50
|
+
const configDir = getConfigDir();
|
|
37
51
|
const configPath = path.join(configDir, 'config.json');
|
|
38
52
|
|
|
39
53
|
try {
|
|
@@ -51,7 +65,7 @@ const saveConfig = (config) => {
|
|
|
51
65
|
// 启动日志
|
|
52
66
|
console.error('=== MCP Project Standards Server Starting ===');
|
|
53
67
|
console.error(`Time: ${new Date().toISOString()}`);
|
|
54
|
-
console.error(`Config Dir: ${
|
|
68
|
+
console.error(`Config Dir: ${getConfigDir()}`);
|
|
55
69
|
console.error('==============================================');
|
|
56
70
|
|
|
57
71
|
// Final MCP Server
|
|
@@ -71,7 +85,7 @@ class ProjectStandardsMCPServer {
|
|
|
71
85
|
|
|
72
86
|
// 创建默认配置文件
|
|
73
87
|
createDefaultConfig() {
|
|
74
|
-
const configDir =
|
|
88
|
+
const configDir = getConfigDir();
|
|
75
89
|
const configPath = path.join(configDir, 'config.json');
|
|
76
90
|
|
|
77
91
|
try {
|
|
@@ -153,16 +167,6 @@ class ProjectStandardsMCPServer {
|
|
|
153
167
|
return result;
|
|
154
168
|
}
|
|
155
169
|
|
|
156
|
-
// API debug tool (legacy)
|
|
157
|
-
async api_debug(params) {
|
|
158
|
-
const result = await api_debug(params, this.config, saveConfig);
|
|
159
|
-
// Update local config if action was 'set'
|
|
160
|
-
if (params?.action === 'set') {
|
|
161
|
-
this.config = getConfig();
|
|
162
|
-
}
|
|
163
|
-
return result;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
170
|
// API login tool
|
|
167
171
|
async api_login(params) {
|
|
168
172
|
const result = await api_login(params, this.config, saveConfig);
|
|
@@ -874,11 +878,24 @@ class ProjectStandardsMCPServer {
|
|
|
874
878
|
}
|
|
875
879
|
});
|
|
876
880
|
|
|
881
|
+
// Apply tool prefix and project name if both provided
|
|
882
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
883
|
+
const projectName = process.env.PROJECT_NAME || '';
|
|
884
|
+
let finalTools = tools;
|
|
885
|
+
if (toolPrefix && projectName) {
|
|
886
|
+
finalTools = tools.map(t => ({
|
|
887
|
+
...t,
|
|
888
|
+
name: `${toolPrefix}_${t.name}`,
|
|
889
|
+
description: `${projectName} - ${t.description}`
|
|
890
|
+
}));
|
|
891
|
+
}
|
|
877
892
|
|
|
878
893
|
result = {
|
|
879
|
-
tools:
|
|
894
|
+
tools: finalTools,
|
|
880
895
|
environment: {
|
|
881
|
-
CONFIG_DIR:
|
|
896
|
+
CONFIG_DIR: getConfigDir(),
|
|
897
|
+
PROJECT_NAME: process.env.PROJECT_NAME || '',
|
|
898
|
+
TOOL_PREFIX: process.env.TOOL_PREFIX || '',
|
|
882
899
|
serverInfo: {
|
|
883
900
|
name: this.name,
|
|
884
901
|
version: this.version
|
|
@@ -949,12 +966,19 @@ class ProjectStandardsMCPServer {
|
|
|
949
966
|
throw new Error('Missing tool name');
|
|
950
967
|
}
|
|
951
968
|
|
|
969
|
+
// Remove tool prefix if present
|
|
970
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
971
|
+
let actualToolName = name;
|
|
972
|
+
if (toolPrefix && name.startsWith(`${toolPrefix}_`)) {
|
|
973
|
+
actualToolName = name.substring(toolPrefix.length + 1);
|
|
974
|
+
}
|
|
975
|
+
|
|
952
976
|
// Check if method exists
|
|
953
|
-
if (!this[
|
|
977
|
+
if (!this[actualToolName]) {
|
|
954
978
|
throw new Error(`Unknown tool: ${name}`);
|
|
955
979
|
}
|
|
956
980
|
|
|
957
|
-
result = await this[
|
|
981
|
+
result = await this[actualToolName](args || {});
|
|
958
982
|
|
|
959
983
|
// Check if result has contentType (special format)
|
|
960
984
|
if (result && result.contentType === "text") {
|
package/src/utils/api_common.js
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
+
// Get config directory based on CONFIG_DIR and TOOL_PREFIX
|
|
5
|
+
const getConfigDir = () => {
|
|
6
|
+
let configDir = process.env.CONFIG_DIR;
|
|
7
|
+
if (!configDir) {
|
|
8
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
9
|
+
if (toolPrefix) {
|
|
10
|
+
configDir = `./.setting.${toolPrefix}`;
|
|
11
|
+
} else {
|
|
12
|
+
configDir = './.setting';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return configDir;
|
|
16
|
+
};
|
|
17
|
+
|
|
4
18
|
// Get API debug config file path
|
|
5
19
|
const getApiConfigPath = () => {
|
|
6
|
-
const configDir =
|
|
20
|
+
const configDir = getConfigDir();
|
|
7
21
|
return path.join(configDir, 'api.json');
|
|
8
22
|
};
|
|
9
23
|
|
|
@@ -30,7 +44,7 @@ const loadApiConfig = () => {
|
|
|
30
44
|
|
|
31
45
|
// Save API debug config
|
|
32
46
|
const saveApiConfig = (apiConfig) => {
|
|
33
|
-
const configDir =
|
|
47
|
+
const configDir = getConfigDir();
|
|
34
48
|
const apiConfigPath = path.join(configDir, 'api.json');
|
|
35
49
|
|
|
36
50
|
try {
|
|
@@ -125,6 +139,7 @@ const detectContentType = (body) => {
|
|
|
125
139
|
};
|
|
126
140
|
|
|
127
141
|
module.exports = {
|
|
142
|
+
getConfigDir,
|
|
128
143
|
getApiConfigPath,
|
|
129
144
|
loadApiConfig,
|
|
130
145
|
saveApiConfig,
|
package/src/utils/api_debug.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
const { getAllowedMethods, loadApiConfig, saveApiConfig, detectContentType } = require('./api_common');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
|
|
4
|
+
// 为 HTTPS 请求创建跳过证书验证的 agent
|
|
5
|
+
const httpsAgent = new https.Agent({
|
|
6
|
+
rejectUnauthorized: false
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* API 调试工具 - 直接执行API请求
|
|
@@ -31,65 +37,43 @@ const { getAllowedMethods, loadApiConfig, saveApiConfig, detectContentType } = r
|
|
|
31
37
|
async function api_debug(params, config, saveConfig) {
|
|
32
38
|
const { url, method = 'GET', headers = {}, query, body, contentType } = params || {};
|
|
33
39
|
|
|
40
|
+
// Resolve dynamic tool names based on prefix and project name
|
|
41
|
+
const toolPrefix = process.env.TOOL_PREFIX || '';
|
|
42
|
+
const projectName = process.env.PROJECT_NAME || '';
|
|
43
|
+
const hasCustomTools = !!(toolPrefix && projectName);
|
|
44
|
+
const configToolName = hasCustomTools ? `${toolPrefix}_api_config` : 'api_config';
|
|
45
|
+
const executeToolName = hasCustomTools ? `${toolPrefix}_api_execute` : 'api_execute';
|
|
46
|
+
|
|
34
47
|
if (!url) {
|
|
35
48
|
return {
|
|
36
49
|
contentType: "text",
|
|
37
50
|
content: [
|
|
38
51
|
{
|
|
39
52
|
type: "text",
|
|
40
|
-
text:
|
|
53
|
+
text: `⚠️ IMPORTANT: You MUST use addApi to add the API to the list first! Use ${configToolName} tool.\n\n🔧 Step 1: Add API to Configuration (REQUIRED)\n\nCall: ${configToolName} with action="addApi" and api={"url":"<your url>","method":"<METHOD>","body":"your corrected JSON here"}\n\n⚠️ REMINDER: You MUST use ${configToolName} with addApi to add the API to the list!`
|
|
41
54
|
},
|
|
42
55
|
{
|
|
43
56
|
type: "text",
|
|
44
|
-
text:
|
|
57
|
+
text: `🔧 Step 2: Execute API by Index\n\nAfter adding the API, call: ${executeToolName} with index=<returned index>\n\nThis will execute the pre-configured API with the correct format.`
|
|
45
58
|
},
|
|
46
59
|
{
|
|
47
60
|
type: "text",
|
|
48
|
-
text:
|
|
61
|
+
text: `🚨 REMINDER: You MUST use addApi first!\n\n- Use ${configToolName} with action="addApi" to add the API to the list\n- Then use ${executeToolName} with the returned index to execute`
|
|
49
62
|
},
|
|
50
63
|
{
|
|
51
64
|
type: "text",
|
|
52
|
-
text:
|
|
65
|
+
text: `💡 IMPORTANT: Remember to use addApi!\n\n- First: ${configToolName} with action="addApi" to add the API\n- Second: ${executeToolName} with index to run the API`
|
|
53
66
|
},
|
|
54
67
|
{
|
|
55
68
|
type: "text",
|
|
56
|
-
text:
|
|
69
|
+
text: `📋 Final Reminder: Use addApi → Then ${executeToolName}\n\n1. First: ${configToolName} with action="addApi"\n2. Then: ${executeToolName} with index=<number>\n\nThis is the ONLY way to handle invalid JSON requests.`
|
|
57
70
|
},
|
|
58
71
|
{
|
|
59
72
|
type: "text",
|
|
60
|
-
text:
|
|
73
|
+
text: `⚠️ ESSENTIAL: You MUST use addApi!\n\n- First: ${configToolName} with action="addApi" to add the API\n- Second: ${executeToolName} with index to run the API`
|
|
61
74
|
}
|
|
62
75
|
]
|
|
63
76
|
};
|
|
64
|
-
/* return {
|
|
65
|
-
contentType: "text",
|
|
66
|
-
content: [
|
|
67
|
-
{
|
|
68
|
-
type: "text",
|
|
69
|
-
text: "⚠️ IMPORTANT: URL parameter is required for API debugging!\n\n🔧 Step 1: Provide URL Parameter\n\nCall: api_debug with url parameter\n\nExample: {\"url\": \"/api/users\", \"method\": \"GET\"}\n\n⚠️ REMINDER: URL is required for API execution!"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
type: "text",
|
|
73
|
-
text: "🔧 Step 2: Optional Parameters\n\nYou can also provide:\n- method: GET, POST, PUT, DELETE, PATCH\n- headers: Additional request headers\n- query: Query parameters\n- body: Request body\n- contentType: Content type override"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
type: "text",
|
|
77
|
-
text: "🚨 REMINDER: URL is mandatory!\n\n- Use api_debug with url parameter\n- URL can be relative (/api/users) or absolute (https://api.example.com/users)"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
type: "text",
|
|
81
|
-
text: "💡 IMPORTANT: Remember to provide URL!\n\n- First: api_debug with url parameter\n- Second: Add other optional parameters as needed"
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
type: "text",
|
|
85
|
-
text: "📋 Final Reminder: URL is required\n\n1. First: api_debug with url parameter\n2. Then: Add optional parameters\n\nThis is the ONLY way to execute API requests."
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
type: "text",
|
|
89
|
-
text: "⚠️ ESSENTIAL: URL parameter is required!\n\n- Use api_debug with url parameter\n- URL can be relative or absolute"
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
};*/
|
|
93
77
|
}
|
|
94
78
|
|
|
95
79
|
try {
|
|
@@ -135,27 +119,27 @@ async function api_debug(params, config, saveConfig) {
|
|
|
135
119
|
content: [
|
|
136
120
|
{
|
|
137
121
|
type: "text",
|
|
138
|
-
text:
|
|
122
|
+
text: `⚠️ IMPORTANT: You MUST use addApi to add the API to the list first! Use ${configToolName} tool.\n\n🔧 Step 1: Add API to Configuration (REQUIRED)\n\nCall: ${configToolName} with action="addApi" and api={"url":"${url}","method":"${requestMethod}","body":"your corrected JSON here"}\n\n⚠️ REMINDER: You MUST use ${configToolName} with addApi to add the API to the list!`
|
|
139
123
|
},
|
|
140
124
|
{
|
|
141
125
|
type: "text",
|
|
142
|
-
text:
|
|
126
|
+
text: `🔧 Step 2: Execute API by Index\n\nAfter adding the API, call: ${executeToolName} with index=<returned index>\n\nThis will execute the pre-configured API with the correct format.`
|
|
143
127
|
},
|
|
144
128
|
{
|
|
145
129
|
type: "text",
|
|
146
|
-
text:
|
|
130
|
+
text: `🚨 REMINDER: You MUST use addApi first!\n\n- Use ${configToolName} with action="addApi" to add the API to the list\n- Then use ${executeToolName} with the returned index to execute`
|
|
147
131
|
},
|
|
148
132
|
{
|
|
149
133
|
type: "text",
|
|
150
|
-
text:
|
|
134
|
+
text: `💡 IMPORTANT: Remember to use addApi!\n\n- First: ${configToolName} with action="addApi" to add the API\n- Second: ${executeToolName} with index to run the API`
|
|
151
135
|
},
|
|
152
136
|
{
|
|
153
137
|
type: "text",
|
|
154
|
-
text:
|
|
138
|
+
text: `📋 Final Reminder: Use addApi → Then ${executeToolName}\n\n1. First: ${configToolName} with action="addApi"\n2. Then: ${executeToolName} with index=<number>\n\nThis is the ONLY way to handle invalid JSON requests.`
|
|
155
139
|
},
|
|
156
140
|
{
|
|
157
141
|
type: "text",
|
|
158
|
-
text:
|
|
142
|
+
text: `⚠️ ESSENTIAL: You MUST use addApi!\n\n- First: ${configToolName} with action="addApi" to add the API\n- Second: ${executeToolName} with index to run the API`
|
|
159
143
|
}
|
|
160
144
|
]
|
|
161
145
|
};
|
|
@@ -219,11 +203,18 @@ async function api_debug(params, config, saveConfig) {
|
|
|
219
203
|
|
|
220
204
|
try {
|
|
221
205
|
// 执行请求
|
|
222
|
-
|
|
206
|
+
const fetchOptions = {
|
|
223
207
|
method: requestMethod,
|
|
224
208
|
headers: finalHeaders,
|
|
225
209
|
body: requestBody
|
|
226
|
-
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// 为 HTTPS 请求添加 agent 以跳过证书验证
|
|
213
|
+
if (finalRequestUrl.startsWith('https')) {
|
|
214
|
+
fetchOptions.agent = httpsAgent;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
response = await fetch(finalRequestUrl, fetchOptions);
|
|
227
218
|
|
|
228
219
|
// 获取响应数据
|
|
229
220
|
const responseContentType = response.headers.get('content-type');
|
|
@@ -244,23 +235,104 @@ async function api_debug(params, config, saveConfig) {
|
|
|
244
235
|
}
|
|
245
236
|
|
|
246
237
|
if (success && response) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
238
|
+
// 自动将接口添加到配置列表中
|
|
239
|
+
try {
|
|
240
|
+
const apiConfig = loadApiConfig();
|
|
241
|
+
if (!apiConfig.list) {
|
|
242
|
+
apiConfig.list = [];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 检查是否已存在相同的接口
|
|
246
|
+
const existingApiIndex = apiConfig.list.findIndex(api =>
|
|
247
|
+
api.url === url && api.method === requestMethod
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
if (existingApiIndex === -1) {
|
|
251
|
+
// 如果不存在,添加到列表
|
|
252
|
+
const newApi = {
|
|
253
|
+
url: url,
|
|
254
|
+
method: requestMethod,
|
|
255
|
+
description: `API added from api_debug: ${url}`,
|
|
256
|
+
headers: headers,
|
|
257
|
+
query: query,
|
|
258
|
+
body: body,
|
|
259
|
+
contentType: contentType
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
apiConfig.list.push(newApi);
|
|
263
|
+
saveApiConfig(apiConfig);
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
success: true,
|
|
267
|
+
message: `Successfully executed API: ${url} (Added to list at index ${apiConfig.list.length - 1})`,
|
|
268
|
+
apiIndex: apiConfig.list.length - 1,
|
|
269
|
+
request: {
|
|
270
|
+
url: finalRequestUrl,
|
|
271
|
+
method: requestMethod,
|
|
272
|
+
headers: finalHeaders,
|
|
273
|
+
body: requestBody
|
|
274
|
+
},
|
|
275
|
+
response: {
|
|
276
|
+
status: response.status,
|
|
277
|
+
statusText: response.statusText,
|
|
278
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
279
|
+
data: responseData
|
|
280
|
+
},
|
|
281
|
+
timestamp: new Date().toISOString()
|
|
282
|
+
};
|
|
283
|
+
} else {
|
|
284
|
+
// 如果已存在,更新接口信息
|
|
285
|
+
apiConfig.list[existingApiIndex] = {
|
|
286
|
+
...apiConfig.list[existingApiIndex],
|
|
287
|
+
url: url,
|
|
288
|
+
method: requestMethod,
|
|
289
|
+
headers: headers,
|
|
290
|
+
query: query,
|
|
291
|
+
body: body,
|
|
292
|
+
contentType: contentType
|
|
293
|
+
};
|
|
294
|
+
saveApiConfig(apiConfig);
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
message: `Successfully executed API: ${url} (Updated existing API at index ${existingApiIndex})`,
|
|
299
|
+
apiIndex: existingApiIndex,
|
|
300
|
+
request: {
|
|
301
|
+
url: finalRequestUrl,
|
|
302
|
+
method: requestMethod,
|
|
303
|
+
headers: finalHeaders,
|
|
304
|
+
body: requestBody
|
|
305
|
+
},
|
|
306
|
+
response: {
|
|
307
|
+
status: response.status,
|
|
308
|
+
statusText: response.statusText,
|
|
309
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
310
|
+
data: responseData
|
|
311
|
+
},
|
|
312
|
+
timestamp: new Date().toISOString()
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
} catch (saveError) {
|
|
316
|
+
// 如果保存失败,仍然返回成功响应
|
|
317
|
+
console.error('Failed to save API to list:', saveError.message);
|
|
318
|
+
return {
|
|
319
|
+
success: true,
|
|
320
|
+
message: `Successfully executed API: ${url} (Failed to save to list)`,
|
|
321
|
+
request: {
|
|
322
|
+
url: finalRequestUrl,
|
|
323
|
+
method: requestMethod,
|
|
324
|
+
headers: finalHeaders,
|
|
325
|
+
body: requestBody
|
|
326
|
+
},
|
|
327
|
+
response: {
|
|
328
|
+
status: response.status,
|
|
329
|
+
statusText: response.statusText,
|
|
330
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
331
|
+
data: responseData
|
|
332
|
+
},
|
|
333
|
+
timestamp: new Date().toISOString()
|
|
334
|
+
};
|
|
335
|
+
}
|
|
264
336
|
} else {
|
|
265
337
|
return {
|
|
266
338
|
success: false,
|
package/src/utils/api_execute.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
const { loadApiConfig, getAllowedMethods } = require('./api_common');
|
|
2
2
|
|
|
3
|
+
// 设置全局环境变量以跳过证书验证
|
|
4
|
+
if (!process.env.NODE_TLS_REJECT_UNAUTHORIZED) {
|
|
5
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
6
|
+
}
|
|
7
|
+
|
|
3
8
|
/**
|
|
4
9
|
* API 执行工具 - 通过索引执行已配置的API
|
|
5
10
|
* @param {Object} params - 参数
|
|
@@ -131,6 +136,7 @@ async function api_execute(params, config, saveConfig) {
|
|
|
131
136
|
};
|
|
132
137
|
|
|
133
138
|
} catch (err) {
|
|
139
|
+
console.error(err);
|
|
134
140
|
throw new Error(`Failed to execute API at index ${index}: ${err.message}`);
|
|
135
141
|
}
|
|
136
142
|
}
|
package/src/utils/api_login.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
const { getLoginUrl, getLoginMethod, getLoginBody, loadApiConfig, saveApiConfig } = require('./api_common');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
|
|
4
|
+
// 为 HTTPS 请求创建跳过证书验证的 agent
|
|
5
|
+
const httpsAgent = new https.Agent({
|
|
6
|
+
rejectUnauthorized: false
|
|
7
|
+
});
|
|
2
8
|
|
|
3
9
|
/**
|
|
4
10
|
* API 登录工具 - 直接执行登录请求(从环境变量获取登录信息)
|
|
@@ -57,11 +63,18 @@ async function api_login(params, config, saveConfig) {
|
|
|
57
63
|
let error = null;
|
|
58
64
|
|
|
59
65
|
try {
|
|
60
|
-
|
|
66
|
+
const fetchOptions = {
|
|
61
67
|
method: loginMethod,
|
|
62
68
|
headers: headers,
|
|
63
69
|
body: loginBody
|
|
64
|
-
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// 为 HTTPS 请求添加 agent 以跳过证书验证
|
|
73
|
+
if (fullLoginUrl.startsWith('https')) {
|
|
74
|
+
fetchOptions.agent = httpsAgent;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
response = await fetch(fullLoginUrl, fetchOptions);
|
|
65
78
|
|
|
66
79
|
// 获取响应数据
|
|
67
80
|
const contentType = response.headers.get('content-type');
|