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 +369 -161
- package/dist/index.js.map +1 -1
- package/package.json +23 -23
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
"
|
|
1426
|
-
"\
|
|
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
|
-
|
|
1589
|
+
categories: z3.array(z3.string()).optional().describe("categories for classification")
|
|
1430
1590
|
},
|
|
1431
|
-
async ({ originDirectory,
|
|
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
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
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 {
|