Skip to main content
Glama
README.md
# Nextcloud MCP Server

A custom [MCP](https://modelcontextprotocol.io) (Model Context Protocol) server that gives Claude the ability to **list, read, write, create folders in, delete, and search files** in a self-hosted Nextcloud instance over WebDAV.

Works with Claude Desktop out of the box (local/stdio), with an optional HTTP/Docker version for remote setups.

## Tools it exposes

**File operations**

| Tool | Description |
|---|---|
| `list_files(path)` | List files/folders at a path |
| `read_file(path)` | Read a text file's contents |
| `write_file(path, content)` | Create or overwrite a text file |
| `create_folder(path)` | Create a folder |
| `delete_item(path)` | Delete a file or folder (permanent beyond trash retention) |
| `search_files(query, path)` | Recursively search filenames |

**Obsidian vault operations**

These understand Markdown notes as an Obsidian vault, not just plain files — parsing frontmatter, `[[wikilinks]]`, and `#tags` the way Obsidian itself would. Built for the common setup where your vault syncs through Nextcloud (via the Nextcloud desktop client) rather than living in a local-only folder, which is what most Obsidian-focused MCP servers assume.

| Tool | Description |
|---|---|
| `get_frontmatter(path)` | Read a note's YAML frontmatter as JSON |
| `update_frontmatter(path, fields)` | Merge new fields into a note's frontmatter without touching the body |
| `list_by_tag(tag, path)` | Find every note carrying a tag, frontmatter or inline |
| `get_backlinks(note, path)` | Find every note that links to a given note |
| `resolve_link(link_text, path)` | Resolve a wikilink to the actual file it points to, fuzzy-matched like Obsidian does |
| `graph_neighbors(note, path, depth)` | List notes connected to a given note by links, out to N hops |

## Which version should I use?

- **`server_stdio.py`** — Recommended for most people. Claude Desktop launches this locally as a subprocess and it talks to Nextcloud over your LAN/Tailscale/VPN directly. No public exposure needed.
- **`server.py`** — An HTTP version for running as a standalone service (e.g. in Docker). Only needed if you want to add this as a **remote custom connector** in Claude — which requires the server to be reachable via a public HTTPS URL (e.g. behind a Cloudflare Tunnel or reverse proxy), since custom connectors are reached from Anthropic's cloud infrastructure, not your local device.

## Setup — Claude Desktop (local, recommended)

1. **Clone this repo** and install dependencies for the Python interpreter Claude Desktop will use:
   ```bash
   git clone https://github.com/yourusername/nextcloud-mcp.git
   cd nextcloud-mcp
   pip install -r requirements.txt
   ```
2. **Create a Nextcloud app password**: in Nextcloud, go to *Settings → Security → App passwords*, create one (e.g. named `claude-mcp`), and save it somewhere safe. Don't use your real account password.
3. **Edit your Claude Desktop config file** (`claude_desktop_config.json`):
   - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
   - Linux: `~/.config/Claude/claude_desktop_config.json`

   Copy the contents of [`claude_desktop_config.example.json`](claude_desktop_config.example.json), and update:
   - `args` to the **absolute path** of `server_stdio.py` on your machine
   - `NEXTCLOUD_URL`, `NEXTCLOUD_USER`, `NEXTCLOUD_PASSWORD` to your own values
4. **Fully restart Claude Desktop** (quit from the system tray/menu bar, not just close the window).

You should now see Nextcloud tools available in your conversations.

## Setup — HTTP/Docker (remote custom connector)

1. Copy `.env.example` to `.env` and fill in your Nextcloud URL, username, and app password.
2. Build and run:
   ```bash
   docker compose up -d --build
   ```
3. Expose the container's port (default `8765`) via a public HTTPS URL — for example a Cloudflare Tunnel, Tailscale Funnel, or a reverse proxy with TLS. A private LAN address alone will not be reachable by Claude's custom connector setup.
4. In Claude, add a custom connector pointing at `https://your-public-url/mcp`.

## Troubleshooting

- **`ModuleNotFoundError: No module named 'mcp.server.fastmcp'`** — you likely installed `mcp` version `2.x`, which restructured the package. This project pins `mcp>=1.6.0,<2.0.0` in `requirements.txt`; reinstall with that constraint.
- **`ModuleNotFoundError` for `requests` or `mcp` even after installing** — if you have multiple Python versions installed, make sure you install dependencies against the *exact* interpreter Claude Desktop launches (check Claude Desktop's MCP logs for the interpreter path if unsure).
- **Server doesn't show up in Claude Desktop** — make sure you fully restarted the app after editing the config, and double-check the `args` path is absolute and correct for your OS.

## Security notes

- Always use a scoped Nextcloud **app password**, not your real account password — revoke it anytime via *Settings → Security → Devices & Sessions*.
- `delete_item()` is permanent beyond Nextcloud's trash retention. Use with care, especially since Claude can call it directly during a conversation.
- Never commit your `.env` file or real credentials — `.gitignore` is already set up to exclude `.env`.

## License

MIT — see [LICENSE](LICENSE).