@zzp123/mcp-zentao 1.2.0 → 1.2.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/dist/index.js +92 -6
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -932,21 +932,107 @@ server.tool("getModules", {
|
|
|
932
932
|
});
|
|
933
933
|
// 文件相关工具
|
|
934
934
|
server.tool("uploadFile", {
|
|
935
|
-
filePath: z.string(),
|
|
935
|
+
filePath: z.string().optional(),
|
|
936
|
+
base64Data: z.string().optional(),
|
|
937
|
+
filename: z.string().optional(),
|
|
936
938
|
uid: z.string().optional()
|
|
937
|
-
}, async ({ filePath, uid }) => {
|
|
939
|
+
}, async ({ filePath, base64Data, filename, uid }) => {
|
|
938
940
|
if (!zentaoApi)
|
|
939
941
|
throw new Error("Please initialize Zentao API first");
|
|
940
942
|
const fs = await import('fs');
|
|
941
943
|
const path = await import('path');
|
|
942
|
-
|
|
943
|
-
|
|
944
|
+
let fileBuffer;
|
|
945
|
+
let finalFilename;
|
|
946
|
+
let savedPath;
|
|
947
|
+
// 如果提供了 base64 数据(复制的图片)
|
|
948
|
+
if (base64Data) {
|
|
949
|
+
// 创建 img 文件夹(如果不存在)
|
|
950
|
+
const imgDir = path.join(process.cwd(), 'img');
|
|
951
|
+
if (!fs.existsSync(imgDir)) {
|
|
952
|
+
fs.mkdirSync(imgDir, { recursive: true });
|
|
953
|
+
}
|
|
954
|
+
// 处理 base64 数据
|
|
955
|
+
const matches = base64Data.match(/^data:image\/(\w+);base64,(.+)$/);
|
|
956
|
+
if (matches) {
|
|
957
|
+
const ext = matches[1];
|
|
958
|
+
const data = matches[2];
|
|
959
|
+
fileBuffer = Buffer.from(data, 'base64');
|
|
960
|
+
finalFilename = filename || `image_${Date.now()}.${ext}`;
|
|
961
|
+
}
|
|
962
|
+
else {
|
|
963
|
+
// 直接的 base64 数据,没有 data URL 前缀
|
|
964
|
+
fileBuffer = Buffer.from(base64Data, 'base64');
|
|
965
|
+
finalFilename = filename || `image_${Date.now()}.png`;
|
|
966
|
+
}
|
|
967
|
+
// 保存到 img 文件夹
|
|
968
|
+
savedPath = path.join(imgDir, finalFilename);
|
|
969
|
+
fs.writeFileSync(savedPath, fileBuffer);
|
|
970
|
+
}
|
|
971
|
+
// 如果提供了文件路径
|
|
972
|
+
else if (filePath) {
|
|
973
|
+
fileBuffer = fs.readFileSync(filePath);
|
|
974
|
+
finalFilename = path.basename(filePath);
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
throw new Error("必须提供 filePath 或 base64Data 参数");
|
|
978
|
+
}
|
|
944
979
|
const result = await zentaoApi.uploadFile({
|
|
945
980
|
file: fileBuffer,
|
|
946
|
-
filename,
|
|
981
|
+
filename: finalFilename,
|
|
947
982
|
uid
|
|
948
983
|
});
|
|
949
|
-
|
|
984
|
+
const response = {
|
|
985
|
+
upload: result,
|
|
986
|
+
};
|
|
987
|
+
if (savedPath) {
|
|
988
|
+
response.savedPath = savedPath;
|
|
989
|
+
}
|
|
990
|
+
return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] };
|
|
991
|
+
});
|
|
992
|
+
server.tool("uploadImageFromClipboard", {
|
|
993
|
+
base64Data: z.string(),
|
|
994
|
+
filename: z.string().optional(),
|
|
995
|
+
uid: z.string().optional()
|
|
996
|
+
}, async ({ base64Data, filename, uid }) => {
|
|
997
|
+
if (!zentaoApi)
|
|
998
|
+
throw new Error("Please initialize Zentao API first");
|
|
999
|
+
const fs = await import('fs');
|
|
1000
|
+
const path = await import('path');
|
|
1001
|
+
// 创建 img 文件夹(如果不存在)
|
|
1002
|
+
const imgDir = path.join(process.cwd(), 'img');
|
|
1003
|
+
if (!fs.existsSync(imgDir)) {
|
|
1004
|
+
fs.mkdirSync(imgDir, { recursive: true });
|
|
1005
|
+
}
|
|
1006
|
+
let fileBuffer;
|
|
1007
|
+
let finalFilename;
|
|
1008
|
+
// 处理 base64 数据
|
|
1009
|
+
const matches = base64Data.match(/^data:image\/(\w+);base64,(.+)$/);
|
|
1010
|
+
if (matches) {
|
|
1011
|
+
const ext = matches[1];
|
|
1012
|
+
const data = matches[2];
|
|
1013
|
+
fileBuffer = Buffer.from(data, 'base64');
|
|
1014
|
+
finalFilename = filename || `clipboard_${Date.now()}.${ext}`;
|
|
1015
|
+
}
|
|
1016
|
+
else {
|
|
1017
|
+
// 直接的 base64 数据,没有 data URL 前缀
|
|
1018
|
+
fileBuffer = Buffer.from(base64Data, 'base64');
|
|
1019
|
+
finalFilename = filename || `clipboard_${Date.now()}.png`;
|
|
1020
|
+
}
|
|
1021
|
+
// 保存到 img 文件夹
|
|
1022
|
+
const savedPath = path.join(imgDir, finalFilename);
|
|
1023
|
+
fs.writeFileSync(savedPath, fileBuffer);
|
|
1024
|
+
// 上传到禅道
|
|
1025
|
+
const result = await zentaoApi.uploadFile({
|
|
1026
|
+
file: fileBuffer,
|
|
1027
|
+
filename: finalFilename,
|
|
1028
|
+
uid
|
|
1029
|
+
});
|
|
1030
|
+
const response = {
|
|
1031
|
+
upload: result,
|
|
1032
|
+
savedPath: savedPath,
|
|
1033
|
+
message: `图片已保存到本地并上传到禅道`
|
|
1034
|
+
};
|
|
1035
|
+
return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] };
|
|
950
1036
|
});
|
|
951
1037
|
server.tool("downloadFile", {
|
|
952
1038
|
fileId: z.number(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zzp123/mcp-zentao",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "禅道项目管理系统的高级API集成包,提供任务管理、Bug跟踪等功能的完整封装,专为Cursor IDE设计的MCP扩展",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.6.1",
|
|
45
|
-
"@zzp123/mcp-zentao": "^1.1
|
|
45
|
+
"@zzp123/mcp-zentao": "^1.2.1",
|
|
46
46
|
"axios": "^1.6.7",
|
|
47
47
|
"chalk": "^4.1.2",
|
|
48
48
|
"form-data": "^4.0.4",
|