# nextcloud-mcp MCP (Model Context Protocol) server for Nextcloud — browse, read, write, and manage files, calendars, tasks, notes, and email via WebDAV/CalDAV/REST APIs. ## Features - **21 file management tools** — browse, search, read, upload, move, copy, delete, trashbin, favorites, versions - **Calendar tools** — list calendars, get/create events (CalDAV) - **Task tools** — get/create/update tasks (CalDAV VTODO) - **Note tools** — get/create notes (Nextcloud Notes API) - **Email tool** — get inbox emails (Nextcloud Mail API) - **Smart size routing** — small files inline (≤10MB), large files via direct URL or chunked upload - **CLI wrapper** — `ncmcp` command for quick testing and scripting ## Quick Start ### 1. Configure Create `.env` in the project root: ```env NEXTCLOUD_URL=https://your-nextcloud.example.com NEXTCLOUD_USERNAME=your_username NEXTCLOUD_PASSWORD=your_app_password ``` > Use an **app password** (Settings → Security → App passwords) instead of your main password. ### 2. Build ```bash npm install npm run build ``` ### 3. Test Connection ```bash node ncmcp.mjs list_files path=/ node ncmcp.mjs get_quota ``` ### 4. Use with MCP (mcporter) Add to your `mcporter.json`: ```json { "nextcloud": { "command": "node", "args": ["path/to/nextcloud-mcp/build/index.js"], "env": { "NEXTCLOUD_URL": "https://your-nextcloud.example.com", "NEXTCLOUD_USERNAME": "your_username", "NEXTCLOUD_PASSWORD": "your_app_password" } } } ``` Then use: `mcporter call nextcloud.list_files --args '{"path":"/"}'` ## CLI Usage (ncmcp) ```bash ncmcp [key=value ...] [positionalPath] [@file] [--curl] ``` **Examples:** ```bash # List files ncmcp list_files path=/Documents # Read a file ncmcp read_file path=/Documents/notes.txt # Upload a file ncmcp upload_file path=/Documents/new.txt content="Hello World" ncmcp upload_file path=/Documents/photo.jpg @./local-photo.jpg # Download (get URL) ncmcp download_file path=/Documents/video.mp4 ncmcp download_file path=/Documents/video.mp4 --curl # prints curl command # Search ncmcp search_files query="report" mimeType="application/pdf" limit=10 # Pipe content echo "file contents" | ncmcp upload_file path=/test.txt ``` ## Tool Reference ### 🔷 Browsing & Discovery | Tool | Description | Key Parameters | |------|-------------|----------------| | `list_files` | List directory contents | `path` (default: `/`), `depth` (`0`/`1`/`infinity`) | | `get_file_info` | Get detailed file/folder metadata | `path` (required) | | `search_files` | Search by name, mime, size, date | `query`, `mimeType`, `minSize`, `maxSize`, `sortBy`, `limit` | | `list_favorites` | List favorited files | `path` (scope) | | `get_quota` | Get storage usage | — | ### 🔷 Read & Download | Tool | Description | Key Parameters | |------|-------------|----------------| | `read_file` | Read file content (text or base64) | `path`, `encoding` (`utf8`/`base64`), `maxSize` (default 10MB) | | `download_file` | Get direct download URL | `path`, `metadata` (default: true) | | `download_folder` | Download folder as ZIP/TAR | `path`, `format` (`zip`/`tar`), `files` (subset), `maxSize` (default 50MB) | ### 🔷 Write & Upload | Tool | Description | Key Parameters | |------|-------------|----------------| | `upload_file` | Upload file via PUT | `path`, `content`, `encoding`, `contentType`, `mtime` | | `create_folder` | Create a new folder | `path` | | `bulk_upload` | Upload multiple files at once | `files[]` (path, content, encoding, contentType) | ### 🔷 Chunked Upload (Large Files) For files too large for a single `upload_file` call (>10MB content in parameter). | Tool | Description | Key Parameters | |------|-------------|----------------| | `chunked_upload_start` | Start upload session | `path`, `totalSize`, `chunkSize` (default 10MB) | | `chunked_upload_chunk` | Upload one chunk (base64) | `uploadId`, `chunkIndex` (1-based), `content` | | `chunked_upload_finish` | Assemble final file | `uploadId`, `mtime` | **Flow:** Start → upload chunks (1..N) → finish. All steps must be in the same session (in-memory state). ### 🔷 Move, Copy, Delete | Tool | Description | Key Parameters | |------|-------------|----------------| | `move_file` | Move/rename file or folder | `source`, `destination`, `overwrite` | | `copy_file` | Copy file or folder | `source`, `destination`, `overwrite` | | `delete_file` | Delete (moves to trashbin) | `path` | ### 🔷 Trashbin | Tool | Description | Key Parameters | |------|-------------|----------------| | `trash_list` | List deleted items | — | | `trash_restore` | Restore from trash | `trashPath` (from `trash_list`) | | `trash_delete` | Permanently delete | `trashPath` | | `trash_empty` | Empty entire trashbin | — (⚠️ destructive) | ### 🔷 Favorites & Versions | Tool | Description | Key Parameters | |------|-------------|----------------| | `set_favorite` | Toggle favorite status | `path`, `favorite` (boolean) | | `get_file_versions` | List file versions | `fileId` (oc:fileid) | | `restore_file_version` | Restore a version | `fileId`, `versionName` | ### 📅 Calendar | Tool | Description | Key Parameters | |------|-------------|----------------| | `list_calendars` | List CalDAV calendars | — | | `get_calendar_events` | Get events in date range | `startDate`, `endDate`, `calendar`, `limit` | | `create_calendar_event` | Create event | `summary`, `startDateTime`/`endDateTime`, `allDay`, `location`, `reminderMinutesBefore` | ### ✅ Tasks | Tool | Description | Key Parameters | |------|-------------|----------------| | `get_tasks` | Get tasks (VTODO) | `status` (`all`/`open`/`completed`), `limit` | | `create_task` | Create task | `summary`, `description`, `due`, `priority` | | `update_task` | Update task | `taskId`, `summary`, `status`, `percentComplete` | ### 📝 Notes | Tool | Description | Key Parameters | |------|-------------|----------------| | `get_notes` | List notes | `limit` | | `create_note` | Create note | `content`, `title`, `category` | | `get_note_content` | Get note by ID | `noteId` | ### 📧 Email | Tool | Description | Key Parameters | |------|-------------|----------------| | `get_emails` | Get inbox emails | `accountId` (default 0), `limit` | ## Size Limits & Routing MCP transports data as JSON over stdio. Large files need special handling: ``` UPLOAD ├─ Content ≤ ~10MB in param → upload_file (PUT) ├─ Content > 10MB → chunked_upload_start/chunk/finish └─ Many small files → bulk_upload (multipart/related) READ ├─ File ≤ maxSize (10MB) → read_file (inline content) └─ File > maxSize → download_file (direct URL) DOWNLOAD FOLDER ├─ Archive ≤ 50MB → download_folder (inline base64) └─ Archive > 50MB → download_folder (direct URL) ``` The limits are MCP transport constraints, not Nextcloud limits. Nextcloud handles files of any size. ## Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `NEXTCLOUD_URL` | Yes | Nextcloud base URL (e.g. `https://cloud.example.com`) | | `NEXTCLOUD_USERNAME` | Yes | Nextcloud username | | `NEXTCLOUD_PASSWORD` | Yes | App password (recommended) or account password | | `DEBUG_NEXTCLOUD_MCP` | No | Set to `1` for debug logging (calendar operations) | ## Troubleshooting ### Connection errors - Verify `NEXTCLOUD_URL` is accessible (no trailing slash) - Check credentials — use an app password, not your main password - Test: `curl -u user:pass https://your-nextcloud.example.com/remote.php/dav/` ### "File too large" errors - Use `download_file` to get a direct URL for large files - Use `chunked_upload_*` tools for large uploads - Adjust `maxSize` parameter if needed ### Search returns empty - The server may not have Full Text Search enabled - The tool falls back to PROPFIND with depth infinity — works but slower on large directories - Narrow the search scope with `path` parameter ### Calendar/Task errors - Ensure CalDAV is enabled on the server - Check that the calendar/task list exists (default: `personal` calendar, `tasks` list) - Set `DEBUG_NEXTCLOUD_MCP=1` for detailed CalDAV logging ### Bulk upload fails - The `/remote.php/dav/bulk` endpoint may not be available on all Nextcloud versions - Fall back to individual `upload_file` calls ## Development ```bash npm run build # Compile TypeScript npm run watch # Watch mode npm run dev # Run with tsx (no build needed) ``` ## Architecture ``` src/ ├── index.ts — MCP server entry point ├── types.ts — Shared TypeScript interfaces ├── client.ts — Nextcloud HTTP client (axios, WebDAV methods) ├── webdav.ts — WebDAV XML builders & parsers ├── caldav.ts — CalDAV XML builders & iCal parsers ├── utils.ts — Shared utilities (path, mime, formatting) └── tools/ ├── index.ts — Tool registry & routing ├── files.ts — 24 file management tools ├── calendar.ts — 3 calendar tools ├── tasks.ts — 3 task tools ├── notes.ts — 3 note tools └── email.ts — 1 email tool ``` ## License MIT