f27a5456f6
Three new SYNO.Docker.Registry tools, reverse-engineered from a live DSM API capture (n4s4 reference disagrees on param names and methods). - search_registry (#5): SYNO.Docker.Registry/search v1 with JSON-encoded q, plus offset/limit/page_size. Renders stars, downloads, official flag, truncated description, and total match count. Read-only. - list_image_tags: SYNO.Docker.Registry/tags v1 with JSON-encoded repo (not name — DSM live capture diverges from n4s4). Response shape is unusual: tag list comes back as the envelope's data field directly. Output capped by limit (default 50); accepts both list and dict response shapes defensively. Read-only. - pull_image (#3): SYNO.Docker.Registry/pull_start v1 with both repository and tag JSON-encoded. Async pull — no pull_status method confirmed on this DSM, so completion is detected by polling SYNO.Docker.Image/list (2–10 s backoff, 240 s budget under the Claude Desktop ~4 min tool-call ceiling). Timeout returns a non-fatal "still running" hint. Short-circuits when the image is already present locally. Confirmation gate required. Tool count: 31 → 34. CLAUDE.md confirmation list updated. New DSM quirks documented for pull_start (no pull_status) and tags (repo param name, top-level data array). Closes #3 Closes #5 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
"""MCP server factory: creates and configures the FastMCP instance."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import TYPE_CHECKING
|
|
|
|
from mcp.server.fastmcp import FastMCP
|
|
|
|
if TYPE_CHECKING:
|
|
from mcp_synology_container.config import AppConfig
|
|
from mcp_synology_container.dsm_client import DsmClient
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_server(config: AppConfig, client: DsmClient) -> FastMCP:
|
|
"""Create and configure the MCP server with all tools registered.
|
|
|
|
Args:
|
|
config: Application configuration.
|
|
client: Authenticated DsmClient instance.
|
|
|
|
Returns:
|
|
Configured FastMCP server ready to run.
|
|
"""
|
|
mcp = FastMCP("mcp-synology-container")
|
|
|
|
from mcp_synology_container.modules.compose import register_compose
|
|
from mcp_synology_container.modules.containers import register_containers
|
|
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.registry import register_registry
|
|
from mcp_synology_container.modules.system import register_system
|
|
|
|
register_projects(mcp, config, client)
|
|
register_containers(mcp, config, client)
|
|
register_compose(mcp, config, client)
|
|
register_images(mcp, config, client)
|
|
register_system(mcp, config, client)
|
|
register_networks(mcp, config, client)
|
|
register_registry(mcp, config, client)
|
|
|
|
logger.info("MCP server configured with all tool modules")
|
|
return mcp
|