Skip to main content
Glama

Vultr MCP

by rsp2k
vpcs.pyโ€ข18.3 kB
""" Vultr VPCs FastMCP Module. This module contains FastMCP tools and resources for managing Vultr VPCs and VPC 2.0 networks. """ from typing import Any, List from typing import Any, List from fastmcp import FastMCP def create_vpcs_mcp(vultr_client) -> FastMCP: """ Create a FastMCP instance for Vultr VPC management. Args: vultr_client: VultrDNSServer instance Returns: Configured FastMCP instance with VPC management tools """ mcp = FastMCP(name="vultr-vpcs") # Helper function to check if string is UUID format def is_uuid_format(value: str) -> bool: """Check if a string looks like a UUID.""" import re uuid_pattern = r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" return bool(re.match(uuid_pattern, value, re.IGNORECASE)) # Helper function to get VPC ID from description or ID async def get_vpc_id(identifier: str) -> str: """ Get the VPC ID from description or existing ID. Args: identifier: VPC description or ID Returns: The VPC ID Raises: ValueError: If the VPC is not found """ # If it looks like a UUID, return as-is if is_uuid_format(identifier): return identifier # Search by description vpcs = await vultr_client.list_vpcs() for vpc in vpcs: if vpc.get("description") == identifier: return vpc["id"] raise ValueError(f"VPC '{identifier}' not found") # Helper function to get VPC 2.0 ID from description or ID async def get_vpc2_id(identifier: str) -> str: """ Get the VPC 2.0 ID from description or existing ID. Args: identifier: VPC 2.0 description or ID Returns: The VPC 2.0 ID Raises: ValueError: If the VPC 2.0 is not found """ # If it looks like a UUID, return as-is if is_uuid_format(identifier): return identifier # Search by description vpc2s = await vultr_client.list_vpc2s() for vpc2 in vpc2s: if vpc2.get("description") == identifier: return vpc2["id"] raise ValueError(f"VPC 2.0 '{identifier}' not found") # VPC resources @mcp.resource("vpcs://list") async def list_vpcs_resource() -> List[dict[str, Any]]: """List all VPCs.""" return await vultr_client.list_vpcs() @mcp.resource("vpcs://{vpc_identifier}") async def get_vpc_resource(vpc_identifier: str) -> dict[str, Any]: """Get details of a specific VPC. Args: vpc_identifier: The VPC description or ID """ vpc_id = await get_vpc_id(vpc_identifier) return await vultr_client.get_vpc(vpc_id) @mcp.resource("vpc2s://list") async def list_vpc2s_resource() -> List[dict[str, Any]]: """List all VPC 2.0 networks.""" return await vultr_client.list_vpc2s() @mcp.resource("vpc2s://{vpc2_identifier}") async def get_vpc2_resource(vpc2_identifier: str) -> dict[str, Any]: """Get details of a specific VPC 2.0. Args: vpc2_identifier: The VPC 2.0 description or ID """ vpc2_id = await get_vpc2_id(vpc2_identifier) return await vultr_client.get_vpc2(vpc2_id) # VPC tools @mcp.tool async def list() -> List[dict[str, Any]]: """List all VPCs in your account. Returns: List of VPC objects with details including: - id: VPC ID - description: User-defined description - region: Region where VPC is located - v4_subnet: IPv4 subnet - v4_subnet_mask: IPv4 subnet mask - date_created: Creation date """ return await vultr_client.list_vpcs() @mcp.tool async def get(vpc_identifier: str) -> dict[str, Any]: """Get detailed information about a specific VPC. Smart identifier resolution: Use VPC description or ID. Args: vpc_identifier: VPC description or ID to retrieve Returns: Detailed VPC information including subnet configuration """ vpc_id = await get_vpc_id(vpc_identifier) return await vultr_client.get_vpc(vpc_id) @mcp.tool async def create( region: str, description: str, v4_subnet: str | None = None, v4_subnet_mask: int | None = None, ) -> dict[str, Any]: """Create a new VPC. Args: region: Region code where the VPC will be created (e.g., "ewr", "lax", "fra") description: Description/label for the VPC v4_subnet: IPv4 subnet for the VPC (e.g., "10.0.0.0", defaults to auto-assigned) v4_subnet_mask: IPv4 subnet mask (e.g., 24, defaults to 24) Returns: Created VPC information including ID and subnet details """ return await vultr_client.create_vpc( region, description, v4_subnet, v4_subnet_mask ) @mcp.tool async def update(vpc_identifier: str, description: str) -> dict[str, str]: """Update VPC description. Smart identifier resolution: Use VPC description or ID. Args: vpc_identifier: VPC description or ID to update description: New description for the VPC Returns: Success confirmation """ vpc_id = await get_vpc_id(vpc_identifier) await vultr_client.update_vpc(vpc_id, description) return { "success": True, "message": f"VPC description updated to '{description}'", "vpc_id": vpc_id, } @mcp.tool async def delete(vpc_identifier: str) -> dict[str, str]: """Delete a VPC. Smart identifier resolution: Use VPC description or ID. Args: vpc_identifier: VPC description or ID to delete Returns: Success confirmation """ vpc_id = await get_vpc_id(vpc_identifier) await vultr_client.delete_vpc(vpc_id) return { "success": True, "message": "VPC deleted successfully", "vpc_id": vpc_id, } # VPC 2.0 tools @mcp.tool async def list_vpc2() -> List[dict[str, Any]]: """List all VPC 2.0 networks in your account. Returns: List of VPC 2.0 objects with details including: - id: VPC 2.0 ID - description: User-defined description - region: Region where VPC 2.0 is located - ip_block: IP block (e.g., "10.0.0.0") - prefix_length: Prefix length (e.g., 24) - date_created: Creation date """ return await vultr_client.list_vpc2s() @mcp.tool async def get_vpc2(vpc2_identifier: str) -> dict[str, Any]: """Get detailed information about a specific VPC 2.0. Smart identifier resolution: Use VPC 2.0 description or ID. Args: vpc2_identifier: VPC 2.0 description or ID to retrieve Returns: Detailed VPC 2.0 information including IP block configuration """ vpc2_id = await get_vpc2_id(vpc2_identifier) return await vultr_client.get_vpc2(vpc2_id) @mcp.tool async def create_vpc2( region: str, description: str, ip_type: str = "v4", ip_block: str | None = None, prefix_length: int | None = None, ) -> dict[str, Any]: """Create a new VPC 2.0 network. Args: region: Region code where the VPC 2.0 will be created (e.g., "ewr", "lax", "fra") description: Description/label for the VPC 2.0 ip_type: IP type ("v4" or "v6", defaults to "v4") ip_block: IP block for the VPC 2.0 (e.g., "10.0.0.0", defaults to auto-assigned) prefix_length: Prefix length (e.g., 24 for /24, defaults to 24) Returns: Created VPC 2.0 information including ID and IP block details """ return await vultr_client.create_vpc2( region, description, ip_type, ip_block, prefix_length ) @mcp.tool async def update_vpc2(vpc2_identifier: str, description: str) -> dict[str, str]: """Update VPC 2.0 description. Smart identifier resolution: Use VPC 2.0 description or ID. Args: vpc2_identifier: VPC 2.0 description or ID to update description: New description for the VPC 2.0 Returns: Success confirmation """ vpc2_id = await get_vpc2_id(vpc2_identifier) await vultr_client.update_vpc2(vpc2_id, description) return { "success": True, "message": f"VPC 2.0 description updated to '{description}'", "vpc2_id": vpc2_id, } @mcp.tool async def delete_vpc2(vpc2_identifier: str) -> dict[str, str]: """Delete a VPC 2.0 network. Smart identifier resolution: Use VPC 2.0 description or ID. Args: vpc2_identifier: VPC 2.0 description or ID to delete Returns: Success confirmation """ vpc2_id = await get_vpc2_id(vpc2_identifier) await vultr_client.delete_vpc2(vpc2_id) return { "success": True, "message": "VPC 2.0 deleted successfully", "vpc2_id": vpc2_id, } # Instance attachment tools @mcp.tool async def attach_to_instance( vpc_identifier: str, instance_identifier: str, vpc_type: str = "vpc" ) -> dict[str, str]: """Attach VPC or VPC 2.0 to an instance. Smart identifier resolution: Use VPC/instance description/label/hostname or ID. Args: vpc_identifier: VPC/VPC 2.0 description or ID to attach instance_identifier: Instance label, hostname, or ID to attach to vpc_type: Type of VPC ("vpc" or "vpc2", defaults to "vpc") Returns: Success confirmation """ # Get instance ID using the instances module pattern if is_uuid_format(instance_identifier): instance_id = instance_identifier else: instances = await vultr_client.list_instances() instance_id = None for instance in instances: if ( instance.get("label") == instance_identifier or instance.get("hostname") == instance_identifier ): instance_id = instance["id"] break if not instance_id: raise ValueError(f"Instance '{instance_identifier}' not found") if vpc_type == "vpc2": vpc2_id = await get_vpc2_id(vpc_identifier) await vultr_client.attach_vpc2_to_instance(instance_id, vpc2_id) return { "success": True, "message": "VPC 2.0 attached to instance successfully", "vpc2_id": vpc2_id, "instance_id": instance_id, } else: vpc_id = await get_vpc_id(vpc_identifier) await vultr_client.attach_vpc_to_instance(instance_id, vpc_id) return { "success": True, "message": "VPC attached to instance successfully", "vpc_id": vpc_id, "instance_id": instance_id, } @mcp.tool async def detach_from_instance( vpc_identifier: str, instance_identifier: str, vpc_type: str = "vpc" ) -> dict[str, str]: """Detach VPC or VPC 2.0 from an instance. Smart identifier resolution: Use VPC/instance description/label/hostname or ID. Args: vpc_identifier: VPC/VPC 2.0 description or ID to detach instance_identifier: Instance label, hostname, or ID to detach from vpc_type: Type of VPC ("vpc" or "vpc2", defaults to "vpc") Returns: Success confirmation """ # Get instance ID using the instances module pattern if is_uuid_format(instance_identifier): instance_id = instance_identifier else: instances = await vultr_client.list_instances() instance_id = None for instance in instances: if ( instance.get("label") == instance_identifier or instance.get("hostname") == instance_identifier ): instance_id = instance["id"] break if not instance_id: raise ValueError(f"Instance '{instance_identifier}' not found") if vpc_type == "vpc2": vpc2_id = await get_vpc2_id(vpc_identifier) await vultr_client.detach_vpc2_from_instance(instance_id, vpc2_id) return { "success": True, "message": "VPC 2.0 detached from instance successfully", "vpc2_id": vpc2_id, "instance_id": instance_id, } else: vpc_id = await get_vpc_id(vpc_identifier) await vultr_client.detach_vpc_from_instance(instance_id, vpc_id) return { "success": True, "message": "VPC detached from instance successfully", "vpc_id": vpc_id, "instance_id": instance_id, } @mcp.tool async def list_instance_networks(instance_identifier: str) -> dict[str, Any]: """List all VPCs and VPC 2.0 networks attached to an instance. Smart identifier resolution: Use instance label, hostname, or ID. Args: instance_identifier: Instance label, hostname, or ID Returns: Combined list of VPCs and VPC 2.0 networks attached to the instance """ # Get instance ID using the instances module pattern if is_uuid_format(instance_identifier): instance_id = instance_identifier else: instances = await vultr_client.list_instances() instance_id = None for instance in instances: if ( instance.get("label") == instance_identifier or instance.get("hostname") == instance_identifier ): instance_id = instance["id"] break if not instance_id: raise ValueError(f"Instance '{instance_identifier}' not found") vpcs = await vultr_client.list_instance_vpcs(instance_id) vpc2s = await vultr_client.list_instance_vpc2s(instance_id) return { "instance_id": instance_id, "vpcs": vpcs, "vpc2s": vpc2s, "total_networks": len(vpcs) + len(vpc2s), } @mcp.tool async def list_by_region(region: str) -> dict[str, Any]: """List VPCs and VPC 2.0 networks in a specific region. Args: region: Region code to filter by (e.g., "ewr", "lax", "fra") Returns: Combined list of VPCs and VPC 2.0 networks in the specified region """ vpcs = await vultr_client.list_vpcs() vpc2s = await vultr_client.list_vpc2s() region_vpcs = [vpc for vpc in vpcs if vpc.get("region") == region] region_vpc2s = [vpc2 for vpc2 in vpc2s if vpc2.get("region") == region] return { "region": region, "vpcs": region_vpcs, "vpc2s": region_vpc2s, "total_networks": len(region_vpcs) + len(region_vpc2s), } @mcp.tool async def get_network_info( identifier: str, vpc_type: str = "auto" ) -> dict[str, Any]: """Get comprehensive network information for VPC or VPC 2.0. Smart identifier resolution: Use VPC/VPC 2.0 description or ID. Args: identifier: VPC/VPC 2.0 description or ID vpc_type: Type to search ("vpc", "vpc2", or "auto" to search both) Returns: Comprehensive network information with usage recommendations """ if vpc_type == "auto": # Try VPC first, then VPC 2.0 try: vpc_id = await get_vpc_id(identifier) vpc = await vultr_client.get_vpc(vpc_id) network_type = "VPC" network_info = vpc except ValueError: try: vpc2_id = await get_vpc2_id(identifier) vpc2 = await vultr_client.get_vpc2(vpc2_id) network_type = "VPC 2.0" network_info = vpc2 except ValueError: raise ValueError( f"Network '{identifier}' not found in VPCs or VPC 2.0s" ) elif vpc_type == "vpc2": vpc2_id = await get_vpc2_id(identifier) network_info = await vultr_client.get_vpc2(vpc2_id) network_type = "VPC 2.0" else: vpc_id = await get_vpc_id(identifier) network_info = await vultr_client.get_vpc(vpc_id) network_type = "VPC" # Enhanced network information enhanced_info = { **network_info, "network_type": network_type, "capabilities": { "scalability": "High" if network_type == "VPC 2.0" else "Standard", "broadcast_traffic": "Filtered" if network_type == "VPC 2.0" else "Processed", "max_instances": "1000+" if network_type == "VPC 2.0" else "100+", "performance": "Enhanced" if network_type == "VPC 2.0" else "Standard", }, "recommendations": [ f"Use {network_type} for your networking needs", "Consider VPC 2.0 for large-scale deployments" if network_type == "VPC" else "VPC 2.0 provides enhanced scalability", "Ensure instances are in the same region for optimal performance", ], } return enhanced_info return mcp

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rsp2k/mcp-vultr'

If you have feedback or need assistance with the MCP directory API, please join our Discord server