Umbraco MCP Server — Setup Guide
This covers running @umbraco-cms/mcp-dev as a live MCP server connected to an AI client (Claude Desktop, Claude Code, Cursor, VS Code, etc). For debugging the package directly on the command line (--list-tools, --call, --debug-config), see the umb-cms-dev-cli skill instead — the same env vars apply either way.
For install steps, verifying the connection, and troubleshooting, use the official docs rather than this skill — they're the source of truth and won't drift out of sync the way a duplicated copy here would:
For per-client configuration, go straight to the guide for the client actually in use rather than the general page above:
Prerequisites
- An Umbraco CMS instance the client can reach over HTTPS (or HTTP on a local network).
- Node.js 22 or later (the package's declared
engines.noderequirement) if the client itself needs to runnpx— most desktop clients bundle their own Node runtime, so this mainly matters if you're invoking the server manually. - An Umbraco API user with the permissions you want the agent to have — see Umbraco's API user documentation. You'll come away with a client ID and client secret; treat the secret like a password (never commit it, never paste it into chat).
Coding Environments: .mcp.json
When the client is a coding agent working against a project (Claude Code, Cursor, VS Code, etc.), the preferred setup is a project-scoped MCP config file — e.g. .mcp.json for Claude Code — rather than a global/user-level config, so the server definition can be checked in and shared across the team without each developer's real secrets:
{
"mcpServers": {
"umbraco-mcp": {
"command": "npx",
"args": ["@umbraco-cms/mcp-dev@latest"],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0",
"UMBRACO_CLIENT_ID": "your-api-user-id",
"UMBRACO_CLIENT_SECRET": "your-api-secret",
"UMBRACO_BASE_URL": "https://localhost:{port}",
"UMBRACO_INCLUDE_TOOL_COLLECTIONS": "document,media,document-type,data-type"
}
}
}
}
Keep real UMBRACO_CLIENT_ID / UMBRACO_CLIENT_SECRET values out of any file that gets committed — use a local, git-ignored env file or your client's secret-reference mechanism instead of hardcoding them in a checked-in .mcp.json.
Don't assume the @latest tag above for every project — the dist-tag depends on the target site's Umbraco major version. The two you'll hit most often:
@latest— Umbraco 18.x (current release)@lts-17— Umbraco 17.x (current LTS)
For anything older (@16 for 16.x, @alpha for the pre-16 package) or to confirm this mapping is still current, check the docs' Version Compatibility table.
Required and Optional Environment Variables
| Env Var | Required | Description |
|---|---|---|
UMBRACO_CLIENT_ID |
Yes | OAuth client ID from the Umbraco API user |
UMBRACO_CLIENT_SECRET |
Yes | OAuth client secret — keep this out of chat, source control, and screenshots |
UMBRACO_BASE_URL |
Yes | Base URL of the Umbraco instance, e.g. https://localhost:44391 |
NODE_TLS_REJECT_UNAUTHORIZED |
No | Set to 0 only for local instances with self-signed certs. Never set this for a production/public base URL. |
UMBRACO_INCLUDE_TOOL_COLLECTIONS |
No | Comma-separated collections to expose (e.g. document,media) — narrows the toolset the client loads |
UMBRACO_READONLY |
No | true removes all mutation tools — the LLM never sees them |
UMBRACO_DRY_RUN |
No | true lets mutation tools run and return a preview without calling the API |
UMBRACO_TOOL_MODES |
No | Comma-separated named modes — presets that enable a curated set of collections (see below) |
UMBRACO_INCLUDE_SLICES |
No | Comma-separated slices — only expose tools whose operation kind matches (see below) |
UMBRACO_EXCLUDE_SLICES |
No | Comma-separated slices to hide — takes precedence over UMBRACO_INCLUDE_SLICES |
Slices and Modes
Beyond collections (document, media, etc.), the server supports two more ways to shape which tools a client sees:
A slice is the operation kind a tool performs (its verb), independent of which collection it belongs to. Every tool is tagged with one or more slices, so slice filtering cuts across collections — e.g. UMBRACO_INCLUDE_SLICES=read,search exposes only read/search tools across every enabled collection. Slices are defined in src/config/slice-registry.ts — the single source of truth; check that file for the current list rather than trusting a copy here (examples: create, read, update, delete, search, publish). Tools with no slices assigned fall back to other.
A mode is a named preset that maps to a fixed set of collections — a shortcut for "give me everything related to X" instead of listing collections by hand via UMBRACO_INCLUDE_TOOL_COLLECTIONS. Set UMBRACO_TOOL_MODES to a comma-separated list to enable more than one. Modes and what each one maps to are defined in src/config/mode-registry.ts — the single source of truth; check that file for the current list rather than trusting a copy here (examples: content, media, users, translation).
Modes, slices, and the collection/tool include-exclude filters all combine (exclude always wins over include) — e.g. UMBRACO_TOOL_MODES=content plus UMBRACO_EXCLUDE_SLICES=delete exposes every content-management tool except deletions.
For the CLI flag equivalents of these same env vars (--umbraco-tool-modes, --umbraco-include-slices, etc.) and the remaining filtering env vars (UMBRACO_INCLUDE_TOOLS, UMBRACO_EXCLUDE_TOOLS, UMBRACO_ALLOWED_MEDIA_PATHS, etc.), see the umb-cms-dev-cli skill's Tool Filtering and Runtime Modes tables rather than duplicating them here.