cloud.redu/mcp
Official55 toolsAgent-native cloud, EU-hosted. Provision VMs, networks & databases on redu.cloud via MCP.
Provisions virtual machines, networks, and databases on EU-hosted cloud infrastructure.
Captured live from the server via tools/list.
whoami
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.
No parameters.
check_deploy_prerequisites
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 }.
Parameters (1)
- modestring
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-checks to KEEP the chosen mode (do NOT re-pass 'guided' on a yolo session; passing it flips the session back to guided). Defaults to the session's sticky mode, or guided if never set.
deploy_overview
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.
No parameters.
prepare_upload
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.
Parameters (2)
- project_dirstring
Path to the local app directory to upload (default current dir).
- is_git_repoboolean
If the dir is a git checkout, set true to honor .gitignore (tar only tracked + non-ignored files).
scaffold_local
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.
Parameters (4)
- runtimestringrequired
App runtime (node/python/go/…) — from plan_deploy.
- portinteger
Port the app listens on.
- needs_postgresboolean
Include a local Postgres container + wire PG* env.
- has_containerboolean
Repo already has a Dockerfile/Containerfile (the compose builds it). If false, write the plan_deploy-generated Dockerfile to ./Dockerfile first.
plan_instance
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).
Parameters (2)
- osHintstring
- sizeHintstring
select_surface
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.)
Parameters (2)
- surfacesarrayrequired
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.
- modestring
Drive mode; omit to use the session's sticky mode.
plan_deploy
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. Also returns a brand-named markdown report (Mermaid diagram + cost) to save as redu-deploy-plan.md and show the user.
Parameters (16)
- runtimestringrequired
Detected app language/runtime (node, python, go, ruby, ...). Informational — the app deploys as a container, so the language does not gate the deploy.
- containerizableboolean
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.
- serves_httpboolean
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`-style runtime) — redu can only deploy web services, so a non-server repo is reported as not-a-web-service instead of being costed. Note: an `EXPOSE` of a debug/IPC port (Chrome DevTools 9222/9242, metrics) is NOT an HTTP listener — set false. Leave unset only if you're confident it serves HTTP.
- portinteger
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.
- startstring
How the app starts (package.json start script / Procfile / Dockerfile CMD).
- has_containerboolean
Whether the repo already has a Dockerfile / compose file.
- needs_postgresboolean
App uses Postgres (deps pg/prisma/sqlalchemy/drizzle or DATABASE_URL).
- needs_redisboolean
App uses Redis (deps redis/ioredis/bullmq/celery or REDIS_URL).
- needs_vector_dbboolean
App uses a vector DB (deps qdrant-client / langchain+embeddings or QDRANT_URL).
- needs_composeboolean
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 ONE VM), NOT deploy_app. A single-service compose that just wraps one Dockerfile can still use deploy_app. plan_deploy raises the app VM to a build-capable floor since a multi-container stack needs more RAM.
- vm_countinteger
Number of app VMs (microservices). v1: usually 1.
- single_vmboolean
Force everything onto a single VM if the user prefers.
- app_flavorstring
Preferred app VM size (default m1.medium). Resolved against the real flavor list.
- db_flavorstring
Preferred managed Postgres VM size (default m1.small). Resolved against the real flavor list.
- heavy_buildboolean
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. Signals: compiled-from-source native code (Rust/C++/CGO/Go-from-source), a monorepo/turborepo build, a Node build with a large heap (NODE_OPTIONS=--max-old-space-size), or bundling Chromium. When true, the plan raises the app VM to a build-capable floor (≥ m1.large) so `deploy_app`'s on-VM build doesn't get OOM-killed. The default m1.medium (4 GB) builds light apps fine but OOMs heavy ones.
- deploy_modestring
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, using sensible defaults. Sticky for the session once set here or via check_deploy_prerequisites.
list_instances
Lists your compute instances.
No parameters.
list_flavors
Lists available instance sizes.
No parameters.
list_images
Lists available OS images.
No parameters.
list_keypairs
Lists your SSH keypairs. If empty, call import_keypair first before creating instances.
No parameters.
list_security_groups
Lists your security groups.
No parameters.
list_private_networks
Lists your private networks.
No parameters.
list_volumes
Lists your block storage volumes.
No parameters.
list_snapshots
Lists your instance snapshots.
No parameters.
list_backups
Lists your volume backups.
No parameters.
list_clusters
Lists your autoscaling clusters.
No parameters.
list_dns_entries
Lists DNS proxy host entries.
No parameters.
list_domains
Lists custom domains you have verified ownership of.
No parameters.
list_regions
Lists available regions.
No parameters.
list_databases
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).
No parameters.
list_relational_databases
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).
No parameters.
list_clickhouse_databases
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).
No parameters.
list_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>.
No parameters.
import_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.
Parameters (2)
- namestringrequired
Name for the keypair (e.g. 'my-laptop'). Must be unique on your account.
- public_keystringrequired
SSH public key to import (the contents of your id_rsa.pub or id_ed25519.pub).
delete_keypair
Removes an SSH keypair from your account by name.
Parameters (1)
- namestringrequired
Name of the keypair to delete.
get_ssh_command
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
Parameters (2)
- instance_idstringrequired
ID of the instance to get the SSH command for.
- keypair_namestring
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.
get_instance_logs
Returns the console log output from an instance.
Parameters (1)
- instance_idstringrequired
ID of the instance to fetch console logs for.
instance_action
Start, stop, or reboot an instance. action must be START, STOP, REBOOT_SOFT, or REBOOT_HARD.
Parameters (2)
- instanceIdstringrequired
- actionstringrequired
create_instance
Creates a compute instance. Use plan_instance first to get valid image_id, flavor_id, keypair_name, network_id. For reduOS, set cloud_init_template='reduos' and flavor m1.xlarge (16GB). SSH keypair must exist. For a public web app, pass dns_entries (gives a .redu.cloud URL) and make sure the security group opens ports 80/443.
Parameters (13)
- idempotency_keystring
- namestringrequired
- image_idstringrequired
- flavor_idstringrequired
- keypair_namestringrequired
- network_idstringrequired
- security_group_namesarray
- portinteger
- dnamestring
- user_datastring
- cloud_init_templatestring
- volumeobject
- imageNamestring
delete_instance
Permanently deletes an instance. This cannot be undone.
Parameters (1)
- idstringrequired
ID of the resource to delete.
create_database
Provisions a managed PostgreSQL database on a dedicated VM on your private network. 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 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.
Parameters (12)
- idempotency_keystring
- namestringrequired
Name for the managed database (lowercase letters, numbers, hyphens).
- flavor_idstringrequired
Instance size for the DB VM — from list_flavors.
- network_idstringrequired
Private network id — from list_private_networks. The DB is reachable only from this network.
- keypair_namestringrequired
SSH keypair name — from list_keypairs (for operating the DB VM).
- db_namestring
The database to create (default 'app').
- db_userstring
The database user (default 'appuser').
- db_passwordstring
Password for the db user. Auto-generated and returned once if omitted.
- versionstring
Postgres major version (default 16).
- extensionsarray
Postgres extensions to pre-install at provision time (allowlisted): 'pgvector'/'vector' (embeddings), 'postgis' (geo), 'pgaudit', 'pg_trgm', 'pgcrypto', 'hstore', 'uuid-ossp', 'citext', 'ltree', 'pg_stat_statements', 'btree_gin', 'btree_gist'. Saves SSHing in to run CREATE EXTENSION; needed by apps like langfuse/lantern (pgvector).
- superuserboolean
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.
- security_group_namesarray
delete_database
Deletes a managed Postgres database and its underlying VM. Pass the numeric database id from list_databases. This cannot be undone.
Parameters (1)
- idstringrequired
ID of the resource to delete.
create_relational_database
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). 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 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.)
Parameters (11)
- idempotency_keystring
- namestringrequired
Name for the managed database (lowercase letters, numbers, hyphens).
- enginestring
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 — ClickHouse is not a relational DB.)
- flavor_idstringrequired
Instance size for the DB VM — from list_flavors.
- network_idstringrequired
Private network id — from list_private_networks. The DB is reachable only from this network.
- keypair_namestringrequired
SSH keypair name — from list_keypairs (for operating the DB VM).
- db_namestring
The database to create (default 'app').
- db_userstring
The database user (default 'appuser').
- db_passwordstring
Password for the db user (letters/numbers/_/- only). Auto-generated and returned once if omitted.
- versionstring
Engine version (e.g. mysql '8.0', mariadb '11.4'). Defaults to the engine's current major if omitted.
- security_group_namesarray
delete_relational_database
Deletes a managed MySQL/MariaDB database and its underlying VM. Pass the numeric id from list_relational_databases. This cannot be undone.
Parameters (1)
- idstringrequired
ID of the resource to delete.
create_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. 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 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'.
Parameters (9)
- idempotency_keystring
- namestringrequired
Name for the managed ClickHouse database (lowercase letters, numbers, hyphens).
- flavor_idstringrequired
Instance size for the ClickHouse VM — from list_flavors. ClickHouse is RAM-hungry; pick m1.small (2GB) or larger.
- network_idstringrequired
Private network id — from list_private_networks. The DB is reachable only from this network.
- keypair_namestringrequired
SSH keypair name — from list_keypairs.
- db_namestring
The database to create (default 'analytics').
- db_userstring
The database user (default 'appuser').
- db_passwordstring
Password for the db user (letters/numbers/_/- only). Auto-generated and returned once if omitted.
- security_group_namesarray
delete_clickhouse
Deletes a managed ClickHouse database and its underlying VM. Pass the numeric id from list_clickhouse_databases. This cannot be undone.
Parameters (1)
- idstringrequired
ID of the resource to delete.
create_redis
Provisions a managed Redis instance on a dedicated VM on your private network. 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 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).
Parameters (8)
- idempotency_keystring
- namestringrequired
Name for the managed Redis instance (lowercase letters, numbers, hyphens).
- flavor_idstringrequired
Instance size for the Redis VM — from list_flavors. m1.small (2GB) is plenty for most caches/queues.
- network_idstringrequired
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.
- keypair_namestringrequired
SSH keypair name — from list_keypairs (for operating the Redis VM).
- versionstring
Redis major version (default '7').
- passwordstring
Redis AUTH password (requirepass). Auto-generated and returned once if omitted.
- security_group_namesarray
delete_redis
Deletes a managed Redis instance and its underlying VM. Pass the numeric id from list_redis. This cannot be undone.
Parameters (1)
- idstringrequired
ID of the resource to delete.
deploy_app
Deploys an app to a VM and exposes it at a public https://<name>-<id>.redu.cloud URL (a random 8-char suffix is appended to <name> for uniqueness — a BARE custom `dname` like `myapp.redu.cloud` ALSO gets a suffix, so to PIN a known URL pass a dname that already includes an 8-char suffix like `myapp-7k2m9x4p.redu.cloud` and wire the app's own URL env to it; single-surface apps can instead just read the injected PUBLIC_URL/APP_URL). The container is built ON the VM — no local Docker/podman needed. PREREQS — run check_deploy_prerequisites first: it auto-selects your network_id + keypair_name (and returns a recipe to mint a keypair if you have none). Pass those two ids here. PORT: pass the port the app actually listens on (plan_deploy detects it / Dockerfile EXPOSE) — redu health-probes that exact port, so a wrong/omitted port (defaults to 3000) fails a non-3000 app (e.g. a static nginx app listens on 80 → pass 80). TWO source modes: (1) GIT — pass `repo` (public; private repos also need git_token). (2) UPLOAD — call prepare_upload first to tar + POST your LOCAL working dir, then pass the returned `source_token` (no git, no PAT; use this for uncommitted code, a fixed clone of a repo you don't own, or private code). The source needs a Containerfile/Dockerfile; redu auto-finds one in common subfolders (Docker/, scripts/, packaging/…) and builds with the repo root as context — for a repo with MULTIPLE Dockerfiles pass `dockerfile`+`context` to pick the right one. If it has NONE, pass dockerfile_content (the one plan_deploy generated) or include a Dockerfile in the uploaded tarball. To wire a DB, pass `database` (auto-injects the connection env + DATABASE_URL — zero setup): `database:'single_vm'` puts Postgres ON the app VM (cheapest; data dies if the VM is replaced); `database:'managed'` provisions a SEPARATE managed-DB VM on the same private network and wires it automatically (data PERSISTS across redeploys; reused on a same-name redeploy) — you do NOT call create_database/create_relational_database for this. Choose the engine with `db_engine` ('postgres' default → PG* env; 'mysql'/'mariadb' → MYSQL_* env + mysql:// URL, for WordPress/Matomo/LAMP apps; mysql/mariadb require database:'managed'). redu also injects APP_URL/PUBLIC_URL (= the app's public URL) into its env, so apps that need their own URL get it (map an app-specific var like BASE_URL to PUBLIC_URL if needed). Build+provision takes ~3-6 min (a bit longer for managed, which also brings up the DB VM); poll list_deployments or get_deployment until status='ready'. On 'build_failed'/'error', call get_deployment(id) to read build_log. ALWAYS run plan_deploy first and confirm the plan + cost with the user before deploying.
Parameters (31)
- idempotency_keystring
- namestringrequired
Name for the deployment / VM (lowercase letters, numbers, hyphens).
- repostring
GIT MODE: public git repo URL (https). For a PRIVATE repo also pass git_token. Omit when using source_token (upload mode).
- source_tokenstring
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, or private code. Omit `repo` when set.
- dockerfile_contentstring
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 include the Dockerfile in the tarball.)
- dockerfilestring
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.
- contextstring
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.
- git_refstring
git mode only: branch/tag/commit to deploy (default: the repo's default branch).
- subdirstring
Build context within the source (e.g. 'demo-go') when the Containerfile/Dockerfile isn't at the root.
- git_tokenstring
git mode only: token to clone a PRIVATE repo. Omit for public repos.
- runtimestring
Informational: node/python/go/… (e.g. from plan_deploy).
- portinteger
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, so a wrong value fails the deploy. Defaults to 3000 only if omitted (e.g. a static nginx app listens on 80 — pass 80).
- dnamestring
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 form yourself: `<label>-<8 lowercase letters/digits>.redu.cloud` (e.g. `myapp-7k2m9x4p.redu.cloud`) — that exact form is used VERBATIM — and wire the app's own URL env to that SAME value. A BARE `<label>.redu.cloud` is NOT used as-is: redu appends a random 8-char suffix for uniqueness, so anything wired to the bare name will NOT match the real URL. Omit to auto-generate (then read the real URL from get_deployment).
- envobject
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.
- db_idinteger
Informational link to a managed Postgres (from create_database/list_databases).
- databasestring
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 managed-DB VM auto-provisioned + wired on the same private network (data PERSISTS across app redeploys; reused on a same-name redeploy). Omit (or 'none') for no DB. With 'managed' you do NOT call create_database/create_relational_database — it's done for you. Choose the engine with db_engine.
- db_enginestring
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 for WordPress/Matomo/NextCloud/most PHP-LAMP apps. Requires database:'managed' (single_vm is Postgres only).
- db_namestring
DB name for single_vm/managed (default 'app').
- db_userstring
DB user for single_vm/managed (default 'appuser').
- db_versionstring
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.
- db_flavor_idstring
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_extensionsarray
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 EXTENSION by hand.
- db_superuserboolean
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.
- redisstring
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 across app redeploys; reused on a same-name redeploy). Omit (or 'none') for no Redis. With 'managed' you do NOT call create_redis — it's done for you. Use when the app needs Redis (REDIS_URL / bullmq / celery / sidekiq / cache).
- redis_versionstring
managed Redis only: version (default '7').
- redis_flavor_idstring
managed Redis only: the dedicated Redis VM size (from list_flavors). Defaults to the app flavor; m1.small is plenty for a cache.
- redis_passwordstring
managed Redis only: a specific password to set (otherwise auto-generated).
- flavor_idstring
Instance size — from list_flavors. Default m1.medium (enough RAM to build on the VM).
- network_idstring
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.
- keypair_namestringrequired
REQUIRED. An EXISTING SSH keypair name — call list_keypairs and reuse one, or import_keypair first.
- security_group_namesarray
deploy_compose
Deploys a MULTI-CONTAINER app — a repo that ships a docker-compose.yml / compose.yaml (app + its own db/redis/worker containers) — onto ONE VM via podman-compose, and exposes ONE service at https://<name>-<id>.redu.cloud. Use this instead of deploy_app when the repo is a compose stack rather than a single Dockerfile. SAME prereqs + source modes as deploy_app: run check_deploy_prerequisites (network_id + keypair_name), then GIT (`repo`, +git_token for private) or UPLOAD (prepare_upload → source_token). PORT: pass the HOST port the exposed service publishes (the LEFT side of its `ports:` mapping) — redu probes + proxies that exact port; pass `service` to name which service it is (plan_deploy detects both). DB: 'compose' (default) uses the stack's own db service (self-contained); 'single_vm'/'managed' provision a Postgres/MySQL and APPEND its conn env (DATABASE_URL/PG*/MYSQL_*) to the project .env — your compose must REFERENCE those vars to use it (we never rewrite your compose file). Build+provision can take 4-40 min (it pulls/builds every service — heavy ClickHouse/Kafka stacks are slow); poll get_deployment until status='ready', and on failure read build_log (it captures podman-compose logs). TIPS: (1) prefer the project's PREBUILT published images — swap any `build:` block for the published `image:` tag (building from source on the VM is less reliable). (2) redu injects APP_URL/PUBLIC_URL (= the app's public URL) into the env — map the app's own URL/cookie-domain var (SERVER_URL/NEXTAUTH_URL/…) to ${PUBLIC_URL}. (3) multi-surface apps (dashboard + API on separate ports) → pass `expose:[{port,service},…]`, each gets its own URL. (4) if the stack needs a ONE-TIME DB migrate/prepare before it serves (Rails `rails db:prepare`, Django `migrate`, Prisma `migrate deploy` — e.g. Lago), pass `migrate_command` (+ `migrate_service`); without it the stack deploys to 'ready' but 502s on real use because the schema is missing. ALWAYS run plan_deploy first and confirm the plan + cost with the user.
Parameters (32)
- idempotency_keystring
- namestringrequired
Name for the deployment / VM (lowercase letters, numbers, hyphens).
- repostring
GIT MODE: public git repo URL that ships a docker-compose file. Private repo also needs git_token. Omit when using source_token.
- source_tokenstring
UPLOAD MODE: token from prepare_upload — deploys an uploaded tarball of your LOCAL dir (no git). Omit `repo` when set.
- git_refstring
git mode only: branch/tag/commit (default: the repo's default branch).
- subdirstring
Directory within the source that contains the compose file (if not at the root).
- git_tokenstring
git mode only: token to clone a PRIVATE repo.
- compose_filestring
Path within the source to the compose file (e.g. 'deploy/docker-compose.yml'). Auto-detected (docker-compose.yml / compose.yaml / …) if omitted.
- migrate_commandstring
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`, Django `python manage.py migrate`, Prisma `prisma migrate deploy`). REQUIRED for any stack whose schema is NOT auto-created on boot (e.g. Lago): WITHOUT it the stack deploys and flips to 'ready' but 502s on real use because the DB schema is missing.
- migrate_servicestring
Compose service to run migrate_command in (defaults to `service`).
- compose_enginestring
Container engine for the compose build (default: the server's choice, usually podman). Set 'docker' to force the docker engine.
- servicestring
The compose SERVICE to expose at the public URL (informational; the exposed port is `port`).
- portinteger
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_deploy detects it.
- dnamestring
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 form yourself: `<label>-<8 lowercase letters/digits>.redu.cloud` (e.g. `myapp-7k2m9x4p.redu.cloud`) — that exact form is used VERBATIM — and wire the app's own URL env to that SAME value. A BARE `<label>.redu.cloud` is NOT used as-is: redu appends a random 8-char suffix for uniqueness, so anything wired to the bare name will NOT match the real URL. Omit to auto-generate (then read the real URL from get_deployment).
- exposearray
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 another's URL (a frontend that calls its API — e.g. Lago's front -> API): GENERATE each surface's dname up front as `<label>-<8 lowercase letters/digits>.redu.cloud` (used VERBATIM) and wire the app's cross-surface URL env (LAGO_API_URL, LAGO_FRONT_URL, FRONTEND_URL, NEXT_PUBLIC_API_URL, …) to those EXACT values. Do NOT use a bare `<label>.redu.cloud` — redu appends a random suffix, so config wired to the bare name breaks.
- envobject
Env vars APPENDED to the compose project's .env (for ${VAR} interpolation). We never rewrite your compose file.
- databasestring
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 single_vm/managed the conn env (DATABASE_URL/PG*/MYSQL_*) is APPENDED to the project .env — your compose service must REFERENCE it (e.g. environment: - DATABASE_URL=${DATABASE_URL}) to actually use it; we never modify your compose file. Choose engine with db_engine.
- db_enginestring
managed only: 'postgres' (default) → PG* env; 'mysql'/'mariadb' → MYSQL_* env. mysql/mariadb require database:'managed'.
- db_namestring
DB name for single_vm/managed (default 'app').
- db_userstring
DB user for single_vm/managed (default 'appuser').
- db_versionstring
DB version for single_vm/managed (Postgres '16'|'15'|'14'; MySQL '8.0'; MariaDB '11.4').
- db_extensionsarray
single_vm/managed Postgres: extensions to pre-install (pgvector, postgis, pgaudit, …).
- db_superuserboolean
single_vm/managed Postgres: grant the DB user SUPERUSER (dedicated DB VM, so safe).
- db_flavor_idstring
managed only: the dedicated DB VM size (from list_flavors). Defaults to the app flavor.
- redisstring
'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 compose file). Omit/'none' to use the stack's own redis container. With 'managed' you do NOT call create_redis.
- redis_versionstring
managed Redis only: version (default '7').
- redis_flavor_idstring
managed Redis only: the dedicated Redis VM size (from list_flavors). Defaults to the app flavor.
- redis_passwordstring
managed Redis only: a specific password to set (otherwise auto-generated).
- flavor_idstring
App VM size — from list_flavors. A multi-container stack often wants m1.large+; plan_deploy sizes it.
- network_idstring
Private network id — auto-selected from check_deploy_prerequisites if omitted.
- keypair_namestringrequired
REQUIRED. An EXISTING SSH keypair name — from list_keypairs / import_keypair.
- security_group_namesarray
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.
No parameters.
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.
Parameters (1)
- idintegerrequired
Deployment id from list_deployments.
get_deployment
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).
Parameters (1)
- idintegerrequired
Deployment id from list_deployments.
create_snapshot
Creates a snapshot of a running instance.
Parameters (2)
- instanceIdstringrequired
- snapshotNamestringrequired
delete_snapshot
Deletes a snapshot by ID.
Parameters (1)
- idstringrequired
ID of the resource to delete.
create_volume
Creates a block storage volume.
Parameters (2)
- namestringrequired
- sizeintegerrequired
get_domain_verification
Returns the DNS TXT record to add for custom domain ownership verification. Add the record to your DNS provider, then call verify_domain.
Parameters (1)
- domainstringrequired
The custom domain to verify ownership of (e.g. app.example.com).
check_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.
Parameters (1)
- github_patstring
GitHub Personal Access Token to validate (repo + workflow scopes required)
create_controller
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.
Parameters (3)
- github_patstringrequired
GitHub Personal Access Token (repo + workflow scopes)
- repostringrequired
GitHub repo to run agents on, e.g. 'owner/repo'
- worker_countinteger
Number of worker VMs to provision (default 3)
trigger_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.
Parameters (2)
- controller_urlstringrequired
HTTPS URL of your controller VM
- trigger_tokenstringrequired
Trigger token from the controller
get_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.
Parameters (2)
- controller_urlstringrequired
HTTPS URL of your controller VM, e.g. https://redu-controller-abc123.redu.cloud
- log_tokenstring
Log token for fetching controller logs (optional — returned by this tool on first call)
setup_agent_session
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'.
Parameters (2)
- github_patstringrequired
GitHub Personal Access Token (repo + workflow scopes)
- repostringrequired
GitHub repo, e.g. 'owner/repo'
setup_agent_fleet
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.
Parameters (3)
- github_patstringrequired
GitHub Personal Access Token with repo + workflow scopes. Used to clone the repo and open PRs.
- repostringrequired
GitHub repo to run agents on, e.g. 'owner/my-app'. Must be accessible with the PAT.
- worker_countinteger
Number of parallel worker VMs (default 3). Each works on a separate task simultaneously.
README not available yet.
Install
claude_desktop_config.json
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.redu.cloud/mcp"
]
}
}
}Desktop config is stdio-only; this bridges via mcp-remote. Native remote: Settings > Connectors.