feat(infra): MCP 인프라 서버 통합 — 7개 도구 + core/ 분리
mcp-infra-server를 gpu-services/infra/로 통합. core/ 순수 로직은 Agent/NanoClaude에서도 직접 import 가능. 도구: docker_status, docker_logs, service_health, disk_usage, tailscale_status, ollama_models, mlx_models. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
"""Host configuration and tool-host validation.
|
||||
|
||||
All host IPs are Tailscale IPs (except nas-company which also works via Tailscale).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class HostConfig:
|
||||
ip: str
|
||||
user: str
|
||||
auth: str # "key" | "password"
|
||||
docker_path: str = "docker"
|
||||
needs_sudo: bool = False
|
||||
password: str | None = None # only for auth="password"
|
||||
|
||||
|
||||
HOSTS: dict[str, HostConfig] = {
|
||||
"gpu": HostConfig(
|
||||
ip="100.111.160.84",
|
||||
user="hyungi",
|
||||
auth="key",
|
||||
),
|
||||
"macmini": HostConfig(
|
||||
ip="100.76.254.116",
|
||||
user="hyungi",
|
||||
auth="key",
|
||||
),
|
||||
"nas-company": HostConfig(
|
||||
ip="100.71.132.52",
|
||||
user="hyungi",
|
||||
auth="password",
|
||||
docker_path="/usr/local/bin/docker",
|
||||
needs_sudo=True,
|
||||
password=os.getenv("NAS_COMPANY_PASSWORD"),
|
||||
),
|
||||
}
|
||||
|
||||
# Per-tool allowed hosts — invalid host → immediate error
|
||||
TOOL_HOST_MAP: dict[str, list[str]] = {
|
||||
"docker_status": ["gpu", "nas-company"],
|
||||
"docker_logs": ["gpu", "nas-company"],
|
||||
"disk_usage": ["gpu", "macmini", "nas-company"],
|
||||
"ollama_models": ["gpu", "macmini"],
|
||||
"mlx_models": ["macmini"],
|
||||
}
|
||||
|
||||
# SSH timeouts
|
||||
SSH_TIMEOUT = 5 # connection timeout (seconds)
|
||||
CMD_TIMEOUT = 10 # command execution timeout (seconds)
|
||||
MAX_RETRIES = 1 # retry once on failure
|
||||
|
||||
|
||||
def validate_host(tool: str, host: str) -> HostConfig:
|
||||
"""Validate host is allowed for tool and return config. Raises ValueError if invalid."""
|
||||
allowed = TOOL_HOST_MAP.get(tool)
|
||||
if allowed and host not in allowed:
|
||||
raise ValueError(
|
||||
f"'{host}'는 {tool}에서 지원하지 않습니다. 허용: {', '.join(allowed)}"
|
||||
)
|
||||
config = HOSTS.get(host)
|
||||
if not config:
|
||||
raise ValueError(
|
||||
f"알 수 없는 호스트: '{host}'. 허용: {', '.join(HOSTS.keys())}"
|
||||
)
|
||||
return config
|
||||
Reference in New Issue
Block a user