perf: shorten all tool docstrings to reduce tools/list payload

Reduced tools/list JSON payload from ~45 KB to 5.7 KB by replacing
verbose multi-paragraph docstrings with 1-2 line summaries on all
14 @mcp.tool() functions. Fixes Claude Desktop truncation of tools/list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 11:58:11 +02:00
parent 500dc73324
commit fc706fb809
+27 -191
View File
@@ -106,10 +106,7 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def list_shares(): async def list_shares():
"""List all shared folders visible to the authenticated user. """List all shared folders. Returns name/path/volume-usage table."""
Returns a formatted table with share name, path, and volume status.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -164,23 +161,8 @@ def register_filestation(
sort_by: str = "name", sort_by: str = "name",
sort_direction: str = "asc", sort_direction: str = "asc",
): ):
"""List the contents of a directory on the NAS. """List directory contents. path: share-relative (e.g. /docker).
offset/limit for pagination, sort_by/sort_direction for ordering."""
Use share paths as returned by list_shares (e.g. "/dev", "/data"),
not volume paths (e.g. "/volume1/dev" will not work).
Args:
path: Share-relative path on the NAS (e.g. "/dev" or "/data/photos").
offset: Number of items to skip (for pagination).
limit: Maximum items to return (1-500, default 100).
sort_by: Sort field — one of: name, size, user, group, mtime, atime,
crtime, posix, type.
sort_direction: "asc" or "desc".
Returns:
Formatted table with name and type, plus the total item count
for pagination context.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
# Validate inputs # Validate inputs
@@ -266,21 +248,8 @@ def register_filestation(
recursive: bool = True, recursive: bool = True,
max_results: int = 200, max_results: int = 200,
): ):
"""Search for files matching a glob pattern within a directory. """Search files by glob pattern under path. pattern: e.g. "*.yaml".
recursive/max_results optional."""
Starts an async DSM search task, polls until complete, then cleans up.
Use share paths as returned by list_shares (e.g. "/docker").
Args:
path: Root directory to search from (e.g. "/docker").
pattern: Filename glob pattern (e.g. "*.yaml", "report*.pdf").
recursive: Search subdirectories (default True).
max_results: Maximum number of matches to return (default 200, max 1000).
Returns:
Formatted table with path, type, size, and modification time,
plus total match count.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
limit = max(1, min(max_results, 1000)) limit = max(1, min(max_results, 1000))
@@ -400,17 +369,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def download(path: str): async def download(path: str):
"""Download a single file from the NAS and return its content as base64. """Download a file as base64 (max 10 MB). path: share-relative.
Returns JSON {filename, size, content_base64}."""
Files larger than 10 MB are rejected — use SFTP or another method instead.
Use share paths as returned by list_shares (e.g. "/docker/app/config.yaml").
Args:
path: Absolute share-relative path to the file on the NAS.
Returns:
JSON object with "filename", "size" (bytes), and "content_base64".
"""
import base64 import base64
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
@@ -439,19 +399,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def get_info(path: str): async def get_info(path: str):
"""Get detailed metadata for one or more files or folders on the NAS. """Get metadata (type/size/owner/permissions/timestamps) for one or more paths.
path: comma-separated share-relative paths."""
Accepts a single path or a comma-separated list of paths.
Use share paths as returned by list_shares (e.g. "/dev/file.txt").
Args:
path: One or more share-relative paths, comma-separated
(e.g. "/dev/notes.txt" or "/dev/notes.txt,/data/photo.jpg").
Returns:
Formatted table with type, size, owner, permissions, and timestamps
for each requested path.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
paths = [p.strip() for p in path.split(",") if p.strip()] paths = [p.strip() for p in path.split(",") if p.strip()]
@@ -540,22 +489,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def check_exist(path: str): async def check_exist(path: str):
"""Check whether one or more files or folders exist on the NAS. """Check if one or more paths exist. path: comma-separated share-relative paths.
Returns Yes/No table."""
Accepts a single path or a comma-separated list of paths.
Use share paths as returned by list_shares (e.g. "/dev/file.txt").
Note: SYNO.FileStation.CheckExist returns error 400 on this firmware for all
parameter formats. This tool falls back to SYNO.FileStation.List::getinfo, which
returns an entry per path with name=None when the path does not exist.
Args:
path: One or more share-relative paths, comma-separated
(e.g. "/dev/notes.txt" or "/dev/notes.txt,/data/photo.jpg").
Returns:
Formatted table with each path and whether it exists (Yes / No).
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
paths = [p.strip() for p in path.split(",") if p.strip()] paths = [p.strip() for p in path.split(",") if p.strip()]
@@ -603,17 +538,8 @@ def register_filestation(
name: str, name: str,
create_parents: bool = False, create_parents: bool = False,
): ):
"""Create a new folder on the NAS. """Create a folder. path: parent dir, name: folder name (not full path).
create_parents: make missing parents."""
Args:
path: Parent directory path (e.g. "/docker").
name: New folder name — not a full path (e.g. "my-app").
create_parents: Create missing intermediate parent directories
if True (default False).
Returns:
Full path of the created folder, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -635,16 +561,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def rename(path: str, new_name: str): async def rename(path: str, new_name: str):
"""Rename a file or folder on the NAS. """Rename a file or folder. path: current share-relative path,
new_name: bare name only (not full path)."""
Args:
path: Absolute share-relative path to the item
(e.g. "/docker/old-name.yaml").
new_name: New name — not a full path (e.g. "new-name.yaml").
Returns:
New absolute path after rename, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -666,19 +584,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def copy(src: str, dst: str, overwrite: bool = False): async def copy(src: str, dst: str, overwrite: bool = False):
"""Copy a file or folder to a new location on the NAS. """Copy src to dst directory.
WARNING: overwrite=True replaces existing items (default False)."""
WARNING: Set overwrite=True only when you intentionally want to replace
an existing item at the destination.
Args:
src: Source absolute path (e.g. "/docker/app/compose.yaml").
dst: Destination directory path (e.g. "/backup/docker").
overwrite: Replace existing item at destination (default False).
Returns:
Destination path on success, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -711,19 +618,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def move(src: str, dst: str, overwrite: bool = False): async def move(src: str, dst: str, overwrite: bool = False):
"""Move a file or folder to a new location on the NAS. """Move src to dst directory.
WARNING: overwrite=True replaces existing items (default False)."""
WARNING: Set overwrite=True only when you intentionally want to replace
an existing item at the destination.
Args:
src: Source absolute path (e.g. "/docker/app/old-compose.yaml").
dst: Destination directory path (e.g. "/backup/docker").
overwrite: Replace existing item at destination (default False).
Returns:
Destination path on success, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -756,20 +652,8 @@ def register_filestation(
@mcp.tool() @mcp.tool()
async def delete(path: str, confirmed: bool = False): async def delete(path: str, confirmed: bool = False):
"""Delete a file or folder on the NAS. """Delete a file or folder. IRREVERSIBLE.
confirmed=False (default) shows preview only; pass confirmed=True to actually delete."""
WARNING: This operation is irreversible. Without confirmed=True,
returns only a preview — no changes are made.
Args:
path: Absolute share-relative path to delete.
confirmed: Must be True to actually delete. Defaults to False
(preview only — no DSM call).
Returns:
Preview message if confirmed=False; success or Error: message
if confirmed=True.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
if not confirmed: if not confirmed:
@@ -810,25 +694,8 @@ def register_filestation(
format: str = "zip", format: str = "zip",
password: str = "", password: str = "",
): ):
"""Compress files or folders into an archive on the NAS. """Compress paths into an archive. dest_file_path: full path incl. filename.
level: store/fastest/fast/normal/moderate/maximum. format: zip/7z."""
Creates a new archive asynchronously. Progress is polled until the operation
completes. Use share paths as returned by list_shares.
Args:
paths: List of share-relative paths to include in the archive
(e.g. ["/data/report.pdf", "/data/photos"]).
dest_file_path: Full destination path including filename
(e.g. "/backup/archive.zip").
level: Compression level — "store", "fastest", "fast", "normal",
"moderate" (default), or "maximum".
mode: Archive write mode — "add" (default), "update", or "refreshen".
format: Archive format — "zip" (default) or "7z".
password: Optional password to encrypt the archive (default: none).
Returns:
Path of the created archive on success, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
_valid_levels = {"store", "fastest", "fast", "normal", "moderate", "maximum"} _valid_levels = {"store", "fastest", "fast", "normal", "moderate", "maximum"}
@@ -880,26 +747,8 @@ def register_filestation(
create_subfolder: bool = False, create_subfolder: bool = False,
password: str = "", password: str = "",
): ):
"""Extract an archive file to a destination folder on the NAS. """Extract a ZIP or 7z archive to dest_folder_path.
overwrite/keep_dir/create_subfolder/password optional."""
Supports ZIP and 7z archives. Runs asynchronously; progress is polled
until the extraction completes. Use share paths as returned by list_shares.
Args:
file_path: Share-relative path to the archive file
(e.g. "/backup/archive.zip").
dest_folder_path: Destination folder for extracted contents
(e.g. "/data/extracted").
overwrite: Replace existing files at the destination (default False).
keep_dir: Preserve the directory structure inside the archive
(default True).
create_subfolder: Create a subfolder named after the archive to hold
extracted contents (default False).
password: Password for encrypted archives (default: none).
Returns:
Destination folder path on success, or an Error: message.
"""
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError
try: try:
@@ -940,21 +789,8 @@ def register_filestation(
overwrite: bool = False, overwrite: bool = False,
create_parents: bool = True, create_parents: bool = True,
): ):
"""Upload a file to a directory on the NAS from base64-encoded content. """Upload base64-encoded content as filename into path (max 50 MB).
WARNING: overwrite=True replaces existing file (default False)."""
WARNING: Set overwrite=True only when you intentionally want to replace
an existing file.
Args:
path: Destination directory path on the NAS (e.g. "/docker/app").
filename: Filename to create (e.g. "compose.yaml").
content_base64: Base64-encoded file content.
overwrite: Replace existing file at destination (default False).
create_parents: Create missing parent directories (default True).
Returns:
Full path of the uploaded file, or an Error: message.
"""
import base64 import base64
from mcp_synology_filestation.client import SynologyError from mcp_synology_filestation.client import SynologyError