@chenyingxian/zentao-mcp 0.1.1 → 0.1.2
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/.env.example +8 -6
- package/CONFIG.md +41 -11
- package/CONFIG.zh-CN.md +41 -11
- package/README.md +45 -20
- package/README.zh-CN.md +45 -20
- package/package.json +1 -1
- package/src/index.js +1 -1
- package/src/zentao-client.js +52 -3
package/.env.example
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
ZENTAO_BASE_URL=https://zentao.example.com
|
|
2
|
-
ZENTAO_ACCOUNT=admin
|
|
3
|
-
ZENTAO_PASSWORD=change-me
|
|
4
|
-
# Optional: use a pre-issued V1 token instead of logging in with account/password.
|
|
5
|
-
ZENTAO_TOKEN=
|
|
6
|
-
ZENTAO_TIMEOUT_MS=15000
|
|
1
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
2
|
+
ZENTAO_ACCOUNT=admin
|
|
3
|
+
ZENTAO_PASSWORD=change-me
|
|
4
|
+
# Optional: use a pre-issued V1 token instead of logging in with account/password.
|
|
5
|
+
ZENTAO_TOKEN=
|
|
6
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
7
|
+
# Optional: put the variables above in another local file and expose only this path to your MCP client.
|
|
8
|
+
ZENTAO_CONFIG_FILE=
|
package/CONFIG.md
CHANGED
|
@@ -19,13 +19,27 @@ ZENTAO_BASE_URL=https://zentao.example.com
|
|
|
19
19
|
ZENTAO_TOKEN=your-token
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
## Optional Variables
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
ZENTAO_TIMEOUT_MS=15000
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
## Optional Variables
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
26
|
+
ZENTAO_CONFIG_FILE=/path/to/zentao.env
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`ZENTAO_TIMEOUT_MS` controls the HTTP request timeout in milliseconds.
|
|
30
|
+
|
|
31
|
+
`ZENTAO_CONFIG_FILE` points to a local KEY=value config file. This is useful when you do not want to show credentials in the MCP client configuration UI.
|
|
32
|
+
|
|
33
|
+
Example config file:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
37
|
+
ZENTAO_ACCOUNT=your-account
|
|
38
|
+
ZENTAO_PASSWORD=your-password
|
|
39
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Environment variables override values from `ZENTAO_CONFIG_FILE`.
|
|
29
43
|
|
|
30
44
|
## MCP Client Example
|
|
31
45
|
|
|
@@ -34,7 +48,7 @@ ZENTAO_TIMEOUT_MS=15000
|
|
|
34
48
|
"mcpServers": {
|
|
35
49
|
"zentao": {
|
|
36
50
|
"command": "npx",
|
|
37
|
-
"args": ["@chenyingxian/zentao-mcp"],
|
|
51
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
38
52
|
"env": {
|
|
39
53
|
"ZENTAO_BASE_URL": "https://zentao.example.com",
|
|
40
54
|
"ZENTAO_ACCOUNT": "your-account",
|
|
@@ -42,9 +56,25 @@ ZENTAO_TIMEOUT_MS=15000
|
|
|
42
56
|
"ZENTAO_TIMEOUT_MS": "15000"
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
```
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Credentials can also be kept out of the MCP client config:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"zentao": {
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
71
|
+
"env": {
|
|
72
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
48
78
|
|
|
49
79
|
## Token Helper
|
|
50
80
|
|
package/CONFIG.zh-CN.md
CHANGED
|
@@ -19,13 +19,27 @@ ZENTAO_BASE_URL=https://zentao.example.com
|
|
|
19
19
|
ZENTAO_TOKEN=your-token
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
## 可选变量
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
ZENTAO_TIMEOUT_MS=15000
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
## 可选变量
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
26
|
+
ZENTAO_CONFIG_FILE=/path/to/zentao.env
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`ZENTAO_TIMEOUT_MS` 用于控制 HTTP 请求超时时间,单位为毫秒。
|
|
30
|
+
|
|
31
|
+
`ZENTAO_CONFIG_FILE` 指向一个本地 KEY=value 配置文件。这样 MCP 客户端配置里只需要展示文件路径,不需要直接展示密码。
|
|
32
|
+
|
|
33
|
+
配置文件示例:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
37
|
+
ZENTAO_ACCOUNT=your-account
|
|
38
|
+
ZENTAO_PASSWORD=your-password
|
|
39
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
环境变量会覆盖 `ZENTAO_CONFIG_FILE` 文件里的同名配置。
|
|
29
43
|
|
|
30
44
|
## MCP 客户端示例
|
|
31
45
|
|
|
@@ -34,7 +48,7 @@ ZENTAO_TIMEOUT_MS=15000
|
|
|
34
48
|
"mcpServers": {
|
|
35
49
|
"zentao": {
|
|
36
50
|
"command": "npx",
|
|
37
|
-
"args": ["@chenyingxian/zentao-mcp"],
|
|
51
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
38
52
|
"env": {
|
|
39
53
|
"ZENTAO_BASE_URL": "https://zentao.example.com",
|
|
40
54
|
"ZENTAO_ACCOUNT": "your-account",
|
|
@@ -42,9 +56,25 @@ ZENTAO_TIMEOUT_MS=15000
|
|
|
42
56
|
"ZENTAO_TIMEOUT_MS": "15000"
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
```
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
也可以把账号密码放在本地配置文件中,MCP 客户端只配置路径:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"zentao": {
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
71
|
+
"env": {
|
|
72
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
48
78
|
|
|
49
79
|
## Token 辅助脚本
|
|
50
80
|
|
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ npx @chenyingxian/zentao-mcp
|
|
|
24
24
|
|
|
25
25
|
## Configuration
|
|
26
26
|
|
|
27
|
-
Set the following environment variables in your MCP client:
|
|
27
|
+
Set the following environment variables in your MCP client:
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
30
|
ZENTAO_BASE_URL=https://zentao.example.com
|
|
@@ -42,26 +42,51 @@ ZENTAO_TOKEN=your-token
|
|
|
42
42
|
Optional:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
ZENTAO_TIMEOUT_MS=15000
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If you do not want to expose credentials directly in the MCP client config, put them in a local config file:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
52
|
+
ZENTAO_ACCOUNT=your-account
|
|
53
|
+
ZENTAO_PASSWORD=your-password
|
|
54
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then expose only the file path to the MCP client:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"zentao": {
|
|
54
63
|
"command": "npx",
|
|
55
|
-
"args": ["@chenyingxian/zentao-mcp"],
|
|
56
|
-
"env": {
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
65
|
+
"env": {
|
|
66
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Environment variables override values from `ZENTAO_CONFIG_FILE`.
|
|
74
|
+
|
|
75
|
+
## MCP Client Example
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"mcpServers": {
|
|
80
|
+
"zentao": {
|
|
81
|
+
"command": "npx",
|
|
82
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
83
|
+
"env": {
|
|
84
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
65
90
|
|
|
66
91
|
## Get a Token
|
|
67
92
|
|
package/README.zh-CN.md
CHANGED
|
@@ -32,30 +32,55 @@ ZENTAO_ACCOUNT=your-account
|
|
|
32
32
|
ZENTAO_PASSWORD=your-password
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
也可以直接使用已签发的 v1 token:
|
|
35
|
+
也可以直接使用已签发的 v1 token:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
ZENTAO_BASE_URL=https://zentao.example.com
|
|
39
|
-
ZENTAO_TOKEN=your-token
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
ZENTAO_TOKEN=your-token
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
如果不希望密码直接展示在 MCP 客户端配置里,可以把真实配置写到本地配置文件:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ZENTAO_BASE_URL=https://zentao.example.com
|
|
46
|
+
ZENTAO_ACCOUNT=your-account
|
|
47
|
+
ZENTAO_PASSWORD=your-password
|
|
48
|
+
ZENTAO_TIMEOUT_MS=15000
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
然后 MCP 客户端只配置文件路径:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"zentao": {
|
|
48
57
|
"command": "npx",
|
|
49
|
-
"args": ["@chenyingxian/zentao-mcp"],
|
|
50
|
-
"env": {
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
59
|
+
"env": {
|
|
60
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
环境变量会覆盖 `ZENTAO_CONFIG_FILE` 文件里的同名配置。
|
|
68
|
+
|
|
69
|
+
## MCP 客户端示例
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"zentao": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["-y", "@chenyingxian/zentao-mcp@latest"],
|
|
77
|
+
"env": {
|
|
78
|
+
"ZENTAO_CONFIG_FILE": "/path/to/zentao.env"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
59
84
|
|
|
60
85
|
## 获取 Token
|
|
61
86
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
package/src/zentao-client.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import { readFile } from "node:fs/promises";
|
|
2
3
|
import { basename } from "node:path";
|
|
3
4
|
|
|
@@ -467,9 +468,57 @@ export class ZentaoClient {
|
|
|
467
468
|
* @param {NodeJS.ProcessEnv} env Process environment.
|
|
468
469
|
* @returns {ZentaoClient} ZenTao client.
|
|
469
470
|
*/
|
|
470
|
-
export function createClientFromEnv(env = process.env) {
|
|
471
|
-
|
|
472
|
-
}
|
|
471
|
+
export function createClientFromEnv(env = process.env) {
|
|
472
|
+
const fileConfig = env.ZENTAO_CONFIG_FILE ? readEnvConfigFile(env.ZENTAO_CONFIG_FILE) : {};
|
|
473
|
+
const merged = { ...fileConfig, ...compactEnv(env) };
|
|
474
|
+
return new ZentaoClient({ baseUrl: merged.ZENTAO_BASE_URL, account: merged.ZENTAO_ACCOUNT, password: merged.ZENTAO_PASSWORD, token: merged.ZENTAO_TOKEN, timeoutMs: merged.ZENTAO_TIMEOUT_MS });
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Read a simple KEY=value config file.
|
|
479
|
+
* @param {string} filePath Config file path.
|
|
480
|
+
* @returns {Record<string, string>} Parsed config.
|
|
481
|
+
*/
|
|
482
|
+
function readEnvConfigFile(filePath) {
|
|
483
|
+
const text = readFileSync(filePath, "utf8");
|
|
484
|
+
return parseEnvFile(text);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Parse dotenv-like config text without adding a runtime dependency.
|
|
489
|
+
* @param {string} text Raw config text.
|
|
490
|
+
* @returns {Record<string, string>} Parsed key-value pairs.
|
|
491
|
+
*/
|
|
492
|
+
function parseEnvFile(text) {
|
|
493
|
+
const result = {};
|
|
494
|
+
for (const line of String(text).split(/\r?\n/)) {
|
|
495
|
+
const trimmed = line.trim();
|
|
496
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
497
|
+
const match = trimmed.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
|
|
498
|
+
if (!match) continue;
|
|
499
|
+
result[match[1]] = unquoteEnvValue(match[2].trim());
|
|
500
|
+
}
|
|
501
|
+
return result;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Remove simple dotenv quotes from one value.
|
|
506
|
+
* @param {string} value Raw config value.
|
|
507
|
+
* @returns {string} Unquoted value.
|
|
508
|
+
*/
|
|
509
|
+
function unquoteEnvValue(value) {
|
|
510
|
+
if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) return value.slice(1, -1);
|
|
511
|
+
return value;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Keep only defined non-empty environment values so config files can provide defaults.
|
|
516
|
+
* @param {NodeJS.ProcessEnv} env Process environment.
|
|
517
|
+
* @returns {Record<string, string>} Compact environment.
|
|
518
|
+
*/
|
|
519
|
+
function compactEnv(env) {
|
|
520
|
+
return Object.fromEntries(Object.entries(env).filter(([, value]) => value !== undefined && value !== ""));
|
|
521
|
+
}
|
|
473
522
|
|
|
474
523
|
/**
|
|
475
524
|
* Normalize a ZenTao site URL.
|