fix: v0.2.7 — remove -> str annotations and trim docstrings to reduce tools/list payload

FastMCP generates outputSchema for every tool with a return annotation,
roughly doubling the tools/list payload size. Multi-line docstrings with
Args/Returns sections add further bulk that Claude Desktop must parse.

- Strip -> str from all 23 @mcp.tool() functions
- Trim every tool docstring to a single descriptive line (≤100 chars)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-21 09:04:17 +02:00
parent a1d4b1d709
commit ad199674e7
7 changed files with 46 additions and 210 deletions
@@ -64,13 +64,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
"""Register all container management tools with the MCP server."""
@mcp.tool()
async def list_containers(project_name: str | None = None) -> str:
"""List containers, optionally filtered by project name.
Args:
project_name: Optional project name to filter containers.
If omitted, lists all containers.
"""
async def list_containers(project_name: str | None = None):
"""List all containers, optionally filtered by project name."""
try:
data = await client.request(
"SYNO.Docker.Container",
@@ -107,12 +102,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
return "\n".join(lines).rstrip()
@mcp.tool()
async def get_container_status(container_name: str) -> str:
"""Get detailed status, uptime, and resource usage of a container.
Args:
container_name: Name of the container to inspect.
"""
async def get_container_status(container_name: str):
"""Get detailed status, uptime, ports, and mounts for a container."""
# SYNO.Docker.Container/get accepts the clean name (no hash prefix).
clean_name = _strip_hash_prefix(container_name)
try:
@@ -134,14 +125,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
container_name: str,
tail: int = 100,
keyword: str | None = None,
) -> str:
"""Get log output from a container.
Args:
container_name: Name of the container.
tail: Number of recent log lines to return (default 100).
keyword: Optional keyword to filter log lines.
"""
):
"""Get recent log output from a container, with optional keyword filter."""
resolved_name = await _resolve_container_name(client, container_name)
params: dict[str, Any] = {
"name": resolved_name,
@@ -181,15 +166,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
return header + "\n".join(lines)
@mcp.tool()
async def container_stats(container_name: str) -> str:
"""Get live resource usage statistics for a container.
Reports CPU %, RAM used/limit, Network I/O (rx/tx), and Block I/O
(read/write) for the named container.
Args:
container_name: Name of the container (e.g. "jenkins").
"""
async def container_stats(container_name: str):
"""Get live CPU, memory, network, and block I/O stats for a container."""
try:
data = await client.request("SYNO.Docker.Container", "stats")
except Exception as e:
@@ -270,17 +248,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
container_name: str,
command: str,
confirmed: bool = False,
) -> str:
"""Execute a command in a running container.
This executes a shell command inside the container. Use with caution.
Requires confirmation before executing.
Args:
container_name: Name of the container.
command: Shell command to execute.
confirmed: Must be True to proceed. Set to True to confirm execution.
"""
):
"""Execute a shell command inside a running container. Requires confirmed=True."""
if not confirmed:
return (
f"About to run in container '{container_name}':\n"
@@ -313,16 +282,8 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
return "\n".join(result_lines)
@mcp.tool()
async def delete_container(container_name: str, confirmed: bool = False) -> str:
"""Delete a container.
Container must be stopped before deletion. Without confirmed=True,
returns a preview only.
Args:
container_name: Name of the container.
confirmed: Must be True to proceed. Set to True to confirm deletion.
"""
async def delete_container(container_name: str, confirmed: bool = False):
"""Delete a stopped container. Requires confirmed=True."""
if not confirmed:
return (
f"Preview: would delete container '{container_name}'.\n"