Sanity MCP Server
Provides tools for full CRUD operations, GROQ queries, document management, reference tracking, diff, history, bulk operations, and draft status on Sanity content platform.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Sanity MCP Server show me the last 10 published posts with their categories"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
š® Sanity MCP Server
The self-hosted Sanity MCP that Sanity deprecated. Full CRUD, atomic transactions, reference tracking, and tools the official server doesn't have.
Why This Exists
Sanity's official MCP server (@sanity/mcp-server) is archived. They want you to use their hosted solution at mcp.sanity.io with OAuth.
That's fine if you want:
OAuth flows for every AI tool
Dependency on Sanity's infrastructure
No offline or air-gapped usage
Whatever tools they decide to expose
This MCP gives you:
š Simple token auth ā one env var, done
š Self-hosted ā runs anywhere, no external dependencies
š ļø More tools ā reference tracking, diff, history, bulk ops
ā” Works offline ā no OAuth dance, no hosted service required
Related MCP server: Agentic CMS
Quick Start
npx @purple-horizons/sanity-mcpOr install globally:
npm install -g @purple-horizons/sanity-mcpMCP Configuration
Add to your Claude Desktop, Cursor, or VS Code config:
{
"mcpServers": {
"sanity": {
"command": "npx",
"args": ["@purple-horizons/sanity-mcp"],
"env": {
"SANITY_PROJECT_ID": "your-project-id",
"SANITY_DATASET": "production",
"SANITY_TOKEN": "sk-your-token"
}
}
}
}Tools
š Read Operations
Tool | Description |
| Execute any GROQ query |
| Fetch a single document by ID |
| List documents by type with pagination |
| Full-text search across content |
| Discover all document types |
| Get schema info for a type |
| Count documents matching a filter |
āļø Write Operations
Tool | Description |
| Create a new document |
| Replace an entire document |
| Partially update specific fields |
| Delete a document |
| Publish a draft |
| Move published to draft |
š Unique Tools (Not in Sanity's Official MCP)
Tool | Description |
| Find all documents referencing a given doc ā essential before deleting |
| Compare two documents ā draft vs published, or any two docs |
| Get revision history ā see who changed what |
| Atomic batch operations ā all succeed or all fail |
| Check publish state ā draft, published, or both |
What Makes This Better
1. Reference Tracking
Before you delete that image asset, you probably want to know what's using it:
sanity_references id="image-abc123"
ā Shows all 47 blog posts using that imageSanity's official MCP doesn't have this. You'd find out the hard way.
2. Document Diffing
Content editor made changes. What changed?
sanity_diff idA="drafts.post-xyz" idB="post-xyz"
ā Shows exactly which fields differSee the diff before you publish. Or compare any two documents.
3. Atomic Bulk Operations
Update 50 documents and they all need to succeed together? One transaction:
sanity_bulk operations=[
{ "patch": { "id": "post-1", "set": { "featured": true }}},
{ "patch": { "id": "post-2", "set": { "featured": false }}},
...
]
ā All or nothing. No partial states.With dryRun: true, validate before executing.
4. Draft Status at a Glance
Is there a draft? Is it published? Both?
sanity_draft_status id="post-abc123"
ā { status: "both", hasUnpublishedChanges: true }No more manually checking drafts.{id} vs {id}.
Environment Variables
Variable | Required | Default | Description |
| ā | ā | Your Sanity project ID |
| ā |
| Dataset name |
| ā | ā | API token (required for writes) |
| ā |
| API version |
Getting Your Token
Go to sanity.io/manage
Select your project ā API ā Tokens
Add new token with Editor or higher permissions
Copy and set as
SANITY_TOKEN
GROQ Examples
// All posts, newest first
*[_type == "post"] | order(_createdAt desc)
// Specific post by slug
*[_type == "post" && slug.current == "hello-world"][0]
// Posts with expanded author
*[_type == "post"]{
title,
slug,
"author": author->name,
"category": category->title
}
// Count by category
{
"total": count(*[_type == "post"]),
"published": count(*[_type == "post" && !(_id in path("drafts.**"))])
}
// Full-text search
*[_type == "post" && title match "AI*"]Development
# Clone
git clone https://github.com/Purple-Horizons/sanity-mcp.git
cd sanity-mcp
# Install
npm install
# Build
npm run build
# Test
npm test
# Run locally
npm run devComparison
Feature | This MCP | Sanity Official |
Self-hosted | ā | ā (archived) |
Simple token auth | ā | OAuth only |
Works offline | ā | ā |
Reference tracking | ā | ā |
Document diff | ā | ā |
Bulk transactions | ā | ā |
Draft status | ā | ā |
Revision history | ā | ā |
Schema discovery | ā | ā |
Full CRUD | ā | ā |
GROQ queries | ā | ā |
Release management | ā | ā |
Semantic search | ā | ā |
tl;dr: We're better for self-hosting, developer tooling, and content operations. They're better if you need releases and semantic search with embeddings.
License
MIT Ā© Purple Horizons
Links
Available Tools
18 toolssanity_bulkA
Execute multiple operations in a single atomic transaction. All succeed or all fail together.
Inputs: operations (required), dryRun.
sanity_countB
Count documents matching a GROQ filter
Inputs: filter (required), params.
sanity_createB
Create a new document in Sanity CMS. Requires write token.
Inputs: _type (required), document (required), _id.
sanity_deleteB
Delete a document. Requires write token.
Inputs: id (required).
sanity_diffA
Compare two documents and see what fields differ. Useful for comparing draft vs published or two versions.
Inputs: idA (required), idB (required).
sanity_draft_statusA
Check if a document has unpublished changes. Shows both draft and published versions if they exist.
Inputs: id (required).
sanity_get_documentB
Get a single Sanity document by its ID
Inputs: id (required).
sanity_get_type_infoA
Get information about a document type including field names and document count
Inputs: type (required).
sanity_get_typesA
Get all document types in the Sanity dataset
Inputs: no named parameters.
sanity_historyB
Get the revision history of a document. See who changed what and when.
Inputs: id (required), limit.
sanity_list_documentsA
List documents of a specific type with pagination
Inputs: type (required), limit, offset, order.
sanity_patchC
Partially update a document. Requires write token.
Inputs: id (required), set, unset, inc, +1 more.
sanity_publishA
Publish a draft document (moves from drafts.* to published). Requires write token.
Inputs: id (required).
sanity_queryB
Execute a GROQ query against Sanity CMS. GROQ is a query language similar to GraphQL but designed for JSON documents. Examples: *[_type == "post"] gets all posts, *[_type == "post" && slug.current == "my-post"][0] gets a specific post.
Inputs: query (required), params.
sanity_referencesA
Find all documents that reference a given document. Essential before deleting to avoid broken references.
Inputs: id (required), limit.
sanity_searchB
Search for documents using full-text search across titles, names, descriptions, and body content
Inputs: searchTerm (required), types, limit.
sanity_unpublishA
Unpublish a document (moves to drafts.*). Requires write token.
Inputs: id (required).
sanity_updateA
Replace an entire document. Requires write token.
Inputs: id (required), document (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelogā¦
TDQS
Scored across 18 tools
Every tool has a clearly distinct purpose: create, update, patch, delete, publish, unpublish, query, search, list, get, diff, history, references, etc. No two tools overlap in functionality.
All tools follow a consistent 'sanity_verb_noun' pattern using snake_case, e.g., sanity_create, sanity_publish, sanity_list_documents. No mixed conventions.
18 tools is slightly above the ideal 3-15 range, but the scope of a CMS (CRUD, publishing, search, history, diffs) justifies the count. Still reasonable.
The toolset covers the full document lifecycle: CRUD, patch, publish/unpublish, query, search, history, diffs, references, bulk operations, and type introspection. No obvious gaps.
Maintenance
Related MCP Connectors
Hosted MCP server for AI-driven data ops. Create apps, manage schemas, and CRUD structured data.
Self-hosted MCP server: 26 deterministic dev, security, and EVM tools.
A hosted MCP server for planning, scheduling, media, analytics, and social publishing.
MCP server for InsForge BaaS ā database, storage, edge functions, and deployments
Related MCP Servers
AlicenseAqualityBmaintenanceLocal-first MCP server for AI content governance. 13 tools for model/content management, validation, normalization, and i18n across any framework.237MIT- AlicenseBqualityCmaintenanceOpen-source MCP server that turns any CMS backend into an AI-agent-ready content management system. It provides tools for content CRUD, idea management, and publication tracking, with safety features requiring human approval for publishing.52MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for uploading local images to Sanity CMS. Enables AI assistants to upload files from your filesystem directly into Sanity as image assets.114 npm1MIT
- AlicenseNot gradedqualityCmaintenanceProvides a sovereign, MIT-licensed MCP server for professional-service workflows, running entirely on your infrastructure with Ed25519 cryptographic signing for every action.MIT