Remove pull_image + list_registries; mark Gruppen 6+7 as entfällt

DSM methods for SYNO.Docker.Image/pull and SYNO.Docker.Registry/get
did not behave as expected in production testing against the NAS.
Tools deregistered, modules deleted, tests removed, CLAUDE.md updated.
Tool count: 19 → 17.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-13 20:03:17 +02:00
parent 5fe8f5bc73
commit 6fa35e1b48
6 changed files with 10 additions and 428 deletions
+1 -52
View File
@@ -1,8 +1,7 @@
"""MCP tools for SYNO.Docker.Image: list, check updates, delete, pull."""
"""MCP tools for SYNO.Docker.Image: list, check updates, delete."""
from __future__ import annotations
import asyncio
import json
import logging
import sys
@@ -270,56 +269,6 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None:
return f"Deleted {display_name}{size_str} freed."
@mcp.tool()
async def pull_image(image: str) -> str:
"""Pull a Docker image from the active registry.
Splits the image reference into repository and tag, triggers the pull
via DSM, then polls the image list until the image appears (up to 120 s).
Args:
image: Image reference as "name:tag" (e.g. "postgres:17.8").
Tag defaults to "latest" when omitted.
"""
repository, sep, tag = image.rpartition(":")
if not sep:
repository = image
tag = "latest"
try:
await client.request(
"SYNO.Docker.Image",
"pull",
params={"repository": repository, "tag": tag},
)
except Exception as e:
return f"Error starting pull of '{image}': {e}"
# DSM starts the pull asynchronously; poll until the image appears.
deadline = 120
interval = 3
elapsed = 0
while elapsed < deadline:
await asyncio.sleep(interval)
elapsed += interval
try:
img_data = await client.request(
"SYNO.Docker.Image",
"list",
params={"limit": "-1", "offset": "0", "show_dsm": "false"},
)
except Exception:
continue
for img in img_data.get("images", []):
if img.get("repository") == repository and tag in (img.get("tags") or []):
size_str = _human_size(img.get("size", 0))
return f"Pulled {repository}:{tag}{size_str}."
return (
f"Pull of '{repository}:{tag}' started but did not complete within "
f"{deadline} s. Check DSM Container Manager for status."
)
@mcp.tool()
async def check_image_updates(project_name: str | None = None) -> str:
"""Check for available image updates for a project or all images.
@@ -1,49 +0,0 @@
"""MCP tools for SYNO.Docker.Registry: list."""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from mcp.server.fastmcp import FastMCP
from mcp_synology_container.config import AppConfig
from mcp_synology_container.dsm_client import DsmClient
logger = logging.getLogger(__name__)
def register_registries(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None:
"""Register all registry management tools with the MCP server."""
@mcp.tool()
async def list_registries() -> str:
"""List all configured Docker registries.
Shows name, URL, and marks the currently active registry.
Uses SYNO.Docker.Registry/get which returns the registries array
and the name of the currently active registry in the "using" field.
"""
try:
data = await client.request("SYNO.Docker.Registry", "get")
except Exception as e:
return f"Error listing registries: {e}"
registries = data.get("registries", [])
using = data.get("using", "")
if not registries:
return "No registries configured."
lines = [f"Registries ({len(registries)} total):", ""]
for reg in registries:
name = reg.get("name", "?")
url = reg.get("url", "?")
active_marker = " [active]" if name == using else ""
mirror_marker = " [mirror enabled]" if reg.get("enable_registry_mirror") else ""
lines.append(f" {name}{active_marker}")
lines.append(f" URL: {url}{mirror_marker}")
lines.append("")
return "\n".join(lines).rstrip()
-2
View File
@@ -31,7 +31,6 @@ def create_server(config: AppConfig, client: DsmClient) -> FastMCP:
from mcp_synology_container.modules.images import register_images
from mcp_synology_container.modules.networks import register_networks
from mcp_synology_container.modules.projects import register_projects
from mcp_synology_container.modules.registries import register_registries
from mcp_synology_container.modules.system import register_system
register_projects(mcp, config, client)
@@ -40,7 +39,6 @@ def create_server(config: AppConfig, client: DsmClient) -> FastMCP:
register_images(mcp, config, client)
register_system(mcp, config, client)
register_networks(mcp, config, client)
register_registries(mcp, config, client)
logger.info("MCP server configured with all tool modules")
return mcp