fix: v0.9.1 — clearer messages for exec/redeploy/check_image_updates
Three live-verified MCP weaknesses (update run 2026-06-22): - exec_in_container: SYNO.Docker.Container/exec does not exist on this DSM firmware (code 103, like pause/unpause). Catch it and return a guiding "not supported on this firmware" message instead of the raw DSM error; the tool stays available for firmwares that do implement exec. - redeploy_project: the failure hint suggested stop_project + start_project, but start_project does not recreate on a new image (it restarts the old one). Both failure hints now point back at redeploy_project and warn about parallel pull_image lock contention (DSM 2101/2202). - check_image_updates: docstring and output now state it only reflects DSM digest drift on already-pulled tags and does NOT discover newer version tags (use list_image_tags + release notes for that). Tests updated accordingly; CHANGELOG + version bumped to 0.9.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -269,6 +269,14 @@ def register_containers(mcp: FastMCP, config: AppConfig, client: DsmClient) -> N
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
if getattr(e, "code", None) == 103 or "does not exist" in str(e).lower():
|
||||
return (
|
||||
"exec_in_container is not supported on this DSM firmware "
|
||||
"(Container Manager exposes no 'exec' API method). "
|
||||
"To read a file inside a container, use the synology-filestation "
|
||||
"'download' tool on the bind-mount path; to run a command, use the "
|
||||
"Container Manager UI terminal."
|
||||
)
|
||||
return f"Error executing command in '{container_name}': {e}"
|
||||
|
||||
output = data.get("output", "")
|
||||
|
||||
@@ -369,7 +369,9 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None:
|
||||
|
||||
@mcp.tool()
|
||||
async def check_image_updates(project_name: str | None = None):
|
||||
"""Check which local images have updates available (upgradable flag from NAS registry)."""
|
||||
"""Report which local images DSM flags as upgradable (digest drift on
|
||||
already-pulled tags). Does NOT discover newer version tags (e.g. 0.8.2 →
|
||||
0.8.3) — use list_image_tags + the image's official releases for that."""
|
||||
try:
|
||||
data = await client.request(
|
||||
"SYNO.Docker.Image",
|
||||
@@ -416,4 +418,11 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None:
|
||||
if not upgradable:
|
||||
lines.append("All images are up to date.")
|
||||
|
||||
lines.append("")
|
||||
lines.append(
|
||||
"Note: 'upgradable' reflects digest drift on tags you already have; it "
|
||||
"does NOT detect newer version tags. Use list_image_tags + the image's "
|
||||
"release notes to find newer versions."
|
||||
)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
@@ -166,7 +166,9 @@ def register_projects(mcp: FastMCP, config: AppConfig, client: DsmClient) -> Non
|
||||
if status not in ("RUNNING", "STOPPED", "BUILD_FAILED", ""):
|
||||
return (
|
||||
f"Cannot redeploy '{project_name}': unexpected status '{status}'.\n"
|
||||
f"Workaround: use stop_project + start_project separately."
|
||||
"Wait for the current operation to finish, then retry redeploy_project. "
|
||||
"(start_project alone does NOT recreate on a new image — it only restarts "
|
||||
"the existing container.)"
|
||||
)
|
||||
|
||||
results: list[str] = []
|
||||
@@ -269,7 +271,13 @@ def register_projects(mcp: FastMCP, config: AppConfig, client: DsmClient) -> Non
|
||||
f"redeploy_project to recover."
|
||||
)
|
||||
else:
|
||||
results.append("Workaround: use stop_project + start_project separately.")
|
||||
results.append(
|
||||
"The project was not modified. Retry redeploy_project — it stops the "
|
||||
"project and recreates the containers on the new image. Do NOT use "
|
||||
"start_project to apply a new tag (it only restarts the old image). A "
|
||||
"transient DSM 2101/2202 here is usually a lock from a concurrent "
|
||||
"operation — e.g. a parallel pull_image — so don't pull and deploy at once."
|
||||
)
|
||||
|
||||
return "\n".join(results)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user