- Set up Astro + Starlight for documentation - Create comprehensive docs covering: - Getting started (introduction, installation, quickstart) - Configuration (environment variables, vCenter connection) - Deployment (Docker, OAuth multi-user) - Reference (94 tools, RBAC permissions, architecture) - VMware-inspired blue color scheme - Custom logo and styling - Search enabled via Pagefind
9.8 KiB
9.8 KiB
| title | description |
|---|---|
| Architecture | Technical overview of mcvsphere internals |
import { Aside } from '@astrojs/starlight/components';
System Architecture
┌─────────────────────────────────────────────────────────────┐
│ MCP Client (Claude Code) │
└──────────────────────────┬──────────────────────────────────┘
│
│ MCP Protocol
│ (stdio or streamable-http)
│
┌──────────────────────────▼──────────────────────────────────┐
│ mcvsphere │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ FastMCP │ │
│ │ - Protocol handling (JSON-RPC 2.0) │ │
│ │ - Tool registration and dispatch │ │
│ │ - Resource serving │ │
│ │ - OAuth integration (OIDCProxy) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ RBACMiddleware │ │
│ │ - Intercepts all tool calls │ │
│ │ - Extracts user from OAuth token │ │
│ │ - Enforces permission checks │ │
│ │ - Audit logging │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Tool Implementations │ │
│ │ - vm_lifecycle.py (7 tools) │ │
│ │ - power_ops.py (6 tools) │ │
│ │ - snapshots.py (5 tools) │ │
│ │ - guest_ops.py (7 tools) │ │
│ │ - ... (94 tools total) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Connection Manager │ │
│ │ - pyvmomi ServiceInstance │ │
│ │ - Connection pooling │ │
│ │ - Reconnection handling │ │
│ └───────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│
│ vSphere API (SOAP/REST)
│
┌──────────────────────────▼──────────────────────────────────┐
│ VMware vCenter / ESXi │
└─────────────────────────────────────────────────────────────┘
Source Layout
src/mcvsphere/
├── __init__.py # Package entry point, version
├── server.py # FastMCP server setup
├── config.py # Pydantic Settings configuration
├── connection.py # vSphere connection manager
├── auth.py # OIDCProxy configuration
├── middleware.py # RBAC middleware
├── permissions.py # Permission levels and mappings
├── audit.py # Audit logging
└── tools/ # MCP tool implementations
├── __init__.py
├── vm_lifecycle.py
├── power_ops.py
├── snapshots.py
├── guest_ops.py
├── serial_console.py
├── disk_mgmt.py
├── nic_mgmt.py
├── ovf_ops.py
├── host_mgmt.py
├── datastore_ops.py
└── vcenter_ops.py
Key Components
FastMCP Server (server.py)
The core MCP server built on FastMCP:
from fastmcp import FastMCP
mcp = FastMCP(
name="mcvsphere",
instructions="VMware vSphere management server..."
)
# Tools are registered via decorators
@mcp.tool()
def list_vms() -> list[dict]:
"""List all virtual machines."""
return connection.list_vms()
Configuration (config.py)
Pydantic Settings model for type-safe configuration:
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
vcenter_host: str
vcenter_user: str
vcenter_password: str
vcenter_insecure: bool = False
mcp_transport: Literal["stdio", "streamable-http"] = "stdio"
oauth_enabled: bool = False
# ...
Connection Manager (connection.py)
Manages the pyvmomi ServiceInstance connection:
class VSphereConnection:
def __init__(self, settings: Settings):
self.si = SmartConnect(
host=settings.vcenter_host,
user=settings.vcenter_user,
pwd=settings.vcenter_password,
sslContext=self._get_ssl_context()
)
def list_vms(self) -> list[dict]:
content = self.si.RetrieveContent()
# ... pyvmomi operations
RBAC Middleware (middleware.py)
Intercepts all tool calls for permission checking:
from fastmcp import Middleware
class RBACMiddleware(Middleware):
async def on_call_tool(self, context, call_next):
# 1. Extract user from OAuth token
claims = self._extract_user_from_context(context.fastmcp_context)
groups = claims.get("groups", [])
# 2. Check permission
tool_name = context.message.name
if not check_permission(tool_name, groups):
raise PermissionDeniedError(...)
# 3. Execute with audit logging
result = await call_next(context)
audit_log(tool_name, claims, result)
return result
OAuth Configuration (auth.py)
Configures FastMCP's OIDCProxy for token validation:
from fastmcp.server.auth import OIDCProxy
def create_auth_provider(settings: Settings) -> OIDCProxy | None:
if not settings.oauth_enabled:
return None
return OIDCProxy(
issuer_url=settings.oauth_issuer_url,
client_id=settings.oauth_client_id,
client_secret=settings.oauth_client_secret,
redirect_uri=f"{settings.oauth_base_url}/auth/callback",
required_scopes=[], # Authentik uses opaque tokens
)
Data Flow
Tool Invocation (STDIO mode)
- Claude Code sends JSON-RPC request via stdin
- FastMCP parses and validates request
- Tool function executes
- pyvmomi calls vSphere API
- Result serialized and returned via stdout
Tool Invocation (HTTP + OAuth mode)
- Client sends HTTP POST with Bearer token
- OIDCProxy validates JWT via JWKS
- RBACMiddleware extracts claims, checks permissions
- Tool function executes
- Audit log written
- Result returned as HTTP response
Performance Considerations
Connection Reuse
A single pyvmomi connection is shared across all requests. This avoids the overhead of establishing new connections for each tool call.
Lazy Loading
vCenter inventory is fetched on-demand rather than cached. This ensures data freshness but means each tool call queries vCenter directly.
Resource Pooling
For high-volume deployments, consider running multiple mcvsphere instances behind a load balancer. Each instance maintains its own vCenter connection.
Security Model
STDIO Mode
- No authentication (trusts the parent process)
- Single-user by design
- Credentials passed via environment variables
HTTP + OAuth Mode
- JWT validation via OIDC provider
- Group-based RBAC
- Audit trail with user identity
- Service account connection to vCenter (user identity tracked in audit logs, not vCenter permissions)