8461970523
Code Review (REVIEW.md): - Fixed parseSearchResponse skipping first result (critical bug) - Fixed trashbin/versions/chunked paths missing /remote.php/dav prefix - Fixed trash_restore to use original file location instead of /restore endpoint - Fixed createTask/updateTask missing iCal text escaping - Added 409 handling for createFolder (parent missing) - Extracted duplicate decodeXmlText to utils.ts - Extracted duplicate generateUID to utils.ts (shared with calendar/tasks) - Removed 5 dead code functions (parseVEVENT, extractVEventBlocks, unfoldICalLines, getCalDAVXmlHeaders, local decodeXmlText) - Cleaned unused imports across all tool files Testing (RESULTS.md): - 35 tests passed, 1 skipped (trash_empty), 1 server limitation (bulk_upload) - Tested all 21+ file tools, edge cases (spaces, unicode, overwrite, empty folders) - Verified chunked upload end-to-end Documentation (README.md): - Complete tool reference (21 file + 10 other tools) - Quick start, CLI usage, size limits, troubleshooting - Architecture overview
9.1 KiB
9.1 KiB
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 —
ncmcpcommand for quick testing and scripting
Quick Start
1. Configure
Create .env in the project root:
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
npm install
npm run build
3. Test Connection
node ncmcp.mjs list_files path=/
node ncmcp.mjs get_quota
4. Use with MCP (mcporter)
Add to your mcporter.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)
ncmcp <tool> [key=value ...] [positionalPath] [@file] [--curl]
Examples:
# 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 |
| 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_URLis 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_fileto get a direct URL for large files - Use
chunked_upload_*tools for large uploads - Adjust
maxSizeparameter 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
pathparameter
Calendar/Task errors
- Ensure CalDAV is enabled on the server
- Check that the calendar/task list exists (default:
personalcalendar,taskslist) - Set
DEBUG_NEXTCLOUD_MCP=1for detailed CalDAV logging
Bulk upload fails
- The
/remote.php/dav/bulkendpoint may not be available on all Nextcloud versions - Fall back to individual
upload_filecalls
Development
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