Skip to main content
Glama
dkruyt

Hetzner Cloud MCP Server

by dkruyt

create_server

Provision a new virtual server on Hetzner Cloud by specifying its name, type, operating system image, location, and SSH keys.

Instructions

Create a new server. Creates a new server with the specified configuration. Examples: - Basic server: {"name": "web-server", "server_type": "cx11", "image": "ubuntu-22.04"} - With SSH keys: {"name": "app-server", "server_type": "cx21", "image": "debian-11", "ssh_keys": [123, 456]} - Custom location: {"name": "db-server", "server_type": "cx31", "image": "ubuntu-22.04", "location": "fsn1"}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Implementation Reference

  • The handler function decorated with @mcp.tool() that implements the create_server tool. It resolves server type, image, location, and SSH keys from names/IDs, creates the server via hcloud client, and returns server details and action info.
    def create_server(params: CreateServerParams) -> Dict[str, Any]: """ Create a new server. Creates a new server with the specified configuration. Examples: - Basic server: {"name": "web-server", "server_type": "cx11", "image": "ubuntu-22.04"} - With SSH keys: {"name": "app-server", "server_type": "cx21", "image": "debian-11", "ssh_keys": [123, 456]} - Custom location: {"name": "db-server", "server_type": "cx31", "image": "ubuntu-22.04", "location": "fsn1"} """ try: # Get the objects needed for the API call try: # Debug the objects server_types = client.server_types.get_all() images = client.images.get_all() locations = client.locations.get_all() # Print available options for debugging server_type_names = [st.name for st in server_types] image_names = [img.name for img in images] location_names = [loc.name for loc in locations] # Try to get objects by name server_type_obj = client.server_types.get_by_name(params.server_type) image_obj = client.images.get_by_name(params.image) location_obj = client.locations.get_by_name(params.location) # Check if objects were found if server_type_obj is None: return {"error": f"Server type '{params.server_type}' not found. Available types: {server_type_names}"} if image_obj is None: return {"error": f"Image '{params.image}' not found. Available images: {image_names}"} if location_obj is None: return {"error": f"Location '{params.location}' not found. Available locations: {location_names}"} # Handle SSH keys if provided - convert IDs to objects or use names ssh_keys = [] if params.ssh_keys: for ssh_key in params.ssh_keys: # If SSH key is an integer ID, get the object if isinstance(ssh_key, int): ssh_key_obj = client.ssh_keys.get_by_id(ssh_key) if ssh_key_obj: ssh_keys.append(ssh_key_obj) # If SSH key is a string name, get the object elif isinstance(ssh_key, str): ssh_key_obj = client.ssh_keys.get_by_name(ssh_key) if ssh_key_obj: ssh_keys.append(ssh_key_obj) # Create server with objects instead of strings response = client.servers.create( name=params.name, server_type=server_type_obj, image=image_obj, location=location_obj, ssh_keys=ssh_keys ) except Exception as e: return {"error": f"Failed to create server: {str(e)}"} # Extract server and action information server = response.server action = response.action # Don't wait for the action to complete - the method doesn't exist return { "server": server_to_dict(server), "action": { "id": action.id, "status": action.status, "command": action.command, "progress": action.progress, "error": action.error, "started": action.started.isoformat() if action.started else None, "finished": action.finished.isoformat() if action.finished else None, } if action else None, "root_password": response.root_password, # Only provided when no SSH keys are used } except Exception as e: return {"error": f"Failed to create server: {str(e)}"}
  • Pydantic BaseModel defining the input schema for the create_server tool parameters.
    class CreateServerParams(BaseModel): name: str = Field(..., description="Name of the server") server_type: str = Field(..., description="Server type (e.g., cx11, cx21, etc.)") image: str = Field(..., description="Image name or ID (e.g., ubuntu-22.04, debian-11, etc.)") location: Optional[str] = Field("nbg1", description="Location (e.g., nbg1, fsn1, etc.)") ssh_keys: Optional[List[int]] = Field(None, description="List of SSH key IDs")
  • Helper function to convert Hetzner Server object to a dictionary, used in the response of create_server and other server tools.
    def server_to_dict(server: Server) -> Dict[str, Any]: """Convert a Server object to a dictionary with relevant information.""" return { "id": server.id, "name": server.name, "status": server.status, "created": server.created.isoformat() if server.created else None, "server_type": server.server_type.name if server.server_type else None, "image": server.image.name if server.image else None, "datacenter": server.datacenter.name if server.datacenter else None, "location": server.datacenter.location.name if server.datacenter and server.datacenter.location else None, "public_net": { "ipv4": server.public_net.ipv4.ip if server.public_net and server.public_net.ipv4 else None, "ipv6": server.public_net.ipv6.ip if server.public_net and server.public_net.ipv6 else None, }, "included_traffic": server.included_traffic, "outgoing_traffic": server.outgoing_traffic, "ingoing_traffic": server.ingoing_traffic, "backup_window": server.backup_window, "rescue_enabled": server.rescue_enabled, "locked": server.locked, "protection": { "delete": server.protection["delete"] if server.protection else False, "rebuild": server.protection["rebuild"] if server.protection else False, }, "labels": server.labels, "volumes": [volume.id for volume in server.volumes] if server.volumes else [], }

Latest Blog Posts

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/dkruyt/mcp-hetzner'

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