@dyno181cm.nexsoft/zentao_mcp 1.2.2 → 1.2.3
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/build/tools.js +27 -4
- package/build/zentaoClient.js +11 -17
- package/package.json +1 -1
package/build/tools.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import * as os from "os";
|
|
3
3
|
import * as path from "path";
|
|
4
|
+
import fs from "fs";
|
|
4
5
|
import { ZentaoClient } from "./zentaoClient.js";
|
|
5
6
|
const client = new ZentaoClient();
|
|
7
|
+
const activeDownloads = new Map();
|
|
6
8
|
/**
|
|
7
9
|
* Registers Zentao-specific tools to the Model Context Protocol (MCP) server.
|
|
8
10
|
*
|
|
@@ -129,10 +131,31 @@ export function registerTools(server) {
|
|
|
129
131
|
const ext = extension ? (extension.startsWith('.') ? extension : `.${extension}`) : '';
|
|
130
132
|
const targetPath = path.join(os.tmpdir(), `zentao_file_${fileId}${ext}`);
|
|
131
133
|
try {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
// If it already exists on disk and is not currently being downloaded
|
|
135
|
+
if (fs.existsSync(targetPath) && !activeDownloads.has(targetPath)) {
|
|
136
|
+
return {
|
|
137
|
+
content: [{ type: "text", text: `File already exists locally at: ${targetPath}` }],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// If it is currently being downloaded, await the active promise
|
|
141
|
+
if (activeDownloads.has(targetPath)) {
|
|
142
|
+
await activeDownloads.get(targetPath);
|
|
143
|
+
return {
|
|
144
|
+
content: [{ type: "text", text: `File downloaded successfully to: ${targetPath}` }],
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// Start new download and track it
|
|
148
|
+
const downloadPromise = client.downloadFile(fileId, targetPath);
|
|
149
|
+
activeDownloads.set(targetPath, downloadPromise);
|
|
150
|
+
try {
|
|
151
|
+
const savedPath = await downloadPromise;
|
|
152
|
+
return {
|
|
153
|
+
content: [{ type: "text", text: `File downloaded successfully to: ${savedPath}` }],
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
activeDownloads.delete(targetPath);
|
|
158
|
+
}
|
|
136
159
|
}
|
|
137
160
|
catch (error) {
|
|
138
161
|
return {
|
package/build/zentaoClient.js
CHANGED
|
@@ -84,24 +84,18 @@ export class ZentaoClient {
|
|
|
84
84
|
* @throws {Error} If account/password env vars are missing or if the API request fails.
|
|
85
85
|
*/
|
|
86
86
|
async login() {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
this.token = response.data.token;
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
throw new Error('Login failed: Token not found in response');
|
|
100
|
-
}
|
|
87
|
+
if (!this.account || !this.password) {
|
|
88
|
+
throw new Error('ZENTAO_ACCOUNT or ZENTAO_PASSWORD is not set in environment variables');
|
|
89
|
+
}
|
|
90
|
+
const response = await this.client.post('/tokens', {
|
|
91
|
+
account: this.account,
|
|
92
|
+
password: this.password,
|
|
93
|
+
});
|
|
94
|
+
if (response.data && response.data.token) {
|
|
95
|
+
this.token = response.data.token;
|
|
101
96
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
throw error;
|
|
97
|
+
else {
|
|
98
|
+
throw new Error('Login failed: Token not found in response');
|
|
105
99
|
}
|
|
106
100
|
}
|
|
107
101
|
/**
|