sync2nas-mcp
by mirkcale
README.md
# sync2nas-mcp
MCP服务器,用于同步本地电脑和远程 NAS的文件(通过SMB/CIFS协议)。
## 功能特性
- **文件同步**: 支持三种同步模式(本地→NAS、NAS→本地、双向同步)
- **自定义路径映射**: 通过 `customPattern` 灵活控制文件上传的目录结构
- **文件过滤**: 通过 `fileFilter` 只同步指定文件名
- **文件比较**: 智能检测文件差异
- **文件传输**: 支持单个文件的上传和下载
- **目录浏览**: 列出NAS上的文件和文件夹
- **自动创建目录**: 上传时自动创建远程目录
- **动态切换共享**: 支持运行时临时切换SMB共享文件夹
## 安装
```bash
# 克隆项目
git clone <repository-url>
cd auto_resync
# 安装依赖
pnpm install
# 构建项目
pnpm run build
```
## 配置
### 1. 环境变量配置
复制 `.env.example` 为 `.env` 并填写配置:
```bash
cp .env.example .env
```
编辑 `.env` 文件:
```env
# NAS连接配置
SMB_HOST=192.168.1.100
SMB_PORT=445
SMB_SHARE=共享文件夹名称
SMB_USERNAME=your_username
SMB_PASSWORD=your_password
SMB_DOMAIN=
# 同步配置
DEFAULT_SYNC_MODE=local-to-nas
DEFAULT_LOCAL_PATH=C:\Users\yourname\Documents
DEFAULT_REMOTE_PATH=/
DELETE_ORPHANED=false
# 忽略模式(逗号分隔)
IGNORE_PATTERNS=.DS_Store,Thumbs.db,*.tmp,*.temp,.git,node_modules
# 自定义路径映射(可选)
CUSTOM_PATTERN=
# 文件过滤(只同步指定文件名,逗号分隔)
FILE_FILTER=
```
### 2. Claude Desktop 配置
编辑 `%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"sync2nas": {
"command": "node",
"args": ["C:\\path\\to\\auto_resync\\dist\\index.js"],
"env": {
"SMB_HOST": "192.168.1.100",
"SMB_SHARE": "共享文件夹名称",
"SMB_USERNAME": "your_username",
"SMB_PASSWORD": "your_password"
}
}
}
}
```
### 3. 使用 MCP Inspector 调试
```bash
npx @modelcontextprotocol/inspector node dist/index.js
```
然后打开 http://127.0.0.1:6274 进行测试。
## 使用方法
### 可用工具
#### 1. sync-files
同步本地文件夹到NAS或从NAS同步到本地。
**参数:**
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|--------|------|
| `localPath` | string | 是 | - | 本地文件夹路径 |
| `remotePath` | string | 否 | `/` | NAS上的远程路径 |
| `share` | string | 否 | - | SMB共享名称(不传则使用默认配置) |
| `syncMode` | string | 否 | `local-to-nas` | 同步模式:`local-to-nas`、`nas-to-local`、`bidirectional` |
| `customPattern` | string | 否 | - | 自定义目录映射 |
| `fileFilter` | string[] | 否 | - | 只同步指定文件名 |
| `ignorePatterns` | string[] | 否 | `[]` | 忽略的文件模式 |
| `deleteOrphaned` | boolean | 否 | `false` | 是否删除目标端孤立文件 |
**customPattern 规则:**
`customPattern` 只定义目录映射,文件名会自动附加。支持的占位符:
- `{1}` - 本地路径的第1层目录
- `{2}` - 本地路径的第2层目录
- `{3}` - 本地路径的第3层目录
- `{n}` - 本地路径的第n层目录
- `{-1}` - 文件所在的父目录名
**示例:**
假设本地结构为 `面试相关/1/2/3/番茄钟.xlsx`:
| customPattern | 远程路径 | 说明 |
|---------------|----------|------|
| `{1}/{3}` | `/1/3/番茄钟.xlsx` | 保留第1、3层目录 |
| `{1}/{-1}` | `/1/3/番茄钟.xlsx` | 保留第1层 + 父目录 |
| `{3}` | `/3/番茄钟.xlsx` | 只保留第3层目录 |
| (空) | `/番茄钟.xlsx` | 直接放根目录 |
#### 2. compare-files
比较本地文件和NAS文件的差异。
**参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `localPath` | string | 是 | 本地文件夹路径 |
| `remotePath` | string | 否 | NAS上的远程路径(默认 `/`) |
| `ignorePatterns` | string[] | 否 | 忽略的文件模式 |
#### 3. upload-file
上传单个文件到NAS。
**参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `localPath` | string | 是 | 本地文件路径 |
| `remotePath` | string | 是 | NAS上的目标路径 |
#### 4. download-file
从NAS下载单个文件。
**参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `remotePath` | string | 是 | NAS上的文件路径 |
| `localPath` | string | 是 | 本地目标路径 |
#### 5. list-remote-files
列出NAS上的文件和文件夹。
**参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `remotePath` | string | 否 | 要列出的远程路径(默认 `/`) |
| `recursive` | boolean | 否 | 是否递归列出子目录 |
#### 6. test-connection
测试NAS连接状态,无需参数。
#### 7. get-time
获取当前时间,无需参数。
### 可用资源
- `workbuddy-mcp://status` - 服务器状态信息
- `workbuddy-mcp://config` - 同步配置信息
- `workbuddy-mcp://help` - 帮助文档
### 可用提示模板
- `quick-sync` - 快速同步本地文件夹到NAS
- `compare-and-report` - 比较本地和NAS文件差异并生成报告
- `smart-sync` - 智能同步:自动检测并同步有变化的文件
- `backup-to-nas` - 备份本地重要文件夹到NAS
## 使用示例
### 示例1:同步文件夹到NAS根目录
```
请同步 C:\Users\lyy84\Desktop\面试相关 到NAS
```
### 示例2:使用自定义路径映射
```
请同步 C:\Users\lyy84\Desktop\面试相关 到NAS
customPattern 设为 {1}/{3}
```
这样 `1/2/3/番茄钟.xlsx` 会上传到 `/1/3/番茄钟.xlsx`
### 示例3:只同步指定文件
```
请同步 C:\Users\lyy84\Desktop\面试相关 到NAS
只同步 番茄钟.xlsx 这个文件
```
### 示例4:切换共享文件夹同步
```
请同步 C:\Users\lyy84\Desktop\文件 到NAS,共享文件夹用 "备份"
```
### 示例5:查看同步结果
同步完成后会返回统计信息:
```json
{
"success": true,
"message": "同步完成",
"share": "临时文件",
"stats": {
"totalFiles": 2,
"uploaded": 2,
"downloaded": 0,
"deleted": 0,
"skipped": 0,
"errors": 0,
"duration": "0.15秒"
}
}
```
## 项目结构
```
auto_resync/
├── src/
│ ├── index.ts # MCP服务器入口
│ ├── constants.ts # 常量定义(MCP_SERVER_NAME等)
│ ├── types.ts # 类型定义(SmbConfig, SyncConfig等)
│ ├── tools/
│ │ └── sync.ts # 工具定义(sync-files, compare-files等)
│ ├── resources/
│ │ ├── config.ts # MCP资源定义
│ │ └── prompts.ts # 提示模板定义
│ └── utils/
│ ├── smb-client.ts # SMB连接管理(含@EnsureConnected装饰器)
│ ├── file-sync.ts # 文件同步逻辑
│ └── config.ts # 配置加载
├── test/
│ └── server.test.ts # 测试文件
├── dist/ # TypeScript编译输出
├── .env # 环境变量配置(不提交到仓库)
├── .env.example # 环境变量示例
├── package.json
├── tsconfig.json
├── vitest.config.ts # 测试配置
└── README.md
```
## 开发命令
```bash
# 构建
pnpm run build
# 运行测试
pnpm test
# 启动MCP Inspector调试
npx @modelcontextprotocol/inspector node dist/index.js
```
## 注意事项
1. **安全性**: 密码等敏感信息通过 `.env` 配置,不要提交到代码仓库
2. **网络**: 确保本地电脑和NAS在同一网络中
3. **权限**: 确保SMB用户有足够权限访问共享文件夹
4. **SMB协议**: 路径使用正斜杠 `/`,代码会自动处理Windows反斜杠
5. **Synology NAS**: `readdir` 在访问共享根目录时可能有问题,`local-to-nas` 模式会自动跳过
## 故障排除
### 连接失败
- 检查NAS地址和端口是否正确
- 确认用户名和密码是否正确
- 检查防火墙是否阻止了SMB连接(端口445)
- 确认NAS的SMB服务已启用
### 同步失败
- 检查本地路径是否存在
- 确认远程路径是否有写入权限
- 查看MCP Inspector Console中的错误日志
## 许可证
MIT License
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues