Render Integration Guide
Technology: render · Category: hosting · Last reviewed: 2026-08-23
Source: https://tech-stack.codeamanilabs.org/guide/render
Insight:
Render covers what serverless can't — long-running services, background workers, cron jobs, and managed Postgres/Redis with persistent connections. Reach for it when you need an always-on server process rather than the Vercel/Netlify function model.
██████╗ ███████╗███╗ ██╗██████╗ ███████╗██████╗
██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗
██████╔╝█████╗ ██╔██╗ ██║██║ ██║█████╗ ██████╔╝
██╔══██╗██╔══╝ ██║╚██╗██║██║ ██║██╔══╝ ██╔══██╗
██║ ██║███████╗██║ ╚████║██████╔╝███████╗██║ ██║
╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝╚═════╝ ╚══════╝╚═╝ ╚═╝
Render Integration Guide
Focus: Managing Render cloud infrastructure from Claude Code using the official Render MCP server and REST API automation.
Overview
Render is a unified cloud platform for deploying web services, private services, static sites, background workers, cron jobs, and managed Postgres / Key Value (Redis-compatible) datastores. The official Render MCP server (GA on 2025-08-21) lets Claude Code inspect services, query databases, fetch logs, analyze metrics, trigger deploys, and create new resources — all through natural language without leaving your session.
Here is the big picture — a single git push fans out into all of Render's service types, so you can reason about the whole platform at a glance:
flowchart LR
A["git push to main"] --> B["Render auto-build"]
B --> C["Web service"]
B --> D["Background worker"]
B --> E["Cron job"]
B --> F["Static site"]
C --> G["Managed Postgres / Redis"]
D --> G
E --> G
Official Documentation
| Resource | URL |
|---|---|
| Render Docs | https://render.com/docs |
| Render MCP Server | https://render.com/docs/mcp-server |
| MCP server source | https://github.com/render-oss/render-mcp-server |
| AI/LLM Support | https://render.com/docs/llm-support |
| Render REST API | https://api-docs.render.com |
Blueprint (render.yaml) spec |
https://render.com/docs/blueprint-spec |
| Render Dashboard | https://dashboard.render.com |
MCP Server Setup
Official Render MCP Server (Remote, Recommended)
Render hosts an official MCP server at https://mcp.render.com/mcp. Authenticate with OAuth (recommended, browser sign-in) or with a Render API key (for non-interactive environments). The server is open source at github.com/render-oss/render-mcp-server; prefer the hosted endpoint over running it locally so it stays current as new tools ship.
You are about to give Claude Code a direct line into your infrastructure — here is how a natural-language request flows through the MCP server to your live services:
sequenceDiagram
participant U as "You"
participant C as "Claude Code"
participant M as "Render MCP"
participant R as "Render services"
U->>C: "Why is my API down?"
C->>M: list_services
M->>R: query status
R-->>M: status results
M->>R: get_logs + get_metrics
R-->>M: logs and metrics
M-->>C: diagnostic data
C-->>U: summary and fix
# OAuth (recommended) — registers the server, then you authorize in the browser
claude mcp add --transport http --client-id claude render https://mcp.render.com/mcp
# then run /mcp inside Claude Code → select "render" → Authenticate
# API key (non-interactive) — Bearer token instead of OAuth
claude mcp add --transport http render \
https://mcp.render.com/mcp \
--header "Authorization: Bearer ${RENDER_API_KEY}"
.mcp.json Configuration (API-key auth)
{
"mcpServers": {
"render": {
"type": "http",
"url": "https://mcp.render.com/mcp",
"headers": {
"Authorization": "Bearer ${RENDER_API_KEY}"
}
}
}
}
Get your API key from: https://dashboard.render.com/u/settings → API Keys. After connecting, set the active workspace once per session — prompt "Set my Render workspace to <name>"; every tool call is scoped to that workspace.
Available MCP Tools (by resource)
| Resource | Actions |
|---|---|
| Workspaces | list workspaces · set current workspace · get current workspace details |
| Services | create (web service · static site · cron job · Postgres · Key Value) · list · get details · update all env vars |
| Deploys | trigger a deploy (optionally clearing build cache) · list deploy history · get a deploy |
| Logs | list logs by filter · list values for a log label |
| Metrics | CPU / memory · instance count · datastore connection counts · response counts by status code · response times (Pro workspace+) · outbound bandwidth |
| Render Postgres | create · list · get · run a read-only SQL query |
| Render Key Value | create · list · get |
What the MCP server can't do. It creates only web services, static sites, cron jobs, Postgres, and Key Value — not background workers, private services, or image-backed services, and it can't set IP allowlists. For existing services it only triggers deploys and updates env vars; it does not modify scaling settings or other operational controls. Use
render.yamlor the REST API for those.
Render CLI
Render ships an official CLI (render, GA — v2.24.0 at review time; source at
github.com/render-oss/cli). It complements the MCP server for terminal and
CI/CD work — triggering deploys, tailing logs, opening a psql or SSH session,
and validating Blueprints.
# Install (macOS/Linux)
brew install render # or: curl -fsSL https://raw.githubusercontent.com/render-oss/cli/refs/heads/main/bin/install.sh | sh
render login # browser CLI-token auth; then pick an active workspace
render workspace set # switch the active workspace at any time
| Command | Does |
|---|---|
render services |
List services/datastores in the active workspace (interactive menu) |
render deploys create [SERVICE_ID] |
Trigger a deploy — --wait, --commit <sha>, --image <tag> |
render deploys list [SERVICE_ID] |
Deploy history for a service |
render psql [DATABASE_ID] |
Open psql; -c "SQL" runs one query and exits |
render ssh [SERVICE_ID] |
SSH into a running instance; --ephemeral for an isolated shell |
render blueprints validate [FILE] |
Validate a render.yaml (defaults to ./render.yaml) |
render skills [install|list] |
Install Render agent skills for Claude Code / Codex / Cursor |
For CI/CD, authenticate non-interactively with RENDER_API_KEY (takes
precedence over CLI tokens) and pass -o json + --confirm:
export RENDER_API_KEY=rnd_...
render deploys create "$RENDER_SERVICE_ID" --output json --confirm --wait
REST API Integration
The REST API is the lowest-level programmatic interface, underneath both the CLI and the MCP server — reach for it when you need a field the CLI/MCP don't expose (e.g. creating background workers or private services).
Get your services
curl https://api.render.com/v1/services \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" | jq '.[] | {id, name, status}'
Trigger a manual deploy
SERVICE_ID="srv-..."
curl -X POST "https://api.render.com/v1/services/$SERVICE_ID/deploys" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"clearCache": "do_not_clear"}'
Create a web service (TypeScript)
const response = await fetch("https://api.render.com/v1/services", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RENDER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
// type enum: web_service | static_site | private_service | background_worker | cron_job
type: "web_service",
name: "my-api",
ownerId: "usr-...", // workspace/owner ID (usr-… or tea-…)
repo: "https://github.com/my-org/my-repo", // repo is a plain URL string
branch: "main", // top-level; defaults to the repo's default branch
autoDeploy: "yes", // "yes" | "no"
serviceDetails: {
runtime: "node", // field is "runtime" (docker|elixir|go|node|python|ruby|rust|image)
plan: "starter", // starter|standard|pro|pro_plus|pro_max|pro_ultra|free
region: "oregon",
// build/start commands live under envSpecificDetails for native runtimes
envSpecificDetails: {
buildCommand: "npm ci && npm run build",
startCommand: "node dist/index.js",
},
},
}),
});
const service = await response.json();
console.log("Created:", service.service.serviceDetails.url);
Python helper for Render API
import os, requests
RENDER_API_KEY = os.environ["RENDER_API_KEY"]
BASE = "https://api.render.com/v1"
HEADERS = {"Authorization": f"Bearer {RENDER_API_KEY}", "Content-Type": "application/json"}
def get_services():
return requests.get(f"{BASE}/services", headers=HEADERS).json()
def get_logs(service_id: str, limit: int = 100):
return requests.get(
f"{BASE}/services/{service_id}/logs",
headers=HEADERS,
params={"limit": limit},
).json()
def trigger_deploy(service_id: str):
return requests.post(
f"{BASE}/services/{service_id}/deploys",
headers=HEADERS,
json={"clearCache": "do_not_clear"},
).json()
render.yaml Blueprint (Infrastructure as Code)
A Blueprint (render.yaml at your repo root) is the single source of truth for an interconnected set of services, databases, and environment groups. Commit it to Git, connect the repo in the Dashboard, and Render provisions everything in one pass. By default Render re-syncs affected resources on every push to the linked branch, so you manage infra the same way you manage code — via PRs and git push.
flowchart LR
A["Edit render.yaml"] --> B["git push to linked branch"]
B --> C["Render reads Blueprint"]
C --> D["Sync web service<br/>build · start · scaling"]
C --> E["Sync managed Postgres"]
C --> F["Sync env var group"]
D --> G["Live infrastructure"]
E --> G
F --> G
A web service + managed Postgres + a shared env group, fully wired:
# render.yaml
services:
- type: web
name: amani-api
runtime: node
plan: starter
region: oregon
buildCommand: npm ci && npm run build
startCommand: node dist/index.js
autoDeployTrigger: commit
envVarGroups:
- amani-shared
envVars:
# Wire the DATABASE_URL straight from the managed database below
- key: DATABASE_URL
fromDatabase:
name: amani-db
property: connectionString
# Prompt for this secret once during Blueprint creation (never stored in Git)
- key: RENDER_API_KEY
sync: false
# Let Render generate a strong random secret
- key: SESSION_SECRET
generateValue: true
databases:
- name: amani-db
plan: basic-256mb
databaseName: amani
user: amani
region: oregon
postgresMajorVersion: "17"
envVarGroups:
- name: amani-shared
envVars:
- key: NODE_ENV
value: production
- key: TZ
value: Africa/Nairobi
Gotcha — sync overwrites, but never deletes. Dashboard edits to a Blueprint-managed resource are overwritten on the next sync if they conflict with the YAML, so make changes in
render.yaml, not the UI. Conversely, removing a resource from the file does not delete it — syncing never deletes existing resources, so you must delete them manually in the Dashboard. Also never manage one resource from two Blueprints, and list all fields when importing an existing resource (omitted fields fall back to defaults that likely differ from your current setup).
Environment Variables
# Required
RENDER_API_KEY=rnd_... # From dashboard.render.com → Settings → API Keys
# Your service variables (set via dashboard or API)
DATABASE_URL=postgresql://...
PORT=10000 # Render injects PORT automatically
Set environment variables via API:
curl -X PUT "https://api.render.com/v1/services/$SERVICE_ID/env-vars" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '[{"key":"MY_VAR","value":"my-value"}]'
Automation Workflows
Claude Code Slash Command: Service Health Check
.claude/commands/render-health.md:
Check the health of all Render services.
Use the Render MCP tool `list_services` to get all services and their status.
For any service that is NOT "live", use `get_logs` to fetch recent logs and diagnose the issue.
Provide a summary table of service name, status, and any detected errors.
Usage: /project:render-health
GitHub Actions: Deploy after Tests Pass
# .github/workflows/render-deploy.yml
name: Deploy to Render
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22' }
- run: npm ci && npm test
deploy:
needs: test
runs-on: ubuntu-latest
steps:
- name: Trigger Render deploy
env:
RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }}
SERVICE_ID: ${{ secrets.RENDER_SERVICE_ID }}
run: |
curl -X POST "https://api.render.com/v1/services/$SERVICE_ID/deploys" \
-H "Authorization: Bearer $RENDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"clearCache":"do_not_clear"}'
- name: Wait for deploy and check status
env:
RENDER_API_KEY: ${{ secrets.RENDER_API_KEY }}
SERVICE_ID: ${{ secrets.RENDER_SERVICE_ID }}
run: |
for i in {1..20}; do
status=$(curl -s "https://api.render.com/v1/services/$SERVICE_ID/deploys?limit=1" \
-H "Authorization: Bearer $RENDER_API_KEY" | jq -r '.[0].deploy.status')
echo "Status: $status"
if [ "$status" = "live" ]; then echo "Deploy succeeded!"; exit 0; fi
if [ "$status" = "deactivated" ]; then echo "Deploy failed!"; exit 1; fi
sleep 15
done
echo "Timeout waiting for deploy"; exit 1
Common Use Cases
| Use Case | Approach |
|---|---|
| Inspect failing service | MCP logs + metrics tools |
| Query production DB | MCP read-only SQL query on a Postgres database |
| Create new service | MCP create (web / static / cron / Postgres / Key Value) or REST API POST |
| Create a worker / private service | REST API POST or render.yaml (not supported by MCP) |
| Deploy on merge | GitHub Actions + REST API deploys endpoint, or MCP trigger-deploy |
| Env var management | MCP update-env-vars or REST API PUT |
| Monitor resource usage | MCP metrics tools |
Troubleshooting
| Issue | Fix |
|---|---|
| Service stuck in "building" | Check get_logs for build errors |
| Port connection refused | Ensure app listens on process.env.PORT |
| 503 on requests | Service may be suspended (free tier) |
| Deploy not triggering | Render auto-deploys on git push — check webhook in dashboard |
| API key invalid | Generate a new key in dashboard → Settings → API Keys |
| Database connection failed | Check DATABASE_URL env var; allow external connections in DB settings |
Official docs: