plan_deploy
ActiveTool of cloud.redu/mcp
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 schema
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"runtime"
],
"properties": {
"port": {
"type": "integer",
"description": "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.",
"exclusiveMinimum": 0
},
"start": {
"type": "string",
"description": "How the app starts (package.json start script / Procfile / Dockerfile CMD)."
},
"runtime": {
"type": "string",
"minLength": 1,
"description": "Detected app language/runtime (node, python, go, ruby, ...). Informational — the app deploys as a container, so the language does not gate the deploy."
},
"vm_count": {
"type": "integer",
"default": 1,
"maximum": 10,
"minimum": 1,
"description": "Number of app VMs (microservices). v1: usually 1."
},
"db_flavor": {
"type": "string",
"default": "m1.small",
"description": "Preferred managed Postgres VM size (default m1.small). Resolved against the real flavor list."
},
"single_vm": {
"type": "boolean",
"default": false,
"description": "Force everything onto a single VM if the user prefers."
},
"app_flavor": {
"type": "string",
"default": "m1.medium",
"description": "Preferred app VM size (default m1.medium). Resolved against the real flavor list."
},
"deploy_mode": {
"enum": [
"guided",
"yolo"
],
"type": "string",
"description": "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."
},
"heavy_build": {
"type": "boolean",
"description": "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."
},
"needs_redis": {
"type": "boolean",
"default": false,
"description": "App uses Redis (deps redis/ioredis/bullmq/celery or REDIS_URL)."
},
"serves_http": {
"type": "boolean",
"description": "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."
},
"has_container": {
"type": "boolean",
"default": false,
"description": "Whether the repo already has a Dockerfile / compose file."
},
"needs_compose": {
"type": "boolean",
"default": false,
"description": "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."
},
"needs_postgres": {
"type": "boolean",
"default": false,
"description": "App uses Postgres (deps pg/prisma/sqlalchemy/drizzle or DATABASE_URL)."
},
"containerizable": {
"type": "boolean",
"default": true,
"description": "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."
},
"needs_vector_db": {
"type": "boolean",
"default": false,
"description": "App uses a vector DB (deps qdrant-client / langchain+embeddings or QDRANT_URL)."
}
},
"additionalProperties": false
}No endpoints wrapped at confidence ≥ 0.70.
Parent server
cloud.redu/mcp
1/7 registries