feat: add get_thumbnail, list_favorites, add_favorite, delete_favorite (v0.3.1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 17:11:05 +02:00
parent ff79d438b0
commit 79b7384aeb
4 changed files with 177 additions and 2 deletions
@@ -1138,3 +1138,118 @@ def register_filestation(
return f"Error: {e}"
return f"Deleted sharing link: {link_id}"
# ── thumbnail + favorites tools ───────────────────────────────────────
@mcp.tool()
async def get_thumbnail(path: str, size: str = "large"):
"""Fetch a thumbnail for an image. Returns JSON: filename, size_bytes, content_base64."""
import base64
import json as _json
from mcp_synology_filestation.client import SynologyError
valid_sizes = {"small", "medium", "large", "original"}
if size not in valid_sizes:
return f"Error: size must be one of {sorted(valid_sizes)}"
try:
img_bytes = await client.get_thumbnail_bytes(path, size)
except SynologyError as e:
return f"Error: {e}"
filename = path.rsplit("/", 1)[-1]
return _json.dumps(
{
"filename": filename,
"size_bytes": len(img_bytes),
"content_base64": base64.b64encode(img_bytes).decode(),
}
)
@mcp.tool()
async def list_favorites():
"""List all FileStation favorites. Table: name, path, type, status, real path, modified."""
from mcp_synology_filestation.client import SynologyError
try:
data = await client.request(
"SYNO.FileStation.Favorite",
"list",
version=2,
params={
"offset": 0,
"limit": 200,
"additional": json.dumps(["real_path", "size", "time"]),
},
)
except SynologyError as e:
return f"Error: {e}"
favorites: list[dict] = data.get("favorites", [])
total: int = data.get("total", len(favorites))
if not favorites:
return "No favorites found."
rows: list[tuple[str, ...]] = []
for fav in favorites:
name = fav.get("name", "")
fpath = fav.get("path", "")
ftype = "folder" if fav.get("isdir", False) else "file"
status = fav.get("status", "")
add = fav.get("additional", {})
real_path = add.get("real_path", "")
mtime = add.get("time", {}).get("mtime")
rows.append((name, fpath, ftype, status, real_path, _fmt_time(mtime)))
headers = ("Name", "Path", "Type", "Status", "Real Path", "Modified")
col_widths = [max(len(h), *(len(r[i]) for r in rows)) for i, h in enumerate(headers)]
def _sep() -> str:
return "+" + "+".join("-" * (w + 2) for w in col_widths) + "+"
def _row(vals: tuple[str, ...]) -> str:
return "| " + " | ".join(f"{v:<{col_widths[i]}}" for i, v in enumerate(vals)) + " |"
lines = [_sep(), _row(headers), _sep()]
for r in rows:
lines.append(_row(r))
lines.append(_sep())
lines.append(f"\n{total} favorite(s)")
return "\n".join(lines)
@mcp.tool()
async def add_favorite(path: str, name: str):
"""Add a path to FileStation favorites. name: display label for the favorite."""
from mcp_synology_filestation.client import SynologyError
try:
await client.request(
"SYNO.FileStation.Favorite",
"add",
version=2,
params={"path": path, "name": name, "index": -1},
)
except SynologyError as e:
return f"Error: {e}"
return f"Added favorite '{name}'{path}"
@mcp.tool()
async def delete_favorite(path: str):
"""Delete a FileStation favorite by path."""
from mcp_synology_filestation.client import SynologyError
try:
await client.request(
"SYNO.FileStation.Favorite",
"delete",
version=2,
params={"path": path},
)
except SynologyError as e:
return f"Error: {e}"
return f"Deleted favorite for {path}"