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:
@@ -106,10 +106,7 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def list_shares():
|
||||
"""List all shared folders visible to the authenticated user.
|
||||
|
||||
Returns a formatted table with share name, path, and volume status.
|
||||
"""
|
||||
"""List all shared folders. Returns name/path/volume-usage table."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -164,23 +161,8 @@ def register_filestation(
|
||||
sort_by: str = "name",
|
||||
sort_direction: str = "asc",
|
||||
):
|
||||
"""List the contents of a directory on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""List directory contents. path: share-relative (e.g. /docker).
|
||||
offset/limit for pagination, sort_by/sort_direction for ordering."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
# Validate inputs
|
||||
@@ -266,21 +248,8 @@ def register_filestation(
|
||||
recursive: bool = True,
|
||||
max_results: int = 200,
|
||||
):
|
||||
"""Search for files matching a glob pattern within a directory.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Search files by glob pattern under path. pattern: e.g. "*.yaml".
|
||||
recursive/max_results optional."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
limit = max(1, min(max_results, 1000))
|
||||
@@ -400,17 +369,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def download(path: str):
|
||||
"""Download a single file from the NAS and return its content as 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".
|
||||
"""
|
||||
"""Download a file as base64 (max 10 MB). path: share-relative.
|
||||
Returns JSON {filename, size, content_base64}."""
|
||||
import base64
|
||||
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
@@ -439,19 +399,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def get_info(path: str):
|
||||
"""Get detailed metadata for one or more files or folders on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Get metadata (type/size/owner/permissions/timestamps) for one or more paths.
|
||||
path: comma-separated share-relative paths."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
paths = [p.strip() for p in path.split(",") if p.strip()]
|
||||
@@ -540,22 +489,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def check_exist(path: str):
|
||||
"""Check whether one or more files or folders exist on the NAS.
|
||||
|
||||
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).
|
||||
"""
|
||||
"""Check if one or more paths exist. path: comma-separated share-relative paths.
|
||||
Returns Yes/No table."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
paths = [p.strip() for p in path.split(",") if p.strip()]
|
||||
@@ -603,17 +538,8 @@ def register_filestation(
|
||||
name: str,
|
||||
create_parents: bool = False,
|
||||
):
|
||||
"""Create a new folder on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Create a folder. path: parent dir, name: folder name (not full path).
|
||||
create_parents: make missing parents."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -635,16 +561,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def rename(path: str, new_name: str):
|
||||
"""Rename a file or folder on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Rename a file or folder. path: current share-relative path,
|
||||
new_name: bare name only (not full path)."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -666,19 +584,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def copy(src: str, dst: str, overwrite: bool = False):
|
||||
"""Copy a file or folder to a new location on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Copy src to dst directory.
|
||||
WARNING: overwrite=True replaces existing items (default False)."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -711,19 +618,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def move(src: str, dst: str, overwrite: bool = False):
|
||||
"""Move a file or folder to a new location on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Move src to dst directory.
|
||||
WARNING: overwrite=True replaces existing items (default False)."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -756,20 +652,8 @@ def register_filestation(
|
||||
|
||||
@mcp.tool()
|
||||
async def delete(path: str, confirmed: bool = False):
|
||||
"""Delete a file or folder on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Delete a file or folder. IRREVERSIBLE.
|
||||
confirmed=False (default) shows preview only; pass confirmed=True to actually delete."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
if not confirmed:
|
||||
@@ -810,25 +694,8 @@ def register_filestation(
|
||||
format: str = "zip",
|
||||
password: str = "",
|
||||
):
|
||||
"""Compress files or folders into an archive on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Compress paths into an archive. dest_file_path: full path incl. filename.
|
||||
level: store/fastest/fast/normal/moderate/maximum. format: zip/7z."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
_valid_levels = {"store", "fastest", "fast", "normal", "moderate", "maximum"}
|
||||
@@ -880,26 +747,8 @@ def register_filestation(
|
||||
create_subfolder: bool = False,
|
||||
password: str = "",
|
||||
):
|
||||
"""Extract an archive file to a destination folder on the NAS.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Extract a ZIP or 7z archive to dest_folder_path.
|
||||
overwrite/keep_dir/create_subfolder/password optional."""
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
try:
|
||||
@@ -940,21 +789,8 @@ def register_filestation(
|
||||
overwrite: bool = False,
|
||||
create_parents: bool = True,
|
||||
):
|
||||
"""Upload a file to a directory on the NAS from base64-encoded content.
|
||||
|
||||
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.
|
||||
"""
|
||||
"""Upload base64-encoded content as filename into path (max 50 MB).
|
||||
WARNING: overwrite=True replaces existing file (default False)."""
|
||||
import base64
|
||||
|
||||
from mcp_synology_filestation.client import SynologyError
|
||||
|
||||
Reference in New Issue
Block a user