Sitecore AI MCP Server
Sitecore AI MCP Server
A Model Context Protocol (MCP) server that exposes two read tools over the SitecoreAI / XM Cloud Content Management GraphQL API:
Tool | What it does |
| Fetch one item's full detail: id, name, path, template name, display name, all fields, children count |
| List an item's immediate children, optionally filtered by template |
It runs over stdio, so any MCP client (Claude Desktop, Claude Code, etc.) can launch it as a local subprocess. Authentication uses the OAuth 2.0 client-credentials grant, with an in-memory token manager that caches and proactively refreshes the access token before it expires.
1. Prerequisites
Node.js 18+ (uses the built-in global
fetch).A Sitecore XM Cloud environment (or a self-hosted CM instance) whose Content Management GraphQL API is enabled.
An OAuth client (client id + secret) that is authorised to call that API.
2. Install & build
npm install
npm run buildThis compiles src/** to dist/**. The executable entrypoint is
dist/index.js.
3. Configure environment variables
Copy the example file and fill in the values:
cp .env.example .envVariable | Required | Description |
| ✅ | Content Management GraphQL endpoint, e.g. |
| ✅ | OAuth token endpoint (identity server), e.g. |
| ✅ | OAuth client id |
| ✅ | OAuth client secret |
| ⬜ | OAuth scope, if your identity server requires one |
| ⬜ | OAuth audience, if your identity server requires one |
The server never logs the client secret or the access token. Errors are surfaced with a category (
auth,forbidden,not_found,invalid_template,graphql,network,config) and a short, secret-free detail string.
Access policy (deny-by-default)
Every tool call passes through a path-based policy before any field values or children are read:
Zero-network deny — the well-known Sitecore protected roots (
/sitecore/system,/sitecore/templates,/sitecore/layout) have fixed, public GUIDs, so a request for one is refused with no network call at all.Path gate — for every other id, a minimal path-only lookup runs first, the policy decides, and only then is the item's content fetched. Anything outside the allow-list is denied by default; a denial surfaces as a
[forbidden]tool error.
Variable | Default | Purpose |
|
| Readable path prefixes. Anything not matched is denied. |
|
| Blocked outright unless developer mode is on. |
|
| When |
Why block templates/system/layout by default: an agent that can read — and especially, once write tools exist, edit — a template can take down every page built on it with one plausible-looking change. Keep
SITECORE_DEVELOPER_MODEoff in any environment an agent reaches unsupervised, and turn it on only for a deliberate developer session.Because the tools are keyed by item id (an opaque GUID), the id → path mapping for non-root items requires exactly one lightweight metadata lookup; the gate then runs before any content, field values, or (future) mutation is touched.
Where to generate the OAuth client id / secret
XM Cloud (Sitecore Cloud):
Sign in to the XM Cloud Deploy / Cloud Portal.
Open Credentials (Organization settings → Automation client credentials, or the environment's Developer settings).
Create a new client with the scope/role needed to read content via the Authoring/Content GraphQL API.
Copy the generated Client ID and Client Secret into
.env.The token endpoint for Sitecore Cloud is typically
https://auth.sitecorecloud.io/oauth/token— set that asSITECORE_TOKEN_URL.
Self-hosted XM / CM instance:
Register an OAuth client in your Sitecore Identity Server configuration (a
ClientCredentialsgrant client) with a client id and secret.Grant it the API resource/scope for the GraphQL endpoint.
Use your identity server's token endpoint (e.g.
https://<cm-host>/sitecore/api/identity/tokenor the IdentityServer/connect/token) asSITECORE_TOKEN_URL.
The exact GraphQL schema differs slightly between endpoints. This server targets the XM Cloud Authoring & Management GraphQL API shape (
item(where: { itemId, language, version }),fields { nodes { name value } },children { nodes / totalCount }). If your endpoint uses a different schema, adjust the queries insrc/tools/getItemDetail.tsandsrc/tools/listItems.ts.
4. Register the server in an MCP client
Claude Desktop (claude_desktop_config.json)
Location:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"sitecore-ai": {
"command": "node",
"args": ["C:\\path\\to\\SItecoreAISimpleMCP\\dist\\index.js"],
"env": {
"SITECORE_API_URL": "https://<cm-host>/sitecore/api/authoring/graphql/v1",
"SITECORE_TOKEN_URL": "https://auth.sitecorecloud.io/oauth/token",
"SITECORE_CLIENT_ID": "your-client-id",
"SITECORE_CLIENT_SECRET": "your-client-secret"
}
}
}
}Restart Claude Desktop; the two tools appear under the 🔌 tools menu.
Claude Code
claude mcp add sitecore-ai \
--env SITECORE_API_URL=https://<cm-host>/sitecore/api/authoring/graphql/v1 \
--env SITECORE_TOKEN_URL=https://auth.sitecorecloud.io/oauth/token \
--env SITECORE_CLIENT_ID=your-client-id \
--env SITECORE_CLIENT_SECRET=your-client-secret \
-- node C:\\path\\to\\SItecoreAISimpleMCP\\dist\\index.js5. Usage examples
get_item_detail:
{ "itemId": "110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9", "language": "en" }list_items (optionally filtered by template):
{
"parentId": "0DE95AE4-41AB-4D01-9EB0-67441B7C2450",
"language": "en",
"templateId": "76036F5E-CBCE-46D1-AF0A-4143F9B557AA"
}GUIDs may be dashed, braced ({...}), or raw 32-hex — all forms are accepted.
6. Tests
npm testUnit tests cover:
Token manager — grant request shape, caching, proactive refresh before expiry, concurrent-refresh coalescing,
invalidate(), and 401/network/config error handling (plus a check that the secret never leaks into errors).get_item_detail— field mapping, defaults, version passthrough, not-found handling, and input validation.list_items— child mapping, template filtering (GUID-form-insensitive), invalid-template detection, empty children, not-found, input validation, and policy enforcement (protected parent by id/path, per-child filtering).Access policy — allow-list matching, protected-area blocking, deny by default, sibling-prefix safety, developer-mode lifting the block, and
fromEnvparsing.
Both tool suites mock the GraphQL client; the token-manager suite mocks
fetch.
7. Project structure
src/
index.ts # server entrypoint, registers tools over stdio
sitecoreClient.ts # GraphQL client wrapper (adds bearer token, 401 retry)
itemPath.ts # minimal id -> path lookup used by the policy gate
policy.ts # PathPolicy: deny-by-default allow-list + protected roots
context.ts # ToolContext = { client, policy }
schemas.ts # zod input schemas
errors.ts # SitecoreError + error categories
auth/
tokenManager.ts # OAuth client-credentials fetch/cache/refresh
tools/
getItemDetail.ts # get_item_detail implementation
listItems.ts # list_items implementation
tests/
tokenManager.test.ts
policy.test.ts
getItemDetail.test.ts
listItems.test.tsLicense
MIT