Skip to content

Commit b2bc76b

Browse files
committed
URL-encode trash_path in DAV URLs and fix restore_trash_item annotation
1 parent 4130c73 commit b2bc76b

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

src/nextcloud_mcp/client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import contextlib
44
import xml.etree.ElementTree as ET
55
from typing import Any
6+
from urllib.parse import quote as url_quote
67

78
import niquests
89
from urllib3.util import Retry
@@ -275,16 +276,18 @@ async def trashbin_restore(self, trash_path: str) -> None:
275276
"""Restore a trashed item by MOVEing it to the restore folder."""
276277
session = await self._get_session()
277278
user = self._config.user
278-
src = f"{self._base_url}/remote.php/dav/trashbin/{user}/trash/{trash_path}"
279-
dest = f"{self._base_url}/remote.php/dav/trashbin/{user}/restore/{trash_path}"
279+
encoded = url_quote(trash_path, safe="/")
280+
src = f"{self._base_url}/remote.php/dav/trashbin/{user}/trash/{encoded}"
281+
dest = f"{self._base_url}/remote.php/dav/trashbin/{user}/restore/{encoded}"
280282
response = await session.request("MOVE", src, headers={"Destination": dest})
281283
_raise_for_status(response, f"Restore '{trash_path}'")
282284

283285
async def trashbin_delete(self, trash_path: str = "") -> None:
284286
"""Delete a single item or empty the entire trash (if path is empty)."""
285287
session = await self._get_session()
286288
user = self._config.user
287-
url = f"{self._base_url}/remote.php/dav/trashbin/{user}/trash/{trash_path}"
289+
encoded = url_quote(trash_path, safe="/") if trash_path else ""
290+
url = f"{self._base_url}/remote.php/dav/trashbin/{user}/trash/{encoded}"
288291
response = await session.delete(url)
289292
_raise_for_status(response, "Empty trash" if not trash_path else f"Delete '{trash_path}' from trash")
290293

src/nextcloud_mcp/tools/trashbin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from mcp.server.fastmcp import FastMCP
1010

11-
from ..annotations import DESTRUCTIVE, READONLY
11+
from ..annotations import ADDITIVE_IDEMPOTENT, DESTRUCTIVE, READONLY
1212
from ..client import DAV_NS, NC_NS, OC_NS
1313
from ..permissions import PermissionLevel, require_permission
1414
from ..state import get_client, get_config
@@ -99,7 +99,7 @@ async def list_trash() -> str:
9999

100100

101101
def _register_write_tools(mcp: FastMCP) -> None:
102-
@mcp.tool(annotations=READONLY)
102+
@mcp.tool(annotations=ADDITIVE_IDEMPOTENT)
103103
@require_permission(PermissionLevel.WRITE)
104104
async def restore_trash_item(trash_path: str) -> str:
105105
"""Restore a file or folder from the trash bin to its original location.

0 commit comments

Comments
 (0)