"""MCP Infra Server — thin wrapper over core/ functions. This file ONLY does: 1. MCP tool registration (decorators) 2. Parameter validation 3. Call core/ functions 4. Return results as JSON text All actual logic lives in src/core/. """ from __future__ import annotations import json from mcp.server.fastmcp import FastMCP from .core.docker import docker_status, docker_logs from .core.health import service_health, VALID_SERVICES from .core.system import disk_usage from .core.network import tailscale_status from .core.models import ollama_models, mlx_models from .core.docserver import scheduler_status as _scheduler_status, queue_status as _queue_status from .core.verify import run_verify as _run_verify, VERIFY_COMMANDS mcp = FastMCP( "infra", instructions=( "인프라 모니터링 도구. GPU 서버, Mac mini, 회사 NAS의 " "Docker 상태, 서비스 헬스체크, 디스크 사용량, 네트워크, 모델 목록을 확인합니다." ), ) @mcp.tool() async def check_docker_status(host: str) -> str: """Docker 컨테이너 상태 확인. Args: host: 대상 호스트 (gpu | nas-company) """ result = await docker_status(host) return result.model_dump_json(indent=2) @mcp.tool() async def check_docker_logs(host: str, container: str, lines: int = 50) -> str: """Docker 컨테이너 최근 로그 조회. Args: host: 대상 호스트 (gpu | nas-company) container: 컨테이너 이름 lines: 조회할 줄 수 (기본 50) """ result = await docker_logs(host, container, lines) return result.model_dump_json(indent=2) @mcp.tool() async def check_service_health(service: str) -> str: """서비스 헬스체크. 서비스별 정상 판정 기준이 다름. Args: service: 서비스 이름 (document-server | mlx | mlx-proxy | nanoclaude | ollama-gpu | ollama-macmini) """ result = await service_health(service) return result.model_dump_json(indent=2) @mcp.tool() async def check_disk_usage(host: str) -> str: """디스크 사용량 확인. 85% 초과 시 경고. Args: host: 대상 호스트 (gpu | macmini | nas-company) """ result = await disk_usage(host) return result.model_dump_json(indent=2) @mcp.tool() async def check_tailscale() -> str: """Tailscale 네트워크 상태 확인. 모든 피어 연결 상태를 반환.""" result = await tailscale_status() return result.model_dump_json(indent=2) @mcp.tool() async def check_ollama_models(host: str) -> str: """Ollama 설치 모델 목록 조회. Args: host: 대상 호스트 (gpu | macmini) """ result = await ollama_models(host) return result.model_dump_json(indent=2) @mcp.tool() async def check_mlx_models() -> str: """Mac mini MLX 서버에 로드된 모델 목록 조회.""" result = await mlx_models() return result.model_dump_json(indent=2) @mcp.tool() async def check_scheduler_status() -> str: """Document Server APScheduler 잡 상태. 최근 스케줄러 로그에서 추출.""" result = await _scheduler_status() return json.dumps(result, ensure_ascii=False, indent=2) @mcp.tool() async def check_queue_status() -> str: """Document Server 문서 처리 큐 현황. 최근 큐 로그에서 추출.""" result = await _queue_status() return json.dumps(result, ensure_ascii=False, indent=2) @mcp.tool() async def check_verify(check_name: str) -> str: """인프라 검증 명령 실행 (infra_inventory.md 기반). Args: check_name: 체크 이름 (gpu-snapshot | macmini-snapshot | docserver-health | config-model-match) """ result = await _run_verify(check_name) return json.dumps(result, ensure_ascii=False, indent=2) def main(): mcp.run(transport="stdio") if __name__ == "__main__": main()