Content
# ZSpace NAS MCP
90 MCP tools + 6 skills, allowing Claude/Cursor to directly operate ZSpace NAS.
## You Only Need Some of It
**This repository contains 3 independent components, take what you need. No need to clone the entire repo:**
| You are | You need | You don't need |
|---|---|---|
| **MCP User**(want to let Claude Code control NAS) | `zspace/mcp_server/` + `nas/` + `.env`(**API is built-in MCP**) | Skill / Dashboard / RAG |
| **Skill User**(want to use automation workflows) | Copy `skills/<name>/` to your project | MCP source code / Dashboard / RAG |
| **RAG User**(want semantic search) | `rag-server/` docker compose | Skill / Dashboard |
| **Developer**(want to add new tool/skill) | Clone the entire repo | — |
## MCP User (3 Steps to Install)
```bash
# 1. Install Python packages
git clone <repo> && cd zspace-mcp-poc
pip install -e . # or use ./start.sh deps
# 2. Configure connection
cp zspace/.env.example .env && vi .env # fill in NAS_HOST/USER/PASSWORD
# 3. Connect to Claude Code
./start.sh mcp-cfg # print config → paste to mcp.json
# Restart Claude Code, 90 tools appear automatically
```
First verification: `python skills/nas-setup/scripts/check.py`
## Skill User (Copy to Your Project)
```bash
# Copy needed skill to your Claude Code project
cp -r skills/nas-setup ~/your-project/skills/
# Prerequisites: Your project is already configured with MCP (previous step)
```
Skills are in `skills/` directory, Claude Code automatically discovers them when launched in this directory.
Current 6 skills: `nas-setup` (pre-requisite) `rag-manager` (RAG management) `media-organizer` `ios-memo-bak` `label-manager` `file-organizer`
## RAG User (Docker Deployment to NAS)
```bash
cd rag-server
docker compose up -d # image: coracoo/cherry:nas_rag
# Details: rag-server/README.md
```
## All Optional Components
| Component | Installation method | Purpose |
|---|---|---|
| MCP (required) | `pip install -e .` | 90 tools, Claude Code connects to NAS |
| Skill | Copy to `skills/` | 6 workflows, Agent automatically triggers |
| RAG docker | `docker compose up -d` | Semantic search, deployed on NAS |
| Dashboard | `./start.sh dashboard` | Web UI, iPhone memo entry |
| MCP HTTP transport | `./start.sh mcp-http` | LAN/remote MCP client, Bearer authentication, port 8765 |
| Baidu Netdisk | `zspace/scripts/netdisk_login.py` | OAuth login and then use 28 znetdisk tools |
```
User talks to Claude Code ← Natural language
↓
┌─ Skill layer (skills/) ──────────────┐
│ nas-setup / rag-manager / media-organizer│ ← LLM trigger words → automatically load SKILL.md
│ ios-memo-bak / label-manager / file-org │ ← Combine multiple MCP tools to complete complex processes
└──────────────────┬───────────────────────┘
↓ MCP protocol (stdio, JSON-RPC 2.0)
┌─ MCP layer (zspace/mcp_server/) ────────────────────┐
│ 90 tools (divided by domain) │ ← Claude Code mcp.json configuration automatically discovers
│ tools/{files,storage,zvideo,notebook, │ ← Each tool = 1 NAS API endpoint encapsulation
│ znetdisk,proxy,rag,...} │
└──────────────────┬───────────────────────┘
↓ HTTP (nas/)
┌─ Protocol layer (nas/, top-level shared package) ──────────────────────┐
│ auth.py RSA login + device_id selection │ ← Python library, Skill and MCP reuse
│ client.py NasClient(token automatically renewed) │
└──────────────────┬───────────────────────┘
↓ HTTP
┌─ ZSpace NAS ─────────────────────────────┐
│ :5055 main API (files/movies/notebook/netdisk...) │
│ :8000 RAG docker (semantic search, optional) │
└──────────────────────────────────────────┘
```
**Relationship between the three**: Skill is "what to do" (workflow) → MCP is "how to do" (single-step operation) → `nas/` is "how to connect" (protocol). New users only need to configure MCP, and skills automatically take effect.
## Required & Optional
| Component | Required? | Description |
|---|---|---|
| `.env` configuration | ✅ required | NAS connection information (NAS_HOST/USER/PASSWORD) |
| `zspace.mcp_server` (`-m` entry) | ✅ required | MCP stdio service, Claude Code connects to it |
| `nas-setup` skill | ✅ recommended | First run, verify env + login + optional components |
| `rag-server/` docker | Optional | RAG semantic search. Can still use 86 tools without it, only semantic_search is unavailable |
| `dashboard/` Dashboard | Optional | Web management interface (iPhone memo entry, etc.) |
| MCP HTTP transport | Optional | `./start.sh mcp-http`, LAN/remote MCP client, port 8765 + Bearer |
| Baidu Netdisk OAuth | Optional | 28 znetdisk tools require prior login |
## Installation
```bash
git clone <repo>
cd zspace-mcp-poc
# 1. Configure connection (required)
cp zspace/.env.example .env
vi .env # fill in NAS_HOST / NAS_USER / NAS_PASSWORD
# 2. Install Python dependencies (required)
./start.sh deps
# 3. Connect to Claude Code (required)
./start.sh mcp-cfg # print config snippet, paste to ~/.config/claude-code/mcp.json
# Restart Claude Code → 90 tools appear automatically
# 4. First verification
python skills/nas-setup/scripts/check.py
# Output ✅✅✅
# 5. (Optional) RAG semantic search
cd rag-server && docker compose up -d # requires NAS docker daemon
# 6. (Optional) Web Dashboard
./start.sh dashboard # http://localhost:15050
```
## Usage Example
```
User says in Claude Code: "Give the grade 1 textbook the label 'Grade 1'"
Agent internal execution process:
nas-setup skill automatically loads → check.py verifies .env/login/RAG
→ semantic_search("Grade 1 textbook") → MCP tool → POST NAS RAG daemon
→ returns 3 matches {path, snippet, distance}
→ Agent filters distance < 1.0
→ save_file_label("Grade 1", "path1,path2") → MCP tool → NAS API
→ MCP client displays UI for user approval
→ ✅ completed
```
## File Routing
```
zspace-mcp-poc/
├── nas/ NAS protocol layer (top-level shared package, skill/dashboard/mcp directly depend on)
│ ├── auth.py RSA public key + device_id automatic selection
│ ├── proto.py URL common parameters
│ └── client.py NasClient (token automatically renewed)
│
├── zspace/mcp_server/ MCP Server (entry python -m zspace.mcp_server)
│ ├── __main__.py -m entry
│ ├── main.py FastMCP entry
│ └── tools/ divided by domain
│ ├── files.py file read/write + label
│ ├── storage.py storage pool/hardware/SMART/monitoring
│ ├── zvideo.py ZVideo
│ ├── notebook.py Notebook (17)
│ ├── znetdisk.py Netdisk
│ ├── proxy.py remote access
│ ├── shares.py sharing/download
│ ├── media.py music/photos
│ └── rag.py RAG semantic search
│
├── dashboard/app/ Web Dashboard (entry python -m dashboard.app)
│ ├── __main__.py -m entry
│ ├── main.py FastAPI + Session
│ └── routes/
│ ├── shortcut.py iPhone memo → NAS entry
│ ├── dashboard.py WebUI
│ └── files.py,notebook.py,zvideo.py file/notebook/movie CRUD
│
├── rag-server/ RAG docker service (independently deployed on NAS as file index)
│ ├── app/server.py /search /reindex /index /unindex /status
│ ├── Dockerfile + docker-compose.yml
│ └── README.md REST protocol (endpoint table)
│
├── skills/ 6 automation skills
│ ├── nas-setup/ pre-requisite: verify env/login/optional components
│ ├── rag-manager/ RAG semantic search index management (gate/rebuild/incremental)
│ ├── ios-memo-bak/ iPhone memo → ZSpace notebook
│ ├── media-organizer/ ZVideo classification audit
│ ├── label-manager/ label management
│ └── file-organizer/ file library diagnosis
│
├── pyproject.toml package definition (pip install -e .)
├── docs/API.md NAS endpoint quick reference
├── docs/MCP.md 90 tool detailed documentation
└── start.sh one-click startup (deps/mcp/dashboard/mcp-cfg)
```
## MCP Tool List (90)
### Files & Storage Pool & Monitoring (20)
| Tool | Read/Write | Purpose |
|---|---|---|
| `list_files` | read | list directory |
| `file_info` | read | single file metadata |
| `recent_files` | read | recent access |
| `file_categories` | read | statistics by type |
| `list_storage_pools` | read | storage pools & disks |
| `hardware_info` | read | hardware slot |
| `smart_report` | read | SMART disk health |
| `system_status` | read | NAS comprehensive status |
| `perf_snapshot` | read | SSH real-time performance |
| `whoami` | read | current user |
| `mkdir` | write | create directory |
| `rename` | write | rename |
| `move` | write | move |
| `copy` | write | copy |
| `remove` | ⚠️ delete | irreversible, does not go to recycle bin |
### ZVideo (9)
| Tool | Read/Write | Purpose |
|---|---|---|
| `list_video_classes` | read | classification list (including is_enable/is_system) |
| `latest_movies` / `suggested_movies` / `random_movies` | read | movie browsing |
| `list_video_dirs` | read | source directory |
| `get_video_classification_state` | read | single classification state |
| `add_video_classification` | write | create classification |
| `rename_video_classification` | write | rename classification (classification_id + new_name) |
| `link_folder_to_classification` | write | associate source directory (with is_enable=0 rejection) |
### Notebook (17)
| Tool | Read/Write | Purpose |
|---|---|---|
| `notebook_list/info/search` | read | browse & search |
| `notebook_allclassify/classifylist` | read | classification tree |
| `notebook_totalsize/getconfig` | read | statistics & configuration |
| `notebook_historyinfo/historylist` | read | history versions |
| `notebook_new/modify/delete` | write | CRUD |
| `notebook_pin/updatelabel/movenotepad` | write | pin/label/move |
| `notebook_newclassify/deleteclassify/updateclassify` | write | classification management |
### Baidu Netdisk (28) - requires OAuth login
| Group | Tool | Purpose |
|---|---|---|
| auth | `znetdisk_auth_check/token/userinfo/logout` | OAuth oob login |
| file | `znetdisk_file_list/download/upload/newdir` | cloud disk file management |
| task | `znetdisk_task_list/action` | transmission task |
| sync | `znetdisk_sync_add/list/open/close/delete/home` | NAS cloud disk two-way synchronization |
| autobackup | `znetdisk_autobackup_*` (7) | automatic backup |
| share | `znetdisk_share_verify/filelist/transfer/transfer_result` | ⭐ share link transfer |
| fail | `znetdisk_fail_list` | failure list |
### Sharing & Download & Remote Access (11)
| Tool | Purpose |
|---|---|
| `samba_status / webdav_status / ftp_status / dlna_status` | shared service status |
| `list_downloads / list_shares / list_nshares` | download & share |
| `proxy_login / proxy_url_for_port / proxy_fetch / proxy_list_whitelist` | zos cloud proxy |
### Music & Photos (3)
| Tool | Purpose |
|---|---|
| `list_songs` | song list |
| `list_albums` | photo list |
| `list_album_feeds` | photo content |
### RAG Semantic Search (3) - requires rag-server docker
| Tool | Purpose |
|---|---|
| `semantic_search` | natural language search file content |
| `reindex` | rebuild index |
| `index_status` | index overview |
## Skill List (6)
| Skill | Trigger words | Purpose |
|---|---|---|
| `nas-setup` | initial configuration, verify connection | pre-requisite: verify env/login/optional components (RAG) |
| `rag-manager` | RAG index, reindex | RAG semantic search index lifecycle management |
| `ios-memo-bak` | iPhone memo synchronization | one-click configuration iPhone Shortcut → NAS notebook |
| `media-organizer` | ZVideo organization, frds splitting | read-only audit classification/source directory/movie sampling |
| `label-manager` | label, find by label | label CRUD + reverse query |
| `file-organizer` | duplicate files, orphan files | file library read-only diagnosis |
## Access Standards
<div> </div>
<img src="image_url" style="width:100%">
<a href="link_url"> </a>
<br>
<h1> Heading </h1>
<p> Paragraph </p>
### MCP Client(mcp.json)
```json
{
"mcpServers": {
"zspace-nas": {
"command": "/path/to/.venv/bin/python",
"args": ["-m", "zspace.mcp_server"],
"cwd": "/path/to/zspace-mcp-poc",
"env": {
"NAS_HOST": "192.168.x.x",
"NAS_USER": "<phone>",
"NAS_PASSWORD": "<password>",
"NAS_DEVICE_ID": "<32 hex>"
}
},
"zspace-nas-http": {
"url": "http://192.168.x.x:8765/mcp",
"headers": {
"Authorization": "Bearer <MCP_HTTP_TOKEN from NAS .env>"
}
}
}
}
```
(Local Claude Code uses the `zspace-nas` stdio entry; for local/remote MCP clients, use the `zspace-nas-http` HTTP entry, which do not interfere with each other. On the NAS side, run `./start.sh mcp-http` to enable it.)
### Environment Variables
| Variable | Required | Description |
|---|---|---|
| `NAS_HOST` | ✅ | NAS IP |
| `NAS_USER` | ✅ | Phone number |
| `NAS_PASSWORD` | ✅ | Password |
| `NAS_DEVICE_ID` | Recommended | 32 characters, reuse registered device to bypass SMS verification |
| `KEY_SSH` | Optional | Required for perf_snapshot |
| `NAS_SSH_PORT` | Optional | Default 57922 |
| `NAS_RAG_URL` | Optional | RAG daemon address, default `http://nas:8000` |
### Write Operation Security Rules
1. **Destroy class** (`remove`/`notebook_delete`) does not go to recycle bin, MCP client pops up UI for user approval
2. **Status verification** (`link_folder_to_classification`) directly rejects if target classification is_enable=0
3. **Label override** (`save_file_label`) is overwrite style, check existing labels with `file_info` before adding new labels
## RAG Docker Deployment (Optional)
```bash
cd rag-server
docker compose up -d # image: coracoo/cherry:nas_rag
# Run reindex for the first time
curl -X POST http://nas:8000/reindex -H 'Content-Type: application/json' \
-d '{"scope":"files","full":true}'
```
See REST API details in `rag-server/README.md` (endpoint table).
## Documentation
| Document | Content |
|---|---|
| `docs/API.md` | NAS endpoint quick reference (12 domains, ~900 lines) |
| `docs/MCP.md` | 90 tool parameter/return/endpoint mapping |
| `rag-server/README.md` | RAG REST protocol (endpoint table) |
| `docs/iphone-shortcut.md` | iPhone Shortcut configuration diagram |
## License
MIT — see [LICENSE](LICENSE) for details. PR/Issue/Star welcome.
[CONTRIBUTING.md](CONTRIBUTING.md)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available