file-system-with-oss-mcp 1.3.5 → 1.3.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
@@ -1169,7 +1169,7 @@ var OssMcpServer = class _OssMcpServer {
1169
1169
  this.server = new McpServer(
1170
1170
  {
1171
1171
  name: "onestep/filesystem-oss-mcp",
1172
- version: "1.3.5"
1172
+ version: "1.3.7"
1173
1173
  },
1174
1174
  // 使用正确格式的capabilities配置
1175
1175
  {
@@ -1618,7 +1618,7 @@ ${response.content[0].text}
1618
1618
  for (const file of files) {
1619
1619
  const filePath = fpath2.join(file.parentPath, file.name);
1620
1620
  if (file.isFile()) {
1621
- fileNamePathMap.set(file.name, filePath);
1621
+ fileNamePathMap.set(file.parentPath.replace(originDirectory, "") + "/" + file.name, file.name + "|||" + filePath);
1622
1622
  }
1623
1623
  }
1624
1624
  if (!_OssMcpServer.ONESTEP_MCP_SERVER_ID) {
@@ -1643,16 +1643,25 @@ ${response.content[0].text}
1643
1643
  for (const item of items) {
1644
1644
  for (const key of Object.keys(item)) {
1645
1645
  const fileNames = item[key];
1646
- for (const fileName of fileNames) {
1646
+ for (const fileNameAndParent of fileNames) {
1647
+ const nameAndPath = fileNamePathMap.get(fileNameAndParent).split("|||");
1648
+ const fileName = nameAndPath[0];
1649
+ const filePath = nameAndPath[1];
1647
1650
  const newFilePath = fpath2.join(newDirectory, key, fileName);
1648
1651
  const fileArray = resultMap.get(key);
1649
- if (fileArray) {
1650
- fileArray.push(newFilePath);
1651
- } else {
1652
- resultMap.set(key, [newFilePath]);
1653
- }
1654
1652
  if (copyFileToCategory) {
1655
- await copyFile(fileNamePathMap.get(fileName), newFilePath);
1653
+ if (fileArray) {
1654
+ fileArray.push(newFilePath);
1655
+ } else {
1656
+ resultMap.set(key, [newFilePath]);
1657
+ }
1658
+ await copyFile(filePath, newFilePath);
1659
+ } else {
1660
+ if (fileArray) {
1661
+ fileArray.push(filePath);
1662
+ } else {
1663
+ resultMap.set(key, [filePath]);
1664
+ }
1656
1665
  }
1657
1666
  }
1658
1667
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/services/oss.service.ts","../src/config/config.ts","../src/util/logger.ts","../src/util/aes.ts","../src/api/corp.ts","../src/config/auth/config.ts","../src/api/api.ts","../src/cache.ts","../src/types.ts","../src/api/cherry/client.ts","../src/api/cherry/api.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * 实现阿里云OSS文件上传功能。\r\n * - 上传文件到阿里云OSS\r\n * - 获取可用的OSS配置\r\n */\r\n\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport { OssMcpServer } from \"./server.js\";\r\nimport { getServerConfig } from \"./config/config.js\";\r\nimport { resolve } from \"path\";\r\nimport { config } from \"dotenv\";\r\nimport { OAuthCache } from \"./cache.js\";\r\nimport {logger} from \"./util/logger.js\";\r\n\r\n// 加载当前工作目录中的.env文件\r\nconfig({ path: resolve(process.cwd(), \".env\") });\r\n\r\nexport async function startServer(): Promise<void> {\r\n // 检查是否在stdio模式下运行\r\n const isStdioMode = process.env.NODE_ENV === \"cli\" || process.argv.includes(\"--stdio\");\r\n\r\n // 获取服务器配置\r\n const serverConfig = await getServerConfig(isStdioMode);\r\n // 创建OSS MCP服务器\r\n const server = await OssMcpServer.create();\r\n OAuthCache.getInstance().clear();\r\n \r\n if (isStdioMode) {\r\n // 在stdio模式下运行\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n } else {\r\n // 在HTTP模式下运行\r\n logger.info(`初始化OSS MCP服务器,HTTP模式,端口: ${serverConfig.port}...`);\r\n await server.startHttpServer(serverConfig.port);\r\n }\r\n}\r\n\r\n// 启动服务器\r\nstartServer().catch((error) => {\r\n logger.error(\"启动服务器失败:\", error);\r\n // 等待500毫秒后退出\r\n setTimeout(() => {\r\n process.exit(1);\r\n }, 500);\r\n});\r\n\r\n// setTimeout(async () => {\r\n// const callRec = async function (): Promise<any> {\r\n// const path = \"https://cdn.ionestep.com/NAR1%20ND2A.pdf\";\r\n\r\n// const recResult = await combineFiles([path,\"https://cdn.ionestep.com/3.pdf\",\"https://cdn.ionestep.com/4.pdf\"], \"https://cdn.ionestep.com/bb.png\");\r\n\r\n// console.log(\"recResult:\" + JSON.stringify(recResult));\r\n// }\r\n// await callRec();\r\n// }, 1000*10)","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\r\nimport { z } from \"zod\";\r\nimport { ossService } from \"./services/oss.service.js\";\r\nimport express, { Request, Response } from \"express\";\r\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\r\nimport { IncomingMessage, ServerResponse } from \"http\";\r\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\r\nimport fs, { mkdirSync } from \"fs\";\r\nimport {stat, realpath, readdir, readFile, writeFile, mkdir, rename, copyFile} from \"fs/promises\";\r\nimport {createTwoFilesPatch} from \"diff\";\r\nimport os from 'os';\r\nimport * as fpath from 'path';\r\nimport { minimatch } from 'minimatch';\r\nimport { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\r\nimport { combineFiles, convertMarkdownToDoc, convertPdfToDocxWithPull, convertPdfToMarkdownWithPull, recFilesWithPull, splitPdf } from \"./api/api.js\";\r\nimport { AliOssUploadResult, TextDocType } from \"./types.js\";\r\nimport { logger } from \"./util/logger.js\";\r\nimport { CallMcpToolRequest, CherryClient, ClassifiedResponseData, ExcelWorkbookMeta } from \"./api/cherry/api.js\";\r\nimport { ConfigManager } from \"./config/auth/config.js\";\r\n\r\nexport const Logger = {\r\n log: (...args: any[]) => {\r\n console.log(...args);\r\n },\r\n error: (...args: any[]) => {\r\n console.error(...args);\r\n }\r\n};\r\n\r\nfunction expandHome(filepath: string): string {\r\n if (filepath.startsWith('~/') || filepath === '~') {\r\n return fpath.join(os.homedir(), filepath.slice(1));\r\n }\r\n return filepath;\r\n}\r\n\r\n// Security utilities\r\nasync function validatePath(requestedPath: string): Promise<string> {\r\n const expandedPath = expandHome(requestedPath);\r\n let absolute = fpath.isAbsolute(expandedPath)\r\n ? fpath.resolve(expandedPath)\r\n : fpath.resolve(process.cwd(), expandedPath);\r\n\r\n\r\n // Handle symlinks by checking their real path\r\n try {\r\n const realPath = await realpath(absolute);\r\n return realPath;\r\n } catch (error) {\r\n // For new files that don't exist yet, verify parent directory\r\n const parentDir = fpath.dirname(absolute);\r\n try {\r\n await realpath(parentDir);\r\n return absolute;\r\n } catch {\r\n throw new Error(`Parent directory does not exist: ${parentDir}`);\r\n }\r\n }\r\n}\r\n\r\nconst EditOperation = z.object({\r\n oldText: z.string().describe('Text to search for - must match exactly'),\r\n newText: z.string().describe('Text to replace with')\r\n});\r\n\r\n\r\ninterface FileInfo {\r\n size: number;\r\n created: Date;\r\n modified: Date;\r\n accessed: Date;\r\n isDirectory: boolean;\r\n isFile: boolean;\r\n permissions: string;\r\n}\r\n// Tool implementations\r\nasync function getFileStats(filePath: string): Promise<FileInfo> {\r\n const stats = await stat(filePath);\r\n return {\r\n size: stats.size,\r\n created: stats.birthtime,\r\n modified: stats.mtime,\r\n accessed: stats.atime,\r\n isDirectory: stats.isDirectory(),\r\n isFile: stats.isFile(),\r\n permissions: stats.mode.toString(8).slice(-3),\r\n };\r\n}\r\n\r\nasync function searchFiles(\r\n rootPath: string,\r\n pattern: string,\r\n excludePatterns: string[] = []\r\n): Promise<string[]> {\r\n const results: string[] = [];\r\n\r\n async function search(currentPath: string) {\r\n const entries = await readdir(currentPath, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = fpath.join(currentPath, entry.name);\r\n\r\n try {\r\n // Validate each path before processing\r\n await validatePath(fullPath);\r\n\r\n // Check if path matches any exclude pattern\r\n const relativePath = fpath.relative(rootPath, fullPath);\r\n const shouldExclude = excludePatterns.some(pattern => {\r\n const globPattern = pattern.includes('*') ? pattern : `**/${pattern}/**`;\r\n return minimatch(relativePath, globPattern, { dot: true });\r\n });\r\n\r\n if (shouldExclude) {\r\n continue;\r\n }\r\n\r\n if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {\r\n results.push(fullPath);\r\n }\r\n\r\n if (entry.isDirectory()) {\r\n await search(fullPath);\r\n }\r\n } catch (error) {\r\n // Skip invalid paths during search\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n await search(rootPath);\r\n return results;\r\n}\r\n\r\n// file editing and diffing utilities\r\nfunction normalizeLineEndings(text: string): string {\r\n return text.replace(/\\r\\n/g, '\\n');\r\n}\r\n\r\nfunction createUnifiedDiff(originalContent: string, newContent: string, filepath: string = 'file'): string {\r\n // Ensure consistent line endings for diff\r\n const normalizedOriginal = normalizeLineEndings(originalContent);\r\n const normalizedNew = normalizeLineEndings(newContent);\r\n\r\n return createTwoFilesPatch(\r\n filepath,\r\n filepath,\r\n normalizedOriginal,\r\n normalizedNew,\r\n 'original',\r\n 'modified'\r\n );\r\n}\r\n\r\nasync function applyFileEdits(\r\n filePath: string,\r\n edits: Array<{oldText: string, newText: string}>,\r\n dryRun = false\r\n): Promise<string> {\r\n // Read file content and normalize line endings\r\n const content = normalizeLineEndings(await readFile(filePath, 'utf-8'));\r\n\r\n // Apply edits sequentially\r\n let modifiedContent = content;\r\n for (const edit of edits) {\r\n const normalizedOld = normalizeLineEndings(edit.oldText);\r\n const normalizedNew = normalizeLineEndings(edit.newText);\r\n\r\n // If exact match exists, use it\r\n if (modifiedContent.includes(normalizedOld)) {\r\n modifiedContent = modifiedContent.replace(normalizedOld, normalizedNew);\r\n continue;\r\n }\r\n\r\n // Otherwise, try line-by-line matching with flexibility for whitespace\r\n const oldLines = normalizedOld.split('\\n');\r\n const contentLines = modifiedContent.split('\\n');\r\n let matchFound = false;\r\n\r\n for (let i = 0; i <= contentLines.length - oldLines.length; i++) {\r\n const potentialMatch = contentLines.slice(i, i + oldLines.length);\r\n\r\n // Compare lines with normalized whitespace\r\n const isMatch = oldLines.every((oldLine, j) => {\r\n const contentLine = potentialMatch[j];\r\n return oldLine.trim() === contentLine.trim();\r\n });\r\n\r\n if (isMatch) {\r\n // Preserve original indentation of first line\r\n const originalIndent = contentLines[i].match(/^\\s*/)?.[0] || '';\r\n const newLines = normalizedNew.split('\\n').map((line, j) => {\r\n if (j === 0) return originalIndent + line.trimStart();\r\n // For subsequent lines, try to preserve relative indentation\r\n const oldIndent = oldLines[j]?.match(/^\\s*/)?.[0] || '';\r\n const newIndent = line.match(/^\\s*/)?.[0] || '';\r\n if (oldIndent && newIndent) {\r\n const relativeIndent = newIndent.length - oldIndent.length;\r\n return originalIndent + ' '.repeat(Math.max(0, relativeIndent)) + line.trimStart();\r\n }\r\n return line;\r\n });\r\n\r\n contentLines.splice(i, oldLines.length, ...newLines);\r\n modifiedContent = contentLines.join('\\n');\r\n matchFound = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!matchFound) {\r\n throw new Error(`Could not find exact match for edit:\\n${edit.oldText}`);\r\n }\r\n }\r\n\r\n // Create unified diff\r\n const diff = createUnifiedDiff(content, modifiedContent, filePath);\r\n\r\n // Format diff with appropriate number of backticks\r\n let numBackticks = 3;\r\n while (diff.includes('`'.repeat(numBackticks))) {\r\n numBackticks++;\r\n }\r\n const formattedDiff = `${'`'.repeat(numBackticks)}diff\\n${diff}${'`'.repeat(numBackticks)}\\n\\n`;\r\n\r\n if (!dryRun) {\r\n await writeFile(filePath, modifiedContent, 'utf-8');\r\n }\r\n\r\n return formattedDiff;\r\n}\r\nexport class OssMcpServer {\r\n private readonly server: McpServer;\r\n private sseTransport: SSEServerTransport | null = null;\r\n private cherryClient : CherryClient|null = null;\r\n private static DEFAULT_CATEGORIES = [\"发票\",\"银行流水\",\"銀行詢證函\",\"合同\",\"公司基本資料\",\"个人信息\",\"其他\"];\r\n private static ONESTEP_MCP_SERVER_ID:string;\r\n private static EXCEL_MCP_SERVER_ID:string;\r\n\r\n constructor() {\r\n this.server = new McpServer(\r\n {\r\n name: \"onestep/filesystem-oss-mcp\",\r\n version: \"1.3.5\",\r\n },\r\n // 使用正确格式的capabilities配置\r\n {\r\n capabilities: {\r\n tools: { listChanged: true },\r\n resources: { listChanged: true },\r\n prompts: { listChanged: true },\r\n logging: {}\r\n }\r\n }\r\n );\r\n }\r\n\r\n private async aliOssUpload(filePath: string, targetDir?: string, fileName?: string, configName?: string): Promise<CallToolResult> {\r\n try {\r\n logger.info(`准备上传: ${filePath} 到 ${targetDir || '根目录'}`);\r\n\r\n if (!filePath) {\r\n throw new Error(\"文件路径是必需的\");\r\n }\r\n\r\n // 检查文件是否存在\r\n if (!fs.existsSync(filePath)) {\r\n throw new Error(`文件不存在: ${filePath},请提供正确的文件路径`);\r\n }\r\n\r\n // 执行上传\r\n const result = await ossService.uploadFile({\r\n filePath,\r\n targetDir,\r\n fileName,\r\n configName\r\n });\r\n\r\n if (result.success) {\r\n logger.info(`上传成功: ${result.url}`);\r\n const response = {code:0, msg:\"文件上传成功!\", fileName:`${fpath.basename(filePath)}`, url: result.url}\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: JSON.stringify(response)\r\n }]\r\n };\r\n } else {\r\n logger.error(`上传失败: ${result.error}`);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `上传失败: ${result.error}`\r\n }]\r\n };\r\n }\r\n } catch (error) {\r\n logger.error(`上传过程中出错:`, error);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `上传出错: ${error}`\r\n }]\r\n };\r\n }\r\n }\r\n public async initCherryClient(): Promise<void> {\r\n if (!this.cherryClient) {\r\n const config = (await ConfigManager.getInstance()).getApiConfig();\r\n this.cherryClient = new CherryClient(config, logger);\r\n }\r\n \r\n try {\r\n await this.cherryClient.listMcpServer();\r\n } catch (error) {\r\n logger.error(`Failed to list MCP servers:`, error);\r\n }\r\n\r\n if (!OssMcpServer.ONESTEP_MCP_SERVER_ID) {\r\n OssMcpServer.ONESTEP_MCP_SERVER_ID = Object.values(this.cherryClient.mcpServers).find(server => server.name.indexOf(\"onestepOrder\") > -1)?.id || \"\";\r\n logger.info(`[classify_files_in_directory] ONESTEP_MCP_SERVER_ID: ${OssMcpServer.ONESTEP_MCP_SERVER_ID}`);\r\n }\r\n if (!OssMcpServer.EXCEL_MCP_SERVER_ID) {\r\n OssMcpServer.EXCEL_MCP_SERVER_ID = Object.values(this.cherryClient.mcpServers).find(server => server.name.indexOf(\"excel\") > -1)?.id || \"\";\r\n logger.info(`[classify_files_in_directory] EXCEL_MCP_SERVER_ID: ${OssMcpServer.EXCEL_MCP_SERVER_ID}`);\r\n }\r\n }\r\n\r\n // 工厂方法用于异步初始化\r\n public static async create(): Promise<OssMcpServer> {\r\n const instance = new OssMcpServer();\r\n await instance.registerTools();\r\n setTimeout(async () => {\r\n await instance.initCherryClient();\r\n }, 60000);\r\n\r\n return instance;\r\n }\r\n\r\n public async read_any_file(path:string): Promise<CallToolResult> {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for read_file: ${path}`);\r\n }\r\n \r\n let temPcontent = \"\";\r\n if (path.startsWith(\"http\")) {\r\n const recResult = await recFilesWithPull([path]);\r\n if(recResult.code === 200) {\r\n temPcontent = recResult.data;\r\n return {\r\n content: [{ type: \"text\", text: temPcontent }],\r\n };\r\n }else{\r\n logger.error(`read file ${path} Error:`, recResult.msg);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n const validPath = await validatePath(path);\r\n // 获取文件后缀\r\n const fileExtension = fpath.extname(validPath).toUpperCase();\r\n if(TextDocType.isTextDocType(fileExtension)){\r\n temPcontent = await readFile(validPath, \"utf-8\");\r\n }else if(fileExtension === \".XLSX\" || fileExtension === \".XLS\"){\r\n if(!OssMcpServer.EXCEL_MCP_SERVER_ID){\r\n await this.initCherryClient();\r\n }\r\n // step 1, 获取excel文件元数据\r\n const mcpResponse = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.EXCEL_MCP_SERVER_ID,\r\n method: \"get_workbook_metadata\",\r\n data: {\"filepath\": validPath} as Record<string, any>\r\n });\r\n if(mcpResponse?.isError) {\r\n throw new Error(`Server returned an error `);\r\n }\r\n logger.debug(`get_workbook_metadata response data:${mcpResponse?.content?.[0].text}`)\r\n const text = mcpResponse?.content?.[0].text as string;\r\n // Use Function to safely parse Python dict string representations that use single quotes\r\n const excelMeta = (text.includes(\"'\") ? new Function(\"return \" + text)() : JSON.parse(text)) as ExcelWorkbookMeta;\r\n \r\n // step 2, 读取excel文件内容\r\n logger.info(`excel_sheets.length:${excelMeta.sheets.length}`);\r\n if(excelMeta.sheets.length>0){\r\n const fileSize = excelMeta.size/1024/1024;\r\n logger.info(`excel_file_size:${fileSize}MB`);\r\n if(fileSize > 100){\r\n throw new Error(`文件太大,请不要直接读取。使用skills做统计分析`);\r\n }\r\n for (const sheet of excelMeta.sheets) {\r\n const mcpResponse2 = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.EXCEL_MCP_SERVER_ID,\r\n method: \"read_data_from_excel\",\r\n data: {\"filepath\": validPath, \"sheet_name\": sheet} as Record<string, any>\r\n });\r\n if(mcpResponse2?.isError) {\r\n throw new Error(`Server returned an error `);\r\n }\r\n const excelContent = JSON.stringify(mcpResponse2?.content?.[0].text);\r\n temPcontent += excelContent+\"\\n\"\r\n }\r\n // step 3, 如果内容多于500字符,保存成文本文件,返回文本文件路径\r\n if(temPcontent.length > 500){\r\n const tempFilePath = await this.saveTempFile(temPcontent);\r\n temPcontent = `文件内容过长,已保存到临时文件:${tempFilePath}`;\r\n }\r\n }else{\r\n temPcontent = ''\r\n }\r\n }else{\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n if(ossFile.code === 0) {\r\n const recResult = await recFilesWithPull([ossFile.url]);\r\n if(recResult.code === 200) {\r\n temPcontent = recResult.data;\r\n }else{\r\n console.error(`read file ${validPath} Error:`, recResult.msg);\r\n }\r\n }else{\r\n console.error(`upload file ${validPath} Error:`, ossFile.msg);\r\n }\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: temPcontent }],\r\n };\r\n }\r\n\r\n private async saveTempFile(content: string): Promise<string> {\r\n const tempDir = os.tmpdir();\r\n const tempFileName = `excel_content_${Date.now()}_${Math.random().toString(36).substring(2, 9)}.txt`;\r\n const tempFilePath = fpath.join(tempDir, tempFileName);\r\n await writeFile(tempFilePath, content, \"utf-8\");\r\n return tempFilePath;\r\n }\r\n\r\n private async registerTools(): Promise<void> {\r\n // 获取可用的OSS配置\r\n logger.info('获取所有OSS配置...');\r\n const configs = await ossService.getConfigs();\r\n const configNames = configs.map(config => config.id);\r\n\r\n // 工具:上传文件到OSS\r\n this.server.tool(\r\n \"upload_to_oss\",\r\n \"将文件上传到阿里云OSS\",\r\n {\r\n filePath: z.string().describe(\"要上传的本地文件路径\"),\r\n targetDir: z.string().optional().describe(\"OSS中的目标目录路径(可选)\"),\r\n fileName: z.string().optional().describe(\"上传后的文件名(可选,默认使用原文件名)\"),\r\n configName: z.string().optional().describe(`OSS配置名称(可选,默认为'default')。可用配置: ${configNames.join(', ') || '无'}`)\r\n },\r\n async ({ filePath, targetDir, fileName, configName }) => {\r\n if (!filePath) {\r\n throw new Error(`Invalid arguments for upload_to_oss: ${filePath}`);\r\n }\r\n if (!configName) {\r\n configName = 'default';\r\n }\r\n return await this.aliOssUpload(filePath, targetDir, fileName, configName);\r\n }\r\n );\r\n\r\n // 工具:列出可用的OSS配置\r\n this.server.tool(\r\n \"list_oss_configs\",\r\n \"列出可用的阿里云OSS配置\",\r\n {},\r\n async () => {\r\n try {\r\n const configs = await ossService.getConfigs();\r\n const configNames = configs.map(config => config.id);\r\n\r\n if (configNames.length === 0) {\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: \"未找到OSS配置。请检查环境变量设置。\"\r\n }]\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `可用的OSS配置:\\n${configNames.map(name => `- ${name}`).join('\\n')}`\r\n }]\r\n };\r\n } catch (error) {\r\n logger.error(`获取OSS配置列表时出错:`, error);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `获取配置列表失败: ${error}`\r\n }]\r\n };\r\n }\r\n }\r\n );\r\n // 工具:读取文件内容\r\n this.server.tool(\r\n \"read_any_file\",\r\n \"读取任何文件内容\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n return await this.read_any_file(path);\r\n }\r\n );\r\n // 工具:读取多个文件内容\r\n this.server.tool(\r\n \"read_multiple_files\",\r\n \"读取多个文件内容\",\r\n {paths: z.array(z.string()).describe(\"文件路径列表\")},\r\n async ({ paths }) => {\r\n\r\n if (!paths) {\r\n throw new Error(`Invalid arguments for read_multiple_files`);\r\n }\r\n const results = await Promise.all(\r\n paths.map(async (filePath: string) => {\r\n try {\r\n const validPath = await validatePath(filePath);\r\n const response = await this.read_any_file(validPath);\r\n return `${filePath}:\\n${response.content[0].text}\\n`;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n return `${filePath}: Error - ${errorMessage}`;\r\n }\r\n }),\r\n );\r\n return {\r\n content: [{ type: \"text\", text: results.join(\"\\n---\\n\") }],\r\n };\r\n }\r\n );\r\n // 工具:写入文件内容\r\n this.server.tool(\r\n \"write_file\",\r\n \"写入文件内容\",\r\n {path: z.string().describe(\"文件路径\"), content: z.string().describe(\"要写入的内容\")},\r\n async ({ path, content }) => {\r\n \r\n if (!path) {\r\n throw new Error(`Invalid arguments for write_file`);\r\n }\r\n const validPath = await validatePath(path);\r\n await writeFile(validPath,content, \"utf-8\");\r\n return {\r\n content: [{ type: \"text\", text: `Successfully wrote to ${path}` }],\r\n };\r\n }\r\n );\r\n // 工具:编辑文件内容\r\n this.server.tool(\r\n \"edit_file\",\r\n \"编辑文件内容\",\r\n {path: z.string().describe(\"文件路径\"), edits: z.array(EditOperation).describe(\"编辑操作列表\"), dryRun: z.boolean().default(false).describe('Preview changes using git-style diff format')},\r\n async ({ path, edits, dryRun }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for edit_file`);\r\n }\r\n const validPath = await validatePath(path);\r\n const result = await applyFileEdits(validPath, edits, dryRun);\r\n return {\r\n content: [{ type: \"text\", text: result }],\r\n };\r\n }\r\n );\r\n // 工具:创建目录\r\n this.server.tool(\r\n \"create_directory\",\r\n \"创建目录\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for create_directory`);\r\n }\r\n const validPath = await validatePath(path);\r\n await mkdir(validPath, { recursive: true });\r\n return {\r\n content: [{ type: \"text\", text: `Successfully created directory ${path}` }],\r\n };\r\n }\r\n );\r\n // 工具:列出目录内容\r\n this.server.tool(\r\n \"list_directory\",\r\n \"列出目录内容\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for list_directory`);\r\n }\r\n const validPath = await validatePath(path);\r\n const entries = await readdir(validPath, { withFileTypes: true });\r\n const formatted = entries\r\n .map((entry) => `${entry.isDirectory() ? \"[DIR]\" : \"[FILE]\"} ${entry.name}`)\r\n .join(\"\\n\");\r\n return {\r\n content: [{ type: \"text\", text: formatted }],\r\n };\r\n }\r\n );\r\n // 工具:移动文件\r\n this.server.tool(\r\n \"move_file\",\r\n \"移动文件\",\r\n {source: z.string().describe(\"源文件路径\"), destination: z.string().describe(\"目标文件路径\")},\r\n async ({ source, destination }) => {\r\n if (!source) {\r\n throw new Error(`Invalid arguments for move_file`);\r\n }\r\n const validSourcePath = await validatePath(source);\r\n const validDestPath = await validatePath(destination);\r\n await rename(validSourcePath, validDestPath);\r\n return {\r\n content: [{ type: \"text\", text: `Successfully moved ${source} to ${destination}` }],\r\n };\r\n }\r\n );\r\n // 工具:directory_tree\r\n this.server.tool(\r\n \"directory_tree\",\r\n \"列出目录树\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for directory_tree`);\r\n }\r\n\r\n interface TreeEntry {\r\n name: string;\r\n type: 'file' | 'directory';\r\n children?: TreeEntry[];\r\n }\r\n\r\n async function buildTree(currentPath: string): Promise<TreeEntry[]> {\r\n const validPath = await validatePath(currentPath);\r\n const entries = await readdir(validPath, {withFileTypes: true});\r\n const result: TreeEntry[] = [];\r\n\r\n for (const entry of entries) {\r\n const entryData: TreeEntry = {\r\n name: entry.name,\r\n type: entry.isDirectory() ? 'directory' : 'file'\r\n };\r\n\r\n if (entry.isDirectory()) {\r\n const subPath = fpath.join(currentPath, entry.name);\r\n entryData.children = await buildTree(subPath);\r\n }\r\n\r\n result.push(entryData);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n const treeData = await buildTree(path);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: JSON.stringify(treeData, null, 2)\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:搜索文件\r\n this.server.tool(\r\n \"search_files\",\r\n \"搜索文件\",\r\n {rootPath: z.string().describe(\"根目录路径\"), pattern: z.string().describe(\"搜索模式\"), excludePatterns: z.array(z.string()).default([]).describe(\"排除模式列表\")},\r\n async ({ rootPath, pattern, excludePatterns }) => {\r\n if (!rootPath) {\r\n throw new Error(`Invalid arguments for search_files`);\r\n }\r\n const validPath = await validatePath(rootPath);\r\n const results = await searchFiles(validPath, pattern, excludePatterns);\r\n return {\r\n content: [{ type: \"text\", text: results.length > 0 ? results.join(\"\\n\") : \"No matches found\" }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"get_file_info\",\r\n \"获取文件信息\",\r\n {path: z.string().describe(\"文件路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for get_file_info`);\r\n }\r\n const validPath = await validatePath(path);\r\n const info = await getFileStats(validPath);\r\n return {\r\n content: [{ type: \"text\", text: Object.entries(info)\r\n .map(([key, value]) => `${key}: ${value}`)\r\n .join(\"\\n\") }],\r\n };\r\n }\r\n );\r\n // 工具:classify_files_in_directory_by_file_content\r\n this.server.tool(\r\n \"classify_files_in_directory\",\r\n \"对目录中的文件进行分类,包含子目录里的文件\",\r\n {originDirectory: z.string().describe('Path to the directory to classify'),\r\n categories: z.array(z.string()).optional().describe('categories for classification'),\r\n copyFileToCategory: z.boolean().default(false).describe('是否将文件复制到分类目录')},\r\n async ({originDirectory, categories, copyFileToCategory }) => {\r\n if (!originDirectory) {\r\n throw new Error(`Invalid arguments for classify_files_in_directory`);\r\n }\r\n if(!categories){\r\n categories= OssMcpServer.DEFAULT_CATEGORIES;\r\n }\r\n const newDirectory = await validatePath(originDirectory.split('/').slice(0,-1).join('_classified'));\r\n const files = await readdir(originDirectory, { withFileTypes: true, recursive: true });\r\n const resultMap = new Map<string, string[]>();\r\n const fileNamePathMap = new Map<string, string>();\r\n for(const file of files) {\r\n const filePath = fpath.join(file.parentPath, file.name);\r\n if (file.isFile()) {\r\n fileNamePathMap.set(file.name, filePath);\r\n }\r\n }\r\n \r\n if(!OssMcpServer.ONESTEP_MCP_SERVER_ID){\r\n await this.initCherryClient();\r\n }\r\n const response = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.ONESTEP_MCP_SERVER_ID,\r\n method: \"batchClassifyFileNames\",\r\n data: {\"fileNames\": Array.from(fileNamePathMap.keys()), \"categories\":categories} as Record<string, any>\r\n } as CallMcpToolRequest);\r\n\r\n if(response?.isError){\r\n throw new Error(`can't classify files`);\r\n }else{\r\n const classifiedJson = response?.content[0].text as string;\r\n const classifiedData = (classifiedJson.includes(\"'\") ? new Function(\"return \" + classifiedJson)() : JSON.parse(classifiedJson)) as ClassifiedResponseData;\r\n if(copyFileToCategory){\r\n categories.forEach((category) => {\r\n mkdirSync(fpath.join(newDirectory, category), { recursive: true });\r\n });\r\n }\r\n \r\n const items = Array.isArray(classifiedData.classifiedByFileNames) \r\n ? classifiedData.classifiedByFileNames \r\n : [classifiedData.classifiedByFileNames];\r\n\r\n for (const item of items) {\r\n for (const key of Object.keys(item)) {\r\n const fileNames = item[key];\r\n for (const fileName of fileNames) {\r\n const newFilePath = fpath.join(newDirectory, key, fileName);\r\n const fileArray = resultMap.get(key);\r\n if (fileArray) {\r\n fileArray.push(newFilePath);\r\n } else {\r\n resultMap.set(key, [newFilePath]);\r\n }\r\n if(copyFileToCategory){\r\n await copyFile(fileNamePathMap.get(fileName) as string, newFilePath);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `classified files:\\n${JSON.stringify(Object.fromEntries(resultMap))}`\r\n }],\r\n };\r\n }\r\n );\r\n\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"split_pdf\",\r\n \"pdf拆分\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\"), splitPageNumbers: z.array(z.number()).describe(\"要拆分的页码列表\")},\r\n async ({ path, splitPageNumbers }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for split_pdf tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const splitResult = await splitPdf(tempUrl, splitPageNumbers);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `splitted files:\\n${JSON.stringify(splitResult)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"combine_files\",\r\n \"文件合并,支持图片或者pdf文件\",\r\n {filePaths: z.array(z.string()).describe(\"待合并的文件列表(可以是远程urls)\")},\r\n async ({ filePaths }) => {\r\n if (!filePaths) {\r\n throw new Error(`Invalid arguments for combine_files tool`);\r\n }\r\n \r\n let tempUrls: string[] = [];\r\n for(const filePath of filePaths) {\r\n const fileExtension = fpath.extname(filePath).toUpperCase();\r\n if (fileExtension !== '.PDF' && fileExtension !== '.PNG' && fileExtension !== '.JPG' && fileExtension !== '.JPEG') {\r\n throw new Error(`Invalid file extension for ${filePath}. Only PDF, PNG, JPG, and JPEG files are supported.`);\r\n }\r\n if(filePath.startsWith(\"http\")){\r\n tempUrls.push(filePath);\r\n }else {\r\n const validPath = await validatePath(filePath);\r\n const result = await this.aliOssUpload(validPath);\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrls.push(ossFile.url);\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n }\r\n \r\n\r\n const combinedFile = await combineFiles(tempUrls, \"\" + new Date().getTime() + \"_combined.pdf\");\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `combined file:\\n${JSON.stringify(combinedFile)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"convert_pdf_to_docx\",\r\n \"pdf转换成docx文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for conver_pdf_to_docx tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const convertResult = await convertPdfToDocxWithPull(tempUrl);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `docx file url:\\n${JSON.stringify(convertResult)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容 markdown\r\n this.server.tool(\r\n \"convert_pdf_to_markdown\",\r\n \"pdf转换成markdown文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for conver_pdf_to_markdown tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const convertResult = await convertPdfToMarkdownWithPull(tempUrl);\r\n const buffer = Buffer.from(convertResult, 'base64');\r\n const decodedString = buffer.toString('utf-8');\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${decodedString}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:markdown 2 pdf\r\n this.server.tool(\r\n \"convert_markdown_to_pdf\",\r\n \"markdown转换成pdf文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for convert_markdown_to_pdf tool`);\r\n }\r\n\r\n let content = \"\"\r\n if(path.startsWith(\"http\")){\r\n const resp = await this.read_any_file(path);\r\n content = (resp.content[0].text as string)??\"\"\r\n }else {\r\n const validPath = await validatePath(path);\r\n content = await readFile(validPath,'utf-8');\r\n }\r\n\r\n // content 转换成 base64\r\n const buffer = Buffer.from(content, 'utf-8');\r\n const base64String = buffer.toString('base64');\r\n const convertResult = await convertMarkdownToDoc(base64String, 1);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${convertResult}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:markdown 2 docx\r\n this.server.tool(\r\n \"convert_markdown_to_docx\",\r\n \"markdown转换成docx文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for convert_markdown_to_docx tool`);\r\n }\r\n\r\n let content = \"\"\r\n if(path.startsWith(\"http\")){\r\n const resp = await this.read_any_file(path);\r\n content = (resp.content[0].text as string)??\"\"\r\n }else {\r\n const validPath = await validatePath(path);\r\n content = await readFile(validPath, 'utf-8');\r\n }\r\n\r\n // content 转换成 base64\r\n const buffer = Buffer.from(content, 'utf-8');\r\n const base64String = buffer.toString('base64');\r\n const convertResult = await convertMarkdownToDoc(base64String, 0);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${convertResult}`\r\n }],\r\n };\r\n }\r\n );\r\n}\r\n\r\n async connect(transport: Transport): Promise<void> {\r\n try {\r\n await this.server.connect(transport);\r\n \r\n Logger.log = (...args: any[]) => {\r\n try {\r\n this.server.server.sendLoggingMessage({\r\n level: \"info\",\r\n data: args,\r\n });\r\n } catch (error) {\r\n logger.info(args);\r\n }\r\n };\r\n\r\n Logger.error = (...args: any[]) => {\r\n try {\r\n this.server.server.sendLoggingMessage({\r\n level: \"error\",\r\n data: args,\r\n });\r\n } catch (error) {\r\n logger.error(args);\r\n }\r\n };\r\n\r\n logger.info(\"OSS MCP服务器已连接并准备处理请求\");\r\n } catch (error) {\r\n logger.error(\"连接到传输时出错:\", error);\r\n }\r\n }\r\n\r\n async startHttpServer(port: number): Promise<void> {\r\n const app = express();\r\n\r\n // SSE连接端点 - 修复头部发送冲突\r\n app.get(\"/sse\", (req: Request, res: Response) => {\r\n // 初始化SSE传输,不再自己设置头部,而是让SDK处理\r\n this.sseTransport = new SSEServerTransport(\r\n \"/messages\",\r\n res as unknown as ServerResponse<IncomingMessage>\r\n );\r\n\r\n try {\r\n // 连接到传输层\r\n this.server.connect(this.sseTransport)\r\n .catch((err) => {\r\n logger.error(\"连接到SSE传输时出错:\", err);\r\n });\r\n\r\n // 处理客户端断开连接\r\n req.on('close', () => {\r\n logger.info('SSE客户端断开连接');\r\n this.sseTransport = null;\r\n });\r\n } catch (error) {\r\n logger.error(\"建立SSE连接时出错:\", error);\r\n // 如果连接失败,关闭响应\r\n if (!res.writableEnded) {\r\n res.status(500).end();\r\n }\r\n }\r\n });\r\n\r\n // 消息端点\r\n app.post(\"/messages\", async (req: Request, res: Response) => {\r\n if (!this.sseTransport) {\r\n logger.info(\"尝试发送消息,但SSE传输未初始化\");\r\n res.status(400).json({\r\n error: 'SSE连接未建立',\r\n message: '请先连接到/sse端点'\r\n });\r\n return;\r\n }\r\n\r\n try {\r\n await this.sseTransport.handlePostMessage(\r\n req as unknown as IncomingMessage,\r\n res as unknown as ServerResponse<IncomingMessage>\r\n );\r\n } catch (error) {\r\n console.error(\"处理消息时出错:\", error);\r\n if (!res.writableEnded) {\r\n res.status(500).json({\r\n error: \"内部服务器错误\",\r\n message: String(error)\r\n });\r\n }\r\n }\r\n });\r\n\r\n // 启动服务器\r\n app.listen(port, () => {\r\n Logger.log = console.log;\r\n Logger.error = console.error;\r\n\r\n Logger.log(`HTTP服务器监听端口: ${port}`);\r\n Logger.log(`SSE端点: http://localhost:${port}/sse`);\r\n Logger.log(`消息端点: http://localhost:${port}/messages`);\r\n });\r\n }\r\n}\r\n\r\n","import OSS from 'ali-oss';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { OssConfig, getOssConfig, ServerConfig, getServerConfig } from '../config/config.js';\r\nimport { z } from 'zod';\r\n\r\n// 上传文件参数验证Schema\r\nexport const UploadFileParamsSchema = z.object({\r\n filePath: z.string(),\r\n targetDir: z.string().optional(),\r\n fileName: z.string().optional(),\r\n configName: z.string().optional(),\r\n});\r\n\r\n// 导出上传文件参数类型\r\nexport type UploadFileParams = z.infer<typeof UploadFileParamsSchema>;\r\n\r\n// 上传结果验证Schema\r\nexport const UploadResultSchema = z.object({\r\n success: z.boolean(),\r\n url: z.string().optional(),\r\n error: z.string().optional(),\r\n ossConfigName: z.string().optional(),\r\n});\r\n\r\n// 导出上传结果类型\r\nexport type UploadResult = z.infer<typeof UploadResultSchema>;\r\n\r\n/**\r\n * OSS配置接口(包含ID和名称)\r\n */\r\nexport interface OssConfigWithMeta extends OssConfig {\r\n id: string;\r\n name: string;\r\n}\r\n\r\n/**\r\n * 阿里云OSS服务类\r\n */\r\nexport class OssService {\r\n private clients: Map<string, OSS> = new Map();\r\n private serverConfig?: ServerConfig;\r\n /**\r\n * 获取所有OSS配置\r\n * @returns OSS配置列表\r\n */\r\n async getConfigs(): Promise<OssConfigWithMeta[]> {\r\n if(this.serverConfig == null){\r\n this.serverConfig = await getServerConfig();\r\n }\r\n\r\n const configs: OssConfigWithMeta[] = [];\r\n const allConfigs = this.serverConfig.ossConfig;\r\n\r\n for (const [id, config] of Object.entries(allConfigs)) {\r\n configs.push({\r\n id,\r\n name: `${id.charAt(0).toUpperCase()}${id.slice(1)} 配置`,\r\n ...config\r\n });\r\n }\r\n\r\n return configs;\r\n }\r\n\r\n /**\r\n * 获取OSS客户端\r\n * @param configName 配置名称\r\n * @returns OSS客户端实例\r\n */\r\n private async getClient(configName: string = 'default'): Promise<OSS | null> {\r\n // 检查缓存中是否已有客户端\r\n if (this.clients.has(configName)) {\r\n return this.clients.get(configName) as OSS;\r\n }\r\n\r\n // 获取配置并创建客户端\r\n const config = await getOssConfig(configName);\r\n if (!config) {\r\n return null;\r\n }\r\n\r\n try {\r\n const client = new OSS({\r\n region: config.region,\r\n accessKeyId: config.accessKeyId,\r\n accessKeySecret: config.accessKeySecret,\r\n bucket: config.bucket,\r\n endpoint: config.endpoint\r\n });\r\n\r\n // 缓存客户端实例\r\n this.clients.set(configName, client);\r\n return client;\r\n } catch (error) {\r\n console.error(`Failed to create OSS client for ${configName}:`, error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * 上传文件到OSS\r\n * @param params 上传参数\r\n * @returns 上传结果\r\n */\r\n async uploadFile(params: UploadFileParams): Promise<UploadResult> {\r\n // 验证并解析参数\r\n const validParams = UploadFileParamsSchema.parse(params);\r\n const { filePath, targetDir = 'mcp', fileName, configName = 'default' } = validParams;\r\n\r\n try {\r\n // 检查文件是否存在\r\n if (!fs.existsSync(filePath)) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `File not found: ${filePath}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n\r\n // 获取OSS客户端\r\n const client = await this.getClient(configName);\r\n if (!client) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `OSS config not found for: ${configName}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n\r\n // 确定文件名\r\n const actualFileName = fileName || path.basename(filePath);\r\n\r\n // 构建OSS路径,确保正斜杠格式\r\n let ossPath = actualFileName;\r\n if (targetDir) {\r\n // 规范化目标目录:移除头尾斜杠,然后加上结尾斜杠\r\n const normalizedDir = targetDir.replace(/^\\/+|\\/+$/g, '');\r\n ossPath = normalizedDir ? `${normalizedDir}/${actualFileName}` : actualFileName;\r\n }\r\n\r\n // 上传文件\r\n const result = await client.put(ossPath, filePath);\r\n const config = await getOssConfig(configName);\r\n return UploadResultSchema.parse({\r\n success: true,\r\n url: result.url.replace(/https?:\\/\\/[^/]+/, config!.cdnHost!), //替换域名为CDN域名\r\n ossConfigName: configName\r\n });\r\n } catch (error) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `Upload failed: ${(error as Error).message}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n }\r\n}\r\n\r\n// 导出单例实例\r\nexport const ossService = new OssService();\r\n","import { config } from \"dotenv\";\r\nimport { z } from \"zod\";\r\nimport { logger } from \"../util/logger.js\";\r\nimport { decrypt } from \"../util/aes.js\";\r\nimport { NewApiUser } from \"../types.js\";\r\nimport { getUserSetting } from \"../api/corp.js\";\r\nimport { ConfigManager } from \"./auth/config.js\";\r\nimport * as fpath from 'path';\r\nimport os from 'os';\r\nimport {stat} from \"fs/promises\";\r\nimport { Config } from \"../api/cherry/api.js\";\r\nconfig();\r\n\r\n// OSS配置验证Schema\r\nexport const OssConfigSchema = z.object({\r\n region: z.string(),\r\n accessKeyId: z.string(),\r\n accessKeySecret: z.string(),\r\n bucket: z.string(),\r\n endpoint: z.string(),\r\n cdnHost: z.string()\r\n});\r\n\r\n// 导出OSS配置类型\r\nexport type OssConfig = z.infer<typeof OssConfigSchema>;\r\n\r\n// 服务器配置接口\r\nexport interface ServerConfig {\r\n port: number;\r\n ossConfig: Record<string, OssConfig>;\r\n configSources: {\r\n port: \"cli\" | \"env\" | \"default\";\r\n ossConfig: \"cli\" | \"env\" | \"default\";\r\n };\r\n newApiAuthData: string;\r\n}\r\nfunction expandHome(filepath: string): string {\r\n if (filepath.startsWith('~/') || filepath === '~') {\r\n return fpath.join(os.homedir(), filepath.slice(1));\r\n }\r\n return filepath;\r\n}\r\nfunction normalizePath(p: string): string {\r\n return fpath.normalize(p);\r\n}\r\n// 获取服务器配置\r\nexport async function getServerConfig(isStdioMode: boolean = false): Promise<ServerConfig> {\r\n // 解析命令行参数\r\n logger.info(\"正在加载服务器配置...\");\r\n const newApiAuthData = process.argv.find(arg => arg.startsWith(\"--newApiAuthData=\"));\r\n if (!newApiAuthData) {\r\n logger.error('newApiAuthData argv variable is not set');\r\n throw new Error(\"newApiAuthData environment variable is not set\");\r\n }\r\n\r\n const apiServer = process.argv.find(arg => arg.startsWith(\"--apiServer=\"));\r\n if (!apiServer) {\r\n logger.error('apiServer argv variable is not set');\r\n throw new Error(\"apiServer environment variable is not set\");\r\n }\r\n\r\n const config: ServerConfig = {\r\n port: 3000,\r\n ossConfig: {},\r\n configSources: {\r\n port: \"default\",\r\n ossConfig: \"default\",\r\n },\r\n newApiAuthData: \"\"\r\n };\r\n\r\n // 处理端口配置\r\n config.configSources.port = \"cli\";\r\n\r\n // base64 decode data\r\n let newApiAuthDataRaw = newApiAuthData.substring(\"--newApiAuthData=\".length).trim();\r\n newApiAuthDataRaw = newApiAuthDataRaw.replace(/^['\"`\\\\]+|['\"`\\\\]+$/g, '').trim();\r\n const newApiAuthDataString = Buffer.from(newApiAuthDataRaw, 'base64').toString('utf8');\r\n const newApiAuthDataArry = newApiAuthDataString.split(\"變\");\r\n if (newApiAuthDataArry.length !== 2) {\r\n logger.error('NEW_API_AUTH_DATA environment variable is not set');\r\n throw new Error(\"NEW_API_AUTH_DATA environment variable is not set\");\r\n }\r\n\r\n const newApiAuthDataDecrypt = decrypt(newApiAuthDataArry[0],newApiAuthDataArry[1], \"1234567890123abc7890123456OAcl12\").replace(\"\u0006\",\"\");\r\n const newApiUser = JSON.parse(newApiAuthDataDecrypt) as NewApiUser;\r\n const userSetting = await getUserSetting({serverUrl: newApiUser.newApiServerUrl, accessToken: newApiUser.newApiAccessToken, userId: newApiUser.newApiUserId});\r\n const allOssConfigs = {\"default\":{region: \"cn-hongkong\", accessKeyId: userSetting.accessKeyId, accessKeySecret: userSetting.accessKeySecret, bucket: userSetting.bucketName, endpoint: userSetting.endpoint, cdnHost: userSetting.cdnHost}}\r\n config.ossConfig = allOssConfigs;\r\n config.configSources.ossConfig = \"cli\";\r\n \r\n let apiServerRaw = apiServer.substring(\"--apiServer=\".length).trim();\r\n // 去除可能包含的引号、反引号或反斜杠\r\n apiServerRaw = apiServerRaw.replace(/^['\"`\\\\]+|['\"`\\\\]+$/g, '').trim();\r\n \r\n let apiServerConfig: Config;\r\n try {\r\n if (apiServerRaw.startsWith(\"http\")) {\r\n const url = new URL(apiServerRaw);\r\n apiServerConfig = {\r\n enabled: true,\r\n host: url.hostname,\r\n port: url.port ? parseInt(url.port) : (url.protocol === 'https:' ? 443 : 80),\r\n apiKey: \"\"\r\n };\r\n } else {\r\n let apiServerDataString = apiServerRaw;\r\n if (!apiServerDataString.startsWith(\"{\")) {\r\n apiServerDataString = Buffer.from(apiServerDataString, 'base64').toString('utf8');\r\n }\r\n apiServerConfig = JSON.parse(apiServerDataString) as Config;\r\n }\r\n } catch (e) {\r\n logger.error(`解析 apiServer 配置失败: ${e}`);\r\n throw new Error(\"Invalid apiServer configuration format. It should be a base64 encoded JSON string or a valid URL.\");\r\n }\r\n\r\n // 创建配置管理器\r\n await ConfigManager.init(newApiUser, userSetting, apiServerConfig);\r\n\r\n\r\n // 验证配置\r\n if (Object.keys(config.ossConfig).length === 0) {\r\n logger.warn(\"未找到有效的OSS配置。服务器将启动,但上传功能将不可用。\");\r\n }\r\n\r\n // 打印配置信息(非stdio模式下)\r\n if (!isStdioMode) {\r\n logger.info(\"配置信息:\");\r\n logger.info(JSON.stringify(config));\r\n }\r\n\r\n return config;\r\n}\r\n\r\n// 获取所有OSS配置\r\n async function getAllOssConfigs(): Promise<Record<string, OssConfig>> {\r\n const { ossConfig, } = await getServerConfig(true);\r\n \r\n return ossConfig;\r\n}\r\n\r\n// 获取特定名称的OSS配置\r\nexport async function getOssConfig(name: string = 'default'): Promise<OssConfig | null> {\r\n const configs = await getAllOssConfigs();\r\n const normalizedName = name.toLowerCase();\r\n return configs[normalizedName] || null;\r\n}\r\n\r\n// 获取可用的OSS配置名称列表\r\nexport async function getAvailableOssConfigNames(): Promise<string[]> {\r\n return Object.keys(await getAllOssConfigs());\r\n}\r\n","import winston from 'winston';\r\nimport 'winston-daily-rotate-file';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\n\r\n// Create logs directory if it doesn't exist\r\nconst logsDir = path.join(process.cwd(), 'logs');\r\nif (!fs.existsSync(logsDir)) {\r\n fs.mkdirSync(logsDir, { recursive: true });\r\n}\r\n\r\n// Configure Winston logger\r\nexport const logger = winston.createLogger({\r\n level: 'debug',\r\n format: winston.format.combine(\r\n winston.format.timestamp({\r\n format: 'YYYY-MM-DD HH:mm:ss.SSS'\r\n }),\r\n winston.format.errors({ stack: true }),\r\n winston.format.splat(),\r\n winston.format.json()\r\n ),\r\n defaultMeta: { service: 'mcp-oss' },\r\n transports: [\r\n // Write to rotating log files only to avoid interfering with MCP protocol\r\n new winston.transports.DailyRotateFile({\r\n filename: path.join(logsDir, 'mcp-oss-%DATE%.log'),\r\n datePattern: 'YYYY-MM-DD',\r\n zippedArchive: true,\r\n maxSize: '20m',\r\n maxFiles: '14d',\r\n format: winston.format.combine(\r\n winston.format.timestamp(),\r\n winston.format.json()\r\n )\r\n })\r\n ]\r\n});\r\n\r\n// Log unhandled errors\r\nprocess.on('uncaughtException', (error) => {\r\n logger.error('Uncaught Exception:', error);\r\n process.exit(1);\r\n});\r\n\r\nprocess.on('unhandledRejection', (error) => {\r\n logger.error('Unhandled Rejection:', error);\r\n});\r\n","import * as crypto from 'crypto'\r\n\r\n// 加密函数\r\nexport function encrypt(text: string, secretKey: string, iv: string): { iv: string; encryptedData: string } {\r\n const _iv = Buffer.from(iv, 'hex')\r\n const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secretKey), _iv)\r\n let encrypted = cipher.update(text, 'utf8', 'hex')\r\n encrypted += cipher.final('hex')\r\n return {\r\n iv: _iv.toString('hex'),\r\n encryptedData: encrypted\r\n }\r\n}\r\n\r\n// 解密函数\r\nexport function decrypt(encryptedData: string, iv: string, secretKey: string): string {\r\n const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(secretKey), Buffer.from(iv, 'hex'))\r\n let decrypted = decipher.update(encryptedData, 'hex', 'utf8')\r\n decrypted += decipher.final('utf8')\r\n return decrypted\r\n}\r\n","export interface UserSetting{\n\tonestepHost:string;\n\tappId :string ;\n\tclientId :string ;\n\tapiKey :string ;\n\tsecretKey :string ;\n\tversion :string ;\n\t\n\t//ticket system\n\tticketHost :string ;\n\tticketApiKey :string ;\n\tuserId :number ;\n\t// alioss\n\tendpoint :string ;\n\taccessKeyId :string ;\n\taccessKeySecret :string ;\n\tbucketName :string ;\n\tcdnHost :string ;\n}\nexport const getAiApiToken = async ({\n serverUrl,\n accessToken,\n userId\n}: {\n serverUrl: string\n accessToken: string\n userId: string\n}): Promise<string> => {\n // fetch 实现登录功能\n const res = await fetch(`${serverUrl}/api/token?p=1&size=1`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'new-api-user': userId\n }\n })\n const data = await res.json()\n if (data.success) {\n return 'sk-' + data.data.items[0].key\n } else {\n throw new Error(data.msg)\n }\n}\n\nexport const getUserSetting = async ({\n serverUrl,\n accessToken,\n userId\n}: {\n serverUrl: string\n accessToken: string\n userId: string\n}): Promise<UserSetting> => {\n // fetch 实现登录功能\n const res = await fetch(`${serverUrl}/api/user/setting`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'new-api-user': userId\n }\n })\n\n const data = (await res.json()).data as UserSetting\n return data;\n}","import { Config } from '../../api/cherry/api.js';\r\nimport { UserSetting } from '../../api/corp.js';\r\nimport { NewApiUser, OAuthConfig } from '../../types.js';\r\nimport { logger } from '../../util/logger.js';\r\n\r\nexport class ConfigManager {\r\n private static instance: ConfigManager;\r\n private static onestepClients: Record<string, string> = {\"saber\": \"saber_secret\", \"onestep_user\": \"ewkej3243242\"};\r\n private oAuthConfig: OAuthConfig;\r\n private newApiUser : NewApiUser;\r\n private apiConfig: Config;\r\n private constructor() {\r\n this.oAuthConfig= {} as OAuthConfig;\r\n this.newApiUser = {} as NewApiUser;\r\n this.apiConfig = {} as Config;\r\n }\r\n\r\n public static async getInstance(): Promise<ConfigManager> {\r\n if (!ConfigManager.instance) {\r\n throw new Error(\"the instance is not created\");\r\n }\r\n\r\n return ConfigManager.instance;\r\n }\r\n public static async init(newApiUser : NewApiUser, userSetting:UserSetting, apiConfig: Config): Promise<ConfigManager> {\r\n if (!ConfigManager.instance) {\r\n ConfigManager.instance = new ConfigManager();\r\n await ConfigManager.instance.loadConfig(userSetting);\r\n ConfigManager.instance.newApiUser = newApiUser;\r\n ConfigManager.instance.apiConfig = apiConfig;\r\n }\r\n\r\n return ConfigManager.instance;\r\n }\r\n\r\n private async loadConfig(userSetting:UserSetting): Promise<void> {\r\n // Try environment variables first\r\n const envConfig = {\r\n apiKey: process.env.OAUTH_API_KEY,\r\n secretKey: process.env.OAUTH_SECRET_KEY,\r\n host: process.env.OAUTH_HOST,\r\n appId : \"client003\",\r\n basicAuth :\"c2FiZXI6c2FiZXJfc2VjcmV0\",\r\n version :\"1.0\"\r\n };\r\n \r\n // Otherwise, try to load from config file\r\n try {\r\n // If all required env vars are present, use them\r\n if (envConfig.apiKey && envConfig.secretKey && envConfig.host) {\r\n this.oAuthConfig = envConfig as OAuthConfig;\r\n logger.info('Using environment variables for configuration.');\r\n }else if(userSetting.apiKey && userSetting.secretKey && userSetting.onestepHost){\r\n const clientId = userSetting.clientId;\r\n const clientSecret = ConfigManager.onestepClients[clientId];\r\n this.oAuthConfig = {apiKey:userSetting.apiKey,\r\n secretKey:userSetting.secretKey,\r\n host:userSetting.onestepHost,\r\n appId:userSetting.appId,\r\n basicAuth: btoa(`${clientId}:${clientSecret}`),\r\n version:userSetting.version}\r\n }else{\r\n throw new Error('Missing oAuthConfig.');\r\n }\r\n } catch (error) {\r\n throw new Error(`Failed to load configuration. ${error}`);\r\n }\r\n }\r\n\r\n public getOAuthConfig(): OAuthConfig {\r\n return this.oAuthConfig;\r\n }\r\n public getNewApiUser(): NewApiUser {\r\n return this.newApiUser;\r\n }\r\n public getApiConfig(): Config {\r\n return this.apiConfig;\r\n }\r\n}","import { request, RequestOptions } from \"https\";\r\nimport { IncomingMessage } from \"http\";\r\nimport {LoginResponse } from '../types.js';\r\nimport { OAuthCache } from '../cache.js';\r\nimport { ConfigManager } from '../config/auth/config.js';\r\nimport { logger } from \"../util/logger.js\";\r\nexport const thirdparyLogin = async (\r\n grantType: string\r\n): Promise<LoginResponse> => {\r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n \r\n // Check cache first\r\n const cache = OAuthCache.getInstance();\r\n const cacheKey = `${config.apiKey}_${config.secretKey}`;\r\n const cachedData = cache.get(cacheKey);\r\n\r\n if (cachedData) {\r\n return {\r\n code: 200,\r\n msg: \"Success (from cache)\",\r\n data: cachedData\r\n };\r\n }\r\n\r\n const postData = JSON.stringify({ \r\n grantType, \r\n apiKey: config.apiKey, \r\n secretKey: config.secretKey \r\n });\r\n \r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'Authorization':`Basic ${config.basicAuth}`\r\n },\r\n };\r\n\r\n return new Promise((resolve, reject) => {\r\n const req = request(config.host + '/api/onestep-ess/thirdparty/oauth/1.0/token', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n try {\r\n const parsedResponse: LoginResponse = JSON.parse(responseBody);\r\n if (parsedResponse.code === 200 && parsedResponse.data) {\r\n // Store in cache if login successful\r\n cache.set(cacheKey, parsedResponse.data);\r\n resolve(parsedResponse);\r\n }else{\r\n reject(\"Login failed, response:\"+JSON.stringify(parsedResponse));\r\n }\r\n } catch (error) {\r\n reject(new Error(`Failed to parse response: ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(5000);\r\n req.write(postData);\r\n req.end();\r\n });\r\n};\r\n\r\ninterface ClassifyFilesResponse {\r\n code: number;\r\n msg: string;\r\n data:string;\r\n}\r\nexport const classifyFiles = async (\r\n fileUrl: string\r\n): Promise<ClassifyFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n const postData = JSON.stringify({ \r\n fileUrl, \r\n splitPdf: 0, \r\n trimPage: 0,\r\n provider: \"dify\"\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n console.log(\"classifyFiles request:\", JSON.stringify(options));\r\n const req = request(config.host + '/api/onestep-jod/docs2png/classifyFile', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n resolve(JSON.parse(responseBody));\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*120);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\ninterface RecFilesResponse {\r\n code: number;\r\n msg: string;\r\n status:number\r\n data:string;\r\n}\r\n\r\nexport const recFilesWithPull = async (\r\n fileUrls: string[],\r\n): Promise<RecFilesResponse> => {\r\n const response = await recFiles(fileUrls);\r\n if(response.code === 200 && response.status == 0){\r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n logger.info(\"recall recFiles response:\", response);\r\n return await recFilesWithPull(fileUrls);\r\n }else{\r\n logger.info(\"recFiles final response:\", response);\r\n return response;\r\n }\r\n}\r\nconst recFiles = async (\r\n fileUrls: string[],\r\n): Promise<RecFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n const postData = JSON.stringify({ \r\n fileUrls, \r\n splitPdf: 0, \r\n trimPage: 0,\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"recFiles request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/recFiles?t='+new Date().getTime(), options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"recFiles response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n jsonObject.status = jsonObject.data.status;\r\n jsonObject.data = JSON.stringify(jsonObject.data);\r\n resolve(jsonObject);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\nexport const splitPdf = async (\r\n path: string,\r\n splitPageNumbers: number[],\r\n): Promise<Record<string, string>> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n originPdfUrl: path, \r\n splitPageNumbers\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"splitPdf request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/splitPdf', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"splitPdf response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject.data.splitPdfUrlMap);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const combineFiles = async (\r\n urlList: string[],\r\n outFileName: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n urlList, \r\n outFileName\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"mergePdfs request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/mergePdfs', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"mergePdfs response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject.data);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const convertPdfToDocxWithPull = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const pullResult =async function (pdfUrl: string): Promise<string> { \r\n const response = await convertPdfToDocx(pdfUrl);\r\n if(response.startsWith(\"http\")){\r\n return response;\r\n }else if(response.startsWith(\"68747470\")){ \r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n return pullResult(pdfUrl);\r\n }else{ \r\n throw new Error(`Failed to convert PDF to Markdown: ${response}`);\r\n }\r\n }\r\n return await pullResult(pdfUrl);\r\n}\r\nexport const convertPdfToDocx = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n pdfUrl, \r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertPdfToDocx request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/pdf2docx', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertPdfToDocx response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const convertMarkdownToDoc = async (\r\n markdown: string,\r\n resultType:number\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n markdown, \r\n resultType\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertMarkdownToDoc request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/markdown2Doc', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertMarkdownToDoc response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\nexport const convertPdfToMarkdownWithPull = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const transactionId = await convertPdfToMarkdown(pdfUrl);\r\n const pullResult =async function (transactionId: string): Promise<string> { \r\n const response = await fetchResult(transactionId);\r\n if(response.code ==200){\r\n return response.data;\r\n }else if(response.code == 202){ \r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n return pullResult(transactionId);\r\n }else{ \r\n throw new Error(`Failed to convert the document to Markdown: ${response.msg}`);\r\n }\r\n }\r\n return await pullResult(transactionId);\r\n}\r\n\r\nconst fetchResult = async (\r\n transactionId: string,\r\n): Promise<RecFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'get',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"fetchResult request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/fetchResult?transactionId=' + transactionId, options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"fetchResult response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.end();\r\n });\r\n}\r\nconst convertPdfToMarkdown = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n url:pdfUrl, \r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertPdfToMarkdown request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/doc2Markdown', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertPdfToMarkdown response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}","import type { OauthResponseData } from './types.js';\r\n\r\ninterface CacheItem {\r\n data: OauthResponseData;\r\n expiry: number;\r\n}\r\n\r\nexport class OAuthCache {\r\n private static instance: OAuthCache;\r\n private cache: Map<string, CacheItem>;\r\n private readonly CACHE_DURATION = 30 * 60 * 1000; // 30 minutes in milliseconds\r\n\r\n private constructor() {\r\n this.cache = new Map();\r\n }\r\n\r\n public static getInstance(): OAuthCache {\r\n if (!OAuthCache.instance) {\r\n OAuthCache.instance = new OAuthCache();\r\n }\r\n return OAuthCache.instance;\r\n }\r\n\r\n public set(key: string, data: OauthResponseData): void {\r\n const expiry = Date.now() + this.CACHE_DURATION;\r\n this.cache.set(key, { data, expiry });\r\n }\r\n\r\n public get(key: string): OauthResponseData | null {\r\n const item = this.cache.get(key);\r\n if (!item) return null;\r\n\r\n if (Date.now() > item.expiry) {\r\n this.cache.delete(key);\r\n return null;\r\n }\r\n\r\n return item.data;\r\n }\r\n\r\n public clear(): void {\r\n this.cache.clear();\r\n }\r\n} ","export interface OauthResponseData {\r\n accessToken: string\r\n tokenType: string\r\n refreshToken: string\r\n userId: string \r\n oauthId: string \r\n userName: string\r\n account: string \r\n expiresIn: number\r\n}\r\nexport interface AliOssUploadResult {\r\n code:number;\r\n msg:string;\r\n fileName:string;\r\n url:string;\r\n}\r\nexport interface LoginResponse {\r\n code: number\r\n msg: string \r\n data: OauthResponseData\r\n}\r\n\r\nexport interface LoginError extends Error {\r\n code: number;\r\n msg: string;\r\n} \r\n\r\nexport interface OAuthConfig {\r\n apiKey: string;\r\n secretKey: string;\r\n host: string;\r\n\tappId :string ;\r\n\tbasicAuth :string ;\r\n\tversion :string ;\r\n}\r\nexport interface NewApiUser {\r\n newApiServerUrl:string;\r\n newApiAccessToken:string;\r\n newApiUserId:string;\r\n newApiGroup:string;\r\n}\r\nexport enum TextDocType { \r\n // 纯文本文件类型 \r\n TXT = \"TXT\",\r\n // Markdown 文件类型\r\n MD = \"MD\",\r\n // CSV 文件类型\r\n CSV = \"CSV\",\r\n LOG=\"LOG\",\r\n XML=\"XML\",\r\n JSON=\"JSON\",\r\n HTML=\"HTML\",\r\n YAML=\"YAML\",\r\n JS=\"JS\",\r\n CSS=\"CSS\",\r\n SQL=\"SQL\",\r\n // 其他文件类型\r\n OTHER = \"OTHER\",\r\n}\r\n\r\nexport enum DocType {\r\n UNKNOWN = \"UNKNOWN\",\r\n BR = \"BR\",\r\n CR = \"CR\",\r\n NNC1 = \"NNC1\",\r\n NNC2 = \"NNC2\",\r\n NAR1 = \"NAR1\",\r\n ND2A = \"ND2A\",\r\n ND2B = \"ND2B\",\r\n ND4 = \"ND4\",\r\n NR1 = \"NR1\",\r\n NDR1 = \"NDR1\",\r\n NSC1 = \"NSC1\",\r\n AD = \"AD\",\r\n IR1263 = \"IR1263\",\r\n EXTRA_FIRST_PAGE = \"EXTRA_FIRST_PAGE\",\r\n PASSPORT = \"PASSPORT\",\r\n ID = \"IDCARD\", // 对应 Java: ID (\"IDCARD\")\r\n PROOFOFADDRESS = \"PROOFOFADDRESS\",\r\n}\r\n\r\nexport namespace TextDocType {\r\n export function isTextDocType(docType: string): boolean {\r\n return docType.length > 0 && Object.values(TextDocType).includes(docType.slice(1).toUpperCase() as TextDocType);\r\n }\r\n}\r\nexport namespace DocType {\r\n export function name(nameValue: string): DocType {\r\n for (const key in DocType) {\r\n if (DocType[key as keyof typeof DocType] === nameValue) {\r\n return DocType[key as keyof typeof DocType] as DocType;\r\n }\r\n }\r\n return DocType.UNKNOWN;\r\n }\r\n\r\n export function nameContains(nameValue: string): DocType {\r\n for (const key in DocType) {\r\n const docTypeValue = DocType[key as keyof typeof DocType];\r\n // Ensure we are checking against the string values of the enum\r\n if (typeof docTypeValue === 'string' && nameValue.includes(docTypeValue)) {\r\n return docTypeValue;\r\n }\r\n }\r\n return DocType.UNKNOWN;\r\n }\r\n}\r\n\r\n","import winston from 'winston';\r\nimport { CallMcpToolRequest, CallMcpToolResponse, McpResponseItem } from './api.js';\r\nimport { Client } from '@modelcontextprotocol/sdk/client';\r\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\r\n\r\nexport class McpClient {\r\n client: Client;\r\n logger: winston.Logger;\r\n\r\n constructor(client: Client, logger: winston.Logger) {\r\n this.client = client;\r\n this.logger = logger;\r\n }\r\n\r\n async CallTool(request: CallMcpToolRequest): Promise<CallMcpToolResponse> {\r\n // Create the request object for the underlying client\r\n const req = {\r\n method: \"tools/call\",\r\n params: {\r\n name: request.method,\r\n arguments: request.data\r\n }\r\n } as CallToolRequest;\r\n\r\n const response: CallMcpToolResponse = {\r\n isError: false,\r\n content: []\r\n };\r\n\r\n let contents: McpResponseItem[] = [];\r\n \r\n try {\r\n \r\n const result = await this.client.callTool(req.params, CallToolResultSchema, { timeout: 30 * 60 * 1000 });\r\n response.isError = result.isError as boolean;\r\n \r\n // Process content based on type\r\n if (result.content && Array.isArray(result.content)) {\r\n for (const content of result.content) {\r\n switch (content.type) {\r\n case \"text\":\r\n contents.push({\r\n type: content.type,\r\n text: content.text || \"\"\r\n });\r\n break;\r\n case \"image\":\r\n contents.push({\r\n type: content.type,\r\n text: content.data || content.url || \"\"\r\n });\r\n break;\r\n case \"audio\":\r\n contents.push({\r\n type: content.type,\r\n text: content.data || content.url || \"\"\r\n });\r\n break;\r\n default:\r\n this.logger.error(\"not supported content: %j\", content);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n response.content = contents;\r\n return response;\r\n } catch (err) {\r\n this.logger.error(\"CallTool failed: %s\", err instanceof Error ? err.message : String(err));\r\n response.isError = true;\r\n contents.push({\r\n type: \"text\",\r\n text: err instanceof Error ? err.message : String(err)\r\n });\r\n response.content = contents;\r\n return response;\r\n }\r\n }\r\n}","import winston from \"winston\";\nimport { McpClient } from \"./client.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n\nexport interface Config{\n\tenabled:boolean;\n\thost: string ;\n\tport: number;\n\tapiKey: string;\n}\nexport interface ListMcpServerRequest{\n\n}\n\nexport interface McpServer{\n id: string;\n name: string;\n type:string;\n description: string;\n url: string;\n}\nexport interface Servers{\n servers:Record<string, McpServer>;\n}\nexport interface ListMcpServerResponse{\n success:boolean;\n data: Servers;\n}\n\nexport interface GetMcpServerInfoRequest{\n serverId: string;\n}\nexport interface GetMcpServerInfoResponse{\n success:boolean;\n data: McpServer;\n}\n\nexport interface CallMcpToolRequest{\n serverId: string;\n method: string;\n data: Record<string, any>;\n}\n\nexport interface McpResponseItem{\n type:string;\n text:string;\n}\nexport interface CallMcpToolResponse{\n isError:boolean;\n content:McpResponseItem[];\n}\n\nexport interface ClassifiedResponseData{\n classifiedByFileNames:Record<string, string[]>[] | Record<string, string[]>;\n}\nexport interface ExcelWorkbookMeta{\n filename: string,\n sheets: string[],\n size: number,\n modified: number\n}\n\nexport class CherryClient {\n config: Config;\n logger: winston.Logger;\n mcpServers: Record<string, McpServer>;\n mcpClients: Record<string, McpClient>;\n\n constructor(config: Config, logger: winston.Logger) {\n this.config = config;\n this.logger = logger;\n this.mcpServers = {};\n this.mcpClients = {};\n }\n async listMcpServer(): Promise<ListMcpServerResponse> {\n // fetch listMcpServer\n this.logger.info(`Fetching list of MCP servers(http://${this.config.host}:${this.config.port}/v1/mcps)`);\n const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n }\n })\n\n const data = (await res.json()) as ListMcpServerResponse;\n this.mcpServers = data.data.servers;\n return data;\n }\n async getMcpServerInfo(request: GetMcpServerInfoRequest): Promise<GetMcpServerInfoResponse> {\n const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps/${request.serverId}`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n }\n })\n const data = (await res.json()) as GetMcpServerInfoResponse\n return data;\n }\n\n async callTool(request: CallMcpToolRequest): Promise<CallMcpToolResponse> {\n let mcpClient = this.mcpClients[request.serverId];\n if(mcpClient == null){ \n const transport = new StreamableHTTPClientTransport(new URL(`http://${this.config.host}:${this.config.port}/v1/mcps/${request.serverId}/mcp`),\n {requestInit: {headers: {Authorization: `Bearer ${this.config.apiKey}`}}});\n const client = new Client({\n name: \"oss-mcp-client\",\n version: \"1.0.0\"\n },{})\n this.logger.info(\"Connecting to cherry MCP server...\");\n await client.connect(transport);\n mcpClient = new McpClient(client, this.logger);\n this.mcpClients[request.serverId] = mcpClient;\n }\n\n try {\n return await mcpClient.CallTool(request);\n } catch (err) {\n this.logger.error(\"CallTool failed: %s\", err instanceof Error ? err.message : String(err));\n throw err;\n }\n }\n}"],"mappings":"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","names":["z","fs","path","config","z","config","fs","path","fs","os","fpath","config","resolve","resolve","config","path","pdfUrl","transactionId","TextDocType","DocType","logger","request","config","logger","request","os","z","pattern","fs","config","path","configs","configNames","resolve","config","config","resolve"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/services/oss.service.ts","../src/config/config.ts","../src/util/logger.ts","../src/util/aes.ts","../src/api/corp.ts","../src/config/auth/config.ts","../src/api/api.ts","../src/cache.ts","../src/types.ts","../src/api/cherry/client.ts","../src/api/cherry/api.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * 实现阿里云OSS文件上传功能。\r\n * - 上传文件到阿里云OSS\r\n * - 获取可用的OSS配置\r\n */\r\n\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport { OssMcpServer } from \"./server.js\";\r\nimport { getServerConfig } from \"./config/config.js\";\r\nimport { resolve } from \"path\";\r\nimport { config } from \"dotenv\";\r\nimport { OAuthCache } from \"./cache.js\";\r\nimport {logger} from \"./util/logger.js\";\r\n\r\n// 加载当前工作目录中的.env文件\r\nconfig({ path: resolve(process.cwd(), \".env\") });\r\n\r\nexport async function startServer(): Promise<void> {\r\n // 检查是否在stdio模式下运行\r\n const isStdioMode = process.env.NODE_ENV === \"cli\" || process.argv.includes(\"--stdio\");\r\n\r\n // 获取服务器配置\r\n const serverConfig = await getServerConfig(isStdioMode);\r\n // 创建OSS MCP服务器\r\n const server = await OssMcpServer.create();\r\n OAuthCache.getInstance().clear();\r\n \r\n if (isStdioMode) {\r\n // 在stdio模式下运行\r\n const transport = new StdioServerTransport();\r\n await server.connect(transport);\r\n } else {\r\n // 在HTTP模式下运行\r\n logger.info(`初始化OSS MCP服务器,HTTP模式,端口: ${serverConfig.port}...`);\r\n await server.startHttpServer(serverConfig.port);\r\n }\r\n}\r\n\r\n// 启动服务器\r\nstartServer().catch((error) => {\r\n logger.error(\"启动服务器失败:\", error);\r\n // 等待500毫秒后退出\r\n setTimeout(() => {\r\n process.exit(1);\r\n }, 500);\r\n});\r\n\r\n// setTimeout(async () => {\r\n// const callRec = async function (): Promise<any> {\r\n// const path = \"https://cdn.ionestep.com/NAR1%20ND2A.pdf\";\r\n\r\n// const recResult = await combineFiles([path,\"https://cdn.ionestep.com/3.pdf\",\"https://cdn.ionestep.com/4.pdf\"], \"https://cdn.ionestep.com/bb.png\");\r\n\r\n// console.log(\"recResult:\" + JSON.stringify(recResult));\r\n// }\r\n// await callRec();\r\n// }, 1000*10)","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\r\nimport { z } from \"zod\";\r\nimport { ossService } from \"./services/oss.service.js\";\r\nimport express, { Request, Response } from \"express\";\r\nimport { SSEServerTransport } from \"@modelcontextprotocol/sdk/server/sse.js\";\r\nimport { IncomingMessage, ServerResponse } from \"http\";\r\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\r\nimport fs, { mkdirSync } from \"fs\";\r\nimport {stat, realpath, readdir, readFile, writeFile, mkdir, rename, copyFile} from \"fs/promises\";\r\nimport {createTwoFilesPatch} from \"diff\";\r\nimport os from 'os';\r\nimport * as fpath from 'path';\r\nimport { minimatch } from 'minimatch';\r\nimport { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\r\nimport { combineFiles, convertMarkdownToDoc, convertPdfToDocxWithPull, convertPdfToMarkdownWithPull, recFilesWithPull, splitPdf } from \"./api/api.js\";\r\nimport { AliOssUploadResult, TextDocType } from \"./types.js\";\r\nimport { logger } from \"./util/logger.js\";\r\nimport { CallMcpToolRequest, CherryClient, ClassifiedResponseData, ExcelWorkbookMeta } from \"./api/cherry/api.js\";\r\nimport { ConfigManager } from \"./config/auth/config.js\";\r\n\r\nexport const Logger = {\r\n log: (...args: any[]) => {\r\n console.log(...args);\r\n },\r\n error: (...args: any[]) => {\r\n console.error(...args);\r\n }\r\n};\r\n\r\nfunction expandHome(filepath: string): string {\r\n if (filepath.startsWith('~/') || filepath === '~') {\r\n return fpath.join(os.homedir(), filepath.slice(1));\r\n }\r\n return filepath;\r\n}\r\n\r\n// Security utilities\r\nasync function validatePath(requestedPath: string): Promise<string> {\r\n const expandedPath = expandHome(requestedPath);\r\n let absolute = fpath.isAbsolute(expandedPath)\r\n ? fpath.resolve(expandedPath)\r\n : fpath.resolve(process.cwd(), expandedPath);\r\n\r\n\r\n // Handle symlinks by checking their real path\r\n try {\r\n const realPath = await realpath(absolute);\r\n return realPath;\r\n } catch (error) {\r\n // For new files that don't exist yet, verify parent directory\r\n const parentDir = fpath.dirname(absolute);\r\n try {\r\n await realpath(parentDir);\r\n return absolute;\r\n } catch {\r\n throw new Error(`Parent directory does not exist: ${parentDir}`);\r\n }\r\n }\r\n}\r\n\r\nconst EditOperation = z.object({\r\n oldText: z.string().describe('Text to search for - must match exactly'),\r\n newText: z.string().describe('Text to replace with')\r\n});\r\n\r\n\r\ninterface FileInfo {\r\n size: number;\r\n created: Date;\r\n modified: Date;\r\n accessed: Date;\r\n isDirectory: boolean;\r\n isFile: boolean;\r\n permissions: string;\r\n}\r\n// Tool implementations\r\nasync function getFileStats(filePath: string): Promise<FileInfo> {\r\n const stats = await stat(filePath);\r\n return {\r\n size: stats.size,\r\n created: stats.birthtime,\r\n modified: stats.mtime,\r\n accessed: stats.atime,\r\n isDirectory: stats.isDirectory(),\r\n isFile: stats.isFile(),\r\n permissions: stats.mode.toString(8).slice(-3),\r\n };\r\n}\r\n\r\nasync function searchFiles(\r\n rootPath: string,\r\n pattern: string,\r\n excludePatterns: string[] = []\r\n): Promise<string[]> {\r\n const results: string[] = [];\r\n\r\n async function search(currentPath: string) {\r\n const entries = await readdir(currentPath, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = fpath.join(currentPath, entry.name);\r\n\r\n try {\r\n // Validate each path before processing\r\n await validatePath(fullPath);\r\n\r\n // Check if path matches any exclude pattern\r\n const relativePath = fpath.relative(rootPath, fullPath);\r\n const shouldExclude = excludePatterns.some(pattern => {\r\n const globPattern = pattern.includes('*') ? pattern : `**/${pattern}/**`;\r\n return minimatch(relativePath, globPattern, { dot: true });\r\n });\r\n\r\n if (shouldExclude) {\r\n continue;\r\n }\r\n\r\n if (entry.name.toLowerCase().includes(pattern.toLowerCase())) {\r\n results.push(fullPath);\r\n }\r\n\r\n if (entry.isDirectory()) {\r\n await search(fullPath);\r\n }\r\n } catch (error) {\r\n // Skip invalid paths during search\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n await search(rootPath);\r\n return results;\r\n}\r\n\r\n// file editing and diffing utilities\r\nfunction normalizeLineEndings(text: string): string {\r\n return text.replace(/\\r\\n/g, '\\n');\r\n}\r\n\r\nfunction createUnifiedDiff(originalContent: string, newContent: string, filepath: string = 'file'): string {\r\n // Ensure consistent line endings for diff\r\n const normalizedOriginal = normalizeLineEndings(originalContent);\r\n const normalizedNew = normalizeLineEndings(newContent);\r\n\r\n return createTwoFilesPatch(\r\n filepath,\r\n filepath,\r\n normalizedOriginal,\r\n normalizedNew,\r\n 'original',\r\n 'modified'\r\n );\r\n}\r\n\r\nasync function applyFileEdits(\r\n filePath: string,\r\n edits: Array<{oldText: string, newText: string}>,\r\n dryRun = false\r\n): Promise<string> {\r\n // Read file content and normalize line endings\r\n const content = normalizeLineEndings(await readFile(filePath, 'utf-8'));\r\n\r\n // Apply edits sequentially\r\n let modifiedContent = content;\r\n for (const edit of edits) {\r\n const normalizedOld = normalizeLineEndings(edit.oldText);\r\n const normalizedNew = normalizeLineEndings(edit.newText);\r\n\r\n // If exact match exists, use it\r\n if (modifiedContent.includes(normalizedOld)) {\r\n modifiedContent = modifiedContent.replace(normalizedOld, normalizedNew);\r\n continue;\r\n }\r\n\r\n // Otherwise, try line-by-line matching with flexibility for whitespace\r\n const oldLines = normalizedOld.split('\\n');\r\n const contentLines = modifiedContent.split('\\n');\r\n let matchFound = false;\r\n\r\n for (let i = 0; i <= contentLines.length - oldLines.length; i++) {\r\n const potentialMatch = contentLines.slice(i, i + oldLines.length);\r\n\r\n // Compare lines with normalized whitespace\r\n const isMatch = oldLines.every((oldLine, j) => {\r\n const contentLine = potentialMatch[j];\r\n return oldLine.trim() === contentLine.trim();\r\n });\r\n\r\n if (isMatch) {\r\n // Preserve original indentation of first line\r\n const originalIndent = contentLines[i].match(/^\\s*/)?.[0] || '';\r\n const newLines = normalizedNew.split('\\n').map((line, j) => {\r\n if (j === 0) return originalIndent + line.trimStart();\r\n // For subsequent lines, try to preserve relative indentation\r\n const oldIndent = oldLines[j]?.match(/^\\s*/)?.[0] || '';\r\n const newIndent = line.match(/^\\s*/)?.[0] || '';\r\n if (oldIndent && newIndent) {\r\n const relativeIndent = newIndent.length - oldIndent.length;\r\n return originalIndent + ' '.repeat(Math.max(0, relativeIndent)) + line.trimStart();\r\n }\r\n return line;\r\n });\r\n\r\n contentLines.splice(i, oldLines.length, ...newLines);\r\n modifiedContent = contentLines.join('\\n');\r\n matchFound = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!matchFound) {\r\n throw new Error(`Could not find exact match for edit:\\n${edit.oldText}`);\r\n }\r\n }\r\n\r\n // Create unified diff\r\n const diff = createUnifiedDiff(content, modifiedContent, filePath);\r\n\r\n // Format diff with appropriate number of backticks\r\n let numBackticks = 3;\r\n while (diff.includes('`'.repeat(numBackticks))) {\r\n numBackticks++;\r\n }\r\n const formattedDiff = `${'`'.repeat(numBackticks)}diff\\n${diff}${'`'.repeat(numBackticks)}\\n\\n`;\r\n\r\n if (!dryRun) {\r\n await writeFile(filePath, modifiedContent, 'utf-8');\r\n }\r\n\r\n return formattedDiff;\r\n}\r\nexport class OssMcpServer {\r\n private readonly server: McpServer;\r\n private sseTransport: SSEServerTransport | null = null;\r\n private cherryClient : CherryClient|null = null;\r\n private static DEFAULT_CATEGORIES = [\"发票\",\"银行流水\",\"銀行詢證函\",\"合同\",\"公司基本資料\",\"个人信息\",\"其他\"];\r\n private static ONESTEP_MCP_SERVER_ID:string;\r\n private static EXCEL_MCP_SERVER_ID:string;\r\n\r\n constructor() {\r\n this.server = new McpServer(\r\n {\r\n name: \"onestep/filesystem-oss-mcp\",\r\n version: \"1.3.7\",\r\n },\r\n // 使用正确格式的capabilities配置\r\n {\r\n capabilities: {\r\n tools: { listChanged: true },\r\n resources: { listChanged: true },\r\n prompts: { listChanged: true },\r\n logging: {}\r\n }\r\n }\r\n );\r\n }\r\n\r\n private async aliOssUpload(filePath: string, targetDir?: string, fileName?: string, configName?: string): Promise<CallToolResult> {\r\n try {\r\n logger.info(`准备上传: ${filePath} 到 ${targetDir || '根目录'}`);\r\n\r\n if (!filePath) {\r\n throw new Error(\"文件路径是必需的\");\r\n }\r\n\r\n // 检查文件是否存在\r\n if (!fs.existsSync(filePath)) {\r\n throw new Error(`文件不存在: ${filePath},请提供正确的文件路径`);\r\n }\r\n\r\n // 执行上传\r\n const result = await ossService.uploadFile({\r\n filePath,\r\n targetDir,\r\n fileName,\r\n configName\r\n });\r\n\r\n if (result.success) {\r\n logger.info(`上传成功: ${result.url}`);\r\n const response = {code:0, msg:\"文件上传成功!\", fileName:`${fpath.basename(filePath)}`, url: result.url}\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: JSON.stringify(response)\r\n }]\r\n };\r\n } else {\r\n logger.error(`上传失败: ${result.error}`);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `上传失败: ${result.error}`\r\n }]\r\n };\r\n }\r\n } catch (error) {\r\n logger.error(`上传过程中出错:`, error);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `上传出错: ${error}`\r\n }]\r\n };\r\n }\r\n }\r\n public async initCherryClient(): Promise<void> {\r\n if (!this.cherryClient) {\r\n const config = (await ConfigManager.getInstance()).getApiConfig();\r\n this.cherryClient = new CherryClient(config, logger);\r\n }\r\n \r\n try {\r\n await this.cherryClient.listMcpServer();\r\n } catch (error) {\r\n logger.error(`Failed to list MCP servers:`, error);\r\n }\r\n\r\n if (!OssMcpServer.ONESTEP_MCP_SERVER_ID) {\r\n OssMcpServer.ONESTEP_MCP_SERVER_ID = Object.values(this.cherryClient.mcpServers).find(server => server.name.indexOf(\"onestepOrder\") > -1)?.id || \"\";\r\n logger.info(`[classify_files_in_directory] ONESTEP_MCP_SERVER_ID: ${OssMcpServer.ONESTEP_MCP_SERVER_ID}`);\r\n }\r\n if (!OssMcpServer.EXCEL_MCP_SERVER_ID) {\r\n OssMcpServer.EXCEL_MCP_SERVER_ID = Object.values(this.cherryClient.mcpServers).find(server => server.name.indexOf(\"excel\") > -1)?.id || \"\";\r\n logger.info(`[classify_files_in_directory] EXCEL_MCP_SERVER_ID: ${OssMcpServer.EXCEL_MCP_SERVER_ID}`);\r\n }\r\n }\r\n\r\n // 工厂方法用于异步初始化\r\n public static async create(): Promise<OssMcpServer> {\r\n const instance = new OssMcpServer();\r\n await instance.registerTools();\r\n setTimeout(async () => {\r\n await instance.initCherryClient();\r\n }, 60000);\r\n\r\n return instance;\r\n }\r\n\r\n public async read_any_file(path:string): Promise<CallToolResult> {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for read_file: ${path}`);\r\n }\r\n \r\n let temPcontent = \"\";\r\n if (path.startsWith(\"http\")) {\r\n const recResult = await recFilesWithPull([path]);\r\n if(recResult.code === 200) {\r\n temPcontent = recResult.data;\r\n return {\r\n content: [{ type: \"text\", text: temPcontent }],\r\n };\r\n }else{\r\n logger.error(`read file ${path} Error:`, recResult.msg);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n const validPath = await validatePath(path);\r\n // 获取文件后缀\r\n const fileExtension = fpath.extname(validPath).toUpperCase();\r\n if(TextDocType.isTextDocType(fileExtension)){\r\n temPcontent = await readFile(validPath, \"utf-8\");\r\n }else if(fileExtension === \".XLSX\" || fileExtension === \".XLS\"){\r\n if(!OssMcpServer.EXCEL_MCP_SERVER_ID){\r\n await this.initCherryClient();\r\n }\r\n // step 1, 获取excel文件元数据\r\n const mcpResponse = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.EXCEL_MCP_SERVER_ID,\r\n method: \"get_workbook_metadata\",\r\n data: {\"filepath\": validPath} as Record<string, any>\r\n });\r\n if(mcpResponse?.isError) {\r\n throw new Error(`Server returned an error `);\r\n }\r\n logger.debug(`get_workbook_metadata response data:${mcpResponse?.content?.[0].text}`)\r\n const text = mcpResponse?.content?.[0].text as string;\r\n // Use Function to safely parse Python dict string representations that use single quotes\r\n const excelMeta = (text.includes(\"'\") ? new Function(\"return \" + text)() : JSON.parse(text)) as ExcelWorkbookMeta;\r\n \r\n // step 2, 读取excel文件内容\r\n logger.info(`excel_sheets.length:${excelMeta.sheets.length}`);\r\n if(excelMeta.sheets.length>0){\r\n const fileSize = excelMeta.size/1024/1024;\r\n logger.info(`excel_file_size:${fileSize}MB`);\r\n if(fileSize > 100){\r\n throw new Error(`文件太大,请不要直接读取。使用skills做统计分析`);\r\n }\r\n for (const sheet of excelMeta.sheets) {\r\n const mcpResponse2 = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.EXCEL_MCP_SERVER_ID,\r\n method: \"read_data_from_excel\",\r\n data: {\"filepath\": validPath, \"sheet_name\": sheet} as Record<string, any>\r\n });\r\n if(mcpResponse2?.isError) {\r\n throw new Error(`Server returned an error `);\r\n }\r\n const excelContent = JSON.stringify(mcpResponse2?.content?.[0].text);\r\n temPcontent += excelContent+\"\\n\"\r\n }\r\n // step 3, 如果内容多于500字符,保存成文本文件,返回文本文件路径\r\n if(temPcontent.length > 500){\r\n const tempFilePath = await this.saveTempFile(temPcontent);\r\n temPcontent = `文件内容过长,已保存到临时文件:${tempFilePath}`;\r\n }\r\n }else{\r\n temPcontent = ''\r\n }\r\n }else{\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n if(ossFile.code === 0) {\r\n const recResult = await recFilesWithPull([ossFile.url]);\r\n if(recResult.code === 200) {\r\n temPcontent = recResult.data;\r\n }else{\r\n console.error(`read file ${validPath} Error:`, recResult.msg);\r\n }\r\n }else{\r\n console.error(`upload file ${validPath} Error:`, ossFile.msg);\r\n }\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n return {\r\n content: [{ type: \"text\", text: temPcontent }],\r\n };\r\n }\r\n\r\n private async saveTempFile(content: string): Promise<string> {\r\n const tempDir = os.tmpdir();\r\n const tempFileName = `excel_content_${Date.now()}_${Math.random().toString(36).substring(2, 9)}.txt`;\r\n const tempFilePath = fpath.join(tempDir, tempFileName);\r\n await writeFile(tempFilePath, content, \"utf-8\");\r\n return tempFilePath;\r\n }\r\n\r\n private async registerTools(): Promise<void> {\r\n // 获取可用的OSS配置\r\n logger.info('获取所有OSS配置...');\r\n const configs = await ossService.getConfigs();\r\n const configNames = configs.map(config => config.id);\r\n\r\n // 工具:上传文件到OSS\r\n this.server.tool(\r\n \"upload_to_oss\",\r\n \"将文件上传到阿里云OSS\",\r\n {\r\n filePath: z.string().describe(\"要上传的本地文件路径\"),\r\n targetDir: z.string().optional().describe(\"OSS中的目标目录路径(可选)\"),\r\n fileName: z.string().optional().describe(\"上传后的文件名(可选,默认使用原文件名)\"),\r\n configName: z.string().optional().describe(`OSS配置名称(可选,默认为'default')。可用配置: ${configNames.join(', ') || '无'}`)\r\n },\r\n async ({ filePath, targetDir, fileName, configName }) => {\r\n if (!filePath) {\r\n throw new Error(`Invalid arguments for upload_to_oss: ${filePath}`);\r\n }\r\n if (!configName) {\r\n configName = 'default';\r\n }\r\n return await this.aliOssUpload(filePath, targetDir, fileName, configName);\r\n }\r\n );\r\n\r\n // 工具:列出可用的OSS配置\r\n this.server.tool(\r\n \"list_oss_configs\",\r\n \"列出可用的阿里云OSS配置\",\r\n {},\r\n async () => {\r\n try {\r\n const configs = await ossService.getConfigs();\r\n const configNames = configs.map(config => config.id);\r\n\r\n if (configNames.length === 0) {\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: \"未找到OSS配置。请检查环境变量设置。\"\r\n }]\r\n };\r\n }\r\n\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `可用的OSS配置:\\n${configNames.map(name => `- ${name}`).join('\\n')}`\r\n }]\r\n };\r\n } catch (error) {\r\n logger.error(`获取OSS配置列表时出错:`, error);\r\n return {\r\n isError: true,\r\n content: [{\r\n type: \"text\",\r\n text: `获取配置列表失败: ${error}`\r\n }]\r\n };\r\n }\r\n }\r\n );\r\n // 工具:读取文件内容\r\n this.server.tool(\r\n \"read_any_file\",\r\n \"读取任何文件内容\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n return await this.read_any_file(path);\r\n }\r\n );\r\n // 工具:读取多个文件内容\r\n this.server.tool(\r\n \"read_multiple_files\",\r\n \"读取多个文件内容\",\r\n {paths: z.array(z.string()).describe(\"文件路径列表\")},\r\n async ({ paths }) => {\r\n\r\n if (!paths) {\r\n throw new Error(`Invalid arguments for read_multiple_files`);\r\n }\r\n const results = await Promise.all(\r\n paths.map(async (filePath: string) => {\r\n try {\r\n const validPath = await validatePath(filePath);\r\n const response = await this.read_any_file(validPath);\r\n return `${filePath}:\\n${response.content[0].text}\\n`;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n return `${filePath}: Error - ${errorMessage}`;\r\n }\r\n }),\r\n );\r\n return {\r\n content: [{ type: \"text\", text: results.join(\"\\n---\\n\") }],\r\n };\r\n }\r\n );\r\n // 工具:写入文件内容\r\n this.server.tool(\r\n \"write_file\",\r\n \"写入文件内容\",\r\n {path: z.string().describe(\"文件路径\"), content: z.string().describe(\"要写入的内容\")},\r\n async ({ path, content }) => {\r\n \r\n if (!path) {\r\n throw new Error(`Invalid arguments for write_file`);\r\n }\r\n const validPath = await validatePath(path);\r\n await writeFile(validPath,content, \"utf-8\");\r\n return {\r\n content: [{ type: \"text\", text: `Successfully wrote to ${path}` }],\r\n };\r\n }\r\n );\r\n // 工具:编辑文件内容\r\n this.server.tool(\r\n \"edit_file\",\r\n \"编辑文件内容\",\r\n {path: z.string().describe(\"文件路径\"), edits: z.array(EditOperation).describe(\"编辑操作列表\"), dryRun: z.boolean().default(false).describe('Preview changes using git-style diff format')},\r\n async ({ path, edits, dryRun }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for edit_file`);\r\n }\r\n const validPath = await validatePath(path);\r\n const result = await applyFileEdits(validPath, edits, dryRun);\r\n return {\r\n content: [{ type: \"text\", text: result }],\r\n };\r\n }\r\n );\r\n // 工具:创建目录\r\n this.server.tool(\r\n \"create_directory\",\r\n \"创建目录\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for create_directory`);\r\n }\r\n const validPath = await validatePath(path);\r\n await mkdir(validPath, { recursive: true });\r\n return {\r\n content: [{ type: \"text\", text: `Successfully created directory ${path}` }],\r\n };\r\n }\r\n );\r\n // 工具:列出目录内容\r\n this.server.tool(\r\n \"list_directory\",\r\n \"列出目录内容\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for list_directory`);\r\n }\r\n const validPath = await validatePath(path);\r\n const entries = await readdir(validPath, { withFileTypes: true });\r\n const formatted = entries\r\n .map((entry) => `${entry.isDirectory() ? \"[DIR]\" : \"[FILE]\"} ${entry.name}`)\r\n .join(\"\\n\");\r\n return {\r\n content: [{ type: \"text\", text: formatted }],\r\n };\r\n }\r\n );\r\n // 工具:移动文件\r\n this.server.tool(\r\n \"move_file\",\r\n \"移动文件\",\r\n {source: z.string().describe(\"源文件路径\"), destination: z.string().describe(\"目标文件路径\")},\r\n async ({ source, destination }) => {\r\n if (!source) {\r\n throw new Error(`Invalid arguments for move_file`);\r\n }\r\n const validSourcePath = await validatePath(source);\r\n const validDestPath = await validatePath(destination);\r\n await rename(validSourcePath, validDestPath);\r\n return {\r\n content: [{ type: \"text\", text: `Successfully moved ${source} to ${destination}` }],\r\n };\r\n }\r\n );\r\n // 工具:directory_tree\r\n this.server.tool(\r\n \"directory_tree\",\r\n \"列出目录树\",\r\n {path: z.string().describe(\"目录路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for directory_tree`);\r\n }\r\n\r\n interface TreeEntry {\r\n name: string;\r\n type: 'file' | 'directory';\r\n children?: TreeEntry[];\r\n }\r\n\r\n async function buildTree(currentPath: string): Promise<TreeEntry[]> {\r\n const validPath = await validatePath(currentPath);\r\n const entries = await readdir(validPath, {withFileTypes: true});\r\n const result: TreeEntry[] = [];\r\n\r\n for (const entry of entries) {\r\n const entryData: TreeEntry = {\r\n name: entry.name,\r\n type: entry.isDirectory() ? 'directory' : 'file'\r\n };\r\n\r\n if (entry.isDirectory()) {\r\n const subPath = fpath.join(currentPath, entry.name);\r\n entryData.children = await buildTree(subPath);\r\n }\r\n\r\n result.push(entryData);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n const treeData = await buildTree(path);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: JSON.stringify(treeData, null, 2)\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:搜索文件\r\n this.server.tool(\r\n \"search_files\",\r\n \"搜索文件\",\r\n {rootPath: z.string().describe(\"根目录路径\"), pattern: z.string().describe(\"搜索模式\"), excludePatterns: z.array(z.string()).default([]).describe(\"排除模式列表\")},\r\n async ({ rootPath, pattern, excludePatterns }) => {\r\n if (!rootPath) {\r\n throw new Error(`Invalid arguments for search_files`);\r\n }\r\n const validPath = await validatePath(rootPath);\r\n const results = await searchFiles(validPath, pattern, excludePatterns);\r\n return {\r\n content: [{ type: \"text\", text: results.length > 0 ? results.join(\"\\n\") : \"No matches found\" }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"get_file_info\",\r\n \"获取文件信息\",\r\n {path: z.string().describe(\"文件路径\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for get_file_info`);\r\n }\r\n const validPath = await validatePath(path);\r\n const info = await getFileStats(validPath);\r\n return {\r\n content: [{ type: \"text\", text: Object.entries(info)\r\n .map(([key, value]) => `${key}: ${value}`)\r\n .join(\"\\n\") }],\r\n };\r\n }\r\n );\r\n // 工具:classify_files_in_directory_by_file_content\r\n this.server.tool(\r\n \"classify_files_in_directory\",\r\n \"对目录中的文件进行分类,包含子目录里的文件\",\r\n {originDirectory: z.string().describe('Path to the directory to classify'),\r\n categories: z.array(z.string()).optional().describe('categories for classification'),\r\n copyFileToCategory: z.boolean().default(false).describe('是否将文件复制到分类目录')},\r\n async ({originDirectory, categories, copyFileToCategory }) => {\r\n if (!originDirectory) {\r\n throw new Error(`Invalid arguments for classify_files_in_directory`);\r\n }\r\n if(!categories){\r\n categories= OssMcpServer.DEFAULT_CATEGORIES;\r\n }\r\n const newDirectory = await validatePath(originDirectory.split('/').slice(0,-1).join('_classified'));\r\n const files = await readdir(originDirectory, { withFileTypes: true, recursive: true });\r\n const resultMap = new Map<string, string[]>();\r\n const fileNamePathMap = new Map<string, string>();\r\n for(const file of files) {\r\n const filePath = fpath.join(file.parentPath, file.name);\r\n if (file.isFile()) {\r\n fileNamePathMap.set(file.parentPath.replace(originDirectory, '')+\"/\"+file.name, file.name+\"|||\"+filePath);\r\n }\r\n }\r\n \r\n if(!OssMcpServer.ONESTEP_MCP_SERVER_ID){\r\n await this.initCherryClient();\r\n }\r\n const response = await this.cherryClient?.callTool({\r\n serverId: OssMcpServer.ONESTEP_MCP_SERVER_ID,\r\n method: \"batchClassifyFileNames\",\r\n data: {\"fileNames\": Array.from(fileNamePathMap.keys()), \"categories\":categories} as Record<string, any>\r\n } as CallMcpToolRequest);\r\n\r\n if(response?.isError){\r\n throw new Error(`can't classify files`);\r\n }else{\r\n const classifiedJson = response?.content[0].text as string;\r\n const classifiedData = (classifiedJson.includes(\"'\") ? new Function(\"return \" + classifiedJson)() : JSON.parse(classifiedJson)) as ClassifiedResponseData;\r\n if(copyFileToCategory){\r\n categories.forEach((category) => {\r\n mkdirSync(fpath.join(newDirectory, category), { recursive: true });\r\n });\r\n }\r\n \r\n const items = Array.isArray(classifiedData.classifiedByFileNames) \r\n ? classifiedData.classifiedByFileNames \r\n : [classifiedData.classifiedByFileNames];\r\n\r\n for (const item of items) {\r\n for (const key of Object.keys(item)) {\r\n const fileNames = item[key];\r\n for (const fileNameAndParent of fileNames) {\r\n const nameAndPath = (fileNamePathMap.get(fileNameAndParent) as string).split(\"|||\");\r\n const fileName = nameAndPath[0];\r\n const filePath = nameAndPath[1];\r\n const newFilePath = fpath.join(newDirectory, key, fileName);\r\n const fileArray = resultMap.get(key);\r\n if(copyFileToCategory){\r\n if (fileArray) {\r\n fileArray.push(newFilePath);\r\n } else {\r\n resultMap.set(key, [newFilePath]);\r\n }\r\n await copyFile(filePath, newFilePath);\r\n }else{\r\n if (fileArray) {\r\n fileArray.push(filePath);\r\n } else {\r\n resultMap.set(key, [filePath]);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n \r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `classified files:\\n${JSON.stringify(Object.fromEntries(resultMap))}`\r\n }],\r\n };\r\n }\r\n );\r\n\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"split_pdf\",\r\n \"pdf拆分\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\"), splitPageNumbers: z.array(z.number()).describe(\"要拆分的页码列表\")},\r\n async ({ path, splitPageNumbers }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for split_pdf tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const splitResult = await splitPdf(tempUrl, splitPageNumbers);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `splitted files:\\n${JSON.stringify(splitResult)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"combine_files\",\r\n \"文件合并,支持图片或者pdf文件\",\r\n {filePaths: z.array(z.string()).describe(\"待合并的文件列表(可以是远程urls)\")},\r\n async ({ filePaths }) => {\r\n if (!filePaths) {\r\n throw new Error(`Invalid arguments for combine_files tool`);\r\n }\r\n \r\n let tempUrls: string[] = [];\r\n for(const filePath of filePaths) {\r\n const fileExtension = fpath.extname(filePath).toUpperCase();\r\n if (fileExtension !== '.PDF' && fileExtension !== '.PNG' && fileExtension !== '.JPG' && fileExtension !== '.JPEG') {\r\n throw new Error(`Invalid file extension for ${filePath}. Only PDF, PNG, JPG, and JPEG files are supported.`);\r\n }\r\n if(filePath.startsWith(\"http\")){\r\n tempUrls.push(filePath);\r\n }else {\r\n const validPath = await validatePath(filePath);\r\n const result = await this.aliOssUpload(validPath);\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrls.push(ossFile.url);\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n }\r\n \r\n\r\n const combinedFile = await combineFiles(tempUrls, \"\" + new Date().getTime() + \"_combined.pdf\");\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `combined file:\\n${JSON.stringify(combinedFile)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容\r\n this.server.tool(\r\n \"convert_pdf_to_docx\",\r\n \"pdf转换成docx文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for conver_pdf_to_docx tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const convertResult = await convertPdfToDocxWithPull(tempUrl);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `docx file url:\\n${JSON.stringify(convertResult)}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:获取文件内容 markdown\r\n this.server.tool(\r\n \"convert_pdf_to_markdown\",\r\n \"pdf转换成markdown文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for conver_pdf_to_markdown tool`);\r\n }\r\n let tempUrl = \"\";\r\n if(path.startsWith(\"http\")){\r\n tempUrl = path;\r\n }else {\r\n const validPath = await validatePath(path);\r\n const result = await this.aliOssUpload(validPath);\r\n // 处理并打印服务器返回的结果\r\n if (result.isError) {\r\n console.error(`[aliOssUpload] Server returned an error`);\r\n if (result.content && result.content.length > 0) {\r\n result.content.forEach(contentItem => {\r\n if (contentItem.type === 'text') {\r\n console.error(`[aliOssUpload] Error detail: ${contentItem.text}`);\r\n } else {\r\n console.error(`[aliOssUpload] Error detail item:`, contentItem);\r\n }\r\n });\r\n } else {\r\n console.error(`[aliOssUpload] Server returned an unspecified error.`);\r\n }\r\n throw new Error(`Server returned an error `);\r\n } else if (result.content && result.content.length > 0) {\r\n console.log(`[aliOssUpload] Upload successful. Server response:${result.content[0].text}`);\r\n const ossFile = JSON.parse(result.content[0].text as string) as AliOssUploadResult;\r\n tempUrl = ossFile.url\r\n } else {\r\n console.log(`[aliOssUpload] Tool call completed, but server returned no specific content. Full result:`, result.result);\r\n throw new Error(`Server returned an error `);\r\n }\r\n }\r\n\r\n const convertResult = await convertPdfToMarkdownWithPull(tempUrl);\r\n const buffer = Buffer.from(convertResult, 'base64');\r\n const decodedString = buffer.toString('utf-8');\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${decodedString}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:markdown 2 pdf\r\n this.server.tool(\r\n \"convert_markdown_to_pdf\",\r\n \"markdown转换成pdf文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for convert_markdown_to_pdf tool`);\r\n }\r\n\r\n let content = \"\"\r\n if(path.startsWith(\"http\")){\r\n const resp = await this.read_any_file(path);\r\n content = (resp.content[0].text as string)??\"\"\r\n }else {\r\n const validPath = await validatePath(path);\r\n content = await readFile(validPath,'utf-8');\r\n }\r\n\r\n // content 转换成 base64\r\n const buffer = Buffer.from(content, 'utf-8');\r\n const base64String = buffer.toString('base64');\r\n const convertResult = await convertMarkdownToDoc(base64String, 1);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${convertResult}`\r\n }],\r\n };\r\n }\r\n );\r\n // 工具:markdown 2 docx\r\n this.server.tool(\r\n \"convert_markdown_to_docx\",\r\n \"markdown转换成docx文件\",\r\n {path: z.string().describe(\"文件路径(可以是远程url)\")},\r\n async ({ path }) => {\r\n if (!path) {\r\n throw new Error(`Invalid arguments for convert_markdown_to_docx tool`);\r\n }\r\n\r\n let content = \"\"\r\n if(path.startsWith(\"http\")){\r\n const resp = await this.read_any_file(path);\r\n content = (resp.content[0].text as string)??\"\"\r\n }else {\r\n const validPath = await validatePath(path);\r\n content = await readFile(validPath, 'utf-8');\r\n }\r\n\r\n // content 转换成 base64\r\n const buffer = Buffer.from(content, 'utf-8');\r\n const base64String = buffer.toString('base64');\r\n const convertResult = await convertMarkdownToDoc(base64String, 0);\r\n return {\r\n content: [{\r\n type: \"text\",\r\n text: `${convertResult}`\r\n }],\r\n };\r\n }\r\n );\r\n}\r\n\r\n async connect(transport: Transport): Promise<void> {\r\n try {\r\n await this.server.connect(transport);\r\n \r\n Logger.log = (...args: any[]) => {\r\n try {\r\n this.server.server.sendLoggingMessage({\r\n level: \"info\",\r\n data: args,\r\n });\r\n } catch (error) {\r\n logger.info(args);\r\n }\r\n };\r\n\r\n Logger.error = (...args: any[]) => {\r\n try {\r\n this.server.server.sendLoggingMessage({\r\n level: \"error\",\r\n data: args,\r\n });\r\n } catch (error) {\r\n logger.error(args);\r\n }\r\n };\r\n\r\n logger.info(\"OSS MCP服务器已连接并准备处理请求\");\r\n } catch (error) {\r\n logger.error(\"连接到传输时出错:\", error);\r\n }\r\n }\r\n\r\n async startHttpServer(port: number): Promise<void> {\r\n const app = express();\r\n\r\n // SSE连接端点 - 修复头部发送冲突\r\n app.get(\"/sse\", (req: Request, res: Response) => {\r\n // 初始化SSE传输,不再自己设置头部,而是让SDK处理\r\n this.sseTransport = new SSEServerTransport(\r\n \"/messages\",\r\n res as unknown as ServerResponse<IncomingMessage>\r\n );\r\n\r\n try {\r\n // 连接到传输层\r\n this.server.connect(this.sseTransport)\r\n .catch((err) => {\r\n logger.error(\"连接到SSE传输时出错:\", err);\r\n });\r\n\r\n // 处理客户端断开连接\r\n req.on('close', () => {\r\n logger.info('SSE客户端断开连接');\r\n this.sseTransport = null;\r\n });\r\n } catch (error) {\r\n logger.error(\"建立SSE连接时出错:\", error);\r\n // 如果连接失败,关闭响应\r\n if (!res.writableEnded) {\r\n res.status(500).end();\r\n }\r\n }\r\n });\r\n\r\n // 消息端点\r\n app.post(\"/messages\", async (req: Request, res: Response) => {\r\n if (!this.sseTransport) {\r\n logger.info(\"尝试发送消息,但SSE传输未初始化\");\r\n res.status(400).json({\r\n error: 'SSE连接未建立',\r\n message: '请先连接到/sse端点'\r\n });\r\n return;\r\n }\r\n\r\n try {\r\n await this.sseTransport.handlePostMessage(\r\n req as unknown as IncomingMessage,\r\n res as unknown as ServerResponse<IncomingMessage>\r\n );\r\n } catch (error) {\r\n console.error(\"处理消息时出错:\", error);\r\n if (!res.writableEnded) {\r\n res.status(500).json({\r\n error: \"内部服务器错误\",\r\n message: String(error)\r\n });\r\n }\r\n }\r\n });\r\n\r\n // 启动服务器\r\n app.listen(port, () => {\r\n Logger.log = console.log;\r\n Logger.error = console.error;\r\n\r\n Logger.log(`HTTP服务器监听端口: ${port}`);\r\n Logger.log(`SSE端点: http://localhost:${port}/sse`);\r\n Logger.log(`消息端点: http://localhost:${port}/messages`);\r\n });\r\n }\r\n}\r\n\r\n","import OSS from 'ali-oss';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { OssConfig, getOssConfig, ServerConfig, getServerConfig } from '../config/config.js';\r\nimport { z } from 'zod';\r\n\r\n// 上传文件参数验证Schema\r\nexport const UploadFileParamsSchema = z.object({\r\n filePath: z.string(),\r\n targetDir: z.string().optional(),\r\n fileName: z.string().optional(),\r\n configName: z.string().optional(),\r\n});\r\n\r\n// 导出上传文件参数类型\r\nexport type UploadFileParams = z.infer<typeof UploadFileParamsSchema>;\r\n\r\n// 上传结果验证Schema\r\nexport const UploadResultSchema = z.object({\r\n success: z.boolean(),\r\n url: z.string().optional(),\r\n error: z.string().optional(),\r\n ossConfigName: z.string().optional(),\r\n});\r\n\r\n// 导出上传结果类型\r\nexport type UploadResult = z.infer<typeof UploadResultSchema>;\r\n\r\n/**\r\n * OSS配置接口(包含ID和名称)\r\n */\r\nexport interface OssConfigWithMeta extends OssConfig {\r\n id: string;\r\n name: string;\r\n}\r\n\r\n/**\r\n * 阿里云OSS服务类\r\n */\r\nexport class OssService {\r\n private clients: Map<string, OSS> = new Map();\r\n private serverConfig?: ServerConfig;\r\n /**\r\n * 获取所有OSS配置\r\n * @returns OSS配置列表\r\n */\r\n async getConfigs(): Promise<OssConfigWithMeta[]> {\r\n if(this.serverConfig == null){\r\n this.serverConfig = await getServerConfig();\r\n }\r\n\r\n const configs: OssConfigWithMeta[] = [];\r\n const allConfigs = this.serverConfig.ossConfig;\r\n\r\n for (const [id, config] of Object.entries(allConfigs)) {\r\n configs.push({\r\n id,\r\n name: `${id.charAt(0).toUpperCase()}${id.slice(1)} 配置`,\r\n ...config\r\n });\r\n }\r\n\r\n return configs;\r\n }\r\n\r\n /**\r\n * 获取OSS客户端\r\n * @param configName 配置名称\r\n * @returns OSS客户端实例\r\n */\r\n private async getClient(configName: string = 'default'): Promise<OSS | null> {\r\n // 检查缓存中是否已有客户端\r\n if (this.clients.has(configName)) {\r\n return this.clients.get(configName) as OSS;\r\n }\r\n\r\n // 获取配置并创建客户端\r\n const config = await getOssConfig(configName);\r\n if (!config) {\r\n return null;\r\n }\r\n\r\n try {\r\n const client = new OSS({\r\n region: config.region,\r\n accessKeyId: config.accessKeyId,\r\n accessKeySecret: config.accessKeySecret,\r\n bucket: config.bucket,\r\n endpoint: config.endpoint\r\n });\r\n\r\n // 缓存客户端实例\r\n this.clients.set(configName, client);\r\n return client;\r\n } catch (error) {\r\n console.error(`Failed to create OSS client for ${configName}:`, error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * 上传文件到OSS\r\n * @param params 上传参数\r\n * @returns 上传结果\r\n */\r\n async uploadFile(params: UploadFileParams): Promise<UploadResult> {\r\n // 验证并解析参数\r\n const validParams = UploadFileParamsSchema.parse(params);\r\n const { filePath, targetDir = 'mcp', fileName, configName = 'default' } = validParams;\r\n\r\n try {\r\n // 检查文件是否存在\r\n if (!fs.existsSync(filePath)) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `File not found: ${filePath}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n\r\n // 获取OSS客户端\r\n const client = await this.getClient(configName);\r\n if (!client) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `OSS config not found for: ${configName}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n\r\n // 确定文件名\r\n const actualFileName = fileName || path.basename(filePath);\r\n\r\n // 构建OSS路径,确保正斜杠格式\r\n let ossPath = actualFileName;\r\n if (targetDir) {\r\n // 规范化目标目录:移除头尾斜杠,然后加上结尾斜杠\r\n const normalizedDir = targetDir.replace(/^\\/+|\\/+$/g, '');\r\n ossPath = normalizedDir ? `${normalizedDir}/${actualFileName}` : actualFileName;\r\n }\r\n\r\n // 上传文件\r\n const result = await client.put(ossPath, filePath);\r\n const config = await getOssConfig(configName);\r\n return UploadResultSchema.parse({\r\n success: true,\r\n url: result.url.replace(/https?:\\/\\/[^/]+/, config!.cdnHost!), //替换域名为CDN域名\r\n ossConfigName: configName\r\n });\r\n } catch (error) {\r\n return UploadResultSchema.parse({\r\n success: false,\r\n error: `Upload failed: ${(error as Error).message}`,\r\n ossConfigName: configName\r\n });\r\n }\r\n }\r\n}\r\n\r\n// 导出单例实例\r\nexport const ossService = new OssService();\r\n","import { config } from \"dotenv\";\r\nimport { z } from \"zod\";\r\nimport { logger } from \"../util/logger.js\";\r\nimport { decrypt } from \"../util/aes.js\";\r\nimport { NewApiUser } from \"../types.js\";\r\nimport { getUserSetting } from \"../api/corp.js\";\r\nimport { ConfigManager } from \"./auth/config.js\";\r\nimport * as fpath from 'path';\r\nimport os from 'os';\r\nimport {stat} from \"fs/promises\";\r\nimport { Config } from \"../api/cherry/api.js\";\r\nconfig();\r\n\r\n// OSS配置验证Schema\r\nexport const OssConfigSchema = z.object({\r\n region: z.string(),\r\n accessKeyId: z.string(),\r\n accessKeySecret: z.string(),\r\n bucket: z.string(),\r\n endpoint: z.string(),\r\n cdnHost: z.string()\r\n});\r\n\r\n// 导出OSS配置类型\r\nexport type OssConfig = z.infer<typeof OssConfigSchema>;\r\n\r\n// 服务器配置接口\r\nexport interface ServerConfig {\r\n port: number;\r\n ossConfig: Record<string, OssConfig>;\r\n configSources: {\r\n port: \"cli\" | \"env\" | \"default\";\r\n ossConfig: \"cli\" | \"env\" | \"default\";\r\n };\r\n newApiAuthData: string;\r\n}\r\nfunction expandHome(filepath: string): string {\r\n if (filepath.startsWith('~/') || filepath === '~') {\r\n return fpath.join(os.homedir(), filepath.slice(1));\r\n }\r\n return filepath;\r\n}\r\nfunction normalizePath(p: string): string {\r\n return fpath.normalize(p);\r\n}\r\n// 获取服务器配置\r\nexport async function getServerConfig(isStdioMode: boolean = false): Promise<ServerConfig> {\r\n // 解析命令行参数\r\n logger.info(\"正在加载服务器配置...\");\r\n const newApiAuthData = process.argv.find(arg => arg.startsWith(\"--newApiAuthData=\"));\r\n if (!newApiAuthData) {\r\n logger.error('newApiAuthData argv variable is not set');\r\n throw new Error(\"newApiAuthData environment variable is not set\");\r\n }\r\n\r\n const apiServer = process.argv.find(arg => arg.startsWith(\"--apiServer=\"));\r\n if (!apiServer) {\r\n logger.error('apiServer argv variable is not set');\r\n throw new Error(\"apiServer environment variable is not set\");\r\n }\r\n\r\n const config: ServerConfig = {\r\n port: 3000,\r\n ossConfig: {},\r\n configSources: {\r\n port: \"default\",\r\n ossConfig: \"default\",\r\n },\r\n newApiAuthData: \"\"\r\n };\r\n\r\n // 处理端口配置\r\n config.configSources.port = \"cli\";\r\n\r\n // base64 decode data\r\n let newApiAuthDataRaw = newApiAuthData.substring(\"--newApiAuthData=\".length).trim();\r\n newApiAuthDataRaw = newApiAuthDataRaw.replace(/^['\"`\\\\]+|['\"`\\\\]+$/g, '').trim();\r\n const newApiAuthDataString = Buffer.from(newApiAuthDataRaw, 'base64').toString('utf8');\r\n const newApiAuthDataArry = newApiAuthDataString.split(\"變\");\r\n if (newApiAuthDataArry.length !== 2) {\r\n logger.error('NEW_API_AUTH_DATA environment variable is not set');\r\n throw new Error(\"NEW_API_AUTH_DATA environment variable is not set\");\r\n }\r\n\r\n const newApiAuthDataDecrypt = decrypt(newApiAuthDataArry[0],newApiAuthDataArry[1], \"1234567890123abc7890123456OAcl12\").replace(\"\u0006\",\"\");\r\n const newApiUser = JSON.parse(newApiAuthDataDecrypt) as NewApiUser;\r\n const userSetting = await getUserSetting({serverUrl: newApiUser.newApiServerUrl, accessToken: newApiUser.newApiAccessToken, userId: newApiUser.newApiUserId});\r\n const allOssConfigs = {\"default\":{region: \"cn-hongkong\", accessKeyId: userSetting.accessKeyId, accessKeySecret: userSetting.accessKeySecret, bucket: userSetting.bucketName, endpoint: userSetting.endpoint, cdnHost: userSetting.cdnHost}}\r\n config.ossConfig = allOssConfigs;\r\n config.configSources.ossConfig = \"cli\";\r\n \r\n let apiServerRaw = apiServer.substring(\"--apiServer=\".length).trim();\r\n // 去除可能包含的引号、反引号或反斜杠\r\n apiServerRaw = apiServerRaw.replace(/^['\"`\\\\]+|['\"`\\\\]+$/g, '').trim();\r\n \r\n let apiServerConfig: Config;\r\n try {\r\n if (apiServerRaw.startsWith(\"http\")) {\r\n const url = new URL(apiServerRaw);\r\n apiServerConfig = {\r\n enabled: true,\r\n host: url.hostname,\r\n port: url.port ? parseInt(url.port) : (url.protocol === 'https:' ? 443 : 80),\r\n apiKey: \"\"\r\n };\r\n } else {\r\n let apiServerDataString = apiServerRaw;\r\n if (!apiServerDataString.startsWith(\"{\")) {\r\n apiServerDataString = Buffer.from(apiServerDataString, 'base64').toString('utf8');\r\n }\r\n apiServerConfig = JSON.parse(apiServerDataString) as Config;\r\n }\r\n } catch (e) {\r\n logger.error(`解析 apiServer 配置失败: ${e}`);\r\n throw new Error(\"Invalid apiServer configuration format. It should be a base64 encoded JSON string or a valid URL.\");\r\n }\r\n\r\n // 创建配置管理器\r\n await ConfigManager.init(newApiUser, userSetting, apiServerConfig);\r\n\r\n\r\n // 验证配置\r\n if (Object.keys(config.ossConfig).length === 0) {\r\n logger.warn(\"未找到有效的OSS配置。服务器将启动,但上传功能将不可用。\");\r\n }\r\n\r\n // 打印配置信息(非stdio模式下)\r\n if (!isStdioMode) {\r\n logger.info(\"配置信息:\");\r\n logger.info(JSON.stringify(config));\r\n }\r\n\r\n return config;\r\n}\r\n\r\n// 获取所有OSS配置\r\n async function getAllOssConfigs(): Promise<Record<string, OssConfig>> {\r\n const { ossConfig, } = await getServerConfig(true);\r\n \r\n return ossConfig;\r\n}\r\n\r\n// 获取特定名称的OSS配置\r\nexport async function getOssConfig(name: string = 'default'): Promise<OssConfig | null> {\r\n const configs = await getAllOssConfigs();\r\n const normalizedName = name.toLowerCase();\r\n return configs[normalizedName] || null;\r\n}\r\n\r\n// 获取可用的OSS配置名称列表\r\nexport async function getAvailableOssConfigNames(): Promise<string[]> {\r\n return Object.keys(await getAllOssConfigs());\r\n}\r\n","import winston from 'winston';\r\nimport 'winston-daily-rotate-file';\r\nimport path from 'path';\r\nimport fs from 'fs';\r\n\r\n// Create logs directory if it doesn't exist\r\nconst logsDir = path.join(process.cwd(), 'logs');\r\nif (!fs.existsSync(logsDir)) {\r\n fs.mkdirSync(logsDir, { recursive: true });\r\n}\r\n\r\n// Configure Winston logger\r\nexport const logger = winston.createLogger({\r\n level: 'debug',\r\n format: winston.format.combine(\r\n winston.format.timestamp({\r\n format: 'YYYY-MM-DD HH:mm:ss.SSS'\r\n }),\r\n winston.format.errors({ stack: true }),\r\n winston.format.splat(),\r\n winston.format.json()\r\n ),\r\n defaultMeta: { service: 'mcp-oss' },\r\n transports: [\r\n // Write to rotating log files only to avoid interfering with MCP protocol\r\n new winston.transports.DailyRotateFile({\r\n filename: path.join(logsDir, 'mcp-oss-%DATE%.log'),\r\n datePattern: 'YYYY-MM-DD',\r\n zippedArchive: true,\r\n maxSize: '20m',\r\n maxFiles: '14d',\r\n format: winston.format.combine(\r\n winston.format.timestamp(),\r\n winston.format.json()\r\n )\r\n })\r\n ]\r\n});\r\n\r\n// Log unhandled errors\r\nprocess.on('uncaughtException', (error) => {\r\n logger.error('Uncaught Exception:', error);\r\n process.exit(1);\r\n});\r\n\r\nprocess.on('unhandledRejection', (error) => {\r\n logger.error('Unhandled Rejection:', error);\r\n});\r\n","import * as crypto from 'crypto'\r\n\r\n// 加密函数\r\nexport function encrypt(text: string, secretKey: string, iv: string): { iv: string; encryptedData: string } {\r\n const _iv = Buffer.from(iv, 'hex')\r\n const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secretKey), _iv)\r\n let encrypted = cipher.update(text, 'utf8', 'hex')\r\n encrypted += cipher.final('hex')\r\n return {\r\n iv: _iv.toString('hex'),\r\n encryptedData: encrypted\r\n }\r\n}\r\n\r\n// 解密函数\r\nexport function decrypt(encryptedData: string, iv: string, secretKey: string): string {\r\n const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(secretKey), Buffer.from(iv, 'hex'))\r\n let decrypted = decipher.update(encryptedData, 'hex', 'utf8')\r\n decrypted += decipher.final('utf8')\r\n return decrypted\r\n}\r\n","export interface UserSetting{\n\tonestepHost:string;\n\tappId :string ;\n\tclientId :string ;\n\tapiKey :string ;\n\tsecretKey :string ;\n\tversion :string ;\n\t\n\t//ticket system\n\tticketHost :string ;\n\tticketApiKey :string ;\n\tuserId :number ;\n\t// alioss\n\tendpoint :string ;\n\taccessKeyId :string ;\n\taccessKeySecret :string ;\n\tbucketName :string ;\n\tcdnHost :string ;\n}\nexport const getAiApiToken = async ({\n serverUrl,\n accessToken,\n userId\n}: {\n serverUrl: string\n accessToken: string\n userId: string\n}): Promise<string> => {\n // fetch 实现登录功能\n const res = await fetch(`${serverUrl}/api/token?p=1&size=1`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'new-api-user': userId\n }\n })\n const data = await res.json()\n if (data.success) {\n return 'sk-' + data.data.items[0].key\n } else {\n throw new Error(data.msg)\n }\n}\n\nexport const getUserSetting = async ({\n serverUrl,\n accessToken,\n userId\n}: {\n serverUrl: string\n accessToken: string\n userId: string\n}): Promise<UserSetting> => {\n // fetch 实现登录功能\n const res = await fetch(`${serverUrl}/api/user/setting`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'new-api-user': userId\n }\n })\n\n const data = (await res.json()).data as UserSetting\n return data;\n}","import { Config } from '../../api/cherry/api.js';\r\nimport { UserSetting } from '../../api/corp.js';\r\nimport { NewApiUser, OAuthConfig } from '../../types.js';\r\nimport { logger } from '../../util/logger.js';\r\n\r\nexport class ConfigManager {\r\n private static instance: ConfigManager;\r\n private static onestepClients: Record<string, string> = {\"saber\": \"saber_secret\", \"onestep_user\": \"ewkej3243242\"};\r\n private oAuthConfig: OAuthConfig;\r\n private newApiUser : NewApiUser;\r\n private apiConfig: Config;\r\n private constructor() {\r\n this.oAuthConfig= {} as OAuthConfig;\r\n this.newApiUser = {} as NewApiUser;\r\n this.apiConfig = {} as Config;\r\n }\r\n\r\n public static async getInstance(): Promise<ConfigManager> {\r\n if (!ConfigManager.instance) {\r\n throw new Error(\"the instance is not created\");\r\n }\r\n\r\n return ConfigManager.instance;\r\n }\r\n public static async init(newApiUser : NewApiUser, userSetting:UserSetting, apiConfig: Config): Promise<ConfigManager> {\r\n if (!ConfigManager.instance) {\r\n ConfigManager.instance = new ConfigManager();\r\n await ConfigManager.instance.loadConfig(userSetting);\r\n ConfigManager.instance.newApiUser = newApiUser;\r\n ConfigManager.instance.apiConfig = apiConfig;\r\n }\r\n\r\n return ConfigManager.instance;\r\n }\r\n\r\n private async loadConfig(userSetting:UserSetting): Promise<void> {\r\n // Try environment variables first\r\n const envConfig = {\r\n apiKey: process.env.OAUTH_API_KEY,\r\n secretKey: process.env.OAUTH_SECRET_KEY,\r\n host: process.env.OAUTH_HOST,\r\n appId : \"client003\",\r\n basicAuth :\"c2FiZXI6c2FiZXJfc2VjcmV0\",\r\n version :\"1.0\"\r\n };\r\n \r\n // Otherwise, try to load from config file\r\n try {\r\n // If all required env vars are present, use them\r\n if (envConfig.apiKey && envConfig.secretKey && envConfig.host) {\r\n this.oAuthConfig = envConfig as OAuthConfig;\r\n logger.info('Using environment variables for configuration.');\r\n }else if(userSetting.apiKey && userSetting.secretKey && userSetting.onestepHost){\r\n const clientId = userSetting.clientId;\r\n const clientSecret = ConfigManager.onestepClients[clientId];\r\n this.oAuthConfig = {apiKey:userSetting.apiKey,\r\n secretKey:userSetting.secretKey,\r\n host:userSetting.onestepHost,\r\n appId:userSetting.appId,\r\n basicAuth: btoa(`${clientId}:${clientSecret}`),\r\n version:userSetting.version}\r\n }else{\r\n throw new Error('Missing oAuthConfig.');\r\n }\r\n } catch (error) {\r\n throw new Error(`Failed to load configuration. ${error}`);\r\n }\r\n }\r\n\r\n public getOAuthConfig(): OAuthConfig {\r\n return this.oAuthConfig;\r\n }\r\n public getNewApiUser(): NewApiUser {\r\n return this.newApiUser;\r\n }\r\n public getApiConfig(): Config {\r\n return this.apiConfig;\r\n }\r\n}","import { request, RequestOptions } from \"https\";\r\nimport { IncomingMessage } from \"http\";\r\nimport {LoginResponse } from '../types.js';\r\nimport { OAuthCache } from '../cache.js';\r\nimport { ConfigManager } from '../config/auth/config.js';\r\nimport { logger } from \"../util/logger.js\";\r\nexport const thirdparyLogin = async (\r\n grantType: string\r\n): Promise<LoginResponse> => {\r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n \r\n // Check cache first\r\n const cache = OAuthCache.getInstance();\r\n const cacheKey = `${config.apiKey}_${config.secretKey}`;\r\n const cachedData = cache.get(cacheKey);\r\n\r\n if (cachedData) {\r\n return {\r\n code: 200,\r\n msg: \"Success (from cache)\",\r\n data: cachedData\r\n };\r\n }\r\n\r\n const postData = JSON.stringify({ \r\n grantType, \r\n apiKey: config.apiKey, \r\n secretKey: config.secretKey \r\n });\r\n \r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'Authorization':`Basic ${config.basicAuth}`\r\n },\r\n };\r\n\r\n return new Promise((resolve, reject) => {\r\n const req = request(config.host + '/api/onestep-ess/thirdparty/oauth/1.0/token', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n try {\r\n const parsedResponse: LoginResponse = JSON.parse(responseBody);\r\n if (parsedResponse.code === 200 && parsedResponse.data) {\r\n // Store in cache if login successful\r\n cache.set(cacheKey, parsedResponse.data);\r\n resolve(parsedResponse);\r\n }else{\r\n reject(\"Login failed, response:\"+JSON.stringify(parsedResponse));\r\n }\r\n } catch (error) {\r\n reject(new Error(`Failed to parse response: ${error instanceof Error ? error.message : 'Unknown error'}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(5000);\r\n req.write(postData);\r\n req.end();\r\n });\r\n};\r\n\r\ninterface ClassifyFilesResponse {\r\n code: number;\r\n msg: string;\r\n data:string;\r\n}\r\nexport const classifyFiles = async (\r\n fileUrl: string\r\n): Promise<ClassifyFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n const postData = JSON.stringify({ \r\n fileUrl, \r\n splitPdf: 0, \r\n trimPage: 0,\r\n provider: \"dify\"\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n console.log(\"classifyFiles request:\", JSON.stringify(options));\r\n const req = request(config.host + '/api/onestep-jod/docs2png/classifyFile', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n resolve(JSON.parse(responseBody));\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*120);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\ninterface RecFilesResponse {\r\n code: number;\r\n msg: string;\r\n status:number\r\n data:string;\r\n}\r\n\r\nexport const recFilesWithPull = async (\r\n fileUrls: string[],\r\n): Promise<RecFilesResponse> => {\r\n const response = await recFiles(fileUrls);\r\n if(response.code === 200 && response.status == 0){\r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n logger.info(\"recall recFiles response:\", response);\r\n return await recFilesWithPull(fileUrls);\r\n }else{\r\n logger.info(\"recFiles final response:\", response);\r\n return response;\r\n }\r\n}\r\nconst recFiles = async (\r\n fileUrls: string[],\r\n): Promise<RecFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n const postData = JSON.stringify({ \r\n fileUrls, \r\n splitPdf: 0, \r\n trimPage: 0,\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"recFiles request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/recFiles?t='+new Date().getTime(), options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"recFiles response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n jsonObject.status = jsonObject.data.status;\r\n jsonObject.data = JSON.stringify(jsonObject.data);\r\n resolve(jsonObject);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\nexport const splitPdf = async (\r\n path: string,\r\n splitPageNumbers: number[],\r\n): Promise<Record<string, string>> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n originPdfUrl: path, \r\n splitPageNumbers\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"splitPdf request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/splitPdf', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"splitPdf response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject.data.splitPdfUrlMap);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const combineFiles = async (\r\n urlList: string[],\r\n outFileName: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n urlList, \r\n outFileName\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"mergePdfs request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/docs2png/mergePdfs', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"mergePdfs response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject.data);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const convertPdfToDocxWithPull = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const pullResult =async function (pdfUrl: string): Promise<string> { \r\n const response = await convertPdfToDocx(pdfUrl);\r\n if(response.startsWith(\"http\")){\r\n return response;\r\n }else if(response.startsWith(\"68747470\")){ \r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n return pullResult(pdfUrl);\r\n }else{ \r\n throw new Error(`Failed to convert PDF to Markdown: ${response}`);\r\n }\r\n }\r\n return await pullResult(pdfUrl);\r\n}\r\nexport const convertPdfToDocx = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n pdfUrl, \r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertPdfToDocx request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/pdf2docx', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertPdfToDocx response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\nexport const convertMarkdownToDoc = async (\r\n markdown: string,\r\n resultType:number\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n markdown, \r\n resultType\r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertMarkdownToDoc request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/markdown2Doc', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertMarkdownToDoc response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}\r\n\r\nexport const convertPdfToMarkdownWithPull = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const transactionId = await convertPdfToMarkdown(pdfUrl);\r\n const pullResult =async function (transactionId: string): Promise<string> { \r\n const response = await fetchResult(transactionId);\r\n if(response.code ==200){\r\n return response.data;\r\n }else if(response.code == 202){ \r\n await new Promise(resolve => setTimeout(resolve, 30*1000)); // Wait for 1 minute\r\n return pullResult(transactionId);\r\n }else{ \r\n throw new Error(`Failed to convert the document to Markdown: ${response.msg}`);\r\n }\r\n }\r\n return await pullResult(transactionId);\r\n}\r\n\r\nconst fetchResult = async (\r\n transactionId: string,\r\n): Promise<RecFilesResponse> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'get',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"fetchResult request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/fetchResult?transactionId=' + transactionId, options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"fetchResult response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n resolve(jsonObject);\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.end();\r\n });\r\n}\r\nconst convertPdfToMarkdown = async (\r\n pdfUrl: string,\r\n): Promise<string> => {\r\n const response = await thirdparyLogin(\"client_credentials\");\r\n const accessToken = response.data.accessToken;\r\n\r\n const postData = JSON.stringify({ \r\n url:pdfUrl, \r\n });\r\n \r\n const config = (await ConfigManager.getInstance()).getOAuthConfig();\r\n const options: RequestOptions = {\r\n method: 'POST',\r\n // rejectUnauthorized: false,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Content-Length': Buffer.byteLength(postData),\r\n 'cloudx-auth': `Bearer ${accessToken}`,\r\n 'Authorization':`Basic ${config.basicAuth}`,\r\n 'Lan':'en',\r\n 'Locale':'hk'\r\n },\r\n };\r\n return new Promise((resolve, reject) => {\r\n logger.info(\"convertPdfToMarkdown request:\", JSON.stringify(options));\r\n const req = request(config.host+'/api/onestep-jod/jodApi/generateDoc/doc2Markdown', options, (res: IncomingMessage) => {\r\n let responseBody = '';\r\n \r\n res.on('data', (chunk: Buffer) => {\r\n responseBody += chunk.toString();\r\n });\r\n\r\n res.on('end', () => {\r\n logger.info(\"convertPdfToMarkdown response:\", responseBody);\r\n const jsonObject = JSON.parse(responseBody);\r\n if(jsonObject.code == 200){\r\n resolve(jsonObject.data);\r\n }else{\r\n reject(new Error(`Request failed: ${jsonObject.msg}`));\r\n }\r\n });\r\n });\r\n\r\n req.on('error', (error: Error) => {\r\n reject(new Error(`Request failed: ${error.message}`));\r\n });\r\n\r\n req.on('timeout', () => {\r\n req.destroy(new Error('Request timed out'));\r\n });\r\n\r\n req.setTimeout(1000*600);\r\n req.write(postData);\r\n req.end();\r\n });\r\n}","import type { OauthResponseData } from './types.js';\r\n\r\ninterface CacheItem {\r\n data: OauthResponseData;\r\n expiry: number;\r\n}\r\n\r\nexport class OAuthCache {\r\n private static instance: OAuthCache;\r\n private cache: Map<string, CacheItem>;\r\n private readonly CACHE_DURATION = 30 * 60 * 1000; // 30 minutes in milliseconds\r\n\r\n private constructor() {\r\n this.cache = new Map();\r\n }\r\n\r\n public static getInstance(): OAuthCache {\r\n if (!OAuthCache.instance) {\r\n OAuthCache.instance = new OAuthCache();\r\n }\r\n return OAuthCache.instance;\r\n }\r\n\r\n public set(key: string, data: OauthResponseData): void {\r\n const expiry = Date.now() + this.CACHE_DURATION;\r\n this.cache.set(key, { data, expiry });\r\n }\r\n\r\n public get(key: string): OauthResponseData | null {\r\n const item = this.cache.get(key);\r\n if (!item) return null;\r\n\r\n if (Date.now() > item.expiry) {\r\n this.cache.delete(key);\r\n return null;\r\n }\r\n\r\n return item.data;\r\n }\r\n\r\n public clear(): void {\r\n this.cache.clear();\r\n }\r\n} ","export interface OauthResponseData {\r\n accessToken: string\r\n tokenType: string\r\n refreshToken: string\r\n userId: string \r\n oauthId: string \r\n userName: string\r\n account: string \r\n expiresIn: number\r\n}\r\nexport interface AliOssUploadResult {\r\n code:number;\r\n msg:string;\r\n fileName:string;\r\n url:string;\r\n}\r\nexport interface LoginResponse {\r\n code: number\r\n msg: string \r\n data: OauthResponseData\r\n}\r\n\r\nexport interface LoginError extends Error {\r\n code: number;\r\n msg: string;\r\n} \r\n\r\nexport interface OAuthConfig {\r\n apiKey: string;\r\n secretKey: string;\r\n host: string;\r\n\tappId :string ;\r\n\tbasicAuth :string ;\r\n\tversion :string ;\r\n}\r\nexport interface NewApiUser {\r\n newApiServerUrl:string;\r\n newApiAccessToken:string;\r\n newApiUserId:string;\r\n newApiGroup:string;\r\n}\r\nexport enum TextDocType { \r\n // 纯文本文件类型 \r\n TXT = \"TXT\",\r\n // Markdown 文件类型\r\n MD = \"MD\",\r\n // CSV 文件类型\r\n CSV = \"CSV\",\r\n LOG=\"LOG\",\r\n XML=\"XML\",\r\n JSON=\"JSON\",\r\n HTML=\"HTML\",\r\n YAML=\"YAML\",\r\n JS=\"JS\",\r\n CSS=\"CSS\",\r\n SQL=\"SQL\",\r\n // 其他文件类型\r\n OTHER = \"OTHER\",\r\n}\r\n\r\nexport enum DocType {\r\n UNKNOWN = \"UNKNOWN\",\r\n BR = \"BR\",\r\n CR = \"CR\",\r\n NNC1 = \"NNC1\",\r\n NNC2 = \"NNC2\",\r\n NAR1 = \"NAR1\",\r\n ND2A = \"ND2A\",\r\n ND2B = \"ND2B\",\r\n ND4 = \"ND4\",\r\n NR1 = \"NR1\",\r\n NDR1 = \"NDR1\",\r\n NSC1 = \"NSC1\",\r\n AD = \"AD\",\r\n IR1263 = \"IR1263\",\r\n EXTRA_FIRST_PAGE = \"EXTRA_FIRST_PAGE\",\r\n PASSPORT = \"PASSPORT\",\r\n ID = \"IDCARD\", // 对应 Java: ID (\"IDCARD\")\r\n PROOFOFADDRESS = \"PROOFOFADDRESS\",\r\n}\r\n\r\nexport namespace TextDocType {\r\n export function isTextDocType(docType: string): boolean {\r\n return docType.length > 0 && Object.values(TextDocType).includes(docType.slice(1).toUpperCase() as TextDocType);\r\n }\r\n}\r\nexport namespace DocType {\r\n export function name(nameValue: string): DocType {\r\n for (const key in DocType) {\r\n if (DocType[key as keyof typeof DocType] === nameValue) {\r\n return DocType[key as keyof typeof DocType] as DocType;\r\n }\r\n }\r\n return DocType.UNKNOWN;\r\n }\r\n\r\n export function nameContains(nameValue: string): DocType {\r\n for (const key in DocType) {\r\n const docTypeValue = DocType[key as keyof typeof DocType];\r\n // Ensure we are checking against the string values of the enum\r\n if (typeof docTypeValue === 'string' && nameValue.includes(docTypeValue)) {\r\n return docTypeValue;\r\n }\r\n }\r\n return DocType.UNKNOWN;\r\n }\r\n}\r\n\r\n","import winston from 'winston';\r\nimport { CallMcpToolRequest, CallMcpToolResponse, McpResponseItem } from './api.js';\r\nimport { Client } from '@modelcontextprotocol/sdk/client';\r\nimport { CallToolRequest, CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\r\n\r\nexport class McpClient {\r\n client: Client;\r\n logger: winston.Logger;\r\n\r\n constructor(client: Client, logger: winston.Logger) {\r\n this.client = client;\r\n this.logger = logger;\r\n }\r\n\r\n async CallTool(request: CallMcpToolRequest): Promise<CallMcpToolResponse> {\r\n // Create the request object for the underlying client\r\n const req = {\r\n method: \"tools/call\",\r\n params: {\r\n name: request.method,\r\n arguments: request.data\r\n }\r\n } as CallToolRequest;\r\n\r\n const response: CallMcpToolResponse = {\r\n isError: false,\r\n content: []\r\n };\r\n\r\n let contents: McpResponseItem[] = [];\r\n \r\n try {\r\n \r\n const result = await this.client.callTool(req.params, CallToolResultSchema, { timeout: 30 * 60 * 1000 });\r\n response.isError = result.isError as boolean;\r\n \r\n // Process content based on type\r\n if (result.content && Array.isArray(result.content)) {\r\n for (const content of result.content) {\r\n switch (content.type) {\r\n case \"text\":\r\n contents.push({\r\n type: content.type,\r\n text: content.text || \"\"\r\n });\r\n break;\r\n case \"image\":\r\n contents.push({\r\n type: content.type,\r\n text: content.data || content.url || \"\"\r\n });\r\n break;\r\n case \"audio\":\r\n contents.push({\r\n type: content.type,\r\n text: content.data || content.url || \"\"\r\n });\r\n break;\r\n default:\r\n this.logger.error(\"not supported content: %j\", content);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n response.content = contents;\r\n return response;\r\n } catch (err) {\r\n this.logger.error(\"CallTool failed: %s\", err instanceof Error ? err.message : String(err));\r\n response.isError = true;\r\n contents.push({\r\n type: \"text\",\r\n text: err instanceof Error ? err.message : String(err)\r\n });\r\n response.content = contents;\r\n return response;\r\n }\r\n }\r\n}","import winston from \"winston\";\nimport { McpClient } from \"./client.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n\nexport interface Config{\n\tenabled:boolean;\n\thost: string ;\n\tport: number;\n\tapiKey: string;\n}\nexport interface ListMcpServerRequest{\n\n}\n\nexport interface McpServer{\n id: string;\n name: string;\n type:string;\n description: string;\n url: string;\n}\nexport interface Servers{\n servers:Record<string, McpServer>;\n}\nexport interface ListMcpServerResponse{\n success:boolean;\n data: Servers;\n}\n\nexport interface GetMcpServerInfoRequest{\n serverId: string;\n}\nexport interface GetMcpServerInfoResponse{\n success:boolean;\n data: McpServer;\n}\n\nexport interface CallMcpToolRequest{\n serverId: string;\n method: string;\n data: Record<string, any>;\n}\n\nexport interface McpResponseItem{\n type:string;\n text:string;\n}\nexport interface CallMcpToolResponse{\n isError:boolean;\n content:McpResponseItem[];\n}\n\nexport interface ClassifiedResponseData{\n classifiedByFileNames:Record<string, string[]>[] | Record<string, string[]>;\n}\nexport interface ExcelWorkbookMeta{\n filename: string,\n sheets: string[],\n size: number,\n modified: number\n}\n\nexport class CherryClient {\n config: Config;\n logger: winston.Logger;\n mcpServers: Record<string, McpServer>;\n mcpClients: Record<string, McpClient>;\n\n constructor(config: Config, logger: winston.Logger) {\n this.config = config;\n this.logger = logger;\n this.mcpServers = {};\n this.mcpClients = {};\n }\n async listMcpServer(): Promise<ListMcpServerResponse> {\n // fetch listMcpServer\n this.logger.info(`Fetching list of MCP servers(http://${this.config.host}:${this.config.port}/v1/mcps)`);\n const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n }\n })\n\n const data = (await res.json()) as ListMcpServerResponse;\n this.mcpServers = data.data.servers;\n return data;\n }\n async getMcpServerInfo(request: GetMcpServerInfoRequest): Promise<GetMcpServerInfoResponse> {\n const res = await fetch(`http://${this.config.host}:${this.config.port}/v1/mcps/${request.serverId}`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n }\n })\n const data = (await res.json()) as GetMcpServerInfoResponse\n return data;\n }\n\n async callTool(request: CallMcpToolRequest): Promise<CallMcpToolResponse> {\n let mcpClient = this.mcpClients[request.serverId];\n if(mcpClient == null){ \n const transport = new StreamableHTTPClientTransport(new URL(`http://${this.config.host}:${this.config.port}/v1/mcps/${request.serverId}/mcp`),\n {requestInit: {headers: {Authorization: `Bearer ${this.config.apiKey}`}}});\n const client = new Client({\n name: \"oss-mcp-client\",\n version: \"1.0.0\"\n },{})\n this.logger.info(\"Connecting to cherry MCP server...\");\n await client.connect(transport);\n mcpClient = new McpClient(client, this.logger);\n this.mcpClients[request.serverId] = mcpClient;\n }\n\n try {\n return await mcpClient.CallTool(request);\n } catch (err) {\n this.logger.error(\"CallTool failed: %s\", err instanceof Error ? err.message : String(err));\n throw err;\n }\n }\n}"],"mappings":"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","names":["z","fs","path","config","z","config","fs","path","fs","os","fpath","config","resolve","resolve","config","path","pdfUrl","transactionId","TextDocType","DocType","logger","request","config","logger","request","os","z","pattern","fs","config","path","configs","configNames","resolve","config","config","resolve"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-system-with-oss-mcp",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "本地文件处理以及远程oss存储服务",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "type-check": "tsc --noEmit",
24
24
  "lint": "eslint . --ext .ts",
25
25
  "format": "prettier --write \"src/**/*.ts\"",
26
- "pub:release": "pnpm build && npm publish --access public",
26
+ "pub:release": "pnpm build && npm publish --access public --registry=https://registry.npmjs.org",
27
27
  "publish:local": "pnpm build && npm pack",
28
28
  "serve:http": "node dist/index.js --http"
29
29
  },