file-system-with-oss-mcp 1.2.5 → 1.2.7

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 CHANGED
@@ -91,9 +91,11 @@ var ConfigManager = class _ConfigManager {
91
91
  static onestepClients = { "saber": "saber_secret", "onestep_user": "ewkej3243242" };
92
92
  oAuthConfig;
93
93
  newApiUser;
94
+ apiConfig;
94
95
  constructor() {
95
96
  this.oAuthConfig = {};
96
97
  this.newApiUser = {};
98
+ this.apiConfig = {};
97
99
  }
98
100
  static async getInstance() {
99
101
  if (!_ConfigManager.instance) {
@@ -101,11 +103,12 @@ var ConfigManager = class _ConfigManager {
101
103
  }
102
104
  return _ConfigManager.instance;
103
105
  }
104
- static async init(newApiUser, userSetting) {
106
+ static async init(newApiUser, userSetting, apiConfig) {
105
107
  if (!_ConfigManager.instance) {
106
108
  _ConfigManager.instance = new _ConfigManager();
107
109
  await _ConfigManager.instance.loadConfig(userSetting);
108
110
  _ConfigManager.instance.newApiUser = newApiUser;
111
+ _ConfigManager.instance.apiConfig = apiConfig;
109
112
  }
110
113
  return _ConfigManager.instance;
111
114
  }
@@ -143,6 +146,12 @@ var ConfigManager = class _ConfigManager {
143
146
  getOAuthConfig() {
144
147
  return this.oAuthConfig;
145
148
  }
149
+ getNewApiUser() {
150
+ return this.newApiUser;
151
+ }
152
+ getApiConfig() {
153
+ return this.apiConfig;
154
+ }
146
155
  };
147
156
 
148
157
  // src/config/config.ts
@@ -179,6 +188,11 @@ async function getServerConfig(isStdioMode = false) {
179
188
  logger.error("allowedDirectories argv variable is not set");
180
189
  throw new Error("allowedDirectories environment variable is not set");
181
190
  }
191
+ const apiServer = process.argv.find((arg) => arg.startsWith("--apiServer="));
192
+ if (!apiServer) {
193
+ logger.error("apiServer argv variable is not set");
194
+ throw new Error("apiServer environment variable is not set");
195
+ }
182
196
  const config3 = {
183
197
  port: 3e3,
184
198
  ossConfig: {},
@@ -192,7 +206,6 @@ async function getServerConfig(isStdioMode = false) {
192
206
  const directoriesInparam = allowedDirectories.split("=")[1];
193
207
  let tempdirs = directoriesInparam.replaceAll("\\", "\\").split(",") ?? [];
194
208
  const normalizeDirs = tempdirs.map((dir) => normalizePath(expandHome(dir)));
195
- logger.info("Allowed directories:", allowedDirectories);
196
209
  await Promise.all(normalizeDirs.map(async (dir) => {
197
210
  try {
198
211
  const stats = await stat(expandHome(dir));
@@ -206,6 +219,7 @@ async function getServerConfig(isStdioMode = false) {
206
219
  }
207
220
  }));
208
221
  config3.allowedDirectories = normalizeDirs;
222
+ console.log("Allowed directories:", normalizeDirs);
209
223
  config3.configSources.port = "cli";
210
224
  const newApiAuthDataString = Buffer.from(newApiAuthData.split("=")[1], "base64").toString("utf8");
211
225
  const newApiAuthDataArry = newApiAuthDataString.split("\u8B8A");
@@ -219,7 +233,9 @@ async function getServerConfig(isStdioMode = false) {
219
233
  const allOssConfigs = { "default": { region: "cn-hongkong", accessKeyId: userSetting.accessKeyId, accessKeySecret: userSetting.accessKeySecret, bucket: userSetting.bucketName, endpoint: userSetting.endpoint, cdnHost: userSetting.cdnHost } };
220
234
  config3.ossConfig = allOssConfigs;
221
235
  config3.configSources.ossConfig = "cli";
222
- ConfigManager.init(newApiUser, userSetting);
236
+ const apiServerDataString = Buffer.from(apiServer.split("=")[1], "base64").toString("utf8");
237
+ const apiServerConfig = JSON.parse(apiServerDataString);
238
+ await ConfigManager.init(newApiUser, userSetting, apiServerConfig);
223
239
  if (Object.keys(config3.ossConfig).length === 0) {
224
240
  logger.warn("\u672A\u627E\u5230\u6709\u6548\u7684OSS\u914D\u7F6E\u3002\u670D\u52A1\u5668\u5C06\u542F\u52A8\uFF0C\u4F46\u4E0A\u4F20\u529F\u80FD\u5C06\u4E0D\u53EF\u7528\u3002");
225
241
  }
@@ -360,8 +376,8 @@ var ossService = new OssService();
360
376
  // src/server.ts
361
377
  import express from "express";
362
378
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
363
- import fs3 from "fs";
364
- import { stat as stat2, realpath, readdir, readFile, writeFile, mkdir, rename } from "fs/promises";
379
+ import fs3, { mkdirSync } from "fs";
380
+ import { stat as stat2, realpath, readdir, readFile, writeFile, mkdir, rename, copyFile } from "fs/promises";
365
381
  import { createTwoFilesPatch } from "diff";
366
382
  import os2 from "os";
367
383
  import * as fpath2 from "path";
@@ -461,49 +477,6 @@ var thirdparyLogin = async (grantType) => {
461
477
  req.end();
462
478
  });
463
479
  };
464
- var classifyFiles = async (fileUrl) => {
465
- const response = await thirdparyLogin("client_credentials");
466
- const accessToken = response.data.accessToken;
467
- const postData = JSON.stringify({
468
- fileUrl,
469
- splitPdf: 0,
470
- trimPage: 0,
471
- provider: "dify"
472
- });
473
- const config3 = (await ConfigManager.getInstance()).getOAuthConfig();
474
- const options = {
475
- method: "POST",
476
- headers: {
477
- "Content-Type": "application/json",
478
- "Content-Length": Buffer.byteLength(postData),
479
- "cloudx-auth": `Bearer ${accessToken}`,
480
- "Authorization": `Basic ${config3.basicAuth}`,
481
- "Lan": "en",
482
- "Locale": "hk"
483
- }
484
- };
485
- return new Promise((resolve3, reject) => {
486
- console.log("classifyFiles request:", JSON.stringify(options));
487
- const req = request(config3.host + "/api/onestep-jod/docs2png/classifyFile", options, (res) => {
488
- let responseBody = "";
489
- res.on("data", (chunk) => {
490
- responseBody += chunk.toString();
491
- });
492
- res.on("end", () => {
493
- resolve3(JSON.parse(responseBody));
494
- });
495
- });
496
- req.on("error", (error) => {
497
- reject(new Error(`Request failed: ${error.message}`));
498
- });
499
- req.on("timeout", () => {
500
- req.destroy(new Error("Request timed out"));
501
- });
502
- req.setTimeout(1e3 * 120);
503
- req.write(postData);
504
- req.end();
505
- });
506
- };
507
480
  var recFilesWithPull = async (fileUrls) => {
508
481
  const response = await recFiles(fileUrls);
509
482
  if (response.code === 200 && response.status == 0) {
@@ -710,6 +683,54 @@ var convertPdfToDocx = async (pdfUrl) => {
710
683
  req.end();
711
684
  });
712
685
  };
686
+ var convertMarkdownToDoc = async (markdown, resultType) => {
687
+ const response = await thirdparyLogin("client_credentials");
688
+ const accessToken = response.data.accessToken;
689
+ const postData = JSON.stringify({
690
+ markdown,
691
+ resultType
692
+ });
693
+ const config3 = (await ConfigManager.getInstance()).getOAuthConfig();
694
+ const options = {
695
+ method: "POST",
696
+ // rejectUnauthorized: false,
697
+ headers: {
698
+ "Content-Type": "application/json",
699
+ "Content-Length": Buffer.byteLength(postData),
700
+ "cloudx-auth": `Bearer ${accessToken}`,
701
+ "Authorization": `Basic ${config3.basicAuth}`,
702
+ "Lan": "en",
703
+ "Locale": "hk"
704
+ }
705
+ };
706
+ return new Promise((resolve3, reject) => {
707
+ logger.info("convertMarkdownToDoc request:", JSON.stringify(options));
708
+ const req = request(config3.host + "/api/onestep-jod/jodApi/generateDoc/markdown2Doc", options, (res) => {
709
+ let responseBody = "";
710
+ res.on("data", (chunk) => {
711
+ responseBody += chunk.toString();
712
+ });
713
+ res.on("end", () => {
714
+ logger.info("convertMarkdownToDoc response:", responseBody);
715
+ const jsonObject = JSON.parse(responseBody);
716
+ if (jsonObject.code == 200) {
717
+ resolve3(jsonObject.data);
718
+ } else {
719
+ reject(new Error(`Request failed: ${jsonObject.msg}`));
720
+ }
721
+ });
722
+ });
723
+ req.on("error", (error) => {
724
+ reject(new Error(`Request failed: ${error.message}`));
725
+ });
726
+ req.on("timeout", () => {
727
+ req.destroy(new Error("Request timed out"));
728
+ });
729
+ req.setTimeout(1e3 * 600);
730
+ req.write(postData);
731
+ req.end();
732
+ });
733
+ };
713
734
  var convertPdfToMarkdownWithPull = async (pdfUrl) => {
714
735
  const transactionId = await convertPdfToMarkdown(pdfUrl);
715
736
  const pullResult = async function(transactionId2) {
@@ -876,6 +897,134 @@ var DocType = /* @__PURE__ */ ((DocType2) => {
876
897
  DocType2.nameContains = nameContains;
877
898
  })(DocType || (DocType = {}));
878
899
 
900
+ // src/api/cherry/client.ts
901
+ import { CallToolResultSchema } from "@modelcontextprotocol/sdk/types.js";
902
+ var McpClient = class {
903
+ client;
904
+ logger;
905
+ constructor(client, logger2) {
906
+ this.client = client;
907
+ this.logger = logger2;
908
+ }
909
+ async CallTool(request2) {
910
+ const req = {
911
+ method: "tools/call",
912
+ params: {
913
+ name: request2.method,
914
+ arguments: request2.data
915
+ }
916
+ };
917
+ const response = {
918
+ isError: false,
919
+ content: []
920
+ };
921
+ let contents = [];
922
+ try {
923
+ const result = await this.client.callTool(req.params, CallToolResultSchema, { timeout: 60 * 1e3 });
924
+ response.isError = result.isError;
925
+ if (result.content && Array.isArray(result.content)) {
926
+ for (const content of result.content) {
927
+ switch (content.type) {
928
+ case "text":
929
+ contents.push({
930
+ type: content.type,
931
+ text: content.text || ""
932
+ });
933
+ break;
934
+ case "image":
935
+ contents.push({
936
+ type: content.type,
937
+ text: content.data || content.url || ""
938
+ });
939
+ break;
940
+ case "audio":
941
+ contents.push({
942
+ type: content.type,
943
+ text: content.data || content.url || ""
944
+ });
945
+ break;
946
+ default:
947
+ this.logger.error("not supported content: %j", content);
948
+ break;
949
+ }
950
+ }
951
+ }
952
+ response.content = contents;
953
+ return response;
954
+ } catch (err) {
955
+ this.logger.error("CallTool failed: %s", err instanceof Error ? err.message : String(err));
956
+ response.isError = true;
957
+ contents.push({
958
+ type: "text",
959
+ text: err instanceof Error ? err.message : String(err)
960
+ });
961
+ response.content = contents;
962
+ return response;
963
+ }
964
+ }
965
+ };
966
+
967
+ // src/api/cherry/api.ts
968
+ import { Client } from "@modelcontextprotocol/sdk/client";
969
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
970
+ import { uuidv7 } from "zod/v4";
971
+ var CherryClient = class {
972
+ config;
973
+ logger;
974
+ mcpServers;
975
+ mcpClients;
976
+ constructor(config3, logger2) {
977
+ this.config = config3;
978
+ this.logger = logger2;
979
+ this.mcpServers = {};
980
+ this.mcpClients = {};
981
+ }
982
+ async listMcpServer() {
983
+ this.logger.info(`Fetching list of MCP servers(http://${this.config.host}:${this.config.port}/v1/mcps)`);
984
+ const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps`, {
985
+ method: "GET",
986
+ headers: {
987
+ Authorization: `Bearer ${this.config.apiKey}`
988
+ }
989
+ });
990
+ const data = await res.json();
991
+ return data;
992
+ }
993
+ async getMcpServerInfo(request2) {
994
+ const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps/${request2.serverId}`, {
995
+ method: "GET",
996
+ headers: {
997
+ Authorization: `Bearer ${this.config.apiKey}`
998
+ }
999
+ });
1000
+ const data = await res.json();
1001
+ return data;
1002
+ }
1003
+ async callTool(request2) {
1004
+ let mcpClient = this.mcpClients[request2.serverId];
1005
+ if (mcpClient == null) {
1006
+ const transport = new StreamableHTTPClientTransport(
1007
+ new URL(`http://${this.config.host}:${this.config.port}/v1/mcps/${request2.serverId}/mcp`),
1008
+ { requestInit: { headers: { Authorization: `Bearer ${this.config.apiKey}` } }, sessionId: uuidv7().toString() }
1009
+ );
1010
+ const client = new Client({
1011
+ name: "oss-mcp-client",
1012
+ version: "1.0.0"
1013
+ }, {});
1014
+ this.logger.info("Connecting to MCP server...");
1015
+ await transport.start();
1016
+ await client.connect(transport);
1017
+ mcpClient = new McpClient(client, this.logger);
1018
+ }
1019
+ try {
1020
+ return await mcpClient.CallTool(request2);
1021
+ } catch (err) {
1022
+ this.logger.error("CallTool failed: %s", err instanceof Error ? err.message : String(err));
1023
+ throw err;
1024
+ }
1025
+ }
1026
+ };
1027
+
879
1028
  // src/server.ts
880
1029
  var Logger = {
881
1030
  log: (...args) => {
@@ -1049,11 +1198,14 @@ ${diff}${"`".repeat(numBackticks)}
1049
1198
  var OssMcpServer = class _OssMcpServer {
1050
1199
  server;
1051
1200
  sseTransport = null;
1201
+ cherryClient = null;
1202
+ static DEFAULT_CATEGORIES = ["\u53D1\u7968", "\u94F6\u884C\u6D41\u6C34", "\u9280\u884C\u8A62\u8B49\u51FD", "\u5408\u540C", "\u516C\u53F8\u57FA\u672C\u8CC7\u6599", "\u4E2A\u4EBA\u4FE1\u606F", "\u5176\u4ED6"];
1203
+ static CLASSIFY_SERVER_ID;
1052
1204
  constructor() {
1053
1205
  this.server = new McpServer(
1054
1206
  {
1055
1207
  name: "onestep/filesystem-oss-mcp",
1056
- version: "1.2.5"
1208
+ version: "1.2.7"
1057
1209
  },
1058
1210
  // 使用正确格式的capabilities配置
1059
1211
  {
@@ -1115,8 +1267,72 @@ var OssMcpServer = class _OssMcpServer {
1115
1267
  static async create() {
1116
1268
  const instance = new _OssMcpServer();
1117
1269
  await instance.registerTools();
1270
+ setTimeout(async () => {
1271
+ const config3 = (await ConfigManager.getInstance()).getApiConfig();
1272
+ instance.cherryClient = new CherryClient(config3, logger);
1273
+ instance.cherryClient.listMcpServer();
1274
+ }, 5e3);
1118
1275
  return instance;
1119
1276
  }
1277
+ async read_any_file(path3) {
1278
+ if (!path3) {
1279
+ throw new Error(`Invalid arguments for read_file: ${path3}`);
1280
+ }
1281
+ let temPcontent = "";
1282
+ if (path3.startsWith("http")) {
1283
+ const recResult = await recFilesWithPull([path3]);
1284
+ if (recResult.code === 200) {
1285
+ temPcontent = recResult.data;
1286
+ return {
1287
+ content: [{ type: "text", text: temPcontent }]
1288
+ };
1289
+ } else {
1290
+ logger.error(`read file ${path3} Error:`, recResult.msg);
1291
+ throw new Error(`Server returned an error `);
1292
+ }
1293
+ }
1294
+ const validPath = await validatePath(path3);
1295
+ const fileExtension = fpath2.extname(validPath).toUpperCase();
1296
+ if (TextDocType.isTextDocType(fileExtension)) {
1297
+ temPcontent = await readFile(validPath, "utf-8");
1298
+ } else {
1299
+ const result = await this.aliOssUpload(validPath);
1300
+ if (result.isError) {
1301
+ console.error(`[aliOssUpload] Server returned an error`);
1302
+ if (result.content && result.content.length > 0) {
1303
+ result.content.forEach((contentItem) => {
1304
+ if (contentItem.type === "text") {
1305
+ console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);
1306
+ } else {
1307
+ console.error(`[aliOssUpload] Error detail item:`, contentItem);
1308
+ }
1309
+ });
1310
+ } else {
1311
+ console.error(`[aliOssUpload] Server returned an unspecified error.`);
1312
+ }
1313
+ throw new Error(`Server returned an error `);
1314
+ } else if (result.content && result.content.length > 0) {
1315
+ console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);
1316
+ const ossFile = JSON.parse(result.content[0].text);
1317
+ if (ossFile.code === 0) {
1318
+ const recResult = await recFilesWithPull([ossFile.url]);
1319
+ if (recResult.code === 200) {
1320
+ temPcontent = recResult.data;
1321
+ } else {
1322
+ console.error(`read file ${validPath} Error:`, recResult.msg);
1323
+ }
1324
+ } else {
1325
+ console.error(`upload file ${validPath} Error:`, ossFile.msg);
1326
+ }
1327
+ } else {
1328
+ console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);
1329
+ throw new Error(`Server returned an error `);
1330
+ }
1331
+ }
1332
+ return {
1333
+ content: [{ type: "text", text: temPcontent }]
1334
+ };
1335
+ }
1120
1336
  async registerTools() {
1121
1337
  logger.info("\u83B7\u53D6\u6240\u6709OSS\u914D\u7F6E...");
1122
1338
  const configs = await ossService.getConfigs();
@@ -1180,63 +1396,7 @@ ${configNames2.map((name) => `- ${name}`).join("\n")}`
1180
1396
  "\u8BFB\u53D6\u4EFB\u4F55\u6587\u4EF6\u5185\u5BB9",
1181
1397
  { path: z3.string().describe("\u6587\u4EF6\u8DEF\u5F84(\u53EF\u4EE5\u662F\u8FDC\u7A0Burl)") },
1182
1398
  async ({ path: path3 }) => {
1183
- if (!path3) {
1184
- throw new Error(`Invalid arguments for read_file: ${path3}`);
1185
- }
1186
- let temPcontent = "";
1187
- if (path3.startsWith("http")) {
1188
- const recResult = await recFilesWithPull([path3]);
1189
- if (recResult.code === 200) {
1190
- temPcontent = recResult.data;
1191
- return {
1192
- content: [{ type: "text", text: temPcontent }]
1193
- };
1194
- } else {
1195
- logger.error(`read file ${path3} Error:`, recResult.msg);
1196
- throw new Error(`Server returned an error `);
1197
- }
1198
- }
1199
- const validPath = await validatePath(path3);
1200
- const fileExtension = fpath2.extname(validPath).toUpperCase();
1201
- if (TextDocType.isTextDocType(fileExtension)) {
1202
- temPcontent = await readFile(validPath, "utf-8");
1203
- } else {
1204
- const result = await this.aliOssUpload(validPath);
1205
- if (result.isError) {
1206
- console.error(`[aliOssUpload] Server returned an error`);
1207
- if (result.content && result.content.length > 0) {
1208
- result.content.forEach((contentItem) => {
1209
- if (contentItem.type === "text") {
1210
- console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);
1211
- } else {
1212
- console.error(`[aliOssUpload] Error detail item:`, contentItem);
1213
- }
1214
- });
1215
- } else {
1216
- console.error(`[aliOssUpload] Server returned an unspecified error.`);
1217
- }
1218
- throw new Error(`Server returned an error `);
1219
- } else if (result.content && result.content.length > 0) {
1220
- console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);
1221
- const ossFile = JSON.parse(result.content[0].text);
1222
- if (ossFile.code === 0) {
1223
- const recResult = await recFilesWithPull([ossFile.url]);
1224
- if (recResult.code === 200) {
1225
- temPcontent = recResult.data;
1226
- } else {
1227
- console.error(`read file ${validPath} Error:`, recResult.msg);
1228
- }
1229
- } else {
1230
- console.error(`upload file ${validPath} Error:`, ossFile.msg);
1231
- }
1232
- } else {
1233
- console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);
1234
- throw new Error(`Server returned an error `);
1235
- }
1236
- }
1237
- return {
1238
- content: [{ type: "text", text: temPcontent }]
1239
- };
1399
+ return await this.read_any_file(path3);
1240
1400
  }
1241
1401
  );
1242
1402
  this.server.tool(
@@ -1251,9 +1411,9 @@ ${configNames2.map((name) => `- ${name}`).join("\n")}`
1251
1411
  paths.map(async (filePath) => {
1252
1412
  try {
1253
1413
  const validPath = await validatePath(filePath);
1254
- const content = await readFile(validPath, "utf-8");
1414
+ const response = await this.read_any_file(validPath);
1255
1415
  return `${filePath}:
1256
- ${content}
1416
+ ${response.content[0].text}
1257
1417
  `;
1258
1418
  } catch (error) {
1259
1419
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -1422,72 +1582,66 @@ ${ossService.getAllowedDirectories()?.join("\n")}`
1422
1582
  }
1423
1583
  );
1424
1584
  this.server.tool(
1425
- "classify_files_in_directory_by_file_content",
1426
- "\u6839\u636E\u6587\u4EF6\u5177\u4F53\u5185\u5BB9\u5BF9\u76EE\u5F55\u4E2D\u7684\u6587\u4EF6\u8FDB\u884C\u5206\u7C7B",
1585
+ "classify_files_in_directory",
1586
+ "\u5BF9\u76EE\u5F55\u4E2D\u7684\u6587\u4EF6\u8FDB\u884C\u5206\u7C7B",
1427
1587
  {
1428
1588
  originDirectory: z3.string().describe("Path to the directory to classify"),
1429
- newDirectory: z3.string().optional().describe("Path to the new directory after classification")
1589
+ categories: z3.array(z3.string()).optional().describe("categories for classification")
1430
1590
  },
1431
- async ({ originDirectory, newDirectory }) => {
1591
+ async ({ originDirectory, categories }) => {
1432
1592
  if (!originDirectory) {
1433
1593
  throw new Error(`Invalid arguments for classify_files_in_directory`);
1434
1594
  }
1595
+ if (!categories) {
1596
+ categories = _OssMcpServer.DEFAULT_CATEGORIES;
1597
+ }
1598
+ const newDirectory = await validatePath(originDirectory.split("/").slice(0, -1).join("_classified"));
1435
1599
  const files = await readdir(originDirectory, { withFileTypes: true, recursive: true });
1436
1600
  const resultMap = /* @__PURE__ */ new Map();
1601
+ const fileNamePathMap = /* @__PURE__ */ new Map();
1437
1602
  for (const file of files) {
1438
1603
  const filePath = fpath2.join(file.parentPath, file.name);
1439
1604
  if (file.isFile()) {
1440
- const result = await this.aliOssUpload(filePath);
1441
- if (result.isError) {
1442
- console.error(`[aliOssUpload] Server returned an error`);
1443
- if (result.content && result.content.length > 0) {
1444
- result.content.forEach((contentItem) => {
1445
- if (contentItem.type === "text") {
1446
- console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);
1447
- } else {
1448
- console.error(`[aliOssUpload] Error detail item:`, contentItem);
1449
- }
1450
- });
1451
- } else {
1452
- console.error(`[aliOssUpload] Server returned an unspecified error.`);
1453
- }
1454
- throw new Error(`Server returned an error `);
1455
- } else if (result.content && result.content.length > 0) {
1456
- console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);
1457
- const ossFile = JSON.parse(result.content[0].text);
1458
- if (ossFile.code === 0) {
1459
- const classifyResult = await classifyFiles(ossFile.url);
1460
- if (classifyResult.code === 200) {
1461
- console.log(`classify file ${filePath} Success:`, classifyResult.data);
1462
- const docType = DocType.nameContains(classifyResult.data);
1463
- if (resultMap.get(docType) != null) {
1464
- resultMap.get(docType)?.push(filePath);
1465
- } else {
1466
- resultMap.set(docType, [filePath]);
1467
- }
1605
+ fileNamePathMap.set(file.name, filePath);
1606
+ }
1607
+ }
1608
+ if (this.cherryClient?.config.enabled) {
1609
+ if (Object.keys(this.cherryClient.mcpServers).length == 0) {
1610
+ await this.cherryClient?.listMcpServer();
1611
+ }
1612
+ if (!_OssMcpServer.CLASSIFY_SERVER_ID) {
1613
+ _OssMcpServer.CLASSIFY_SERVER_ID = Object.values(this.cherryClient.mcpServers).find((server) => server.name.indexOf("onestep\u516C\u53F8\u8BA2\u5355") > -1)?.id || "";
1614
+ console.log(`[classify_files_in_directory] CLASSIFY_SERVER_ID: ${_OssMcpServer.CLASSIFY_SERVER_ID}`);
1615
+ }
1616
+ }
1617
+ const response = await this.cherryClient?.callTool({
1618
+ serverId: _OssMcpServer.CLASSIFY_SERVER_ID,
1619
+ method: "batchClassifyFileNames",
1620
+ data: { "fileNames": Array.from(fileNamePathMap.keys()), "categories": categories }
1621
+ });
1622
+ if (response?.isError) {
1623
+ throw new Error(`can't classify files`);
1624
+ } else {
1625
+ const classifiedJson = response?.content[0].text;
1626
+ const classifiedData = JSON.parse(classifiedJson);
1627
+ categories.forEach((category) => {
1628
+ mkdirSync(fpath2.join(newDirectory, category), { recursive: true });
1629
+ });
1630
+ classifiedData.classifiedByFileNames.forEach(async (item) => {
1631
+ Object.keys(item).forEach(async (key) => {
1632
+ const fileNames = item[key];
1633
+ fileNames.forEach(async (fileName) => {
1634
+ const newFilePath = fpath2.join(newDirectory, key, fileName);
1635
+ const fileArray = resultMap.get(key);
1636
+ if (fileArray) {
1637
+ fileArray.push(newFilePath);
1468
1638
  } else {
1469
- console.error(`classify file ${filePath} Error:`, classifyResult.msg);
1470
- return {
1471
- content: [{
1472
- type: "text",
1473
- text: `cannot classify file ${filePath} Error: ${classifyResult.msg}`
1474
- }]
1475
- };
1639
+ resultMap.set(key, [newFilePath]);
1476
1640
  }
1477
- } else {
1478
- console.error(`upload file ${filePath} Error:`, ossFile.msg);
1479
- return {
1480
- content: [{
1481
- type: "text",
1482
- text: `cannot classify file ${filePath} Error: ${ossFile.msg}`
1483
- }]
1484
- };
1485
- }
1486
- } else {
1487
- console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);
1488
- throw new Error(`Server returned an error `);
1489
- }
1490
- }
1641
+ await copyFile(fileNamePathMap.get(fileName), newFilePath);
1642
+ });
1643
+ });
1644
+ });
1491
1645
  }
1492
1646
  return {
1493
1647
  content: [{
@@ -1693,6 +1847,60 @@ ${JSON.stringify(convertResult)}`
1693
1847
  };
1694
1848
  }
1695
1849
  );
1850
+ this.server.tool(
1851
+ "convert_markdown_to_pdf",
1852
+ "markdown\u8F6C\u6362\u6210pdf\u6587\u4EF6",
1853
+ { path: z3.string().describe("\u6587\u4EF6\u8DEF\u5F84(\u53EF\u4EE5\u662F\u8FDC\u7A0Burl)") },
1854
+ async ({ path: path3 }) => {
1855
+ if (!path3) {
1856
+ throw new Error(`Invalid arguments for convert_markdown_to_pdf tool`);
1857
+ }
1858
+ let content = "";
1859
+ if (path3.startsWith("http")) {
1860
+ const resp = await this.read_any_file(path3);
1861
+ content = resp.content[0].text ?? "";
1862
+ } else {
1863
+ const validPath = await validatePath(path3);
1864
+ content = await readFile(validPath, "utf-8");
1865
+ }
1866
+ const buffer = Buffer.from(content, "utf-8");
1867
+ const base64String = buffer.toString("base64");
1868
+ const convertResult = await convertMarkdownToDoc(base64String, 1);
1869
+ return {
1870
+ content: [{
1871
+ type: "text",
1872
+ text: `${convertResult}`
1873
+ }]
1874
+ };
1875
+ }
1876
+ );
1877
+ this.server.tool(
1878
+ "convert_markdown_to_docx",
1879
+ "markdown\u8F6C\u6362\u6210docx\u6587\u4EF6",
1880
+ { path: z3.string().describe("\u6587\u4EF6\u8DEF\u5F84(\u53EF\u4EE5\u662F\u8FDC\u7A0Burl)") },
1881
+ async ({ path: path3 }) => {
1882
+ if (!path3) {
1883
+ throw new Error(`Invalid arguments for convert_markdown_to_docx tool`);
1884
+ }
1885
+ let content = "";
1886
+ if (path3.startsWith("http")) {
1887
+ const resp = await this.read_any_file(path3);
1888
+ content = resp.content[0].text ?? "";
1889
+ } else {
1890
+ const validPath = await validatePath(path3);
1891
+ content = await readFile(validPath, "utf-8");
1892
+ }
1893
+ const buffer = Buffer.from(content, "utf-8");
1894
+ const base64String = buffer.toString("base64");
1895
+ const convertResult = await convertMarkdownToDoc(base64String, 0);
1896
+ return {
1897
+ content: [{
1898
+ type: "text",
1899
+ text: `${convertResult}`
1900
+ }]
1901
+ };
1902
+ }
1903
+ );
1696
1904
  }
1697
1905
  async connect(transport) {
1698
1906
  try {