# Hetzner Mcp

> Model Context Protocol server bringing Hetzner to your AI agent

- **Type:** MCP server
- **Install:** `agentstack add mcp-devinoldenburg-hetzner-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [devinoldenburg](https://agentstack.voostack.com/s/devinoldenburg)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [devinoldenburg](https://github.com/devinoldenburg)
- **Source:** https://github.com/devinoldenburg/hetzner-mcp
- **Website:** https://pypi.org/project/hetzner-mcp/

## Install

```sh
agentstack add mcp-devinoldenburg-hetzner-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Hetzner MCP

**Model Context Protocol server for full Hetzner Cloud + Storage API automation**

Expose all official Hetzner operations as MCP tools so AI agents can manage servers, networking, load balancers, firewalls, volumes, DNS zones, and storage boxes from one server.

[](https://pypi.org/project/hetzner-mcp/)
[](https://www.python.org/downloads/)
[](https://modelcontextprotocol.io/)
[](./LICENSE)

---

## Install

```bash
pipx install hetzner-mcp
hetzner-mcp install
```

Then set your token and restart your MCP client:

```bash
export HETZNER_TOKEN="your_token_here"
```

Or configure it once via CLI (persisted local config):

```bash
hetzner-mcp auth set --token "your_token_here"
```

## What It Does

`hetzner-mcp` loads official OpenAPI specs from Hetzner and exposes operations as MCP tools.

- Full Cloud API coverage: `https://api.hetzner.cloud/v1`
- Full Storage API coverage: `https://api.hetzner.com/v1`
- Dynamic tool generation from operation IDs
- Helper tools for discovery, search, and operation schema inspection
- Action polling helper for async action workflows

### Core helper tools

| Tool | What it does |
|------|--------------|
| `list_api_operations` | List all operations with filters (domain/tag/method/query) |
| `search_api_operations` | Search operations by keyword |
| `get_api_operation_details` | Inspect full operation details and input schema |
| `list_api_categories` | List all API categories/tags with docs descriptions |
| `get_api_category_details` | Explain one category in depth with all endpoints inside |
| `list_api_projects` | Show configured project profiles and active credential context |
| `set_active_api_project` | Switch active project profile for agent execution context |
| `wait_for_action` | Poll cloud/storage actions until completion |

All API operations are also exposed directly as tools using the official operation ID names (for example `create_server`, `get_action`, `create_storage_box`).

For agent-friendly documentation, every endpoint and category also has dedicated guide tools:

- Endpoint guide tool pattern: `guide_`
  - Example: `guide_create_server`
- Category guide tool pattern: `category_guide__`
  - Example: `category_guide_cloud_servers`

These guide tools include docs text from the OpenAPI documentation, explicit purpose, parameter explanations, and example tool arguments.

### Docs-first execution lock (required)

This server enforces a docs-first workflow for endpoint execution:

1. Call `guide_` first for the endpoint you want to execute.
2. Then call the endpoint tool itself (for example `create_server`).

If you skip step 1, execution is rejected with a `docs_required` error.

Unlocking is based on **context freshness** (interaction distance in the current session),
not wall-clock time:

- Docs must be read before execution.
- Recently executed endpoints remain trusted while context is still fresh.
- After enough unrelated tool interactions (context drift), docs must be read again.

## Full Coverage

Current generated operation coverage:

- Total operations: **221**
- Cloud operations: **189**
- Storage operations: **32**

You can verify this locally:

```bash
python scripts/verify_operation_coverage.py
```

## Example Prompts

```text
"List all Hetzner operations related to firewalls"
"Create a CX22 server in fsn1-dc14 with my SSH key"
"Attach volume 12345 to server 67890"
"Create a load balancer and add target server 1001"
"Enable rescue mode on server 123 and wait for action completion"
"Create a storage box and reset its password"
"Show operation details for update_storage_box_access_settings"
```

## Authentication

You can configure auth in two ways:

1) Environment variables (recommended for CI/ephemeral environments)
2) Local CLI config file (recommended for local workstation use)

Environment variables (highest precedence):

- `HETZNER_TOKEN` for both Cloud and Storage APIs
- `HETZNER_CLOUD_TOKEN` to override cloud auth token
- `HETZNER_STORAGE_TOKEN` to override storage auth token
- `HETZNER_PROJECT` to choose one configured local project profile for this session

Base URL safety:

- Default API targets are locked to the official Hetzner HTTPS endpoints.
- `HETZNER_CLOUD_BASE_URL` and `HETZNER_STORAGE_BASE_URL` are validated before any token is attached.
- Custom base URLs are blocked by default to prevent credential exfiltration to non-Hetzner hosts.
- For controlled test environments only, opt in explicitly with `HETZNER_ALLOW_CUSTOM_BASE_URLS=true`.

Local CLI config examples:

```bash
# set default token
hetzner-mcp auth set --token "your_token_here"

# auth set auto-probes what the provided key can do
# (cloud/storage + read/write capability hints)

# set per-domain overrides
hetzner-mcp auth set --cloud-token "cloud_token" --storage-token "storage_token"

# inspect effective token sources (env/file/unset)
hetzner-mcp auth show

# open full local config in your editor
hetzner-mcp config edit
```

Multi-project profile examples:

```bash
# create per-environment profiles
hetzner-mcp project add prod --description "Production Hetzner" --token "prod_token" --activate
hetzner-mcp project add staging --description "Staging Hetzner" --token "staging_token"

# project add also auto-detects capability hints for entered keys

# see which profile is active and what each one is for
hetzner-mcp project list

# switch active profile
hetzner-mcp project use staging
```

Capability probing notes:

- `auth set` and `project add` automatically probe entered keys and print capability hints.
- Report format includes per-domain read/write level plus probe status codes (for example `cloud:read+write`, `storage:no-access`).
- Detection uses safe representative `GET`/`POST` checks and is best-effort guidance, not a formal permission matrix.

Config file location:

- `~/.config/hetzner-mcp/config.json` (macOS/Linux)
- `%APPDATA%\\hetzner-mcp\\config.json` (Windows)
- Override path with `HETZNER_MCP_CONFIG_PATH`

Optional runtime controls:

- `HETZNER_CLOUD_BASE_URL`
- `HETZNER_STORAGE_BASE_URL`
- `HETZNER_TIMEOUT_SECONDS`
- `HETZNER_MAX_RETRIES`
- `HETZNER_BACKOFF_BASE_SECONDS`

## Supported MCP Clients

Auto-configuration is included for:

| Client | Auto-config |
|--------|-------------|
| Claude Desktop | Yes |
| Claude Code | Yes |
| Cursor | Yes |
| Cline | Yes |
| Windsurf | Yes |
| OpenCode | Yes |

Run:

```bash
hetzner-mcp install
```

OpenCode integration note:

- This installer writes OpenCode MCP config to the global OpenCode config file (`opencode.jsonc`) under the `mcp` key.
- Legacy `~/.opencode/mcp.json` is not used.

## Manual Configuration

```json
{
  "mcpServers": {
    "hetzner-mcp": {
      "command": "hetzner-mcp-server",
      "args": []
    }
  }
}
```

## CLI Commands

| Command | Description |
|---------|-------------|
| `hetzner-mcp status` | Show effective runtime config + registry + client status |
| `hetzner-mcp doctor [--json]` | Print detailed diagnostics |
| `hetzner-mcp server run [--refresh-specs]` | Run stdio MCP server |
| `hetzner-mcp update` | Refresh specs and re-apply client integration |
| `hetzner-mcp client install` | Configure supported MCP clients |
| `hetzner-mcp client status` | Show client config installation state |
| `hetzner-mcp client repair` | Re-apply configuration entries |
| `hetzner-mcp client uninstall` | Remove MCP config entries |
| `hetzner-mcp auth set ...` | Configure API keys directly from CLI and auto-detect key capabilities |
| `hetzner-mcp auth show` | Show token status and source |
| `hetzner-mcp auth clear [--all]` | Clear stored token entries |
| `hetzner-mcp project add/list/show/use/remove` | Manage multiple project credential profiles (with capability probing on add) |
| `hetzner-mcp config show` | Show stored + effective config |
| `hetzner-mcp config get/set/unset ` | Read/write persisted config keys |
| `hetzner-mcp config edit` | Edit persisted config file in `$EDITOR` |

Legacy aliases still work: `install`, `repair`, `uninstall`, `diagnose`.

## Development

```bash
git clone https://github.com/devinoldenburg/hetzner-mcp.git
cd hetzner-mcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Validate quality
ruff check .
mypy src
pytest

# Refresh specs and inspect counts
python scripts/sync_specs.py
python scripts/verify_operation_coverage.py
```

## Security Notes

- Never commit API tokens.
- Tokens can be read from environment variables or persisted local config, but outbound API targets are validated before Authorization headers are sent.
- Official Hetzner HTTPS base URLs are enforced by default; custom base URLs require explicit opt-in with `HETZNER_ALLOW_CUSTOM_BASE_URLS=true`.
- Dynamic endpoint calls now validate path, query, and JSON body inputs against the loaded OpenAPI schema before making HTTP requests.
- MCP tool responses redact common secret fields such as `token`, `password`, `secret`, and `authorization` to avoid leaking credentials into transcripts.
- `set_active_api_project` now switches the active project for the current MCP session by default; use `persist=true` only when you intentionally want to update local config.
- Server logs are routed to stderr to keep stdio JSON-RPC clean.
- Network retries are limited and capped.

## Troubleshooting

**`ModuleNotFoundError: hetzner_mcp` in local scripts**

- Install editable package: `pip install -e .`

**No operations listed in MCP client**

- Run `hetzner-mcp status`
- Verify config file includes `hetzner-mcp`
- Restart the client process after installation

**Auth failures (`401 unauthorized`)**

- Ensure `HETZNER_TOKEN` or domain-specific token is exported in the client runtime environment

**Rate limiting (`429`)**

- The client retries transient failures automatically; reduce request burst and retry later

## License

MIT

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [devinoldenburg](https://github.com/devinoldenburg)
- **Source:** [devinoldenburg/hetzner-mcp](https://github.com/devinoldenburg/hetzner-mcp)
- **License:** MIT
- **Homepage:** https://pypi.org/project/hetzner-mcp/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-devinoldenburg-hetzner-mcp
- Seller: https://agentstack.voostack.com/s/devinoldenburg
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
