About Renovate
Renovate is an MCP server in the Content category: mCP server for designing Renovate configurations interactively.
Install
claude mcp add renovate -- npx -y renovate-mcpnpx -y renovate-mcpThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Renovate
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
renovate-mcp
An MCP server for designing Renovate configurations interactively. Point it at a local repo and let an LLM help you read, validate, preview, and save renovate.json.
Contents
- What it does
- What this is NOT
- Requirements
- Install
- Platform setup
- Example prompts
- Example session
- Development
- Release flow
- Design notes
What it does
Eleven tools plus a preset reference:
| Tool | Purpose |
|---|---|
check_setup |
Report Renovate CLI + validator availability, versions, and install hints. Also surfaces a platformContext block (RENOVATE_PLATFORM / RENOVATE_ENDPOINT values, token-presence booleans, the platform dry_run would pick when its input is unset, and notes about likely misconfigurations) so callers can verify env before invoking dry_run. Token values are never echoed — only presence booleans. Also runs at startup. |
get_version |
Report the renovate-mcp server version and whether it's a released build (running from node_modules) or a local/dev build (typically launched via command: node against a checkout). |
read_config |
Locate and parse a repo's Renovate config (renovate.json, renovate.json5, .renovaterc*, package.json#renovate, …) in priority order. |
resolve_config |
Expand every extends preset offline. Opt in to fetching github> / gitlab> presets over HTTPS with externalPresets: true. |
explain_config |
Inverse of resolve_config: walk the same preset tree but annotate every leaf field with the chain of presets that touched it. Each leaf is { value, setBy } where setBy lists every contribution in merge order — last entry wins for scalars; for arrays each entry adds its own slice. Same offline-by-default behaviour and same externalPresets / endpoint / platform opt-ins as resolve_config. |
preview_custom_manager |
Preview a customManagers (regex) entry against a local repo — shows file/line hits and extracted dep info. Offline. |
validate_config |
Run renovate-config-validator against a file or inline object. |
lint_config |
Semantic lint for Renovate-specific footguns schema validation misses — malformed /…/ regex patterns plus unknown manager names in matchManagers / excludeManagers. Offline. |
dry_run |
Run Renovate with --dry-run and return the structured JSON report. Defaults to --platform=local against repoPath; pass platform + endpoint + token + repository to run as a real GitHub/GitLab client (needed when the config extends local> presets on a private host). When platform is not passed, the tool reads RENOVATE_PLATFORM from the MCP server's env before defaulting to local. When token is not passed, falls back to RENOVATE_TOKEN from MCP env, then to GITLAB_TOKEN (when platform=gitlab) or GITHUB_TOKEN (when platform=github) — auto-translated to RENOVATE_TOKEN for the spawned Renovate CLI, since Renovate itself only reads that one var. repository accepts GitHub-style owner/repo and GitLab nested-group paths like group/subgroup/project. endpoint/token also flow through in local mode so gitlab>… / github>… preset shortcuts can be redirected at a self-hosted host without setting up a full remote run. No PRs, no pushes. Emits MCP progress notifications during the run when the caller supplies a progressToken. |
dry_run_diff |
Semantic diff between two dry_run reports — added / removed / changed proposed updates plus a compact text rendering. Stateless; takes both reports as inputs. Useful when iterating on a config to see exactly what each tweak did. |
write_config |
Validate, then atomically write a config to disk. Refuses to save invalid configs unless force: true is paired with confirmForce: "YES_OVERRIDE_VALIDATION" — the literal sentinel makes accidental overrides under prompt-injected tool calls harder. |
renovate://presets (resource) |
Markdown index of all 1000+ built-in presets grouped by namespace. |
renovate://presets/{namespace} (resource template) |
Markdown listing for a single namespace (e.g. renovate://presets/config) — cheaper than the full index. |
renovate://preset/{name} (resource template) |
Expanded JSON body for one preset (e.g. renovate://preset/config:recommended). |
See Design notes for implementation details (timeouts, safety caps, auth scrubbing, merge semantics).
What this is NOT
- Not a Renovate replacement. This server doesn't open PRs, run scheduled updates, or execute in CI — it's a design-time companion for a local
renovate.json. Use the real Renovate for the actual dependency-update pipeline. resolve_configis preview-quality. Preset expansion runs against a committed snapshot, and template substitution implements only positional{{argN}}placeholders — non-positional tokens and Handlebars helpers are flagged inwarningsand pass through verbatim. For authoritative output, rundry_run.preview_custom_manageris a subset of Renovate's regex manager. It coverscustomType: "regex",matchStringsStrategyofany/combination/recursive, and{{groupName}}template substitution only — other custom types and full Handlebars (helpers, conditionals) are not implemented. Use it for fast regex iteration; confirm withdry_run.validate_config/dry_runaren't exercised in CI. CI deliberately doesn't install Renovate, so tools that shell out to it are only covered by unit/integration tests that don't require the binary. Run them locally against the Renovate install you intend to deploy with.
Requirements
Required
- Linux or macOS. Windows is not supported —
package.jsondeclares"os": ["darwin", "linux"], sonpm isurfaces anEBADPLATFORMwarning on Windows, and the server exits with a clear stderr message at startup. Run on WSL2 or a Linux/macOS host instead. - Node.js ≥ 24 (aligns with Renovate's own engine requirement).
- Renovate on your
PATH— either a global install (npm i -g renovate) or a project-local install that exposesrenovate+renovate-config-validatorvianpm exec. Only needed forvalidate_config,dry_run, andwrite_config; the offline tools (read_config,resolve_config,preview_custom_manager,lint_config) work without it.
Optional
RENOVATE_BIN/RENOVATE_CONFIG_VALIDATOR_BIN— override binary locations.RENOVATE_MCP_REQUIRE_CLI=false— suppress the startup "partial availability" notice when you only intend to use the offline tools.- Platform env vars —
RENOVATE_PLATFORM,RENOVATE_ENDPOINT, and a token (RENOVATE_TOKEN/GITHUB_TOKEN/GITLAB_TOKEN). Needed fordry_runagainst a remote platform and forresolve_configwithexternalPresets: true. See Platform setup for the matrix and a worked example. - Private-registry credentials for
dry_run— whatever Renovate itself would need at lookup time (COMPOSER_AUTH,NPM_TOKEN/.npmrc, Docker registry creds, or aRENOVATE_HOST_RULESJSON blob). Alternatively encode these ashostRulesin the Renovate config, or pass them per-call via thehostRulesinput ondry_run(no MCP restart needed). Per-callhostRulesare appended to whatever the repo's own config declares. Values reach Renovate as JSON through the tool-call transport, so the calling LLM sees them in its context — prefer the env route if that matters. Without any of these, Renovate's lookup often returns 0 updates silently;dry_runscans its logs for auth failures and surfaces them underproblems.
Note: all env vars (tokens,
COMPOSER_AUTH,RENOVATE_HOST_RULES, binary overrides, …) must be set on the MCP server process itself — via theenvkey inclaude_desktop_config.json/.mcp.json, not your shell — since the MCP server runs as a child of the client and does not inherit shell env.
Install
npx fetches the published package on demand — no manual install needed. For local development, clone and build first:
npm install
npm run build
Add the following mcpServers entry to your client's config file:
{
"mcpServers": {
"renovate": {
"command": "npx",
"args": ["-y", "renovate-mcp"]
}
}
}
For local development, swap to "command": "node" with "args": ["/absolute/path/to/renovate-mcp/dist/index.js"].
Claude Code
Config lives in .mcp.json (project-scoped) or ~/.claude.json (user-scoped).
Claude Desktop
Config lives in ~/Library/Application Support/Claude/claude_desktop_config.json.
Other MCP clients
Any client that can launch a stdio MCP server works — point it at the same command shown above.
Verify the wiring
Restart your client and prompt it:
List the namespaces available under
renovate://presets.
A response listing namespaces like config, docker, npm, helpers, … confirms the server is reachable and the resource is exposed. If the client reports the tool or resource as unavailable, re-check the config file path and command.
Platform setup
The four common configurations differ in three settings: RENOVATE_PLATFORM, RENOVATE_ENDPOINT, and which token env var you set. Pick the row that matches your environment and put the values in your client's mcpServers.renovate.env block.
| Setup | RENOVATE_PLATFORM |
RENOVATE_ENDPOINT |
Token env var |
|---|---|---|---|
| github.com | github |
(omit — defaults to https://api.github.com) |
RENOVATE_TOKEN or GITHUB_TOKEN |
| GitHub Enterprise | github |
https://github.example.com/api/v3/ |
RENOVATE_TOKEN or GITHUB_TOKEN |
| gitlab.com | gitlab |
(omit — defaults to https://gitlab.com/api/v4) |
RENOVATE_TOKEN or GITLAB_TOKEN |
| Self-hosted GitLab | gitlab |
https://gitlab.example.com/api/v4/ |
RENOVATE_TOKEN or GITLAB_TOKEN |
Notes that apply to every row:
- All env vars must be on the MCP server process — set them via the
envkey in.mcp.json/claude_desktop_config.json, not your shell, since the MCP server runs as a child of the client and does not inherit shell env. RENOVATE_TOKENwins when both it and the platform-specific var are set.dry_runandresolve_confighonour the same precedence; fordry_runthe platform-specific var is auto-translated toRENOVATE_TOKENfor the spawned Renovate CLI (Renovate itself only reads that one var).- For repository identifiers, GitLab accepts nested-group paths like
group/subgroup/project, not justgroup/project. - If you only intend to use the offline tools (
read_config,resolve_configwithoutexternalPresets,preview_custom_manager,lint_config), you can skip all of the above.
Worked example — self-hosted GitLab
{
"mcpServers": {
"renovate": {
"command": "npx",
"args": ["-y", "renovate-mcp"],
"env": {
"RENOVATE_PLATFORM": "gitlab",
"RENOVATE_ENDPOINT": "https://gitlab.example.com/api/v4/",
"GITLAB_TOKEN": "<your token>"
}
}
}
}
This is enough for both dry_run (remote-platform runs) and resolve_config (private preset fetches). With this set, dry_run against group/subgroup/project works without passing platform / endpoint / token per call: RENOVATE_PLATFORM and the auto-translated GITLAB_TOKEN cover the platform side, and RENOVATE_ENDPOINT is inherited naturally by the spawned Renovate CLI. For resolve_config, platform and endpoint are tool inputs (not env vars) — pass them when you need local> presets routed through your host, since resolve_config is in-process and doesn't read RENOVATE_* env vars itself.
local> presets
A config that extends local>owner/repo:preset only resolves when there's a platform context to expand it against:
- For
dry_run— passplatform+endpoint+repository(token falls back to env). UsedryRunMode=extractif you only need manifest extraction; the preset preflight is skipped in that mode. - For
resolve_config— passplatform+endpointas inputs and the tool rewriteslocal>into<platform>>and fetches over HTTPS. Without these inputs,local>stays inpresetsUnresolvedwith a pointer to the workaround. Rundry_runafterwards for full-fidelity merging.
Example prompts
Once the server is wired up, try prompts like these. They're written for Claude but work with any MCP-capable client.
Understanding an existing config
- "Read the Renovate config in this repo and summarize what it actually does — expand every preset so I can see the real effective behavior."
- "Resolve my config and list anything that landed in
presetsUnresolved, with the reason for each." - "Why is my
prCreationset tonot-pending? Useexplain_configto trace which preset set it."
Browsing presets
- "List the presets in the
confignamespace." (uses therenovate://presets/configsub-resource — cheaper than pulling the whole index) - "What does
config:recommendedactually enable? Show me its expanded JSON." - "Find a built-in preset that pins GitHub Actions digests."
Self-hosted GitLab / GitHub Enterprise (env set per Platform setup)
- "Resolve my config with external presets enabled, fetching
gitlab>platform/renovate-presetsfrom our self-hosted GitLab athttps://gitlab.example.com/api/v4. Routelocal>presets through the same host." - "Expand
github>acme/renovate-config//basefrom our GitHub Enterprise athttps://github.acme.corp/api/v3." - "Dry-run
infrastructure/kubernetes/our-platform(a nested-group GitLab project) so Renovate can fetch thelocal>presets the config extends."
Authoring a custom manager (regex)
- "I have
# renovate: datasource=docker depName=...comments above image tags in my Dockerfiles. Draft acustomManagersregex entry and preview it against this repo so I can see what it extracts." - "Here's a
customManagersentry — preview it and tell me which files match, which lines hit eachmatchStringsregex, and what dep info gets extracted."
Validating, previewing, saving
- "Validate this proposed config against Renovate's schema without writing it anywhere."
- "Do a dry run and show me which PRs Renovate would open — no pushes."
- "Add
:semanticCommitsto myextends, validate it, and save back torenovate.json."
Example session
A transcript-style walkthrough: design a Dockerfile custom manager from scratch, validate it, dry-run, and save. Turns are abbreviated — your client will show the actual tool-call JSON.
You: I've got
# renovate: datasource=docker depName=<image>comments aboveFROMlines in my Dockerfiles. Draft acustomManagersentry and preview it against this repo.Claude calls
preview_custom_managerwith a first-draftfileMatch+matchStrings. → 4 Dockerfiles matchedfileMatch, 0 lines matchedmatchStrings. The regex anchored onARG, but the Dockerfiles useFROM.You: Rewrite
matchStringsto anchor on the renovate comment, thenFROM <image>:<version>on the next line.Claude calls
preview_custom_manageragain with the fixed regex. → 4 files, 4 line hits. Extracted:postgres:15.3-alpine,redis:7.2,nginx:1.25,node:20.11. Named groupsdepNameandcurrentValuepopulated on every hit.You: Good. Validate the full config inline, with this
customManagersentry alongside my existingextends.Claude calls
validate_configwith the inline config. → valid.You: Now dry-run so I can see what Renovate would actually open.
Claude calls
dry_run. → 2 updates:postgres15.3-alpine → 15.5-alpine,redis7.2 → 7.4. No entries inproblems.You: Save it.
Claude calls
write_configonrenovate.json. → validated, written atomically.
Development
npm run dev # build watch mode
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
npm start # run the built server over stdio
npm test # vitest run (builds first)
npm run test:watch # vitest watch mode
npm run test:coverage # vitest run --coverage (writes coverage/ report)
npm run generate:presets # regenerate src/data/presets.generated.ts from the renovate devDep
npm run generate:managers # regenerate src/data/managers.generated.ts from the renovate devDep
The preset catalogue at src/data/presets.generated.ts and the manager-name list at src/data/managers.generated.ts are committed snapshots of Renovate's built-in presets and manager registry. Runtime code never imports the renovate package — only the scripts/generate-*.mjs scripts do. Regenerate both after bumping the renovate devDependency.
CI runs typecheck, build, and test:coverage on Node 24 for every PR and push to main (see .github/workflows/ci.yml), across an OS matrix of ubuntu-latest and macos-latest with fail-fast: false so a platform-specific regression on either side surfaces. Coverage is uploaded as a per-run artifact from the Ubuntu job only (to avoid name collisions); no threshold is enforced yet. The Ubuntu job also re-runs npm install --package-lock-only and fails on a non-empty diff, catching drift between package.json root metadata (os, engines, bin, dep ranges) and package-lock.json that npm ci does not validate.
.github/workflows/dependency-review.yml runs actions/dependency-review-action on every PR and fails the check when a newly introduced dependency carries a CVE of high severity or above. Findings also render inline in the PR's "Files changed" / Conversation tabs.
.github/workflows/claude.yml is maintainer tooling: it lets the repo owner trigger anthropics/claude-code-action by mentioning @claude in an issue, issue comment, PR review, or PR review comment. It's gated on sender.login == repository_owner, so mentions from anyone else are ignored. The workflow needs the CLAUDE_CODE_OAUTH_TOKEN secret on the repo; outside contributors and forks do not need any Anthropic credentials to work on this project.
Release flow
Releases are automated via release-please (see .github/workflows/release.yaml):
- Merge Conventional Commits to
main(feat:,fix:, etc.) - release-please opens or updates a release PR that bumps the version and updates
CHANGELOG.md - Merging the release PR creates a GitHub release and tag
- The
publishworkflow (.github/workflows/publish.yml) fires on the release event, runs the test suite, smoke-tests the packed tarball end-to-end (install globally, then run an MCPinitializehandshake against the resultingrenovate-mcpbinary), and only then runsnpm publishwith provenance
Publishing uses npm Trusted Publishers — no npm token is stored in the repo. Instead the workflow authenticates to npm via OIDC using the id-token: write permission. Trusted Publishers must be configured on the npm package settings page before OIDC publishes will succeed; this requires the package to already exist, so the first release must be published manually once (npm login && npm publish from a clean build), after which Trusted Publishers can be wired up and all subsequent releases go through this workflow.
Secrets required on the repo: RELEASE_PLEASE_TOKEN (a PAT for release-please). No npm token is needed.
Design notes
Scope and non-goals are summarized in What this is NOT; this section covers implementation decisions behind the scope that is supported.
validate_config,dry_run, andwrite_configshell out to the Renovate CLI rather than importing Renovate as a library — this decouples our Node version from Renovate's (currently Node 24).resolve_config,preview_custom_manager, andlint_configare fully in-process and never invoke the Renovate CLI, so they work without a Renovate install.lint_configis a semantic lint pass that sits alongsidevalidate_configrather than replacing it: schema validation catches structural bugs, the linter catches Renovate-specific footguns that schema validation declares valid — most commonly a pattern like"matchPackageNames": ["/devops\\/pipelines\\/.+"]where a trailing/is missing and Renovate silently degrades the value to an exact-string match that never hits, or a typo like"matchManagers": ["npmm"]that silently applies the rule to zero packages. The ruleset is intentionally small (three rules:dead-regex-missing-slash,unwrapped-regex,matchManagers-unknown-name), scoped to the four regex-aware fields plusmatchManagers/excludeManagers, and tuned to avoid false positives on benign exact strings containing a.. The valid-manager list is snapshotted from therenovatedevDep atsrc/data/managers.generated.ts(regenerate withnpm run generate:managers), and unknown names get a Damerau-Levenshtein "did you mean?" suggestion when something close enough exists. Rule IDs are stable so findings can be suppressed by callers.preview_custom_managerhonors.gitignore(including nested.gitignores and.git/info/exclude) when walking the repo, so generated/vendored directories likedist/,.next/,target/,__pycache__/don't crowd out real hits against themaxFilesWalkedcap.node_modules/and.git/are always skipped as a safety net even when no.gitignoreis present.preview_custom_managerexposes two separate safety caps so the warning text can name which one tripped:maxFilesWalked(default 2000) bounds the directory walk before anyfileMatchtesting, andmaxFilesMatched(default 500) bounds the result set afterfileMatchis applied. Previously a singlemaxFilesScannedconflated the two, leaving the user unable to tell whether to narrowfileMatchor widen the walk.preview_custom_managerruns every user-supplied regex on aworker_threadsworker with a wall-clock budget per operation (default 2 s, configurable viamatchTimeoutMs). Catastrophic backtracking — e.g.^(a+)+b$againstaaaa…c, or(.*)*=against a modestly sized file — would otherwise pin the MCP server's event loop indefinitely. On timeout the worker is terminated and a warning is appended identifying whichfileMatch[i]ormatchStrings[i]was aborted, so the user can simplify the pattern or raise the budget.preview_custom_manageralso stats each matched file before reading it and skips anything larger thanmaxFileBytes(default 5 MiB) with a warning, so a stray lockfile, generated artifact, or SQL dump caught by a loosefileMatchcan't OOM the server.maxHitsPerFilealready bounds output size; this guards input size.resolve_configexpandsextendsagainst a committed snapshot of Renovate's built-in presets (src/data/presets.generated.ts). Externalgithub>/gitlab>fetching is opt-in, uses each platform's contents API with a 10 s timeout, and caches results per call. Theendpointinput swaps in a custom API base for GHE / self-hosted GitLab;platformadditionally rewriteslocal>presets to be fetched against that endpoint.- External preset fetches refuse to follow HTTP redirects (
redirect: "manual") and never attachAuthorization: Bearer …/PRIVATE-TOKEN: …headers to non-https://URLs. Following redirects with custom auth headers can leakRENOVATE_TOKEN/GITHUB_TOKEN/GITLAB_TOKENcross-host (undici only strips the standardAuthorizationheader on cross-origin redirects, notPRIVATE-TOKEN); rejecting them outright avoids the leak path and matches the fact that the GitHub/GitLab content APIs don't normally redirect for valid presets. - External preset fetches cap the response body at 1 MB. A
Content-Lengthover the cap is rejected up front; chunked responses without a declared length are streamed into a bounded buffer that aborts the read once the running total passes the cap. Auth-failure bodies (401/403) are read with an 8 KB cap so a misconfigured endpoint returning a giant HTML error page can't OOM the long-lived MCP process. Preset bodies are tiny in practice, so the cap is well above any legitimate value. - The
endpointinput onresolve_config/explain_config/dry_runis validated before any token-bearing request is built or forwarded to the Renovate child as--endpoint=. Anything that isn't anhttps://URL with a non-empty public host is refused: non-https schemes (http:,file:,data:, …), userinfo (user:pass@host), and any RFC 1918 / loopback / link-local literal (localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16(incl. cloud-metadata),0.0.0.0/8,::1,::,::ffff:*,fc00::/7,fe80::/10). Self-hosted GitHub Enterprise / GitLab on public-DNS https URLs is unaffected. The check is string-level (no DNS) — the goal is to make a prompt-injectedendpointvalue unable to coerce a token-bearing request to an attacker-controlled or internal-only address. resolve_configmerges preset bodies with a close approximation of Renovate's ownmergeChildConfig— arrays concat, objects recursively merge, scalars overwrite — not a bit-identical port. Rule-specific semantics forhostRules,regexManagers/customManagers, and certain boolean flags aren't modeled here. Every response carriesmergeQuality: "preview"plus a human-readabledisclaimerso callers can't miss the limitation; rundry_runfor authoritative output.- When
resolve_configencounters template tokens outside its supported subset, it records a structured entry inwarnings: under-argument cases ({{arg2}}referenced when only one arg was passed) substitute an empty string, while non-positional tokens ({{packageRules}}, Handlebars helpers like{{#if …}}) pass through verbatim. explain_configreuses the same expansion machinery asresolve_config(parsePreset,loadPresetBody,applyArgs,recordTemplateWarnings) so the two can't drift — ifresolve_configresolves a preset,explain_configdoes too. The annotated layer threads each preset body's leaves through a parallelmergeAnnotatedthat preserves contributors instead of dropping them, then pins each contribution with the source name (literalextendsentry, or<own>for the user's input config) and aviachain naming every parent preset traversed to reach it. Arrays accumulate every contribution insetByand concat theirvalues; scalars list every contribution in merge order with the last as the winner.merge_quality: "preview"carries the same disclaimer asresolve_config— Renovate's rule-specific semantics forhostRules,regexManagers, and certain boolean flags aren't modelled.dry_runuses--report-type=fileso we get a structured JSON report instead of scraping stdout. The report path is pre-created with mode 0600 before Renovate is spawned (Renovate overwrites in place withO_TRUNC, preserving the mode), so the on-disk JSON is never world-readable while the run is in flight — Renovate'sproblemsarray can carry host-rule values that we don't want exposed under the defaultumask. The file is unlinked in afinallyblock. When ahostRulesinput is passed it's written to a mode-0600 temp file inos.tmpdir(), handed to Renovate via theRENOVATE_CONFIG_FILEenv var (the CLI has no--config-fileflag), and deleted in afinallyblock. Token/password values — including the platformtokeninput — are scrubbed from the detectedproblemslist and thelogTailfallback before returning.dry_rundefaults to--platform=localso no host token is required, but that mode can't resolvelocal>presets (they have no platform context to expand against) and silently hides non-default-host GitHub/GitLab setups. When the caller doesn't pass aplatforminput, the tool first falls back toRENOVATE_PLATFORMfrom the MCP server's env (if it's one oflocal/github/gitlab) before defaulting tolocal— without that fallback, the wrapper would unconditionally pass--platform=localand silently override an env var the user had set in theirmcp.json. Passingplatform+endpoint+token+repository(or relying on theRENOVATE_PLATFORM/RENOVATE_ENDPOINTenv vars) switches the run to a real platform client so the preset-fetch path works end-to-end;--dry-runis still set, so no PRs are opened. The repository is passed to Renovate as a positional argument because the CLI has no--repositoryflag.endpointandtokenare also forwarded in the defaultplatform=localmode sogitlab>…/github>…preset shortcuts (which are otherwise hardcoded to gitlab.com/github.com) can be redirected at a self-hosted host. As a guard against the silent-failure mode,dry_runpreflight-checks the repo's config: if it extends anylocal>…preset while the effective platform islocal, the tool fails fast with specific remediation rather than spawning a Renovate run that would opaquely reportconfig-validation. The preflight is skipped fordryRunMode=extractso manifest-only extraction can still be attempted.dry_runreturns a top-levelokboolean that isfalsewhenever the CLI exited non-zero OR the structured report contains a validation/error-level problem (level >= 40,message === "config-validation", or a non-emptyvalidationErrorfield). Renovate frequently writes exit-code 0 alongside report-level failures — trusting the exit code alone hides runs that did nothing.dry_runemits MCP progress notifications only when the caller'stools/callincludes_meta.progressToken— no-op otherwise, so legacy clients see zero overhead. A 5-second heartbeat ticks while the child runs; each tick's message is best-effort enriched with the latest Renovate JSON-logmsgseen on stdout. Notifications are also emitted at start and completion. We deliberately don't couple to Renovate's log schema beyond readingmsg, since that schema isn't a stable API.dry_run_diffis stateless on purpose: both reports are passed as inputs, no per-repo state is kept on the server. Updates are keyed by(manager, packageFile, depName)so a version bump on the same dep shows up once underchangedrather than twice asremoved + added. Compared per identity:newValue,newVersion,updateType,branchName,groupName,schedule. Either input can be the raw Renovate report or the fulldry_runsummary (with thereportkey) — the tool unwrapsreportautomatically.write_configwrites to a temp file, validates, then atomically renames — so a failed validation never leaves a broken config on disk. Theforce: trueescape hatch is gated behind a separateconfirmForce: "YES_OVERRIDE_VALIDATION"literal: a single boolean is too easy for a prompt-injected agent to flip, but emitting an unusual sentinel string is a deliberate step that's harder to navigate accidentally.check_setupand the shell-out tools (validate_config,write_config,dry_run) detect Renovate runtime conditions that degrade the tool silently — currently the bundledre2native module failing to load (typically after a Node major-version upgrade leaves a prebuiltre2.nodecompiled against the old ABI). When the WARN appears in Renovate's stderr, the tool response carries awarnings: [{ kind: "re2-unusable", … }]entry alongside its normal output andcheck_setupaggregates the same warning intoSetupStatus.warningsplus the startupinstructionsbanner. Renovate keeps running on JavaScriptRegExpso calls don't fail, but regex-heavy operations (custom managers, validation, lookups) are noticeably slower; the fix hint iscd $(npm root -g)/renovate && npm rebuild re2(or reinstall Renovate). This is passive detection only — the server doesn't rebuild anything itself.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.