Fix Claude Desktop loading: lazy NAS connection on first tool call
Previously the server blocked at startup waiting for query_api_info()
and login() before starting the MCP protocol. Claude Desktop has a short
initialization timeout and dropped the server before the handshake started.
Changes:
- DsmClient: add _ensure_initialized() with asyncio.Lock for thread-safe
lazy init; called automatically at the start of request(), upload_text(),
and download_text() on the first use.
- cli.py serve: remove upfront query_api_info() and auth.login() calls;
the server now starts immediately ("MCP server ready" on stderr) and
connects to the NAS on the first tool invocation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -300,7 +300,7 @@ async def _run_serve(config_path: str | None) -> None:
|
||||
# instead of silently killing the process.
|
||||
from mcp_synology_container.auth import AuthManager
|
||||
from mcp_synology_container.config import load_config
|
||||
from mcp_synology_container.dsm_client import DsmClient, SynologyError
|
||||
from mcp_synology_container.dsm_client import DsmClient
|
||||
from mcp_synology_container.server import create_server
|
||||
|
||||
logger.debug("Loading config from: %s", config_path or "default path")
|
||||
@@ -311,29 +311,19 @@ async def _run_serve(config_path: str | None) -> None:
|
||||
sys.stderr.flush()
|
||||
return
|
||||
|
||||
logger.debug("Connecting to %s", config.base_url)
|
||||
try:
|
||||
async with DsmClient(config.base_url, config.connection.verify_ssl) as client:
|
||||
await client.query_api_info()
|
||||
auth = AuthManager(config)
|
||||
client.set_auth_manager(auth)
|
||||
# Open the HTTP client and register auth — but do NOT connect to the NAS yet.
|
||||
# Lazy init (_ensure_initialized) runs on the first tool call, so Claude Desktop
|
||||
# sees the server as ready immediately without waiting for NAS connectivity.
|
||||
async with DsmClient(config.base_url, config.connection.verify_ssl) as client:
|
||||
auth = AuthManager(config)
|
||||
client.set_auth_manager(auth)
|
||||
|
||||
try:
|
||||
client.sid = await auth.login(client)
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"Login failed: {e}\n")
|
||||
sys.stderr.flush()
|
||||
return
|
||||
|
||||
logger.debug("Login OK, creating MCP server")
|
||||
mcp_server = create_server(config, client)
|
||||
sys.stderr.write("MCP server ready\n")
|
||||
sys.stderr.flush()
|
||||
mcp_server = create_server(config, client)
|
||||
sys.stderr.write("MCP server ready\n")
|
||||
sys.stderr.flush()
|
||||
try:
|
||||
await mcp_server.run_stdio_async()
|
||||
except SynologyError as e:
|
||||
sys.stderr.write(f"DSM error during startup: {e}\n")
|
||||
sys.stderr.flush()
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"Fatal error: {e}\n")
|
||||
sys.stderr.flush()
|
||||
raise
|
||||
except Exception as e:
|
||||
sys.stderr.write(f"MCP server error: {e}\n")
|
||||
sys.stderr.flush()
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user