UNPKG

mira-app-server

Version:

Mira Server - standalone server application using mira-app-core

178 lines 8.08 kB
"use strict"; /** * files 模块工具 * * upload/download 直接走 HttpClient,绕过 Node 下 FileList 未定义的问题(与 CLI 一致)。 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerFileTools = registerFileTools; const zod_1 = require("zod"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const helpers_1 = require("../helpers"); function registerFileTools(mcp, ctx) { mcp.registerTool('files_list', { description: '获取素材库的文件列表(支持过滤)', inputSchema: { libraryId: zod_1.z.string().describe('素材库 ID'), title: zod_1.z.string().optional().describe('按标题模糊搜索'), extension: zod_1.z.string().optional().describe('按扩展名筛选'), tags: zod_1.z.array(zod_1.z.string()).optional().describe('按标签筛选'), folder: zod_1.z.number().optional().describe('按文件夹 ID 筛选'), limit: zod_1.z.number().optional().describe('数量限制'), offset: zod_1.z.number().optional().describe('偏移量'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); const filters = {}; if (args.title) filters.title = args.title; if (args.extension) filters.extension = args.extension; if (args.tags?.length) filters.tags = args.tags; if (args.folder !== undefined) filters.folder = args.folder; if (args.limit !== undefined) filters.limit = args.limit; if (args.offset !== undefined) filters.offset = args.offset; const resp = await client.files().getFiles({ libraryId: args.libraryId, filters }); return Array.isArray(resp) ? resp : resp?.result || []; }); }); mcp.registerTool('files_get', { description: '获取单个文件的详细信息', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]).describe('文件 ID'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().getFile(args.libraryId, String(args.fileId)); }); }); mcp.registerTool('files_upload', { description: '上传一个或多个本地文件到指定素材库。paths 为本地文件路径数组。', inputSchema: { libraryId: zod_1.z.string(), paths: zod_1.z.array(zod_1.z.string()).describe('本地文件绝对路径数组'), tags: zod_1.z.array(zod_1.z.string()).optional().describe('为每个文件附加的标签'), folderId: zod_1.z.string().optional().describe('目标文件夹 ID'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); const formData = new FormData(); for (const p of args.paths) { const abs = path_1.default.resolve(p); if (!fs_1.default.existsSync(abs)) throw new Error(`文件不存在: ${abs}`); const buf = fs_1.default.readFileSync(abs); const blob = new Blob([new Uint8Array(buf)]); const name = path_1.default.basename(abs); const file = new File([blob], name); formData.append('files', file, name); } formData.append('libraryId', args.libraryId); if (args.tags?.length || args.folderId) { formData.append('payload', JSON.stringify({ data: { tags: args.tags, folder_id: args.folderId } })); } return await client.getHttpClient().upload('/api/files/upload', formData); }); }); mcp.registerTool('files_download', { description: '下载文件到本地。output 省略时使用文件原名保存到当前工作目录。', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]), output: zod_1.z.string().optional().describe('保存路径'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); const blob = await client.files().download(args.libraryId, String(args.fileId)); const buffer = Buffer.from(await blob.arrayBuffer()); let outPath = args.output; if (!outPath) { try { const info = await client.files().getFile(args.libraryId, String(args.fileId)); outPath = path_1.default.resolve(process.cwd(), info.title || String(args.fileId)); } catch { outPath = path_1.default.resolve(process.cwd(), String(args.fileId)); } } fs_1.default.writeFileSync(outPath, buffer); return { savedTo: outPath, bytes: buffer.length }; }); }); mcp.registerTool('files_rename', { description: '重命名文件(同文件夹下重名会返回 409)', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]), name: zod_1.z.string().describe('新文件名'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().renameFile(args.libraryId, String(args.fileId), args.name); }); }); mcp.registerTool('files_update', { description: '更新文件元数据(任意键值,如 website 等)', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]), data: zod_1.z.record(zod_1.z.any()).describe('要更新的元数据对象'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().updateFile(args.libraryId, String(args.fileId), args.data); }); }); mcp.registerTool('files_delete', { description: '删除文件(默认移入回收站,permanent=true 彻底删除)', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]), permanent: zod_1.z.boolean().optional().describe('彻底删除而不进回收站'), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().delete(args.libraryId, String(args.fileId), { moveToRecycleBin: !args.permanent, }); }); }); mcp.registerTool('files_restore', { description: '从回收站恢复文件', inputSchema: { libraryId: zod_1.z.string(), fileId: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]), }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().restoreFile(args.libraryId, String(args.fileId)); }); }); mcp.registerTool('files_empty_trash', { description: '清空素材库回收站', inputSchema: { libraryId: zod_1.z.string() }, }, async (args) => { return (0, helpers_1.run)(async () => { const client = ctx.getClient(); return await client.files().emptyTrash(args.libraryId); }); }); } //# sourceMappingURL=files.js.map