Render Useful MCP
Control completo de Render.com para agentes de IA: despliegues, escalado, bases de datos, registros, discos. Los 207 endpoints de la API, generados desde la especificación OpenAPI de Render.
Documentación
render-useful-mcp
Un servidor de Protocolo de Contexto de Modelo (MCP) para Render que expone cada endpoint de la API Pública oficial de Render, además de un puñado de herramientas de nivel superior para los flujos de trabajo que la API cruda hace tediosos.
Escrito en TypeScript. Cada herramienta de API se genera a partir del documento OpenAPI propio de Render, por lo que la cobertura es completa por construcción y se mantiene así.
213 herramientas: las 208 operaciones de la API Pública de Render (versión de especificación 1.0.0), más 5 herramientas de flujo de trabajo para las secuencias que la API cruda hace tediosas.
📖 Sitio de documentación · catálogo de herramientas · llms.txt
Por qué este
La mayoría de los envoltorios de API se detienen en un subconjunto curado de endpoints, que se desactualiza y te deja atascado en el momento en que necesitas algo que el autor omitió.
- Completo, por construcción. Cada operación en el documento OpenAPI propio de Render se convierte en una herramienta. Todo lo que la API permite hacer a tu clave es alcanzable de fábrica, sin necesidad de optar por ello.
- Utilizable por un modelo. Los nombres se resuelven a ids de forma difusa, tu id de espacio de trabajo se completa automáticamente, se puede esperar a los despliegues en una sola llamada, y los fallos vuelven con una pista en lugar de un código de estado desnudo.
- Reducible cuando lo quieras. Cada conjunto de herramientas está activado por defecto;
RENDER_MCP_TOOLSETSyRENDER_MCP_READ_ONLYexisten para restringir la superficie deliberadamente, no para limitarla. - Honesto sobre el riesgo. Las anotaciones destructivas/solo lectura/idempotentes de MCP se derivan de semánticas HTTP reales, para que los clientes puedan tomar decisiones sensatas de aprobación automática, incluidos los
PUTque reemplazan una colección completa, donde todo lo que el llamador omite se elimina. Los secretos se redactan de los registros.
Instalación
Ambos botones rellenan la configuración con una clave de API de marcador de posición: reemplázala después de la instalación.
Claude Code — instálalo globalmente, para que esté ahí en cada proyecto:
claude mcp add render --scope user -e RENDER_API_KEY=rnd_your_key -- npx -y render-useful-mcp
--scope user es la parte que importa. Claude Code usa por defecto el ámbito local, que
registra el servidor solo para el directorio actual, por lo que funciona donde lo instalaste y
falta en todos los demás lugares, que es la razón habitual por la que un servidor recién añadido parece
desaparecer. Los tres ámbitos son:
| Ámbito | Indicador | Dónde vive | Disponible en |
|---|---|---|---|
| Usuario (global) | --scope user | tu configuración de usuario | cada proyecto, cada directorio |
| Proyecto | --scope project | .mcp.json, confirmado | cualquiera que haga checkout del repositorio |
| Local | ninguno (predeterminado) | estado de usuario por directorio | el directorio desde el que se añadió |
Confirma con claude mcp list, y vuelve a ejecutar el comando con --scope user si render no
aparece listado desde un directorio no relacionado.
Claude Code, como plugin — esto conecta el servidor y sus documentos en un solo paso, y los plugins se instalan globalmente por naturaleza:
/plugin marketplace add LuSrodri/render-useful-mcp
/plugin install render-useful-mcp@lusrodri-render
Exporta RENDER_API_KEY en el shell que lanza Claude Code; el plugin lo lee del
entorno en lugar de almacenarlo. Consulta plugin/README.md.
Claude para macOS y Windows, como extensión de escritorio — descarga el paquete .mcpb de
la última versión y ábrelo.
Claude lo instala y pide la clave de API en un formulario, por lo que no se configura nada a mano.
El paquete incluye sus propias dependencias; no necesita npm ni una instalación global de Node.
Las instalaciones de escritorio usan por defecto los conjuntos de herramientas services, logs y env-groups en lugar del
catálogo completo, porque cada definición de herramienta cuesta contexto en cada conversación. Establece
el campo Conjuntos de herramientas a all, o a cualquier lista separada por comas, para cambiarlo.
Requiere Node.js ≥ 20.11 para cada ruta de instalación excepto la extensión de escritorio.
npm install -g render-useful-mcp
O ejecútalo sin instalarlo, que es lo que hace la mayoría de las configuraciones de clientes MCP:
npx -y render-useful-mcp
También está listado en el Registro MCP como
io.github.LuSrodri/render-useful-mcp, por lo que los clientes que navegan por el registro pueden encontrarlo y
configurarlo sin que se les indique el paquete npm manualmente.
Configura tu cliente MCP
Obtén una clave de API desde Panel de Render → Configuración de la cuenta → Claves de API.
Claude Code — globalmente, como arriba:
claude mcp add render --scope user -e RENDER_API_KEY=rnd_your_key -- npx -y render-useful-mcp
Añade RENDER_WORKSPACE_ID de la misma manera si lo conoces:
claude mcp add render --scope user \
-e RENDER_API_KEY=rnd_your_key \
-e RENDER_WORKSPACE_ID=tea_your_workspace_id \
-- npx -y render-useful-mcp
Claude Desktop / cualquier cliente que use mcpServers — añade al archivo de configuración:
{
"mcpServers": {
"render": {
"command": "npx",
"args": ["-y", "render-useful-mcp"],
"env": {
"RENDER_API_KEY": "rnd_your_key_here",
"RENDER_WORKSPACE_ID": "tea_your_workspace_id"
}
}
}
}
RENDER_WORKSPACE_ID es opcional pero recomendado: muchos endpoints de Render requieren un ownerId que el modelo no tiene forma de adivinar, y establecerlo elimina una búsqueda de casi todas las sesiones. Encuéntralo con la herramienta render_list_owners, o léelo desde la URL de tu panel.
Configuración
| Variable | Predeterminado | Descripción |
|---|---|---|
RENDER_API_KEY | — | Requerida. Tu clave de API de Render. |
RENDER_WORKSPACE_ID | — | Id de espacio de trabajo aplicado dondequiera que se necesite un ownerId y no se haya dado ninguno. |
RENDER_MCP_TOOLSETS | all | Reduce la superficie a una lista separada por comas de conjuntos de herramientas. |
RENDER_MCP_READ_ONLY | false | Cuando es verdadero, solo se exponen herramientas no mutantes (GET) en absoluto. |
RENDER_MCP_DYNAMIC_TOOLSETS | true | Registra render_toolsets, que informa los conjuntos de herramientas y su estado. |
RENDER_MCP_TIMEOUT_MS | 60000 | Tiempo de espera por solicitud. |
RENDER_MCP_MAX_RETRIES | 3 | Reintentos para límites de velocidad y errores transitorios del servidor. |
RENDER_MCP_MAX_RESPONSE_BYTES | 400000 | Los resultados de herramientas más grandes que esto se truncan con una nota. |
RENDER_MCP_LOG_LEVEL | info | debug, info, warn, error, silent. Los registros van a stderr. |
RENDER_API_BASE_URL | https://api.render.com/v1 | Anulación para proxies o pruebas. |
Conjuntos de herramientas
Los 17 conjuntos de herramientas están habilitados por defecto
— el servidor expone todo lo que tu clave de API puede alcanzar. Los conjuntos de herramientas son una forma de _reducir_ la superficie a propósito, no una puerta que tengas que desbloquear.| Conjunto de herramientas | Herramientas | Cubre |
|---|---|---|
services | 43 | Servicios, despliegues, dominios personalizados, trabajos únicos, ejecuciones de cron y eventos |
metrics | 23 | Métricas de CPU, memoria, ancho de banda, HTTP, disco y conexiones, más flujos de métricas |
postgres | 21 | Instancias de Postgres, usuarios, exportaciones, recuperación e información de consultas |
workflows | 15 | Flujos de trabajo de Render y tareas de flujo de trabajo |
env-groups | 13 | Grupos de entorno, sus variables y archivos secretos |
projects | 12 | Proyectos y entornos |
webhooks | 11 | Webhooks y configuraciones/anulaciones de notificaciones |
logs | 10 | Consultas de registros, descubrimiento de etiquetas y configuración de flujos de registros |
static-sites | 9 | Reglas de encabezado y rutas de redirección/reescritura para sitios estáticos |
deprecated | 8 | Endpoints de Redis heredados que Render ha reemplazado por la API de Key Value |
key-value | 8 | Instancias de Key Value (compatible con Redis) e información de conexión |
workspaces | 8 | Espacios de trabajo, miembros, el usuario autenticado y registros de auditoría |
disks | 7 | Discos persistentes y sus instantáneas |
blueprints | 6 | Blueprints y sincronizaciones de Blueprint |
network | 5 | Conjuntos de IP salientes dedicados |
registry | 5 | Credenciales de registro de contenedores |
maintenance | 4 | Ejecuciones de mantenimiento programadas |
Razones por las que podrías reducirlo de todos modos:
// A client that struggles with the full catalogue, or a session scoped to one job.
"env": { "RENDER_MCP_TOOLSETS": "services,logs,metrics" }
// An agent that should be able to look but not touch.
"env": { "RENDER_MCP_READ_ONLY": "true" }
Si lo reduces, el modelo aún puede llamar a render_toolsets para ver todo lo que existe y qué grupos están desactivados, para que pueda decirte exactamente qué cambiar. Ampliar la superficie significa editar RENDER_MCP_TOOLSETS y reiniciar el servidor: la revisión de protocolo 2026-07-28 requiere que el resultado de tools/list no varíe por conexión ni como efecto secundario de otra llamada, por lo que el conjunto habilitado se fija al inicio.
Herramientas
Herramientas de flujo de trabajo
Estas están siempre disponibles, en cualquier configuración de conjuntos de herramientas. Existen porque la secuencia cruda equivalente son varias llamadas que el modelo suele hacer mal al primer intento.
| Herramienta | Qué hace |
|---|---|
render_find_service | Resuelve un nombre de servicio — incluido uno parcial o aproximado — a un único servicio de Render, devolviendo su id más alternativas cercanas. |
render_recent_logs | Obtiene líneas de registro recientes para un servicio, resolviendo el nombre del servicio y el id del espacio de trabajo por ti. |
render_service_status | Triaje en una sola llamada para un servicio: su configuración, últimos despliegues, instancias en ejecución y los registros de nivel de error más recientes. |
render_toolsets | Lista cada conjunto de herramientas de Render con su número de herramientas y si está habilitado actualmente. |
render_wait_for_deploy | Sondea un despliegue hasta que alcanza un estado terminal (live, build_failed, update_failed, canceled, deactivated) o hasta que expira el tiempo de espera. |
Herramientas de API
Una por endpoint de Render, nombradas render_<operation_id> — render_list_services, render_create_deploy, render_update_postgres, y así sucesivamente. Cada una lleva el resumen, la descripción, la documentación de parámetros, los enums y las restricciones directamente de la especificación de Render. La lista completa está en la página del catálogo de herramientas.
Haciendo las herramientas utilizables por un modelo
Una herramienta generada solo es tan buena como lo que la especificación dice sobre ella, y la especificación de Render describe formas en lugar de uso. Tres cosas cierran esa brecha:
Las ramas de oneOf mantienen sus nombres y dicen cuál aplica. Desreferenciar un $ref normalmente descarta el nombre del esquema, lo que deja serviceDetails en render_create_service como cinco objetos anónimos estructuralmente similares sin nada que diga cuál va con cuál type. Cada rama ahora lleva su nombre de la especificación de Render como un title, por lo que cron_job → cronJobDetailsPOST y runtime: docker → dockerDetails son decisiones que un modelo realmente puede tomar.
Naming the branches makes the choice readable but not checkable, and Render's spec carries no discriminator: under oneOf's exactly-one rule, a branch that requires nothing — staticSiteDetailsPOST — accepts every payload, which leaves the other four unreachable. src/tools/schema-unions.ts rewrites those unions into if/then rules keyed on the property that selects them, so the mapping is part of the schema rather than advice in a description, and a wrong-branch field is rejected by name instead of as must match exactly one schema in oneOf. A build invariant fails the generator if any oneOf branch is left unreachable, and test/payloads.test.ts checks the property against real payloads for all 208 tools.
Fields no caller can fill are removed. Render's spec reuses response schemas inside request bodies in a couple of places, which drags in values the server generates: a cron job's Docker branch asks for a whole registryCredential object requiring the credential's id and the timestamp of its last change, where a web service takes a plain registryCredentialId. A field that can only be filled with invented values is worse than no field, so src/tools/schema-repairs.ts drops it and the usage note points at image.registryCredentialId, which is where Render actually takes the reference. The generator throws if an entry stops matching, so a fix upstream shows up as a build failure.
A few tools carry hand-written usage notes. src/tools/operation-hints.ts appends a Usage: paragraph to the operations models demonstrably get wrong — create-service gets complete worked examples, update-env-vars-for-service warns that it replaces the whole set, post-job says it is not how you create a cron job. Examples are data, not prose: every one is validated against its own tool schema by the test suite and rendered into the description from the same object, so a published example is one the server provably accepts. The generator throws if a hint names an operation Render has withdrawn, so the file cannot rot silently.
The server sends instructions. src/instructions.ts is delivered once at initialize: id prefixes, resolve-the-name-first, which workflow tool replaces which raw sequence, and the oneOf convention. Cross-tool advice belongs there rather than duplicated into every tool description that needs it.
Creating a cron job that runs a Docker image
The case that motivated all three. A cron job is a service, so:
// render_create_service
{
"type": "cron_job",
"name": "nightly-report",
"ownerId": "tea-…",
"repo": "https://github.com/acme/reports",
"branch": "main",
"serviceDetails": {
// the cronJobDetailsPOST branch
"runtime": "docker",
"schedule": "0 3 * * *", // five-field cron, UTC, required for cron jobs
"plan": "starter",
"region": "oregon",
"envSpecificDetails": {
// the dockerDetails branch, because runtime is docker
"dockerfilePath": "./Dockerfile",
"dockerContext": ".",
"dockerCommand": "python report.py",
},
},
}
For a prebuilt image instead of a build, drop repo/branch, set image to {"ownerId": "tea-…", "imagePath": "docker.io/acme/reports:latest"}, use "runtime": "image", and give envSpecificDetails only the dockerCommand. Change the schedule later with render_update_service; trigger an off-schedule run with render_run_cron_job. render_create_job is a different thing — a one-off command on an existing service.
Design notes
Generated, not hand-written. scripts/generate-operations.ts reads spec/render-openapi.json and emits the tool catalogue. It is strict: an unmapped tag, a name collision, a cyclic $ref, a path parameter missing from its template, or a body property that would shadow a query parameter all fail the build rather than producing a subtly wrong tool. Updating to a new Render API version is: drop in the new spec, run npm run generate, review the diff.
Schemas reach the client intact. Render's spec uses the full range of JSON Schema. Tool schemas are fully dereferenced and passed through, and Ajv validates arguments against them — so enums, patterns, formats and oneOf are all actually enforced. This is why the server uses the SDK's low-level Server rather than McpServer, which accepts only Zod schemas. The one deliberate rewrite is the undiscriminated unions described above: left as the spec writes them, they cannot be satisfied at all.
Bodies are flattened. Request-body properties become top-level tool arguments, which keeps call sites shallow and improves tool-call accuracy. The generator proves at build time that body properties never collide with path or query parameters. The six array- and oneOf-valued bodies keep their structure under a single body argument.
Errors are made actionable. A failure returns the HTTP status, Render's own message and a hint aimed at the actual cause — a 404 suggests confirming the id with a list call, a 401 points at the API key page. A tool that is registered but hidden says which toolset to enable rather than "unknown tool".
Retries are conservative. Rate limits and transient 5xx are retried with decorrelated-jitter backoff, honouring Retry-After. Non-idempotent methods are never replayed on a server error: a retried POST /deploys would deploy twice.
Secrets stay out of logs. Logging is structured JSON on stderr — stdout is the transport — with connection strings, API keys and tokens redacted.
Development
npm install
npm run generate # rebuild the tool catalogue from the OpenAPI spec
npm run docs # re-render every doc that quotes the catalogue
npm run build
npm test
npm run check # generate + docs + lint + typecheck + test
Documentation is generated too
Tool counts, the toolset table, the workflow-tool list, the whole
docs site, llms.txt and llms-full.txt
are all rendered from src/generated/operations.json by scripts/generate-docs.ts. Regions
between <!-- generated:key --> markers in this file and plugin/README.md are rewritten in
place; the site's files are written whole.
npm run docs:check re-renders everything and fails if it differs from what is committed.
CI runs it on every pull request, the Pages workflow runs it before deploying, and the spec
sync runs npm run docs so an API change and the prose describing it arrive in one
reviewable pull request. Numbers in the docs cannot silently drift from the catalogue —
which they had, before this existed.
The test suite covers catalogue invariants (all 208 operations, no dangling $ref, path params required, annotations match HTTP semantics), request mapping, retry and pagination behaviour, the composite tools, and a full in-memory MCP client/server round trip.
Building the desktop extension
npm run build:mcpb # -> build/render-useful-mcp-<version>.mcpb
This stages dist/ plus the production dependency tree into build/mcpb/ and packs it.
The bundle is self-contained by design — Claude runs it with no install step — so the
dependencies are copied out of this repository's node_modules rather than reinstalled,
which is what guarantees the artefact contains the tree the test suite actually ran on.
manifest.json at the repository root is the extension's manifest; npm version keeps its
version in step with the package. To inspect a built bundle:
npx mcpb info build/render-useful-mcp-<version>.mcpb
npx mcpb unpack build/render-useful-mcp-<version>.mcpb /tmp/check
Updating to a new Render API version
This is automated. .github/workflows/spec-sync.yml runs daily, fetches Render's current
API description, regenerates the catalogue and the documentation, and opens a pull
request when the set of tools actually changes — with a summary of which tools were added,
removed or changed shape, and a warning when the change is breaking. Nothing merges
automatically.
Every run writes to its job summary, including the runs that find nothing, so "did it check today?" is answerable from the Actions tab rather than inferred from the absence of a pull request.
Two details of the schedule are deliberate, and both come from the job appearing dead while it was in fact working:
47 5 * * *, not0 6 * * 1. GitHub queues scheduled workflows best-effort and drops them under load; the top of the hour is the most contended slot there is. The one observed scheduled run started nearly four hours late. Daily, at an unremarkable minute, makes a dropped run cost a day rather than a fortnight — and a run that finds no catalogue change exits early, so the cost of daily is a few seconds of CI..github/spec-sync-heartbeat.json. GitHub disables scheduled workflows in repositories that go 60 days without activity, and a disabled workflow cannot re-enable itself. The workflow commits a timestamp to that file whenever the recorded one is more than 20 days old — roughly 18 commits a year, which keeps the clock well clear of the limit and leaves a visible record in the git log that the routine is alive.
To do it by hand, or to check right now:
npm run sync-spec # fetch the current spec into spec/render-openapi.json
npm run generate # rebuild the catalogue from it
git diff src/generated/operations.json
npm test
Render does not serve its OpenAPI document from a stable URL — the documented .json and
.yaml endpoints 404 — so scripts/fetch-spec.ts extracts it from the docs HTML. That is
fragile by nature, so it validates what it extracts (title, server, minimum operation
count) and fails loudly rather than overwriting a good spec with a truncated one. If Render
changes their docs platform, the sync workflow goes red instead of quietly reporting "no
changes" forever.
The generator refuses to emit a catalogue it cannot fully understand — an unmapped tag, a
name collision, a cyclic $ref, a path parameter missing from its template, or a body
property that would shadow a query parameter all fail the build. CI additionally asserts
that the committed catalogue matches what the spec produces, so a spec update without a
regenerate cannot merge.
Releasing
A release publishes to two places: the package to npm, and metadata describing it to the
MCP Registry. Both authenticate with the
workflow's GitHub OIDC token — npm via
Trusted Publishing, the registry via
mcp-publisher login github-oidc — so no npm token or registry secret is stored anywhere.
The npm publish carries a provenance attestation.
npm version patch # or minor / major
git push --follow-tags
Pushing a v* tag runs .github/workflows/publish.yml, which verifies the tag matches
package.json and that the generated catalogue and documentation are current, works out
which of the two targets still need this version, then lints, type-checks, tests, builds and
publishes. It also builds the .mcpb bundle and attaches it to the GitHub Release, which is
the only place the desktop extension is distributed from.
The documentation check is repeated here rather than left to CI because README.md ships
inside the npm tarball and a tag can be cut from any commit. npm versions are immutable, so
a package whose README contradicts the catalogue beside it cannot be taken back.
The order is fixed: npm first, then the registry. The registry proves you own the package
by fetching the published tarball and looking for mcpName in its package.json, so it
cannot accept a version npm has not served yet.
If a release fails for a reason outside the code, re-run it from the Actions tab via Run workflow, selecting the tag under Use workflow from. Each target is checked independently, so a retry after a half-finished release skips whatever already succeeded instead of failing on npm's immutable versions. The workflow rejects dispatches from a branch, so a published version always corresponds to a tag.
The registry manifest
server.json is the registry's copy of this server's metadata. Two of its fields are load
bearing and both are asserted by test/server-json.test.ts:
namemust beio.github.LuSrodri/.... The registry derives the namespace you may publish to from the OIDC token'srepository_ownerclaim and compares it case sensitively, so the lowercased spelling is rejected with a 403.mcpNameinpackage.jsonmust equal that same name. It is the ownership proof described above; without it the registry refuses the package.
The version fields track package.json — npm version keeps them in step via the version
lifecycle script, so mcp-publisher publish also works from a clean local checkout. CI
stamps them from the tag again before publishing, so the tag is what decides what ships.
Privacy
No telemetry, no analytics, no backend. The server runs on your machine and contacts exactly one host — Render's API. Your key is read from the environment, sent only to Render, never written to disk, and redacted from log output. Full detail, including how to verify each claim yourself: PRIVACY.md.
Licencia
MIT — ver LICENSE.
No afiliado con Render. spec/render-openapi.json es la descripción publicada de la API de Render, incluida para que las compilaciones sean reproducibles.