---
phase: 01-foundation
plan: 02
subsystem: api
tags: [pydantic, fastmcp, error-contract, models]

requires:
  - phase: 01-01
    provides: "Installable Python package with module tree"
provides:
  - Complete Pydantic v2 data contract (all shared models)
  - FastMCP server skeleton with tool registration
  - "@structured_tool_handler catch-all decorator for error contract"
  - "python -m vmcluster_mcp entry point"
affects: [01-03, phase-02, phase-03, phase-04, phase-05, phase-06, phase-07]

tech-stack:
  added: [fastmcp]
  patterns: [generic-tool-result, catch-all-decorator, structured-error-contract]

key-files:
  created:
    - vmcluster_mcp/models.py
    - vmcluster_mcp/server.py
    - vmcluster_mcp/__main__.py
    - tests/test_models.py
    - tests/test_server.py
  modified: []

key-decisions:
  - "ToolResult[T] uses Generic[T] with TypeVar for typed tool responses"
  - "ErrorDetail.code is str, not enum — extensible for all phases"
  - "structured_tool_handler wraps every tool; exception → ToolResult(success=False)"
  - "mcp.run() entry point via __main__.py for 'python -m vmcluster_mcp'"

patterns-established:
  - "Error contract: all tools return ToolResult, never raw exceptions"
  - "Decorator pattern: @structured_tool_handler wraps async tool handlers with functools.wraps"
  - "Model imports: 'from .models import ...' for all shared types"

requirements-completed: [FOUND-01, FOUND-02]

duration: 5min
completed: 2026-03-22
---

# Plan 01-02: Data Models + Server Skeleton Summary

**Complete Pydantic v2 data contract with 17 model classes and FastMCP server skeleton enforcing structured error handling via catch-all decorator.**

## What was built

**models.py** — 17 Pydantic v2 model classes covering the full data contract:
- Error contract: ToolResult[T], ErrorDetail
- Cluster: ClusterHandle, NodeDescriptor, ClusterStatus, NodeStatus
- Execution: ExecResult, ExecAllResult  
- Snapshots: SnapshotInfo, SnapshotNodeInfo
- Artifacts: BuildArtifact, SyncStatus, SyncNodeResult, InstallStatus, InstallNodeResult, CompilerError, CompilerWarning, ArtifactBuildResult
- Observability: DmesgResult, DmesgLine
- Network faults: NetFaultHandle, NetFaultInfo

**server.py** — FastMCP("vmcluster-mcp") with @structured_tool_handler decorator that converts any unhandled exception into ToolResult(success=False, error=ErrorDetail(code="INTERNAL_ERROR")).

**__main__.py** — Entry point for `python -m vmcluster_mcp`.

## Verification

- 16 model tests pass (generics, defaults, serialization round-trips)
- 5 server tests pass (exception catch, passthrough, functools.wraps)
- ruff check passes

## Self-Check: PASSED
