# cloud.redu/mcp (remote · mcp.redu.cloud)

Agent-native cloud, EU-hosted. Provision VMs, networks & databases on redu.cloud via MCP.

- Trust score: 72/100 (medium)
- Change this week: +11
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-04

## Components

- remote · `mcp.redu.cloud`: 72/100 (this document), [markdown](https://verifymcp.io/servers/cloud-redu-mcp/mcp.md), [page](https://verifymcp.io/servers/cloud-redu-mcp/mcp)

## Channel facts

- Endpoint: `https://mcp.redu.cloud/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.1.1`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-04.

- **Endpoint Security**: 94/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 24/100
  - AI-judged instruction clarity (poor).
  - Context-footprint check failed: tool/resource definitions use about 21109 tokens (~289/item across 73 items; 73 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 30/100
  - Stability observed for 9 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 96/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 87% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http cloud-redu-mcp https://mcp.redu.cloud/mcp
```

### Codex

```toml
[mcp_servers.cloud-redu-mcp]
url = "https://mcp.redu.cloud/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cloud-redu-mcp": {
      "type": "remote",
      "url": "https://mcp.redu.cloud/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cloud-redu-mcp --url https://mcp.redu.cloud/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  cloud-redu-mcp:
    url: "https://mcp.redu.cloud/mcp"
```

### Other

```json
{
  "mcpServers": {
    "cloud-redu-mcp": {
      "type": "http",
      "url": "https://mcp.redu.cloud/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-04 (score 72, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-03 (score 71, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 70, +8)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 62, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 62, +1)

- [security] The server rewrote its instructions, which are the text every model session reads
- [security] Tool “update_cluster” rewrote its description, which is the text the model reads
- [security] Tool “upgrade_to_cluster” rewrote its description, which is the text the model reads
- [cosmetic] “upgrade_to_cluster” added an optional parameter “high_availability”
- [cosmetic] “upgrade_to_cluster” reworded the description of “max_size”

### 2026-07-28 (score 61, 0)

- [security] New tool “delete_volume”, which the server declares destructive
- [security] Tool “restore_backup” rewrote its description, which is the text the model reads
- [cosmetic] “create_instance” added an optional parameter “boot_volume_id”

### 2026-07-27 (score 61, +2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 59)

First indexed and scored.

## MCP tools (73)

### `whoami` (~54 tokens)

Who am I

Verifies your redu.cloud credential with a REAL server round-trip and returns your identity + live quota. A green result means the key actually works — not merely that one is configured. Use this first if anything is 401ing.

Output parameters:

- `auth_type` (string)
- `next` (string)
- `quota`
- `user`
- `verified` (boolean)

### `check_deploy_prerequisites` (~245 tokens)

Check deploy prerequisites (run before plan_deploy)

The deploy ENTRY GATE — run this first when a user wants to deploy. Verifies the account is ready and AUTO-SELECTS the network_id + keypair_name to pass to deploy_app (so you never hunt for them): (1) account reachable + quota, (2) a private network (picks your default — every account has one), (3) an SSH keypair (if you have none, returns ssh_key_recipe: the exact local ssh-keygen → import_keypair → write SSH_KEY_LOCATION-to-.env steps — run them, in yolo mode without asking). Returns { ready, network_id, keypair_name, missing, ssh_key_recipe }.

Input parameters:

- `mode` (string): guided = confirm each choice with the user; yolo = auto-proceed with sensible defaults (auto-select the default network, auto-create a keypair). STICKY for the session once set — OMIT it on later re-…

Output parameters:

- `account_ok` (boolean)
- `keypair_name` (string|null)
- `missing` (array)
- `mode` (string)
- `network_id` (string|null)
- `next` (string)
- `quota`
- `ready` (boolean)
- `ssh_key_recipe` (array)

### `deploy_overview` (~95 tokens)

How to deploy an app on redu (start here)

Orientation for deploying an app on redu.cloud: the end-to-end flow, the two source modes (git vs upload), how to handle a missing Dockerfile or a database, when (and when NOT) to split a deploy across multiple VMs, verifying a deploy functionally, and how to debug a failed build. Call this first when a user asks to deploy/ship/host an app and you're unsure where to start.

Output parameters:

- `flow` (array)
- `multi_vm` (array)
- `next` (string)
- `source_modes`
- `tips` (array)

### `create_api_key` (~289 tokens)

Create a scoped API key (needs approval)

Mints a NEW least-privilege redu API key for a deployed app or automation to use (e.g. to add a backup feature). GUARDRAIL: the first call does NOT create anything. It returns a confirmation the user must approve, because a key is a long-lived credential that acts on the account and ANY usage of it is BILLED to the account owner. Show the user the name, the exact scopes, and the billing notice, get their explicit approval, then call again with confirm:true. This is required even in yolo/auto mode. The secret is returned ONCE.

Input parameters:

- `confirm` (boolean): Set true ONLY after the user has explicitly approved (see the confirmation the first call returns). Leave unset to get the approval prompt first. Do NOT set it yourself.
- `expires_in_days` (integer): Optional: auto-expire the key after N days.
- `name` (string, required): A recognizable name for the key, e.g. 'supabase-backups'.
- `scopes` (array, required): LEAST-PRIVILEGE scopes the key may use, e.g. ['instance:read','backup:read','backup:create','backup:restore']. Grant only what the feature needs. Discover the catalog via GET /v1/capabilities (gramma…

Output parameters:

- `billing_notice` (string)
- `error` (boolean)
- `expires_at`
- `key` (string)
- `mode` (string)
- `name` (string)
- `needs_confirmation` (boolean)
- `next` (string)
- `scopes`
- `validation`
- `warning` (string)

### `integrate_overview` (~121 tokens)

How to add a redu capability to an app you deployed (start here)

Orientation for wiring a redu.cloud capability (backups, DNS, extra storage, a managed DB, ...) INTO an app already deployed on redu, e.g. 'add a backup feature to the Supabase I deployed on redu'. Explains the pattern: mint a LEAST-PRIVILEGE scoped API key (with the user's approval via create_api_key), inject it into the app, and call the redu API from the app. Call this when a user asks to add/integrate a redu feature into a running deployment and you are unsure how.

Output parameters:

- `next` (string)
- `pattern` (array)
- `recipes`
- `scopes_hint` (string)

### `prepare_upload` (~192 tokens)

Prepare an upload-mode deploy (local tar + upload commands)

Returns the LOCAL shell commands to package your working directory and upload it for an upload-mode deploy (no git, no PAT). Run them in the user's terminal, capture `source_token` from the upload's JSON response, then call deploy_app with that source_token (omit repo). The upload authenticates AUTOMATICALLY with a short-lived ticket minted from your MCP credential — NO API key needed in the command and nothing secret is printed (it falls back to needing $REDU_API_KEY only if minting is unavailable). Excludes node_modules/.git/.venv/build output and .env by default; honors .gitignore when is_git_repo=true.

Input parameters:

- `is_git_repo` (boolean): If the dir is a git checkout, set true to honor .gitignore (tar only tracked + non-ignored files).
- `project_dir` (string): Path to the local app directory to upload (default current dir).

Output parameters:

- `commands` (array)
- `endpoint` (string)
- `excludes` (array)
- `next` (string)

### `scaffold_local` (~202 tokens)

Scaffold a local run (optional preflight)

OPTIONAL preflight: returns a podman-compose.yml + .env so the user can run the app (and a throwaway local Postgres) on THEIR machine before deploying to redu — to see it run / sanity-check the container. Requires local podman/podman-compose. It's a suggestion, not a gate — skip it and go straight to deploy_app any time. Honest caveat: the local Postgres is NOT the managed Postgres, so a green local run does not prove the prod DB wiring.

Input parameters:

- `has_container` (boolean): Repo already has a Dockerfile/Containerfile (the compose builds it). If false, write the plan_deploy-generated Dockerfile to ./Dockerfile first.
- `needs_postgres` (boolean): Include a local Postgres container + wire PG* env.
- `port` (integer): Port the app listens on.
- `runtime` (string, required): App runtime (node/python/go/…) — from plan_deploy.

Output parameters:

- `caveats` (array)
- `commands` (array)
- `files`
- `next` (string)

### `plan_instance` (~79 tokens)

Plan instance (guided options)

Aggregates images/flavors/keypairs/networks/security groups into human-friendly choices. Does not create anything. Happy path: import_keypair → plan_instance → create_instance → get_ssh_command. Call this second (after import_keypair, if you have no keypairs).

Input parameters:

- `osHint` (string)
- `sizeHint` (string)

Output parameters:

- `mode` (string)
- `options`

### `plan_managed_datastore` (~78 tokens)

Plan managed datastore

Plans a direct managed datastore create without provisioning anything. Use this before create_database, create_relational_database, create_redis, or create_clickhouse. For app deployments, prefer deploy_app database:'managed' so plan_deploy includes and wires the datastore automatically.

Input parameters:

- `engine` (string)
- `sizeHint` (string)

Output parameters:

- `mode` (string)
- `next` (string)
- `options`
- `suggested`

### `select_surface` (~219 tokens)

Rank a repo's deployable surfaces and pick the right one (deterministic)

For a repo with SEVERAL runnable parts, call this BEFORE plan_deploy. You enumerate the candidate surfaces (find every Dockerfile/Containerfile, OPEN each, classify by its EXPOSE + CMD — never by directory name) and pass them in; redu RANKS them with fixed rules (a standalone browser desktop/noVNC > a self-contained web app > a keys-required playground > an API > a headless worker > docs/examples). GUIDED: returns the ranked list to present to the user, who picks. YOLO: auto-selects the TOP-ranked surface. Then run plan_deploy on the chosen surface's path + http_port. (A single-surface repo doesn't need this.)

Input parameters:

- `mode` (string): Drive mode; omit to use the session's sticky mode.
- `surfaces` (array, required): EVERY runnable surface you found (run `find . -name Dockerfile -o -name Containerfile`, open each). Be exhaustive — a missed browser-desktop subdir is the #1 cause of a wrong pick.

Output parameters:

- `chosen`
- `mode` (string)
- `next` (string)
- `ranked` (array)

### `plan_deploy` (~2188 tokens)

Plan an app deployment

Turns YOUR repo classification (you scan the repo and pass what you found) into a complete, approvable deploy plan WITHOUT creating anything: picks the VM + managed-Postgres sizes, prices them at the real pricing_rules rates, and checks they FIT your quota — so a plan that can't provision is caught HERE, before any spend. You pass what you detected in the repo (runtime, port, needs_postgres/redis/vector_db); it returns resources + £/hr + £/mo + a feasibility verdict + a checkpoint summary to confirm with the user. Defaults: app VM m1.medium, managed Postgres m1.small; pass single_vm to collapse onto one VM. Only Postgres is auto-provisionable today — Redis / vector-DB needs are flagged, not provisioned. Any containerizable app works (node, python, go, ...) — it deploys as a container, so the language doesn't gate it. Set serves_http:false for a non-web repo (a library, CLI, or language runtime with no HTTP server) and it returns a clean not-a-web-service verdict instead of a costed VM plan. Set heavy_build:true for resource-heavy builds (compiled-from-source native code, a monorepo/turborepo build, a large Node heap) and it raises the app VM to a build-capable floor so the on-VM build doesn't get OOM-killed. Set memory_heavy:true for a RAM-forward app whose persistent state lives in a MANAGED DB / external store (Next.js like cal.com/cal.diy, Rails, Django, JVM/Java apps) — it sizes onto a memory-optimized SMALL-DISK flavor (m1.mem16/m1.mem32: full RAM, a lean 40 GB disk instead of 160 GB) that costs less and snapshots/clusters far faster; do NOT set it if the app keeps lots of data on local disk. Also returns a brand-named markdown report (Mermaid diagram + cost) to save as redu-deploy-plan.md and show the user. Every deploy leaves TWO MANDATORY files at the repo root with DIFFERENT purposes: redu-deploy-plan.md = THIS run's plan/estimate, and redu.md = the DURABLE deploy memory the NEXT deploy reads. If a redu.md exists, READ it FIRST and reuse its known-good pla…

Input parameters:

- `app_flavor` (string): Preferred app VM size (default m1.medium). Resolved against the real flavor list.
- `app_profile` (string): Detected app profile. Set wordpress/woocommerce when source inspection finds wp-config.php, wp-content, WordPress/WooCommerce packages/plugins, or wordpress/woocommerce compose images. This is used f…
- `cluster_media_mode` (string): For WordPress/WooCommerce cluster_target:true, use media_space as the default real fix: Redu creates/reuses an NFS media VM backed by a volume and mounts it at wp-content/uploads. central_media_origi…
- `cluster_target` (boolean): Set TRUE when the user asked to deploy this app as an autoscaling cluster. For WordPress/WooCommerce this requires managed MySQL/MariaDB plus a Redu media space mounted at wp-content/uploads (or an e…
- `containerizable` (boolean): Whether the app can run in a container. Almost always true (a container is the delivery unit); set false ONLY if the app fundamentally can't be containerized — then redu can't deploy it yet.
- `create_media_space` (boolean): For WordPress/WooCommerce cluster_target:true: set TRUE when no suitable media space exists. The plan will include a small media VM + attached volume and deploy_app/deploy_compose will create it.
- `db_engine` (string): Managed DB engine to plan. For WordPress/WooCommerce clusters use mariadb or mysql.
- `db_flavor` (string): Preferred managed Postgres VM size (default m1.small). Resolved against the real flavor list.
- `deploy_mode` (string): guided (default) = ONE approval gate: the user approves the plan, then you proceed with the plan's defaults WITHOUT further sub-questions. yolo = auto-proceed end to end without stopping to ask, usin…
- `has_container` (boolean): Whether the repo already has a Dockerfile / compose file.
- `heavy_build` (boolean): Set TRUE when the BUILD (not the running app) is resource-heavy — the container is built ON the VM today, so a build that needs more RAM/CPU than the idle app must be sized up or it OOMs mid-build. S…
- `media_mount_path` (string): Host mount path on app members for the shared uploads filesystem. Redu mounts this into /var/www/html/wp-content/uploads.
- `media_origin_url` (string): Public base URL where WordPress wp-content/uploads is served when cluster_media_mode:'central_media_origin'. Do not use the DB VM as this origin.
- `media_space_flavor` (string): Preferred media VM size when create_media_space:true. Resolved against list_flavors.
- `media_space_id` (integer): Existing Redu media space id to reuse for WordPress/WooCommerce cluster uploads. Get it from list_media_spaces. Omit when create_media_space:true.
- `media_space_size_gb` (integer): Size of the media space data volume in GB when create_media_space:true.
- `memory_heavy` (boolean): Set TRUE for a RAM-forward RUNNING app whose persistent state lives in a MANAGED DB / external store (NOT on the VM's local disk) — so it needs lots of memory but only a lean disk. Sizes onto a memor…
- `needs_compose` (boolean): Set TRUE when the repo ships a docker-compose.yml / compose.yaml that runs MULTIPLE services (app + its own db/redis/worker containers) as a stack — then deploy with deploy_compose (podman-compose on…
- `needs_postgres` (boolean): App uses Postgres (deps pg/prisma/sqlalchemy/drizzle or DATABASE_URL).
- `needs_redis` (boolean): App uses Redis (deps redis/ioredis/bullmq/celery or REDIS_URL).
- `needs_vector_db` (boolean): App uses a vector DB (deps qdrant-client / langchain+embeddings or QDRANT_URL).
- `port` (integer): Port the app's HTTP server listens on (PORT env / framework default / Dockerfile EXPOSE of a real app port — NOT a debug/IPC port). Omit if the repo has no HTTP server.
- `runtime` (string, required): Detected app language/runtime (node, python, go, ruby, ...). Informational — the app deploys as a container, so the language does not gate the deploy.
- `serves_http` (boolean): Whether the repo actually RUNS an HTTP server that listens on a port. Set FALSE for a library, CLI tool, or language runtime that has no web server (e.g. a package you `import`, or a `bun`/`node`-sty…
- `single_vm` (boolean): Force everything onto a single VM if the user prefers.
- `start` (string): How the app starts (package.json start script / Procfile / Dockerfile CMD).
- `vm_count` (integer): Number of app VMs (microservices). v1: usually 1.
- `worker` (boolean): HEADLESS WORKER / daemon: the repo runs a long-lived process with NO HTTP server (a chaos-monkey, a background/queue worker, an on-infra agent runner). Set TRUE to plan a WORKER deploy — a private VM…

Output parameters:

- `deployable` (boolean)
- `feasible` (boolean)
- `generated_dockerfile` (string|null)
- `mode` (string)
- `next` (string)
- `plan`
- `reason` (string)
- `report_filename` (string)
- `report_markdown` (string)

### `list_instances` (~13 tokens)

List instances

Lists your compute instances.

Output parameters:

- `instances` (array)
- `mode` (string)
- `next` (string)

### `list_flavors` (~14 tokens)

List flavors

Lists available instance sizes.

Output parameters:

- `flavors` (array)
- `mode` (string)
- `next` (string)

### `list_images` (~13 tokens)

List images

Lists available OS images.

Output parameters:

- `images` (array)
- `mode` (string)
- `next` (string)

### `list_keypairs` (~27 tokens)

List keypairs

Lists your SSH keypairs. If empty, call import_keypair first before creating instances.

Output parameters:

- `keypairs` (array)
- `mode` (string)
- `next` (string)

### `list_security_groups` (~14 tokens)

List security groups

Lists your security groups.

Output parameters:

- `mode` (string)
- `next` (string)
- `security_groups` (array)

### `list_private_networks` (~15 tokens)

List private networks

Lists your private networks.

Output parameters:

- `mode` (string)
- `networks` (array)
- `next` (string)

### `list_volumes` (~15 tokens)

List volumes

Lists your block storage volumes.

Output parameters:

- `mode` (string)
- `next` (string)
- `volumes` (array)

### `list_snapshots` (~14 tokens)

List snapshots

Lists your instance snapshots.

Output parameters:

- `mode` (string)
- `next` (string)
- `snapshots` (array)

### `list_backups` (~14 tokens)

List backups

Lists your volume backups.

Output parameters:

- `backups` (array)
- `mode` (string)
- `next` (string)

### `list_clusters` (~14 tokens)

List clusters

Lists your autoscaling clusters.

Output parameters:

- `clusters` (array)
- `mode` (string)
- `next` (string)

### `list_dns_entries` (~15 tokens)

List DNS entries

Lists DNS proxy host entries.

Output parameters:

- `dns` (array)
- `mode` (string)
- `next` (string)

### `list_domains` (~17 tokens)

List verified domains

Lists custom domains you have verified ownership of.

Output parameters:

- `domains` (array)
- `mode` (string)
- `next` (string)

### `list_regions` (~12 tokens)

List regions

Lists available regions.

Output parameters:

- `mode` (string)
- `next` (string)
- `regions` (array)

### `list_databases` (~47 tokens)

List managed Postgres

Lists your managed PostgreSQL databases. Once a row's status is 'ready', it carries the private-network connection details (private_ip, port 5432, db_name, db_user).

Output parameters:

- `databases` (array)
- `mode` (string)
- `next` (string)

### `list_relational_databases` (~68 tokens)

List managed MySQL/MariaDB

Lists your managed MySQL/MariaDB databases (the relational-database resource). Each row carries its engine ('mysql'|'mariadb'); once status is 'ready' it has the private-network connection details (private_ip, port 3306, db_name, db_user).

Output parameters:

- `mode` (string)
- `next` (string)
- `relational_databases` (array)

### `list_media_spaces` (~70 tokens)

List media spaces

Lists Redu media spaces: private NFS media VMs backed by persistent volumes. For WordPress/WooCommerce clusters, reuse one on the app's private network for wp-content/uploads, or pass create_media_space:true to deploy_app/deploy_compose/upgrade_to_cluster so Redu creates one.

Output parameters:

- `media_spaces` (array)
- `mode` (string)
- `next` (string)

### `list_clickhouse_databases` (~66 tokens)

List managed ClickHouse

Lists your managed ClickHouse databases (OLAP / analytics — its own resource, not a relational DB). Once a row's status is 'ready' it carries the private-network connection details (private_ip, ClickHouse HTTP port 8123, db_name, db_user).

Output parameters:

- `clickhouse` (array)
- `mode` (string)
- `next` (string)

### `list_redis` (~69 tokens)

List managed Redis

Lists your managed Redis instances. Once a row's status is 'ready' it carries the private-network connection details (private_ip, port 6379) — connect from another instance on the same private network with redis-cli -h <private_ip> -p 6379 -a <password>.

Output parameters:

- `mode` (string)
- `next` (string)
- `redis` (array)

### `create_media_space` (~244 tokens)

Create a WordPress media space

Creates a private Redu media space: a small NFS VM backed by a persistent volume, intended for WordPress/WooCommerce wp-content/uploads in autoscaling clusters. Prefer letting deploy_app/deploy_compose create this by passing create_media_space:true after plan_deploy approval; use this tool when manually preparing or reusing shared uploads storage.

Input parameters:

- `flavor_id` (string): Small VM flavor id for the NFS media server. m1.small is enough for most WordPress uploads.
- `idempotency_key` (string)
- `keypair_name` (string, required): Existing SSH keypair name.
- `mount_path` (string): Host mount path that app VMs will use before binding into /var/www/html/wp-content/uploads.
- `name` (string, required): Name for the media space, e.g. myshop-media.
- `network_id` (string): Private network id. Use the same network as the WordPress app and managed DB.
- `security_group_names` (array): Security groups for the media VM. Redu opens NFS 2049 from private networks only.
- `size_gb` (integer): Persistent media volume size in GB.

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `upgrade_to_cluster` (~2707 tokens)

Upgrade an instance to an autoscaling cluster

THE WAY TO MAKE AN EXISTING APP HIGHLY AVAILABLE. If the user asks for high availability, redundancy, no single point of failure, surviving a host or VM failure, or 'stay up if a machine dies', this is the tool: point it at their running VM and pass high_availability:true. It needs no rebuild and no redeploy, and the URL does not change. Turns a single running instance into a horizontally-autoscaling cluster: snapshots the instance and puts your SOURCE VM behind an Octavia load balancer as its ALWAYS-ON BASELINE MEMBER, then an autoscaling group adds EXTRA members (booted from that snapshot) on CPU load and scales them back down to zero. FLAVOR — LEAD WITH A MEMORY-OPTIMIZED SMALL-DISK FLAVOR (m1.mem16/m1.mem32) for the cluster, and ideally have the SOURCE VM on one too: clustering snapshots the source VM's FULL disk, so DISK size (not RAM) drives how long the cluster takes to build and to add each member under load — a 40 GB mem flavor is several times faster to snapshot and scale than a 160 GB standard flavor (m1.xlarge) and costs less for the same RAM. If the source VM is on a big-disk flavor, RECOMMEND migrating the app onto a mem-flavor VM first (a root disk cannot be shrunk in place), even though it is extra work — it pays off on every scale-out, and a clustered app is stateless anyway (state in the managed DB) so the lean disk fits. Expect a DRASTICALLY better clustering experience on a mem flavor: far faster cluster-create, snapshots, and every scale-out. The user can override with any flavor. At rest ONLY your source VM serves — there is NO idle extra VM to pay for (the source VM is the cluster's minimum, so the floor is 0 extra members). Use it to LOAD-SCALE a stateless app tier while managed services hold state: it becomes highly-available UNDER LOAD (multiple members behind the LB), but at rest a SINGLE source VM serves — and that source VM is a plain Nova server, not an autoscaled member, so it is NOT auto-replaced if it fails while idle (only the auto…

Input parameters:

- `app_profile` (string): Set wordpress/woocommerce when upgrading an older deployment or raw VM that the backend has not profiled. WordPress/WooCommerce clusters require managed MySQL/MariaDB plus a media_space or explicitly…
- `auto_restructure` (boolean): Instead of just refusing a stateful VM, have redu get its co-located database OFF the VM first, then cluster. FULLY AUTO for a single_vm Postgres (redu deployed it): redu provisions a managed Postgre…
- `cluster_media_mode` (string): For WordPress/WooCommerce, use media_space as the default real cluster fix. local_uploads is refused because wp-content/uploads would diverge across members.
- `confirm_stateless` (boolean): Override the stateful-VM safety refusal. redu REFUSES to cluster a VM that holds its own data (deployed with database:'single_vm' or a compose 'db' service) - a cluster clones the VM into members, so…
- `create_media_space` (boolean): Set TRUE when upgrading a WordPress/WooCommerce deployment that has no media_space_id yet. Redu creates a small NFS media VM + volume, records it, and mounts it on all members.
- `dname` (string): Optional public DNS name for the cluster's load-balancer access point (a .redu.cloud name is auto-generated if omitted).
- `flavor_id` (string, required): Member VM size — from list_flavors. Every autoscaling member uses this flavor. STRONGLY prefer m1.mem16/m1.mem32 (memory-optimized, 40 GB disk): clustering snapshots the source disk, so a lean disk m…
- `high_availability` (boolean): Set TRUE whenever the user asks for HIGH AVAILABILITY, redundancy, 'no single point of failure', 'survive a host/node failure', or 'stay up if a VM dies'. This is the ONLY way to get an HA cluster an…
- `idempotency_key` (string)
- `instance_id` (string, required): The instance to turn into a cluster (from list_instances, or the VM of a deploy_app/deploy_compose deployment). It is snapshotted, and the autoscaling members are booted from that snapshot.
- `keypair_name` (string, required): SSH keypair name — from list_keypairs.
- `max_size` (integer): Peak member count under load (default 5). In the default mode this is EXTRA members added on top of your always-on source VM, and the floor is 0 extra. With high_availability:true the group runs betw…
- `media_mount_path` (string): Host mount path on cluster members. Redu mounts this into /var/www/html/wp-content/uploads for WordPress/WooCommerce.
- `media_origin_url` (string): Public base URL where WordPress wp-content/uploads is served from the central media origin. This should be a separate media origin, not the DB VM.
- `media_space_flavor_id` (string): Flavor id for the media VM when create_media_space:true. Defaults to the cluster member flavor.
- `media_space_id` (integer): Existing Redu media space id to mount on every WordPress/WooCommerce cluster member.
- `media_space_name` (string): Optional name for the media space when create_media_space:true. Defaults to <cluster-name>-media.
- `media_space_size_gb` (integer): Media space data volume size in GB when create_media_space:true (default 20).
- `name` (string, required): Name for the cluster (lowercase letters, numbers, hyphens).
- `network_id` (string, required): Private network id — from list_private_networks. Use the SAME network the app's managed DB / other services are on, so members can reach them by private IP.
- `port` (integer): Port the app listens on / the load balancer forwards to (default 80). Your source VM must actually serve on this port — the load balancer health-checks it.
- `restructure_db_flavor_id` (string): Optional VM size for the provisioned managed database (from list_flavors). Defaults to the member flavor; pick a smaller one (e.g. m1.small) if the DB is light.
- `restructure_engine` (string): For the ASSISTED path (a compose-stack database), which managed engine to provision. WordPress/WooCommerce = 'mysql' (or 'mariadb'). Required when auto_restructure is set and the DB runs inside the c…
- `scale_in_threshold` (number): Average CPU fraction (0-1) below which a member is removed (default 0.2).
- `scale_out_threshold` (number): Average CPU fraction (0-1) above which a member is added (default 0.7).
- `startup_command` (string): Single-line shell command to (re)start the app on each fresh member if the snapshot's own services do not auto-start it. For a podman-compose app: 'cd /opt/app && podman-compose up -d'. Omit to rely…

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `update_cluster` (~399 tokens)

Update a cluster to a new version (in place)

Updates a running autoscaling cluster to a new app version IN PLACE, with NO URL change: snapshots the 'hero' VM (the source/master VM you SSH into and change — it is also the always-on baseline member that serves traffic), then Heat rolling-updates the autoscaled extra members to that snapshot ONE AT A TIME and refreshes the image the group boots future members from — the SAME load balancer and SAME *.redu.cloud URL are kept, and the service stays up during the roll. This is the ONLY way to update a cluster: you do NOT edit live members (they are disposable clones); you change the hero VM (SSH into it, deploy the new version), then update_cluster snapshots it and spreads it to the fleet (the hero already runs your change; this propagates it to the autoscaled members). Zero-downtime is measured, not aspirational: a full roll of every member of a 3-member cluster served 699/699 requests with no failures and never dropped below a majority. That holds ONLY if the app starts on every boot - a member whose app is launched by a first-boot-only script returns empty after replacement, never rejoins the pool, and the roll silently drains the cluster. The snapshot upload can take several minutes on a large disk; poll list_clusters until the stack status is UPDATE_COMPLETE.

Input parameters:

- `idempotency_key` (string)
- `instance_id` (string, required): The 'hero' VM to snapshot and roll to every extra member: the source/master VM you upgraded to a cluster and SSH into to make changes. It is your cluster's always-on baseline member. Its CURRENT disk…
- `stack_id` (string, required): Cluster (Heat stack) id — from list_clusters (id).
- `stack_name` (string, required): Cluster (Heat stack) name — from list_clusters (stack_name).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_cluster` (~206 tokens)

Delete an autoscaling cluster

Deletes an autoscaling cluster — tears down the WHOLE Heat stack: every autoscaled EXTRA member VM, the Octavia load balancer, the pool, the cluster security group, and the cluster's *.redu.cloud proxy host. Your SOURCE (hero) VM is NOT part of the stack and is NOT deleted — it was the always-on baseline member but it is your own VM; delete_instance it separately if you no longer need it. Pass stack_name + stack_id from list_clusters. Deleting extra members individually does NOT work (the autoscaling group re-creates them under load) — this deletes the group itself. The managed database / external store the cluster used is NOT touched (data safety); delete_database it separately when you are done with the data. Cannot be undone.

Input parameters:

- `stack_id` (string, required): Cluster (Heat stack) id — from list_clusters (id).
- `stack_name` (string, required): Cluster (Heat stack) name — from list_clusters (stack_name).

Output parameters:

- `deleted` (boolean)
- `mode` (string)
- `next` (string)
- `stack_id` (string)

### `import_keypair` (~97 tokens)

Import SSH keypair

Registers an existing SSH public key on your account. Use this to import your own public key so you can SSH into instances. The private key never leaves your machine.

Input parameters:

- `name` (string, required): Name for the keypair (e.g. 'my-laptop'). Must be unique on your account.
- `public_key` (string, required): SSH public key to import (the contents of your id_rsa.pub or id_ed25519.pub).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_keypair` (~34 tokens)

Delete keypair

Removes an SSH keypair from your account by name.

Input parameters:

- `name` (string, required): Name of the keypair to delete.

Output parameters:

- `deleted` (boolean)
- `mode` (string)
- `name` (string)

### `get_ssh_command` (~217 tokens)

Get SSH command for instance

Returns the SSH command to connect to an instance via the redu.cloud TCP proxy. For a DEPLOYMENT VM (created by deploy_app/deploy_compose) pass keypair_name — read it from get_deployment — so the command uses `-i ~/.ssh/<keypair_name>` and authenticates with the RIGHT key instead of your default identity (without it, SSH to a deploy VM usually fails). The tool also best-effort looks up the keypair from the deployment if you omit it. Example: ssh -i ~/.ssh/redu-deploy -o IdentitiesOnly=yes -p 22011 ubuntu@myinstance-abc12345.redu.cloud

Input parameters:

- `instance_id` (string, required): ID of the instance to get the SSH command for.
- `keypair_name` (string): The SSH keypair the instance was created with (read it from get_deployment for a deploy VM). When given, the command uses `-i ~/.ssh/<keypair_name>` so it authenticates with the right key.

Output parameters:

- `floating_ip` (string)
- `host` (string)
- `instance_name` (string)
- `instance_status` (string)
- `keypair_name` (string)
- `mode` (string)
- `port` (string)
- `ssh_command` (string)
- `user` (string)

### `get_instance_logs` (~35 tokens)

Get instance logs

Returns the console log output from an instance.

Input parameters:

- `instance_id` (string, required): ID of the instance to fetch console logs for.

Output parameters:

- `logs`
- `mode` (string)

### `instance_action` (~50 tokens)

Instance action (start/stop/reboot)

Start, stop, or reboot an instance. action must be START, STOP, REBOOT_SOFT, or REBOOT_HARD.

Input parameters:

- `action` (string, required)
- `instanceId` (string, required)

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `create_instance` (~405 tokens)

Create instance

Creates a raw compute instance for custom OS/cloud-init workflows. For app/source deployments, prefer check_deploy_prerequisites -> plan_deploy -> deploy_app/deploy_compose; do not use create_instance as a shortcut around the deployment plan. Requires a recent plan_instance. For reduOS, set cloud_init_template='reduos' and flavor m1.xlarge (16GB). SSH keypair must exist. For a public web app on a raw VM, pass dns_entries (gives a .redu.cloud URL through redu's automatic public proxy). The origin app should listen on dns_entries[].port; do not install nginx on the VM unless the app itself needs it, because redu.cloud already creates the public Nginx proxy host.

Input parameters:

- `boot_volume_id` (string): DISASTER RECOVERY: boot this new VM from an EXISTING volume (one restore_backup just created) instead of a fresh image, so the machine comes back with the restored filesystem AS its root disk. The vo…
- `cloud_init_template` (string)
- `dname` (string)
- `dns_entries` (array): Public DNS/proxy entries to create automatically. Use [{ dname:'', port:8080 }] to generate a redu.cloud URL pointing at an origin process on port 8080.
- `flavor_id` (string, required)
- `idempotency_key` (string)
- `imageName` (string)
- `image_id` (string, required)
- `keypair_name` (string, required)
- `name` (string, required)
- `network_id` (string, required)
- `port` (integer)
- `security_group_names` (array)
- `user_data` (string)
- `volume` (object)

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_instance` (~32 tokens)

Delete instance

Permanently deletes an instance. This cannot be undone.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `create_database` (~469 tokens)

Create managed Postgres

Provisions a managed PostgreSQL database on a dedicated VM on your private network. Requires a recent plan_managed_datastore. For app deployments, prefer deploy_app database:'managed' so plan_deploy includes and wires the DB automatically. It is PRIVATE — reachable only from another instance on the same private network, via the DB's internal/private IP (not a public address). Get the ids from plan_managed_datastore/list_flavors/list_private_networks/list_keypairs. Provisioning takes ~5 min; poll list_databases until status='ready', then the connection details (private_ip, port 5432, db_name, db_user) are populated.

Input parameters:

- `db_name` (string): The database to create (default 'app').
- `db_password` (string): Password for the db user. Auto-generated and returned once if omitted.
- `db_user` (string): The database user (default 'appuser').
- `extensions` (array): Postgres extensions to pre-install at provision time (allowlisted): 'pgvector'/'vector' (embeddings), 'postgis' (geo), 'pgaudit', 'pg_trgm', 'pgcrypto', 'hstore', 'uuid-ossp', 'citext', 'ltree', 'pg_…
- `flavor_id` (string, required): Instance size for the DB VM — from list_flavors.
- `idempotency_key` (string)
- `keypair_name` (string, required): SSH keypair name — from list_keypairs (for operating the DB VM).
- `name` (string, required): Name for the managed database (lowercase letters, numbers, hyphens).
- `network_id` (string, required): Private network id — from list_private_networks. The DB is reachable only from this network.
- `security_group_names` (array)
- `superuser` (boolean): Grant the db user SUPERUSER — safe here (a dedicated single-tenant DB VM). Use when the app's own migrations must CREATE EXTENSION or alter roles.
- `version` (string): Postgres major version (default 16).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_database` (~47 tokens)

Delete managed Postgres

Deletes a managed Postgres database and its underlying VM. Pass the numeric database id from list_databases. This cannot be undone.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `create_relational_database` (~505 tokens)

Create managed MySQL/MariaDB

Provisions a managed MySQL (or MariaDB) database on a dedicated VM on your private network — the relational-database resource (use this instead of create_database when the app needs MySQL/MariaDB, e.g. WordPress, NextCloud, Matomo, many PHP/LAMP apps). Requires a recent plan_managed_datastore. For app deployments, prefer deploy_app database:'managed' with db_engine mysql/mariadb so plan_deploy includes and wires the DB automatically. It is PRIVATE — reachable only from another instance on the same private network, via the DB's internal/private IP (port 3306), not a public address. Get the ids from plan_managed_datastore/list_flavors/list_private_networks/list_keypairs. Provisioning takes ~5 min; poll list_relational_databases until status='ready', then the connection details (private_ip, port 3306, db_name, db_user) are populated. MySQL is created with mysql_native_password auth so older clients/apps connect cleanly. (ClickHouse is a separate resource — use create_clickhouse / list_clickhouse_databases.)

Input parameters:

- `db_name` (string): The database to create (default 'app').
- `db_password` (string): Password for the db user (letters/numbers/_/- only). Auto-generated and returned once if omitted.
- `db_user` (string): The database user (default 'appuser').
- `engine` (string): Database engine: 'mysql' (default) or 'mariadb'. Both speak the MySQL protocol (mysql:// URL). Pick the one your app/stack uses. (For analytics/column-store needs use create_clickhouse instead — Clic…
- `flavor_id` (string, required): Instance size for the DB VM — from list_flavors.
- `idempotency_key` (string)
- `keypair_name` (string, required): SSH keypair name — from list_keypairs (for operating the DB VM).
- `name` (string, required): Name for the managed database (lowercase letters, numbers, hyphens).
- `network_id` (string, required): Private network id — from list_private_networks. The DB is reachable only from this network.
- `security_group_names` (array)
- `version` (string): Engine version (e.g. mysql '8.0', mariadb '11.4'). Defaults to the engine's current major if omitted.

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_relational_database` (~53 tokens)

Delete managed MySQL/MariaDB

Deletes a managed MySQL/MariaDB database and its underlying VM. Pass the numeric id from list_relational_databases. This cannot be undone.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `create_clickhouse` (~378 tokens)

Create managed ClickHouse

Provisions a managed ClickHouse database (OLAP / columnar analytics engine, Apache-2.0) on a dedicated VM on your private network — its OWN resource, NOT a relational database. Requires a recent plan_managed_datastore. Use it for analytics / observability workloads that need a column store (PostHog, Langfuse, event analytics, time-series). It is PRIVATE — reachable only from another instance on the same private network, via the DB's internal/private IP on the ClickHouse HTTP port 8123 (CLICKHOUSE_HOST/PORT/USER/PASSWORD/DB env, http://host:8123). Get the ids from plan_managed_datastore/list_flavors (use m1.small+ — ClickHouse needs >=2GB RAM), list_private_networks, list_keypairs. Provisioning takes ~5 min; poll list_clickhouse_databases until status='ready'.

Input parameters:

- `db_name` (string): The database to create (default 'analytics').
- `db_password` (string): Password for the db user (letters/numbers/_/- only). Auto-generated and returned once if omitted.
- `db_user` (string): The database user (default 'appuser').
- `flavor_id` (string, required): Instance size for the ClickHouse VM — from list_flavors. ClickHouse is RAM-hungry; pick m1.small (2GB) or larger.
- `idempotency_key` (string)
- `keypair_name` (string, required): SSH keypair name — from list_keypairs.
- `name` (string, required): Name for the managed ClickHouse database (lowercase letters, numbers, hyphens).
- `network_id` (string, required): Private network id — from list_private_networks. The DB is reachable only from this network.
- `security_group_names` (array)

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_clickhouse` (~49 tokens)

Delete managed ClickHouse

Deletes a managed ClickHouse database and its underlying VM. Pass the numeric id from list_clickhouse_databases. This cannot be undone.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `create_redis` (~353 tokens)

Create managed Redis

Provisions a managed Redis instance on a dedicated VM on your private network. Requires a recent plan_managed_datastore. It is PRIVATE — reachable only from another instance on the same private network, via its internal/private IP on port 6379 (not a public address). AUTH (requirepass) is always enabled. Get the ids from plan_managed_datastore/list_flavors, list_private_networks (or check_deploy_prerequisites), list_keypairs — use the SAME network_id as the app that will connect. Provisioning takes ~5 min; poll list_redis until status='ready', then the connection details (private_ip, port 6379) are populated. Wire an app with REDIS_URL=redis://:<password>@<private_ip>:6379 (pass it via deploy_app env).

Input parameters:

- `flavor_id` (string, required): Instance size for the Redis VM — from list_flavors. m1.small (2GB) is plenty for most caches/queues.
- `idempotency_key` (string)
- `keypair_name` (string, required): SSH keypair name — from list_keypairs (for operating the Redis VM).
- `name` (string, required): Name for the managed Redis instance (lowercase letters, numbers, hyphens).
- `network_id` (string, required): Private network id — from list_private_networks (or check_deploy_prerequisites). Redis is reachable only from this network; use the SAME network as the app that will connect.
- `password` (string): Redis AUTH password (requirepass). Auto-generated and returned once if omitted.
- `security_group_names` (array)
- `version` (string): Redis major version (default '7').

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_redis` (~46 tokens)

Delete managed Redis

Deletes a managed Redis instance and its underlying VM. Pass the numeric id from list_redis. This cannot be undone.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `deploy_app` (~2376 tokens)

Deploy an app (git repo or uploaded source) to a VM

Deploys an app to a VM and exposes it at a public https://<name>-<id>.redu.cloud URL. The container is built ON the VM. PREREQS — run check_deploy_prerequisites first for network_id + keypair_name, then plan_deploy for cost approval. Source can be git repo or prepare_upload source_token. PORT must be the real app listen port. To wire a DB, pass database:'managed' (dedicated managed datastore VM on the same private network, reused on same-name redeploy) or database:'single_vm' for Postgres on the app VM. Choose db_engine ('postgres' default; 'mysql'/'mariadb' for WordPress/Matomo/LAMP, managed only). For WordPress/WooCommerce cluster intent, do not use generic stateless deploy: pass app_profile, cluster_target:true, database:'managed', db_engine:'mariadb' or 'mysql', cluster_media_mode:'media_space', and either media_space_id or create_media_space:true. Redu mounts the media space into wp-content/uploads and refuses unsafe local uploads. Build+provision takes minutes; poll list_deployments/get_deployment.

Input parameters:

- `app_profile` (string): Detected app profile from source inspection. For WordPress/WooCommerce pass wordpress/woocommerce so cluster deploys enforce managed DB + shared media instead of treating local uploads as stateless.
- `cluster_media_mode` (string): Record the WordPress media strategy for future clustering. For real WordPress clusters use media_space by default: Redu mounts a shared uploads filesystem into every member. local_uploads is single-V…
- `cluster_target` (boolean): Set TRUE when the user asked to deploy this app as an autoscaling cluster. For WordPress/WooCommerce this makes the backend require managed MySQL/MariaDB plus media_space/central_media_origin before…
- `context` (string): Build-context dir within the source (default: repo root, or `subdir`). Set when the Dockerfile lives in a subfolder but builds from the repo root.
- `create_media_space` (boolean): For WordPress/WooCommerce cluster_target:true: set TRUE when no suitable media space exists. Redu creates an NFS media VM + persistent volume and mounts it into /var/www/html/wp-content/uploads.
- `database` (string): DB wiring (auto-injects the connection env + DATABASE_URL — zero setup): 'single_vm' = Postgres ON the app VM (cheapest, data dies when the VM is replaced; Postgres only); 'managed' = a SEPARATE mana…
- `db_engine` (string): Managed-DB engine (default 'postgres'). 'mysql'/'mariadb' provision a managed MySQL/MariaDB VM and wire MYSQL_HOST/MYSQL_PORT/MYSQL_USER/MYSQL_PASSWORD/MYSQL_DATABASE + a mysql:// DATABASE_URL — use…
- `db_extensions` (array): managed/single_vm Postgres only: extensions to pre-install (pgvector, postgis, pgaudit, pg_trgm, …). Pass when the app needs one — e.g. langfuse/lantern need pgvector — so you don't have to CREATE EX…
- `db_flavor_id` (string): managed only: VM size for the dedicated Postgres (from list_flavors). Defaults to the app flavor; m1.small is plenty for most. plan_deploy sizes this for you.
- `db_id` (integer): Informational link to a managed Postgres (from create_database/list_databases).
- `db_name` (string): DB name for single_vm/managed (default 'app').
- `db_superuser` (boolean): managed/single_vm Postgres only: grant the app DB user SUPERUSER (dedicated single-tenant DB VM, so safe). Use when the app's migrations create extensions/roles themselves.
- `db_user` (string): DB user for single_vm/managed (default 'appuser').
- `db_version` (string): DB version for single_vm/managed. Postgres: '16'|'15'|'14' (default 16). MySQL: '8.0'. MariaDB: '11.4'|'10.11'. Defaults per engine if omitted.
- `dname` (string): Custom *.redu.cloud subdomain. For a STABLE, KNOWN-AHEAD URL (needed when the app must be told its OWN url — OAuth callbacks, cookie domain, a frontend that calls its API), generate the FULL auto-gen…
- `dockerfile` (string): Path within the source to the Dockerfile (e.g. 'scripts/Dockerfile') when it's NOT at the root. Pair with `context` when the Dockerfile is in a subfolder but COPYs from the repo root.
- `dockerfile_content` (string): A Dockerfile to write into the build dir before building — pass the Dockerfile that plan_deploy generated when the repo has none, or to override a broken one. (In upload mode you can instead just inc…
- `env` (object): Env vars injected into the container at deploy time (e.g. PGHOST/PGPORT/PGUSER/PGPASSWORD/PGDATABASE from a managed Postgres). Never baked into the image.
- `flavor_id` (string): Instance size — from list_flavors. Default m1.medium (enough RAM to build on the VM). For a RAM-heavy app whose state is in a managed DB (Next.js/cal.com, Rails, JVM), prefer m1.mem16/m1.mem32: full…
- `git_ref` (string): git mode only: branch/tag/commit to deploy (default: the repo's default branch).
- `git_token` (string): git mode only: token to clone a PRIVATE repo. Omit for public repos.
- `idempotency_key` (string)
- `keypair_name` (string, required): REQUIRED. An EXISTING SSH keypair name — call list_keypairs and reuse one, or import_keypair first.
- `media_mount_path` (string): Host mount path on the app VM/member. Redu mounts this into /var/www/html/wp-content/uploads.
- `media_origin_url` (string): Public base URL where WordPress wp-content/uploads is served when using central_media_origin. Do not put this on the DB VM.
- `media_space_flavor_id` (string): Flavor id for the media VM when create_media_space:true. Defaults to m1.small/backend default.
- `media_space_id` (integer): Existing Redu media space id to mount at WordPress wp-content/uploads. Get it from list_media_spaces.
- `media_space_name` (string): Optional media space name when create_media_space:true. Defaults to <deployment-name>-media.
- `media_space_size_gb` (integer): Media space data volume size in GB when create_media_space:true (default 20).
- `name` (string, required): Name for the deployment / VM (lowercase letters, numbers, hyphens).
- `network_id` (string): Existing private network id — from check_deploy_prerequisites (auto-selects your default) or list_private_networks. Optional: if omitted, redu auto-selects your default network.
- `port` (integer): REQUIRED in practice: the port the app actually listens on inside the container — pass the port plan_deploy detected / the Dockerfile EXPOSE / the framework default. redu probes THIS port for health,…
- `redis` (string): Redis wiring (auto-injects REDIS_URL/REDIS_HOST/REDIS_PORT/REDIS_PASSWORD — zero setup): 'managed' = a SEPARATE managed Redis VM auto-provisioned + wired on the same private network (data persists ac…
- `redis_flavor_id` (string): managed Redis only: the dedicated Redis VM size (from list_flavors). Defaults to the app flavor; m1.small is plenty for a cache.
- `redis_password` (string): managed Redis only: a specific password to set (otherwise auto-generated).
- `redis_version` (string): managed Redis only: version (default '7').
- `repo` (string): GIT MODE: public git repo URL (https). For a PRIVATE repo also pass git_token. Omit when using source_token (upload mode).
- `runtime` (string): Informational: node/python/go/… (e.g. from plan_deploy).
- `security_group_names` (array)
- `source_token` (string): UPLOAD MODE: token from prepare_upload's curl step — deploys an uploaded tarball of your LOCAL working dir (no git, no PAT). Use this to deploy uncommitted code, a fixed clone of a repo you don't own…
- `subdir` (string): Build context within the source (e.g. 'demo-go') when the Containerfile/Dockerfile isn't at the root.
- `worker` (boolean): HEADLESS WORKER / daemon mode. Deploys a long-running container with NO HTTP server, NO public URL, and NO health probe — ready = the container stays running. The VM still gets a floating IP + SSH st…

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `deploy_compose` (~2012 tokens)

Deploy a docker-compose (multi-container) app to a VM

Deploys a MULTI-CONTAINER app — a repo that ships docker-compose.yml / compose.yaml — onto ONE VM via podman-compose, and exposes one or more services at redu.cloud URLs. Use this instead of deploy_app when the repo is a compose stack. Same prereqs + source modes as deploy_app; always run plan_deploy first. PORT is the HOST port for the exposed service. DB: 'compose' uses the stack's own db container; 'managed' provisions a separate managed Postgres/MySQL/MariaDB VM and appends connection env. For WordPress/WooCommerce cluster intent, do not leave the compose db service/local uploads as state: pass app_profile, cluster_target:true, database:'managed', db_engine:'mariadb' or 'mysql', cluster_media_mode:'media_space', and either media_space_id or create_media_space:true. Redu writes an override file that points the WordPress service at managed DB env and mounts the media space into /var/www/html/wp-content/uploads. Poll get_deployment until ready.

Input parameters:

- `app_profile` (string): Detected app profile from source inspection. For WordPress/WooCommerce pass wordpress/woocommerce so cluster deploys enforce managed DB + shared media instead of treating local uploads as stateless.
- `cluster_media_mode` (string): Record the WordPress media strategy for future clustering. For real WordPress clusters use media_space by default: Redu mounts a shared uploads filesystem into every member. local_uploads is single-V…
- `cluster_target` (boolean): Set TRUE when the user asked to deploy this compose app as an autoscaling cluster. For WordPress/WooCommerce this requires managed MySQL/MariaDB plus media_space/central_media_origin.
- `compose_engine` (string): Container engine for the compose build (default: the server's choice, usually podman). Set 'docker' to force the docker engine.
- `compose_file` (string): Path within the source to the compose file (e.g. 'deploy/docker-compose.yml'). Auto-detected (docker-compose.yml / compose.yaml / …) if omitted.
- `create_media_space` (boolean): For WordPress/WooCommerce cluster_target:true: set TRUE when no suitable media space exists. Redu creates an NFS media VM + persistent volume and mounts it into /var/www/html/wp-content/uploads.
- `database` (string): DB mode: 'compose' (default) = use the compose file's OWN db service (self-contained, nothing extra provisioned); 'single_vm' = Postgres ON the app VM; 'managed' = a SEPARATE managed-PG/MySQL VM. For…
- `db_engine` (string): managed only: 'postgres' (default) → PG* env; 'mysql'/'mariadb' → MYSQL_* env. mysql/mariadb require database:'managed'.
- `db_extensions` (array): single_vm/managed Postgres: extensions to pre-install (pgvector, postgis, pgaudit, …).
- `db_flavor_id` (string): managed only: the dedicated DB VM size (from list_flavors). Defaults to the app flavor.
- `db_name` (string): DB name for single_vm/managed (default 'app').
- `db_superuser` (boolean): single_vm/managed Postgres: grant the DB user SUPERUSER (dedicated DB VM, so safe).
- `db_user` (string): DB user for single_vm/managed (default 'appuser').
- `db_version` (string): DB version for single_vm/managed (Postgres '16'|'15'|'14'; MySQL '8.0'; MariaDB '11.4').
- `dname` (string): Custom *.redu.cloud subdomain. For a STABLE, KNOWN-AHEAD URL (needed when the app must be told its OWN url — OAuth callbacks, cookie domain, a frontend that calls its API), generate the FULL auto-gen…
- `env` (object): Env vars APPENDED to the compose project's .env (for ${VAR} interpolation). We never rewrite your compose file.
- `expose` (array): MULTI-SURFACE apps: expose several services, each gets its OWN *.redu.cloud URL. The FIRST entry is the primary one redu health-gates (its port overrides `port`). CRITICAL when one surface must KNOW…
- `flavor_id` (string): App VM size — from list_flavors. A multi-container stack often wants m1.large+; plan_deploy sizes it.
- `git_ref` (string): git mode only: branch/tag/commit (default: the repo's default branch).
- `git_token` (string): git mode only: token to clone a PRIVATE repo.
- `idempotency_key` (string)
- `keypair_name` (string, required): REQUIRED. An EXISTING SSH keypair name — from list_keypairs / import_keypair.
- `media_mount_path` (string): Host mount path on the app VM/member. Redu mounts this into /var/www/html/wp-content/uploads.
- `media_origin_url` (string): Public base URL where WordPress wp-content/uploads is served when using central_media_origin. Do not put this on the DB VM.
- `media_space_flavor_id` (string): Flavor id for the media VM when create_media_space:true. Defaults to m1.small/backend default.
- `media_space_id` (integer): Existing Redu media space id to mount at WordPress wp-content/uploads. Get it from list_media_spaces.
- `media_space_name` (string): Optional media space name when create_media_space:true. Defaults to <deployment-name>-media.
- `media_space_size_gb` (integer): Media space data volume size in GB when create_media_space:true (default 20).
- `migrate_command` (string): One-time DB prepare/migrate/seed, run AFTER `up -d` and BEFORE the app is marked ready — redu runs `podman-compose run --rm <migrate_service|service> <cmd>` (Rails `bundle exec rails db:prepare`, Dja…
- `migrate_service` (string): Compose service to run migrate_command in (defaults to `service`).
- `name` (string, required): Name for the deployment / VM (lowercase letters, numbers, hyphens).
- `network_id` (string): Private network id — auto-selected from check_deploy_prerequisites if omitted.
- `port` (integer): REQUIRED in practice: the HOST port the exposed service publishes (the LEFT side of its compose `ports:` mapping) — redu health-probes + proxies THIS port, so a wrong value fails the deploy. plan_dep…
- `redis` (string): 'managed' = a SEPARATE managed Redis VM, auto-provisioned + wired; its REDIS_URL/REDIS_* is APPENDED to the project .env — your compose service must REFERENCE it to use it (we never rewrite your comp…
- `redis_flavor_id` (string): managed Redis only: the dedicated Redis VM size (from list_flavors). Defaults to the app flavor.
- `redis_password` (string): managed Redis only: a specific password to set (otherwise auto-generated).
- `redis_version` (string): managed Redis only: version (default '7').
- `repo` (string): GIT MODE: public git repo URL that ships a docker-compose file. Private repo also needs git_token. Omit when using source_token.
- `security_group_names` (array)
- `service` (string): The compose SERVICE to expose at the public URL (informational; the exposed port is `port`).
- `source_token` (string): UPLOAD MODE: token from prepare_upload — deploys an uploaded tarball of your LOCAL dir (no git). Omit `repo` when set.
- `subdir` (string): Directory within the source that contains the compose file (if not at the root).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `deploy_vpn` (~418 tokens)

Deploy a private VPN gateway to reach your VMs' private network (needs approval)

Stands up a redu VPN gateway (WireGuard tunnelled over wstunnel on WSS/443) on your PRIVATE network, so you (or your team) can reach the private IPs of the VMs you deployed on redu, over a single https endpoint — no UDP, no extra ports. This is the TENANT VPN for reaching your OWN deployed resources; it is NOT a general internet VPN. GUARDRAIL: the first call does NOT deploy — it returns the plan + hourly cost for approval, because it creates a BILLED VM. Show the user, get their explicit 'go', then call again with confirm:true (required even in yolo mode). The gateway asset is redu's, deployed onto YOUR VM (you can SSH in to read it). Fresh WireGuard keys are generated per deploy; the client PRIVATE key is returned ONCE and is never stored server-side.

Input parameters:

- `client_cidr` (string): Your tenant PRIVATE-network CIDR (e.g. '10.1.0.0/24') so the client routes it through the tunnel. If omitted, the returned client config only routes the tunnel subnet and you add your CIDR to Allowed…
- `confirm` (boolean): Set true ONLY after the user has explicitly approved (the first call returns the plan + cost). Do NOT set it yourself.
- `flavor_id` (string): Gateway VM size (from list_flavors). The gateway is light; m1.small ('2') is plenty.
- `keypair_name` (string, required): REQUIRED. An EXISTING SSH keypair name (from list_keypairs / import_keypair) for the gateway VM.
- `name` (string): Deployment name (default auto 'vpn-<id>'). Becomes the VM name + the wss://<name>.redu.cloud endpoint.
- `network_id` (string): Private network id (from list_networks). Auto-selected from your default private network if omitted — the VMs you want to reach must be on this network.

Output parameters:

- `access_point` (string)
- `billing_notice` (string)
- `client_config` (string)
- `client_launch` (array)
- `deployment`
- `error` (boolean)
- `mode` (string)
- `needs_confirmation` (boolean)
- `next` (string)
- `server_public_key` (string)
- `validation`
- `warning` (string)

### `list_deployments` (~62 tokens)

List deployments

Lists your app deployments. Each row carries status (provisioning/ready/build_failed/error), the current build phase while provisioning (installing/source/building/built/starting), the public access_point URL, port, repo, and build_log on failure.

Output parameters:

- `deployments` (array)
- `mode` (string)
- `next` (string)

### `delete_deployment` (~87 tokens)

Delete deployment

Deletes a deployment and its underlying app VM. Pass the numeric id from list_deployments. IMPORTANT: if the deployment used database:'managed', the managed Postgres VM is NOT deleted (data safety) — this tool returns its id so you can delete_database it when you're done with the data. Cannot be undone.

Input parameters:

- `id` (integer, required): Deployment id from list_deployments.

Output parameters:

- `deleted` (boolean)
- `id` (number)
- `managed_db`
- `mode` (string)
- `next` (string)

### `get_deployment` (~118 tokens)

Get a deployment (status + build log + reality report)

Fetches ONE deployment by its numeric id (from list_deployments). Returns its current status, the public access_point URL, the underlying VM id, AND the build_log — read this when status is 'build_failed' or 'error' to see exactly why the on-VM build/run failed (no SSH needed). Also returns a reality report_markdown showing the REAL provisioned size + cost (the plan was only an estimate; the user may have up-sized).

Input parameters:

- `id` (integer, required): Deployment id from list_deployments.

Output parameters:

- `build_log` (string|null)
- `deployment`
- `mode` (string)
- `next` (string)
- `redu_md_filename` (string)
- `redu_md_markdown` (string)
- `report_markdown` (string)

### `architecture_diagram` (~245 tokens)

Architecture diagram of your account (read-only)

Read-only. Fetches EVERY resource on your redu.cloud account (VMs, volumes, private networks, managed databases: Postgres/MySQL/MariaDB/ClickHouse/Redis/Qdrant, load balancers, and DNS access points) and renders ONE Mermaid diagram of the whole account, grouped into per-private-network subgraphs with repetition collapsed into count nodes (e.g. "App VM x12"). Returns report_markdown to save as redu_architecture_diagram.md at the repo root, PLUS a redu_md_section that enriches the repo's redu.md with the current account topology, so the NEXT deploy is account-aware: it integrates with services that already exist and picks models/versions/sizes that fit the stack (better decisions, not just avoiding duplicate networks/databases). Nothing is created or changed.

Input parameters:

- `include_load_balancers` (boolean): Include load balancers in the map (default true).
- `include_managed` (boolean): Include managed databases (Postgres/MySQL/MariaDB/ClickHouse/Redis/Qdrant) in the map (default true).
- `include_volumes` (boolean): Include block volumes in the map (default true).

Output parameters:

- `counts`
- `mode` (string)
- `next` (string)
- `redu_md_filename` (string)
- `redu_md_section` (string)
- `report_filename` (string)
- `report_markdown` (string)
- `resources`

### `create_snapshot` (~32 tokens)

Create snapshot

Creates a snapshot of a running instance.

Input parameters:

- `instanceId` (string, required)
- `snapshotName` (string, required)

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_snapshot` (~27 tokens)

Delete snapshot

Deletes a snapshot by ID.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `create_backup` (~136 tokens)

Create backup

Creates a backup, by volumeId or by instanceId (the instance's volume is resolved for you). The backup is held independently of the instance, so it survives the VM. Poll list_backups until the new backup is available.

Input parameters:

- `backupName` (string, required): A name for the backup.
- `instanceId` (string): ID of the instance to back up — its bootable (else first) attached volume is resolved automatically, so no volume:list scope is needed. Provide this OR volumeId.
- `volumeId` (string): ID of the volume to back up (see list_volumes). Provide this OR instanceId.

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `restore_backup` (~258 tokens)

Restore backup

Restores a backup into an existing volume (volumeId), an instance's volume (instanceId), or a new one (volumeName). Poll list_volumes for the restored volume. DISASTER RECOVERY (the original VM is gone, so its volume died with it): restore with volumeName to rebuild the data as a NEW volume. To bring the MACHINE back, pass that volume as create_instance's boot_volume_id - it boots from the restored disk, so the VM returns with its filesystem intact and nothing to mount. Use attach_volume instead only when you want the data as an EXTRA disk on an existing machine (then get_ssh_command -> lsblk -> mount). A restored volume is inert until it is booted from or attached.

Input parameters:

- `backupId` (string, required): ID of the backup to restore (see list_backups).
- `instanceId` (string): Optional: restore into this instance's volume (resolved automatically). The target volume must be available (detached), so stop the instance first.
- `volumeId` (string): Optional: restore into this existing volume.
- `volumeName` (string): Optional: name for a new volume to restore into. Omit volumeId and instanceId to restore into a new volume.

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_backup` (~27 tokens)

Delete backup

Deletes a backup by ID.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `set_managed_backups` (~274 tokens)

Enable/disable automated backups

Turns nightly AUTOMATED (scheduled) backups ON or OFF for a MANAGED data service — the toggle that create_backup (a one-off volume snapshot) is NOT. Once enabled, redu's nightly job backs the service up on its own and prunes to the retention window; see them with list_backups and recover with the service's restore. Works for managed Postgres/MySQL/MariaDB/Redis/Qdrant/ClickHouse and can be flipped ANY time after provisioning, not only at create. Requires a card (automated backups are a paid feature; no-card trials cannot enable them). Pass the service type + its numeric id, enabled, and optional retention (days).

Input parameters:

- `enabled` (boolean, required): true = turn ON nightly AUTOMATED backups for this service; false = turn them off.
- `id` (required): Numeric id of the managed service (from list_databases / list_redis / list_relational_databases / etc.).
- `retention` (integer): How many days of nightly backups to keep (optional; keeps the current setting if omitted).
- `service` (string, required): Which managed data-service type the id belongs to. A managed Postgres from create_database/list_databases is 'postgres'; MySQL/MariaDB from create_relational_database; plus redis/qdrant/clickhouse.

Output parameters:

- `error` (boolean)
- `mode` (string)
- `next` (string)
- `result`

### `create_volume` (~28 tokens)

Create volume

Creates a block storage volume.

Input parameters:

- `name` (string, required)
- `size` (integer, required)

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `attach_volume` (~236 tokens)

Attach volume to instance

Attaches an EXISTING block volume to a running instance as an extra disk. This is how you finish a RESTORE after a VM is gone: restore_backup (volumeName) rebuilds the data into a new volume, then attach_volume puts that volume on a replacement instance — then SSH in (get_ssh_command) and mount it (`lsblk` to find it, usually /dev/vdb, then `mount /dev/vdb /mnt/...`). The volume must be 'available' (not already in-use — detach_volume it first) and in the same project. Attaching does NOT mount or boot from it: the instance keeps booting from its own root disk, the volume shows up as an extra block device. Poll list_volumes until status is 'in-use'.

Input parameters:

- `instance_id` (string, required): Instance to attach it to / detach it from — from list_instances (id).
- `volume_id` (string, required): Volume to attach/detach — from list_volumes (id). For a recovery, this is the volume restore_backup created (restore_backup with volumeName makes a NEW volume from a backup).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `detach_volume` (~173 tokens)

Detach volume from instance

Detaches a block volume from an instance, leaving the volume (and its data) intact and 'available' to attach elsewhere. Unmount it INSIDE the guest first (`umount /mnt/...`) or you risk a dirty filesystem. You cannot detach an instance's ROOT/boot disk while it runs. Use this to move a data volume to another VM, or to free a restore target before restore_backup writes into it. Poll list_volumes until status is 'available'.

Input parameters:

- `instance_id` (string, required): Instance to attach it to / detach it from — from list_instances (id).
- `volume_id` (string, required): Volume to attach/detach — from list_volumes (id). For a recovery, this is the volume restore_backup created (restore_backup with volumeName makes a NEW volume from a backup).

Output parameters:

- `available_keypairs` (array)
- `duplicate` (boolean)
- `error` (boolean)
- `idempotency_key` (string)
- `invalid_keypair_name` (boolean)
- `mode` (string)
- `needs_keypair` (boolean)
- `needs_keypair_name` (boolean)
- `needs_plan` (boolean)
- `next` (string)
- `plan_tool` (string)
- `request`
- `result`
- `validation`

### `delete_volume` (~101 tokens)

Delete volume

Permanently deletes a block storage volume and the data on it. This cannot be undone. The volume must be 'available' (detached) — detach_volume it first, and note you cannot detach a running instance's boot disk. A volume left behind after a restore keeps billing, so delete the ones you no longer need. Any BACKUP the volume was restored from is independent and survives this.

Input parameters:

- `id` (string, required): ID of the resource to delete.

Output parameters:

- `deleted` (boolean)
- `id` (string)
- `mode` (string)
- `next` (string)

### `get_domain_verification` (~57 tokens)

Get domain verification TXT record

Returns the DNS TXT record to add for custom domain ownership verification. Add the record to your DNS provider, then call verify_domain.

Input parameters:

- `domain` (string, required): The custom domain to verify ownership of (e.g. app.example.com).

Output parameters:

- `mode` (string)

### `verify_domain` (~73 tokens)

Verify custom domain

Checks the DNS TXT ownership record for a custom domain and marks it verified when the record is present. Call get_domain_verification first, add the TXT record at your DNS provider, then call this until status is verified.

Input parameters:

- `domain` (string, required): The custom domain to verify ownership of (e.g. app.example.com).

Output parameters:

- `domain` (string)
- `mode` (string)
- `next` (string)
- `result`
- `status` (string)
- `verified_at` (string|null)

### `check_agent_prerequisites` (~78 tokens)

Check autocoding agent prerequisites

Checks if your account has everything needed to run autonomous coding agents. Returns a checklist: API key validity, private network, SSH keypair, and billing. Safe to call anytime — read-only. Call this first before create_controller.

Input parameters:

- `github_pat` (string): GitHub Personal Access Token to validate (repo + workflow scopes required)

Output parameters:

- `all_ok` (boolean)
- `checks`

### `create_controller` (~141 tokens)

Create autocoding agent controller VM

Creates a self-configuring controller VM on redu.cloud. Auto-discovers your network, Ubuntu image, and flavor. Generates and uploads an SSH keypair if you don't have one. The VM bootstraps itself — no SSH or VPN needed. After ~7 minutes, authorize the fleet (run the authorize.sh one-liner it returns) then call trigger_agent_batch.

Input parameters:

- `github_pat` (string, required): GitHub Personal Access Token (repo + workflow scopes)
- `repo` (string, required): GitHub repo to run agents on, e.g. 'owner/repo'
- `worker_count` (integer): Number of worker VMs to provision (default 3)

Output parameters:

- `authorize_command` (string)
- `controller_host` (string)
- `dns` (string)
- `instance_id` (string)
- `log_token` (string)
- `mode` (string)
- `next` (array)
- `ssh_key_name` (string)
- `ssh_private_key` (string)
- `ssh_user` (string)
- `status` (string)
- `trigger_token` (string)

### `trigger_agent_batch` (~167 tokens)

Trigger autocoding agent batch

Starts the autonomous agent batch on your controller VM. Agents read agent-ready tasks from your ROADMAP.md, implement them in parallel, and open PRs. No VPN needed — runs over HTTPS; the controller stays running after you disconnect. Each ROADMAP task MUST be a single checkbox line `- [ ] **Title** — short description *(agent-ready)*` (the `- [ ]`, `**bold title**`, and `*(agent-ready)*` are all required; `##` headings and plain bullets are ignored). If this returns 'No agent-ready tasks', the tasks are mis-formatted — fix them to that exact format and retry.

Input parameters:

- `controller_url` (string, required): HTTPS URL of your controller VM
- `trigger_token` (string, required): Trigger token from the controller

Output parameters:

- `finalize_note` (string)
- `fleet_id` (string)
- `message` (string)
- `ok` (boolean)
- `workers_ready` (boolean)

### `get_agent_status` (~107 tokens)

Get autocoding agent status

Returns the current status of your controller VM. On a freshly set-up VM also returns the trigger token needed to authorize the fleet and to call trigger_agent_batch. Call this after setup_agent_fleet to confirm the VM is ready.

Input parameters:

- `controller_url` (string, required): HTTPS URL of your controller VM, e.g. https://redu-controller-abc123.redu.cloud
- `log_token` (string): Log token for fetching controller logs (optional — returned by this tool on first call)

Output parameters:

- `status`

### `setup_agent_session` (~92 tokens)

Full guided agent setup

One-shot tool that guides you through the complete agent setup: checks prerequisites, creates the controller VM, and returns next steps. Ideal for first-time setup. Call this when a user says 'set up autocoding agents for my repo'.

Input parameters:

- `github_pat` (string, required): GitHub Personal Access Token (repo + workflow scopes)
- `repo` (string, required): GitHub repo, e.g. 'owner/repo'

Output parameters:

- `next_tool` (string)
- `ready` (boolean)
- `repo` (string)

### `setup_agent_fleet` (~501 tokens)

Set up autocoding agent fleet (one shot)

Complete one-shot setup: validates prerequisites, creates a controller VM + worker VMs, auto-creates a public HTTPS URL on port 7070, seeds a starter ROADMAP.md into the repo if absent, and returns the trigger token. Call this when a user says 'set up autocoding agents for my repo' or 'I want agents to work on my codebase'. HOW THE AGENT WORKS: each worker runs Claude Code inside the repo, implements one task, runs the test suite, and opens a pull request. It excels at focused, single-PR, testable units of work — add an endpoint, write tests for a module, fix a specific bug, add a UI page — and is poor at vague/large tasks, design decisions, or anything needing external credentials. TASK FORMAT (strict, one line each): `- [ ] **Title** — short description *(agent-ready)*` — the `- [ ]` checkbox, `**bold title**`, ` — ` separator, and `*(agent-ready)*` are ALL required; `##` headings and plain bullets are ignored. After this returns, the user needs to: (1) authorize the fleet by running the authorize.sh one-liner it returns (it runs `claude setup-token` for a long-lived token installed on the controller) — agents use the user's existing Claude Max/Pro subscription, NOT an API key. This is a shell command the USER runs in their own terminal; do NOT try to read or push the user's credentials yourself. The controller takes ~7 min to boot, so PREFER to poll get_agent_status until it reports the controller is reachable and present the authorize command only once it's ready — that way the user doesn't run it into a long wait. (The command also waits on its own, showing a live progress counter, so a user who runs it early is fine too.) (2) add well-scoped tasks in the format above to ROADMAP.md; (3) call trigger_agent_batch.

Input parameters:

- `github_pat` (string, required): GitHub Personal Access Token with repo + workflow scopes. Used to clone the repo and open PRs.
- `repo` (string, required): GitHub repo to run agents on, e.g. 'owner/my-app'. Must be accessible with the PAT.
- `worker_count` (integer): Number of parallel worker VMs (default 3). Each works on a separate task simultaneously.

Output parameters:

- `authorize_command` (string)
- `controller_host` (string)
- `controller_url` (string)
- `fleet_id` (string)
- `instance_id` (string)
- `log_token` (string)
- `mode` (string)
- `next_steps` (array)
- `repo` (string)
- `ssh_key_name` (string)
- `ssh_private_key` (string)
- `ssh_user` (string)
- `trigger_token` (string)
- `worker_ids` (array)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/cloud-redu-mcp/mcp#diagnostics

## Score history

- 2026-08-04: 72
- 2026-08-03: 71
- 2026-08-02: 70
- 2026-08-01: 70
- 2026-07-31: 70
- 2026-07-30: 62
- 2026-07-29: 62
- 2026-07-28: 61
- 2026-07-27: 61
- 2026-07-26: 59

## Links

- Remote endpoint: https://mcp.redu.cloud/mcp
- Changelog RSS feed: https://verifymcp.io/servers/cloud-redu-mcp/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/cloud-redu-mcp/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/cloud-redu-mcp/mcp
