download_huggingface_model
Download Hugging Face models locally with options to specify files, branches, and filters. Supports concurrent downloads, resume, and retries for efficient transfers.
Instructions
⚡ 高速下载 HuggingFace 模型到本地 - 支持并发下载、断点续传、智能重试,比传统方式快3-5倍。可指定文件、分支、筛选模式等高级选项。
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| allow_patterns | No | 允许下载的文件模式(glob 语法),支持单个或多个模式 | |
| download_dir | No | 下载保存目录(支持相对/绝对路径),默认:~/Downloads/huggingface_models | |
| files | No | 指定下载的具体文件列表(精确匹配文件路径) | |
| force_redownload | No | 强制重新下载(忽略本地缓存) | |
| ignore_patterns | No | 忽略的文件模式(glob 语法),支持单个或多个模式 | |
| repo_id | Yes | HuggingFace 仓库 ID,格式:用户名/模型名 | |
| revision | No | Git 分支、标签或 commit hash,默认:main | main |
Implementation Reference
- src/mcp/tools.js:215-287 (handler)Main handler function that orchestrates the download: validates inputs, constructs options and target directory, invokes downloader.download, handles response and errors.async callDownloadTool(args) { try { // 基础验证 if (!args.repo_id) { return CallToolResult.error( ToolContent.text('缺少必需参数: repo_id') ); } logger.info(`开始下载: ${args.repo_id}`); // 获取配置 const config = getConfig(); const downloadDir = args.download_dir || config.download_dir; // 构建目标目录 const targetDir = require('path').join( downloadDir, args.repo_id.replace('/', '_') ); // 构建选项 const options = { revision: args.revision, pattern: args.pattern, exclude: args.exclude, files: args.files, maxFiles: args.max_files, force: args.force, maxConcurrent: args.max_concurrent, token: args.token || process.env.HF_TOKEN }; // 执行下载 const result = await this.downloader.download( args.repo_id, targetDir, options ); if (result.success) { logger.info(`下载完成: ${result.files} 个文件`); const response = { success: true, repo_id: args.repo_id, path: result.path, files: result.files, size: result.size, duration: result.duration, suggestions: result.suggestions }; return CallToolResult.success( ToolContent.text(JSON.stringify(response, null, 2)) ); } else { logger.error('下载失败:', result.error); return CallToolResult.error( ToolContent.text(JSON.stringify({ success: false, error: result.error, suggestions: result.suggestions }, null, 2)) ); } } catch (error) { logger.error('工具调用失败:', error); return CallToolResult.error( ToolContent.text(`工具调用失败: ${error.message}`) ); } }
- src/mcp/tools.js:157-210 (schema)Defines the input schema, description, and parameters for the download_huggingface_model tool.getDownloadTool() { return new Tool( 'download_huggingface_model', '⚡ 高速下载 HuggingFace 模型到本地', { type: 'object', properties: { repo_id: { type: 'string', description: 'HuggingFace 仓库 ID(格式:owner/repo)', examples: ['2Noise/ChatTTS', 'microsoft/DialoGPT-medium'] }, download_dir: { type: 'string', description: '下载目录(默认:~/Downloads/huggingface_models)' }, revision: { type: 'string', description: 'Git 分支或标签', default: 'main' }, pattern: { type: 'string', description: '下载文件模式(例:*.safetensors)' }, exclude: { type: 'string', description: '排除文件模式(例:*.bin)' }, files: { type: 'array', items: { type: 'string' }, description: '指定下载的文件列表' }, max_files: { type: 'integer', description: '最大下载文件数', default: 100 }, force: { type: 'boolean', description: '强制重新下载', default: false }, max_concurrent: { type: 'integer', description: '最大并发下载数', default: 5 } }, required: ['repo_id'] } ); }
- src/mcp/tools.js:24-31 (registration)Registers the download_huggingface_model tool (via getDownloadTool()) in the list of available MCP tools.getTools() { return [ this.getDownloadTool(), this.getListTool(), this.getExploreTool(), this.getSearchTool() ]; }
- src/mcp/tools.js:446-461 (registration)Dispatches calls to the download_huggingface_model handler via switch case in the central callTool method.async callTool(name, args) { switch (name) { case 'download_huggingface_model': return await this.callDownloadTool(args); case 'list_huggingface_files': return await this.callListTool(args); case 'explore_huggingface_repo': return await this.callExploreTool(args); case 'search_huggingface_files': return await this.callSearchTool(args); default: return CallToolResult.error( ToolContent.text(`未知工具: ${name}`) ); } }
- src/core/downloader.js:110-174 (helper)Core download orchestration helper: lists files to download, ensures directory, invokes downloadManager, computes stats and suggestions.async download(repoId, targetDir, options = {}) { const startTime = Date.now(); const opts = { ...DEFAULT_OPTIONS, ...options }; // 设置认证 if (opts.token || process.env.HF_TOKEN) { this.http.setAuthToken(opts.token || process.env.HF_TOKEN); } try { // 确保目标目录存在 await ensureDirectory(targetDir); // 获取文件列表 const listResult = await this.list(repoId, opts); if (!listResult.success || !listResult.files?.length) { throw new RepositoryError( ErrorCode.NOT_FOUND, '未找到符合条件的文件', { repoId }, ['检查仓库ID和过滤条件'] ); } // 下载文件 const downloadResult = await this.downloadManager.downloadFiles( repoId, listResult.files, targetDir, { revision: opts.revision, maxConcurrent: opts.maxConcurrent, forceRedownload: opts.force, onProgress: opts.onProgress } ); // 计算统计 const duration = Date.now() - startTime; const totalSize = listResult.files.reduce((sum, f) => sum + (f.size || 0), 0); return { success: downloadResult.success, path: targetDir, files: downloadResult.stats.completedFiles, size: formatSize(totalSize), duration: formatDuration(duration), stats: { ...listResult.stats, ...downloadResult.stats }, suggestions: quickSuggestions({ files: listResult.files, stats: listResult.stats, download: downloadResult.stats }) }; } catch (error) { const repoError = error instanceof RepositoryError ? error : mapHttpError(error); return { success: false, error: repoError.toJSON(), suggestions: quickSuggestions({ error: repoError }) }; } }