Sanity × MCP

Live from Sanity · ka4hy9km/production

A field guide · 8 sections

Your content, structured once — editable by people and by AI.

A field guide to Sanity as a headless CMS, and to the Model Context Protocol (MCP) that lets Claude and other AI assistants read and write that content directly. Everything on this page is itself stored in Sanity.

PeopleSanity Studioedit · review · publish
Claude & other AIsMCP servermcp.sanity.io
SanityContent Lake
GROQ queryThis Astro sitestatic HTML
Same contentApps, email, agents…

The basics

What Sanity actually is

A headless CMS: your content lives in a hosted database as structured JSON, and any front end can fetch it.

A traditional CMS like WordPress stores your content and renders your pages. Sanity only does the first half. It is a headless CMS: content is stored as structured data, and you choose how and where it is displayed — a website, an app, an email, or an AI agent.

Three moving parts

  • The Content Lake — Sanity’s hosted, real-time database. Every document is JSON, versioned, and queryable over an API.
  • Sanity Studio — the editing interface. It is an open-source React app you configure in code, so it adapts to your content instead of the other way round.
  • APIs — query content with GROQ (or GraphQL), write it back with mutations, and listen to changes in real time.

This site is a small example: an Astro front end that fetches its explainer sections from a Sanity dataset, with a Studio in the studio/ folder for editing them.

Modelling

Schemas: content as data, defined in code

You describe your content types in TypeScript. Studio builds its editing forms from that.

In Sanity you define the shape of your content with schemas — plain TypeScript files that list document types and their fields. Studio reads them and generates the editing UI, including validation.

Here is a cut-down version of the schema behind every section on this page:

studio/schemaTypes/explainer.ts
export const explainer = defineType({
  name: 'explainer',
  title: 'Explainer section',
  type: 'document',
  fields: [
    defineField({name: 'title', type: 'string'}),
    defineField({name: 'slug', type: 'slug', options: {source: 'title'}}),
    defineField({name: 'order', type: 'number'}),
    defineField({name: 'summary', type: 'text'}),
    defineField({name: 'body', type: 'array', of: [{type: 'block'}, {type: 'codeBlock'}]}),
  ],
})

Rich text is stored as Portable Text — an array of JSON blocks rather than an HTML string. That is what makes it safe for an AI to edit: it can change a paragraph or insert a code block without touching markup.

Querying

Fetching content with GROQ

GROQ is Sanity’s query language: filter documents, then project exactly the fields you need.

GROQ queries read like a filter followed by a shape. This is the exact query this site runs to build the page you are reading:

src/lib/sanity.ts
*[_type == "explainer" && defined(slug.current)] | order(order asc) {
  _id,
  title,
  "slug": slug.current,
  kicker,
  summary,
  body
}

And here is how the Astro site calls it, at build time, with the official JavaScript client:

src/lib/sanity.ts
import {createClient} from '@sanity/client'

const client = createClient({
  projectId: import.meta.env.PUBLIC_SANITY_PROJECT_ID,
  dataset: 'production',
  apiVersion: '2025-10-01',
  useCdn: true,
})

const sections = await client.fetch(SECTIONS_QUERY)

You can try queries live in the Vision tab inside Studio before putting them in code.

The front end

How this Astro site uses Sanity

Astro fetches content when the page is built and ships plain HTML — fast, cheap, and SEO-friendly.

Astro renders this page to static HTML. During the build it queries Sanity, turns the Portable Text into HTML, and highlights the code samples. No JavaScript is needed in the browser to read it.

The publishing loop

  • An editor (or an AI) changes a document in Sanity and publishes it.
  • A Sanity webhook calls your host’s deploy hook (Cloudflare Pages, Netlify, Vercel…).
  • The site rebuilds with the new content, usually within a minute.

In development, npm run dev queries Sanity on every page load, so published changes appear on refresh with no rebuild.

The AI layer

What MCP is

The Model Context Protocol is an open standard for plugging tools and data sources into AI assistants.

The Model Context Protocol (MCP) is an open standard, introduced by Anthropic, that gives AI applications a common way to talk to outside systems. Think of it as a USB-C port for AI: one plug shape, many devices.

Two sides of the connection

  • MCP clients — the AI apps: Claude (claude.ai, the desktop app, Claude Code), Cursor, VS Code, ChatGPT and others.
  • MCP servers — services that expose tools the AI can call, such as “query documents” or “publish a draft”.

When you connect a server, the AI sees a list of its tools with descriptions and input schemas. It decides which tool to call based on your request, the client runs the call, and the result comes back into the conversation.

Setup

Connecting Claude (or any AI) to Sanity

Sanity hosts an official remote MCP server at mcp.sanity.io. Add it to your client and sign in.

Sanity runs a hosted MCP server at https://mcp.sanity.io. There is nothing to install: you point your AI client at that URL and sign in with your Sanity account through OAuth.

The quickest route

From any project, the Sanity CLI detects your editors and configures them for you, using the account you are logged in with:

terminal
npx sanity@latest mcp configure

Claude Code

terminal
claude mcp add Sanity -t http https://mcp.sanity.io --scope user

Start Claude Code again and it will open a browser window to authorise your Sanity account.

Claude on the web or desktop

Add a custom connector in Claude’s settings (Settings → Connectors) and use https://mcp.sanity.io as the URL. Claude walks you through the Sanity sign-in.

Cursor, VS Code and others

mcp.json
{
  "mcpServers": {
    "Sanity": {
      "type": "http",
      "url": "https://mcp.sanity.io"
    }
  }
}

VS Code uses a top-level servers key instead of mcpServers. Clients that only speak local (stdio) MCP can bridge to it with npx mcp-remote https://mcp.sanity.io --transport http-only.

Using a token instead of OAuth

For automations and CI, send an API token in an Authorization: Bearer <token> header instead. The AI then gets exactly that token’s role and nothing more — create a dedicated, narrowly scoped token for this.

In practice

What the AI can do once connected

Query with GROQ, create and patch drafts, publish, manage releases, upload assets, and read your schema.

The Sanity MCP server exposes a few dozen tools. The ones you will use most:

  • Read — query_documents (GROQ), get_document, get_schema, semantic_search.
  • Write — create_documents and patch_documents (both save as drafts), publish_documents, unpublish_documents, discard_drafts.
  • Plan — create_release and create_version to stage a batch of changes together.
  • Assets — upload images or files from a URL, or generate and transform images with AI credits.
  • Project admin — list projects and datasets, manage CORS origins, deploy schemas and Studios.

Prompts to try against this site

prompt
In my Sanity project, list every "explainer" document ordered by
"order", with its title and summary.
prompt
Add a new explainer section called "Webhooks and rebuilds" with
order 9 and kicker "Operations". Write three short paragraphs
explaining how a webhook triggers a site rebuild. Leave it as a draft.
prompt
Rewrite the summary of every explainer section to be under 20 words,
in British English. Show me the changes before publishing anything.

Publish the draft in Studio (or ask the AI to), rebuild, and the new section appears on this page — no code changes.

Safety

Guardrails for letting AI edit content

Drafts, roles, releases and review keep a human in charge of what goes live.

Giving an AI write access to a CMS is safe when the defaults keep people in the loop. Sanity gives you several layers:

  • Drafts first. create_documents and patch_documents write drafts. Nothing reaches your live site until something is published.
  • Permissions follow the user. With OAuth the AI acts as you, with your role. With a token it gets only that token’s role — use a read-only or editor token where you can.
  • Every change is attributed. Edits appear in the document history, so you can see what changed and roll back.
  • Releases group changes. Stage a batch of AI edits in a release and review it as one unit before it goes out.
  • Turn off what you don’t need. Most clients let you disable individual tools, such as image generation, which spends AI credits.