An MCP server for designing Renovate configurations interactively
Overview
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. Or add this entry manually to your client's mcpServers config: Restart your client and try the prompt: "List the namespaces available under renovate://presets." A response listing config, docker, npm, … confirms the server is reachable. Long-form install options are under Install below. - — locate the active renovate.json*, expand every extends preset offline, and trace which preset set each field. - — describe what you want ("automerge patches, group dev deps") and get ranked built-in (and your own local-repo) presets, plus a draft config skeleton when nothing fits. - before running Renovate — regex and JSONata, with Renovate's managerFilePatterns glob/regex file selection, file/line hits and extracted dep info.
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.
Quick start
Needs Node.js ≥ 24.11 on Linux or macOS. With Claude Code:
npm install -g renovate-mcp
claude mcp add renovate -s user -- renovate-mcp
claude mcp list # renovate should show as connected
Then try the prompt: “List the namespaces available under renovate://presets.” A response listing config, docker, npm, … confirms the server is reachable. No tokens are needed for the offline tools. Other clients, tokens and upgrades are under Install below.
What you can do
- Read and explain configs — locate the active
renovate.json*, expand everyextendspreset offline, and trace which preset set each field. - Discover presets from intent — describe what you want (“automerge patches, group dev deps”) and get ranked built-in (and your own local-repo) presets, plus a draft config skeleton when nothing fits.
- Preview custom managers before running Renovate — regex and JSONata, with Renovate’s
managerFilePatternsglob/regex file selection, file/line hits and extracted dep info. - Validate and lint — schema validation plus a semantic lint pass for Renovate-specific footguns (unwrapped regexes, unknown manager names, deprecated keys).
- Dry-run against a local checkout or a remote GitHub/GitLab — see exactly which PRs Renovate would open.
- Save back atomically — round-trip writes preserve comments and key order in existing JSON-with-comments files.
Tools & resources
Eighteen tools, seven resources, and four workflow prompts. Each tool name below links to its full reference in docs/tools.md.
| Tool | Purpose |
|---|---|
check_setup |
Report Renovate CLI + validator availability, versions, install hints, and a platformContext block for env diagnosis. Also runs at startup. Pass an optional repoPath to add a repoContext block diagnosing the repo’s git origin, config endpoint/platform, endpoint reachability, and token coverage. |
get_version |
Report the renovate-mcp server version and whether it’s a released or local/dev build. |
read_config |
Locate and parse a repo’s Renovate config in Renovate’s own discovery order. |
suggest_presets |
Search built-in (and optional local-repo) presets by natural-language intent; ranks matches and sketches an unvalidated draft config skeleton for multi-facet or weakly-covered intents. Offline. |
resolve_config |
Expand every extends preset offline. Opt in to fetching github> / gitlab> / gitea> / forgejo> presets over HTTPS, or Bitbucket Cloud presets via local> + platform. |
explain_config |
Inverse of resolve_config: annotate every leaf field with the chain of presets that set it. |
resolve_config_diff |
Offline structural diff of two fully-resolved configs — changed fields plus an order-insensitive set diff of array keys (packageRules, customManagers, …). The refactor-friendly counterpart to dry_run_diff. |
test_package_rules |
Offline what-if: which packageRules match a hypothetical dependency, which matcher decided each, and what each contributes — plus the branchName / commitMessage / prTitle the matched config would render for it. Faithful matching (Renovate’s real matchers in a worker); fields you don’t supply are reported as unevaluatable, not non-matches, and the rendered names list the post-lookup template variables they could not fill. |
preview_custom_manager |
Preview a customManagers entry (regex or JSONata) against a local repo. Offline. |
validate_config |
Run renovate-config-validator against a file or inline object. |
lint_config |
Semantic lint pass for Renovate-specific footguns the schema validator declares valid. Offline. |
dry_run |
Run Renovate with --dry-run and return the structured JSON report. Local-by-default; remote with platform + endpoint + token + repository. No PRs, no pushes. |
dry_run_diff |
Stateless semantic diff between two dry_run reports — added / removed / changed updates. |
annotate_dry_run |
Attribute each proposed update in a dry_run report to the packageRules that caused it; flags rules that never matched and report fields the matchers needed but the report lacked. Stateless + offline. |
explain_dependency |
Answer “why was/wasn’t dependency X updated?” from a dry_run report: per-occurrence skipReason, proposed updates, warnings, a one-line verdict and remedy hints; optionally the packageRules that matched it. Stateless + offline. |
explain_schedule |
Answer “when will this schedule actually run?”: active-now plus the next run windows in UTC and the config’s timezone, computed with Renovate’s own schedule matcher; invalid schedules return Renovate’s message and the fact that it then runs at any time. Offline. |
migrate_config |
Apply Renovate’s built-in migrations and return the migrated config plus a unified diff. Does not write. |
write_config |
Validate, then atomically write a config to disk. Preserves comments/key order on existing JSON-with-comments files; for package.json edits only the nested renovate key. |
renovate://presets (resource) |
Markdown index of all built-in presets grouped by namespace. |
renovate://presets/{namespace} (resource) |
Markdown listing for a single namespace. |
renovate://preset/{name} (resource) |
Expanded JSON body for one preset. |
renovate://options (resource) |
Markdown index of all Renovate config options, split into repository and global/self-hosted-only sections. |
renovate://option/{name} (resource) |
Full definition of one config option as JSON. |
renovate://managers (resource) |
Markdown list of all manager names, including custom managers. |
renovate://datasources (resource) |
Markdown list of all built-in datasource ids. |
Prompts. Four workflow prompts package the tool sequences above into ready-to-run starting points. Claude Code surfaces MCP prompts as slash commands (e.g. /mcp__renovate__design-renovate-config); other MCP clients expose them through their own prompt picker.
| Prompt | Drives |
|---|---|
design-renovate-config |
check_setup → read_config → suggest_presets → resolve_config/explain_config → validate_config/lint_config → dry_run → write_config on confirmation. |
debug-package-rule |
check_setup → read_config → test_package_rules (matches + rendered names) → dry_run (with reportOutputPath) → annotate_dry_run → explain_dependency → a verdict naming rule indices and matchers. |
author-custom-manager |
Draft a customManagers entry → preview_custom_manager iteratively → validate_config/lint_config → dry_run → write_config on confirmation. |
onboard-repo |
For repos without a config: check_setup → read_config (expect none) → dry_run (extract mode) → suggest_presets → lint_config/validate_config → write_config on confirmation → full dry_run. |
Requirements
- 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. Use WSL2 or a Linux/macOS host instead. - Node.js ≥ 24.11 (aligns with Renovate’s own engine requirement).
Renovate ships bundled — the renovate package is a runtime dependency, so validate_config, dry_run, and write_config work out of the box with no separate install. The offline tools (read_config, suggest_presets, resolve_config, explain_config, resolve_config_diff, test_package_rules, preview_custom_manager, lint_config, dry_run_diff, annotate_dry_run, explain_dependency, migrate_config) never spawn Renovate at all — nor do check_setup (by default it reads version metadata from the bundled install instead of spawning) or get_version (it only reports the renovate-mcp server’s own version).
Optional env vars:
RENOVATE_BIN/RENOVATE_CONFIG_VALIDATOR_BIN— override the bundled binaries. When set, the override always wins.RENOVATE_MCP_REQUIRE_CLI=false— suppress the startup “partial availability” notice when you only intend to use the offline tools.- Platform + token env vars — see
docs/platform-setup.mdfor the per-platform matrix. GITHUB_COM_TOKEN— authenticates github.com datasource lookups (release notes,github-tags/github-releases/github-actions). Distinct from the platform token and never auto-derived from it; set it when github.com-hosted deps are resolved under the defaultdry_runplatform: local. Seedocs/security.md.
Heads up: MCP servers do not inherit your shell env. Set every env var via the
envkey in.mcp.json/claude_desktop_config.json. Seedocs/security.md.
Install
1. Install the package
npm install -g renovate-mcp
Install before you register the server. The package bundles Renovate (about 670 packages, 350 MB), so a client that starts npx -y renovate-mcp against a cold npm cache downloads all of that during server startup and can time out.
Upgrade with npm install -g renovate-mcp@latest and restart your client. With nvm or fnm, global packages belong to one Node version — reinstall after switching.
2. Register it with your client
Claude Code:
claude mcp add renovate -s user -- renovate-mcp
-s user makes the server available in every project. Leave it out to register it for the current project only, or use -s project to write a shared .mcp.json.
Claude Desktop and other GUI clients don’t load your shell’s PATH, so with nvm, fnm or Homebrew they may find no Node or an older one. Use absolute paths:
which node # → "command"
echo "$(npm root -g)/renovate-mcp/dist/index.js" # → "args"
Claude Desktop reads ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"renovate": {
"command": "/Users/you/.nvm/versions/node/v24.14.1/bin/node",
"args": ["/Users/you/.nvm/versions/node/v24.14.1/lib/node_modules/renovate-mcp/dist/index.js"]
}
}
}
Any other client that can launch a stdio MCP server works with the same command.
3. Add tokens (optional)
The offline tools need nothing. Add env vars only for what you use:
| Use case | Env vars |
|---|---|
Local dry_run on a repo with github.com dependencies |
GITHUB_COM_TOKEN (read-only PAT, avoids anonymous rate limits) |
dry_run against GitHub, or private github> presets |
RENOVATE_PLATFORM=github + GITHUB_TOKEN |
dry_run against GitLab, or private gitlab> presets |
RENOVATE_PLATFORM=gitlab + GITLAB_TOKEN |
Self-hosted GitLab and GitHub Enterprise also need RENOVATE_ENDPOINT — see Platform setup.
In Claude Code, re-register with -e:
claude mcp remove renovate -s user
claude mcp add renovate -s user -e GITHUB_COM_TOKEN=ghp_xxx -- renovate-mcp
-estores the value in plain text in~/.claude.json. Keep tokens inuserorlocalscope, never in aproject-scope.mcp.jsonthat gets committed.-eaccepts several values, so keep the--beforerenovate-mcp.- Other clients take the same variables in an
"env": { … }block next to"args".
Alternatives
- npx without a global install — register
npx -y renovate-mcpinstead, after warming the npm cache once withnpm exec --yes --package=renovate-mcp -- node -e 0. - Installer script —
curl -fsSL https://raw.githubusercontent.com/tibuntu/renovate-mcp/main/install.sh | bashruns steps 1 and 2 interactively: it checks Node, asks fornpxor global mode, verifies the server with an MCPinitializehandshake, and registers it viaclaude mcp addwhen the Claude Code CLI is on PATH. Flags (afterbash -s --):--global,--npx,--no-mcp-add,--mcp-scope=user|project|local,--version=X.Y.Z; also accepted as env vars (RENOVATE_MCP_GLOBAL=1,RENOVATE_MCP_NO_MCP_ADD=1,RENOVATE_MCP_VERSION=…). - From source — clone, run
npm install && npm run build, and point your client atnode /absolute/path/to/renovate-mcp/dist/index.js.
Platform setup
For dry_run against a remote platform or resolve_config with externalPresets: true:
| Setup | RENOVATE_PLATFORM |
RENOVATE_ENDPOINT |
Token |
|---|---|---|---|
| github.com | github |
(omit) | RENOVATE_TOKEN or GITHUB_TOKEN |
| GitHub Enterprise | github |
https://github.example.com/api/v3/ |
RENOVATE_TOKEN or GITHUB_TOKEN |
| gitlab.com | gitlab |
(omit) | RENOVATE_TOKEN or GITLAB_TOKEN |
| Self-hosted GitLab | gitlab |
https://gitlab.example.com/api/v4/ |
RENOVATE_TOKEN or GITLAB_TOKEN |
| gitea.com / Forgejo (code.forgejo.org) | — | (omit) | RENOVATE_TOKEN or GITEA_TOKEN / FORGEJO_TOKEN |
| Self-hosted Gitea / Forgejo | — | https://forgejo.example.com/api/v1/ |
RENOVATE_TOKEN or GITEA_TOKEN / FORGEJO_TOKEN |
| Bitbucket Cloud | — | (omit) | RENOVATE_TOKEN or BITBUCKET_TOKEN |
The Gitea / Forgejo / Bitbucket Cloud rows apply to the resolve_config family only: dry_run runs Renovate as local / github / gitlab and never reads those tokens. Pass platform (gitea / forgejo / bitbucket) and endpoint as tool inputs instead of RENOVATE_PLATFORM / RENOVATE_ENDPOINT.
See docs/platform-setup.md for a worked self-hosted GitLab example, local> preset handling, and private-registry credentials.
Example prompts
Once the server is wired up, try prompts like these. 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.”
Discovering & browsing presets
- “I want to automerge patch and minor updates and group my dev dependencies — suggest presets for that, search my
../renovate-presetsrepo too, and draft a config I can validate.” - “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.” (or use
suggest_presetswith that intent)
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 or JSONata)
- “I have
# renovate: datasource=docker depName=...comments above image tags in my Dockerfiles. Draft acustomManagersregex entry withmanagerFilePatterns: ["**/Dockerfile"]and preview it against this repo so I can see what it extracts.” - “Here’s a
customManagersentry — preview it and tell me which files matchmanagerFilePatterns, which lines hit eachmatchStringsregex, and what dep info gets extracted.” - “My custom manager still uses
fileMatch. Lint the config, then runmigrate_configso it becomesmanagerFilePatterns.” - “Draft a
customType: \"jsonata\"customManager withfileFormat: \"yaml\"to extract Helm chart dependencies (name,version,repository) fromChart.yaml, and preview it against this repo.”
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.”
- “Why didn’t Renovate update
lodash? Run a dry run and explain that dependency.” - “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=comments aboveFROMlines in my Dockerfiles. Draft acustomManagersentry and preview it against this repo.Claude calls
preview_custom_managerwith a first-draftmanagerFilePatterns(**/Dockerfile) +matchStrings. → 4 Dockerfiles matchedmanagerFilePatterns, 0 lines matchedmatchStrings. The regex anchored onARG, but the Dockerfiles useFROM.You: Rewrite
matchStringsto anchor on the renovate comment, thenFROM :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; because the file already existed and parsed as JSON-with-comments, the round-trip serializer preserved the surrounding comments and key order — only thecustomManagersslice was edited in place.
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
npm run generate:presets # regenerate src/data/presets.generated.ts
npm run generate:managers # regenerate src/data/managers.generated.ts
npm run generate:migrations # regenerate src/data/migrations.generated.ts
npm run generate:options # regenerate src/data/options.generated.ts
npm run generate:datasources # regenerate src/data/datasources.generated.ts
npm run sync:jsonata-pin # sync package.json's jsonata pin to Renovate's own
npm run check:snapshot-versions # fail if any src/data/*.generated.ts is stale vs installed renovate
See docs/development.md for snapshot-file mechanics, CI matrix, the nightly upstream-drift workflow, dependency review, and integration-test setup.
Further reading
docs/tools.md— full per-tool reference with all inputs, outputs, and edge cases.docs/platform-setup.md— per-platform env vars, worked example,local>presets, private-registry credentials.docs/security.md— token handling, env-var precedence, endpoint allowlist, redirect/body-cap policy, inline-secrets warning.docs/operations.md— timeouts, caps, large-report escape hatch,oksemantics, RE2 / nodeEnv handling, progress notifications.docs/architecture.md— shell-out vs import, worker isolation, round-trip writer, preset catalogue.docs/development.md— snapshot mechanics, CI matrix, nightly drift workflow, integration testing.
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_configmerges faithfully. Preset expansion runs offline against a committed snapshot, then folds with Renovate’s realmergeChildConfigin a worker thread —mergeQuality: "faithful"(it falls back to an approximate in-process merge as"preview"only if the worker is unavailable). Template substitution still implements only positional{{argN}}placeholders — non-positional tokens and Handlebars helpers are flagged inwarningsand pass through verbatim. For full config resolution (datasource lookups, etc.), rundry_run.preview_custom_manageris a subset of Renovate’s custom managers. It coverscustomType: "regex"(withmatchStringsStrategyofany/combination/recursive) andcustomType: "jsonata"(withfileFormat: "json" | "yaml" | "toml"). File selection follows Renovate’smanagerFilePatternssemantics (globs or/regex/, entries unioned like Renovate’s extract phase); the deprecatedfileMatchis still accepted with a warning. Template substitution is{{groupName}}only — full Handlebars helpers/conditionals are not implemented. Other custom types (e.g.html) are out of scope. Use it for fast iteration; confirm withdry_run. Full coverage matrix indocs/tools.md#preview_custom_manager.dry_runstill uses fake binaries in CI. The bundled Renovate is available (it’s a runtime dependency), andvalidate_config/write_confighave real-validator integration tests (test/integration/realValidator.test.ts) exercising the actual bundledrenovate-config-validator— butdry_runitself still runs per-PR against fake binaries viaRENOVATE_BIN/RENOVATE_CONFIG_VALIDATOR_BINenv overrides, for determinism and speed. A separate nightly workflow re-runs the full suite againstrenovate@latestend-to-end. Rundry_runlocally against a real config to validate behaviour.
Install
This server does not publish a one-line install command.
Open the repository installation guide New to MCP? Start with the mcpskill.org guide →Configuration
{
"mcpServers": {
"renovate": {
"command": "/Users/you/.nvm/versions/node/v24.14.1/bin/node",
"args": ["/Users/you/.nvm/versions/node/v24.14.1/lib/node_modules/renovate-mcp/dist/index.js"]
}
}
}