Sanity MCP server
Enable AI agents to interact with your Sanity workspace through the Model Context Protocol (MCP).
The Sanity Model Context Protocol (MCP) server enables AI assistants like Claude Code and Cursor to interact directly with your Sanity projects.
With the MCP server, agents can go beyond code generation and perform advanced content management operations in your Sanity projects. Agents can execute GROQ queries, manage releases, and patch documents with full awareness of your schema, eliminating the need to manually supply context.
Installation
The Sanity MCP server is hosted on Sanity's own infrastructure on https://mcp.sanity.io. It follows Anthropic's official MCP specification and works with any MCP-compatible client. It supports authentication through both OAuth (default) and token-based authentication.
Prerequisites:
- An MCP-compatible client, such as Claude Code, Cursor, VS Code, Lovable, Replit or v0
- A Sanity account
Quick install via Sanity CLI
The easiest way to get started is using the Sanity CLI. It detects the most common AI-powered editors (Cursor, VS Code, Claude Code) and automatically configures the MCP server for you.
npx sanity@latest mcp configure
pnpm dlx sanity@latest mcp configure
yarn dlx sanity@latest mcp configure
bunx sanity@latest mcp configure
This command uses your logged-in CLI user for authentication, so you don't need to manually authenticate or manage API tokens.
Claude Code
Run the following command in your terminal to add the Sanity MCP server. The next time you run Claude Code, it will have access to the MCP and you can authenticate with OAuth.
claude mcp add Sanity -t http https://mcp.sanity.io --scope user
Cursor
Use the link below to directly install the Sanity MCP server in Cursor. Once installed, you'll be prompted to authorize access.
You can confirm the server is running by opening the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and running View: Open MCP Settings.
Alternatively, you can manually update your configuration:
- Open the Command Palette and run View: Open MCP Settings.
- Select + New MCP Server in the settings pane. This will open your
mcp.jsonfile. - Add the following configuration:
{
"mcpServers": {
"Sanity": {
"type": "http",
"url": "https://mcp.sanity.io"
}
}
}Once you save the file, Cursor detects the new server and prompts you to authenticate via OAuth to complete the connection.
VS Code
- Open Visual Studio Code.
- In the Command Palette (
Cmd+Shift+P/Ctrl+Shift+P), run: MCP: Open User Configuration. - Update the
mcp.jsonfile with the following configuration and save the file:
{
"servers": {
"Sanity": {
"type": "http",
"url": "https://mcp.sanity.io"
}
}
}Once you save the file, VS Code detects the new server and prompts you to authenticate via OAuth to complete the connection.
OpenCode
You can add Sanity as a remote MCP server in your OpenCode configuration.
- Open your OpenCode config file.
- Add the following configuration to the
mcpsection:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"sanity": {
"type": "remote",
"url": "https://mcp.sanity.io",
"oauth": {}
}
}
}Save the file and authenticate with Sanity by running: opencode mcp auth sanity
Once authenticated, you can use Sanity tools in your prompts by mentioning sanity. For more details, see the OpenCode MCP documentation.
v0
v0 is an AI agent from Vercel that helps anyone create real code and full-stack apps. Ship features, refine designs, update copy, and create live prototypes – all with a prompt. Here's how you add the Sanity MCP:
- In the v0 prompt input field, click Prompt Tools (bottom left).
- Select MCPs, then click Add New.
- Select Sanity.
- Click Authorize.
- Follow the prompt to authenticate with your Sanity account via OAuth.
Lovable
You can add Sanity as a "Personal connector" in Lovable.
- In Lovable, go to Settings > Connectors > Personal connectors.
- Click New MCP server.
- Enter
Sanityas the name andhttps://mcp.sanity.ioas the Server URL. - Click Add & authorize.
- Follow the prompt to authenticate with your Sanity account via OAuth.
For more details on managing connectors, see the Lovable MCP documentation.
Replit
You can add Sanity as a custom MCP server in Replit Agent.
- Go to the Integrations Page, then scroll down to MCP Servers for Replit Agent.
- Click Add MCP server.
- Enter
Sanityas the name andhttps://mcp.sanity.ioas the Server URL. - Click Test & Save.
- Follow the prompt to authenticate with your Sanity account via OAuth.
Once saved, you can ask Replit Agent to use Sanity by mentioning it in your chat. For more details, see the Replit MCP documentation.
Other clients
If your client does not support remote MCP servers, you may be able to use a proxy such as mcp-remote.
{
"mcpServers": {
"Sanity": {
"command": "npx",
"args": [
"mcp-remote",
"https://mcp.sanity.io",
"--transport",
"http-only"
]
}
}
}Authorization
The Sanity MCP server uses OAuth by default to perform operations on your behalf. You may instead provide an API token by setting the Authorization header in your MCP config. When configured with the header, the server will not use OAuth. Tool calls will use the API token in accordance with its role and scoped to its permissions.
{
"mcpServers": {
"Sanity": {
"url": "https://mcp.sanity.io",
"headers": {
"Authorization": "Bearer sk..."
}
}
}
}You can create API tokens from sanity.io/manage or with the sanity CLI's tokens command. You can also provide a personal token, which will share your role and permissions, as well as link you to any changes in the revision history.
Run commands (or tools)
Once configured and started, authenticate with your Sanity credentials if prompted. You can then use natural language to work with Sanity development tasks, such as:
- Help me migrate this project to Sanity.
- Run a GROQ query for all articles written by Mark.
- Add localization to my article document type.
- Help me migrate existing content to a new schema shape.
- List all releases in this dataset.
mcp.sanity.io provides both editorial and development-focused tools for content operations, schema exploration, GROQ query execution, project management tasks such as creating and managing resources like datasets and API keys, and migration assistance. These tools allow your AI assistant to interact with your Sanity data directly.
Available tools
The following is a list of available tools and their uses:
Upload a ChatGPT web attachment or generated file to a Content Lake dataset. Pass the file through ChatGPT web file input; ChatGPT web supplies a temporary download URL that Sanity fetches. Works when the ChatGPT web sandbox cannot make HTTP requests. Choose image or file as assetType. Returns an operationId; use assets_upload_status to retrieve the asset and document field reference. Attach the reference with patch_documents, preserving existing field values. If the download URL expires, pass the file again for a fresh URL and a new requestKey. Check the destination before repeating an upload whose outcome is unknown. Source size and fetch time limits apply; processing may take several minutes.
Start an image or file upload from a public HTTPS URL to a Content Lake dataset. Returns an operationId immediately; use assets_upload_status to retrieve the asset and document field reference. Attach the returned reference with patch_documents, preserving existing field values. Submit uploads individually and check their operation IDs together with assets_upload_status. Honor HTTP Retry-After when rate limited. If a request is interrupted before an operationId is returned, check the destination before repeating the upload. Source size and fetch time limits apply; processing may take several minutes. For a local or private file, use `dataset_assets_upload_from_file` when available. For files in ChatGPT web, use `dataset_assets_upload_from_web_chatgpt`.
Start an image, video, or file upload from a public HTTPS URL to a Media Library. Optionally add a version to an existing asset. Returns an operationId immediately; use assets_upload_status to retrieve the asset, assetInstance, and uploadSession. Submit uploads individually and check their operation IDs together with assets_upload_status. Honor HTTP Retry-After when rate limited. If a request is interrupted before an operationId is returned, check the destination before repeating the upload. Source size and fetch time limits apply; processing may take several minutes. If you cannot use this tool because you have a local file or another asset that is not publicly hosted, call `give_sanity_feedback` and explain why.
Deprecated. Use media_library_upload_from_url with the same arguments. This tool does not start an upload.
Check one to 20 asset uploads using operationIds. Wait at least pollAfterMs between checks and group running uploads in one call. Honor HTTP Retry-After when rate limited. A status lookup error does not mean the upload failed. Results include asset IDs, URLs, and references; set includeMetadata for full metadata. Results are available for up to 24 hours. If an upload outcome is unknown, check the destination before repeating it.
Prepare a one-use URL for uploading an image or file up to 50 MiB to a Content Lake dataset. Works with browser-selected files, readable chat attachments, generated files, and local files. The client needs access to the bytes and HTTP POST capability; no shell or CLI is required. Prepare after the file is available. POST the raw bytes to uploadUrl before uploadExpiresAt. The HTTP response returns the asset and document reference. If the upload response is lost, prepare a new upload URL and resend the same file bytes and upload parameters. For files in ChatGPT web, use `dataset_assets_upload_from_web_chatgpt`.
Provide local Sanity CLI guidance for uploading an image or file asset to a Content Lake dataset. This tool does not read or upload the file.
Fetch a deployed schema. Omit workspaceName to use the sole active schema, or the default workspace when several exist. Explicit workspace names are exact. Resolves each workspace using this precedence: MCP-managed, then Studio-deployed, then legacy `system.schema`. Use `list_workspace_schemas` when several schema sources are available, then pass the advertised `schemaId` to inspect that exact schema.
List every deployed schema for a project and dataset, grouped by source (MCP-managed, Studio-deployed, or legacy). Duplicate workspace names and multiple Studio applications are expected; each entry includes a schemaId for exact reads with get_schema.
Directly deploy schema types to the cloud.
Deploy a managed Sanity Studio bound to an MCP-managed schema. Creates a hosted Studio whose URL follows the current environment — `sanity.studio` on production, `studio.sanity.work` on staging — and returns the concrete `studioUrl` in the response.
Requires an existing MCP-managed schema at the same `(projectId, dataset, workspaceName)` address — call `deploy_schema` first if none exists. Re-run after subsequent `deploy_schema` calls so the deployed Studio picks up the latest schema.Create one or more draft documents by directly providing structured content. Creates drafts (drafts.* prefix) unless releaseId is specified for version creation.
Create a version document (versions.{releaseId}.* prefix) for a specific release. Versions are separate from drafts and published documents, and are used for scheduled release workflows. When adding a document to a release with content changes, call create_version before patch_documents, then patch the returned version ID with the same releaseId. Do not patch the published or draft ID first because that creates an unrelated draft.
Update existing documents with @sanity/client patch() operations. Set documents to an object keyed by document ID, such as {"article-1":{"patches":[{"set":{"title":"New title"}}]}}.
Each document’s patches are applied as one transaction. Send at most 25 documents per call; split larger updates into more calls. Edits are saved to the draft or release version, never directly to published content.
For release edits, create the version first, then patch its versions.{releaseId}.* ID with the same releaseId. Do not patch the published ID before creating the release version.Query documents from Sanity using GROQ. Pass only the GROQ string in query. Do not include JavaScript imports, template wrappers, or defineQuery(). When using variables, set params to a JSON object such as {"type":"post"}.
Results are not truncated; use field projections and GROQ slices to request only what you need.
For unfamiliar GROQ syntax, functions, or query patterns, fetch get_sanity_rules({rules: ["groq"]}) before proceeding.Trigger async AI image generation for a document field.
Trigger async AI transformation of an existing image.
Fetch a single document by its exact ID. This is a direct ID lookup only - it does not search, filter, or query. Use when you have a specific document ID and need its full content.
Publish one or more drafts. Set ids to an array such as [{"id":"article-1"}]. Use the exact IDs returned by create_documents, query_documents, or get_document.
Unpublish one or more published documents (moves them back to drafts)
Discard one or more draft documents (deletes drafts while keeping published documents intact)
Discard one or more document versions from a release
Lists all organizations the user has access to in Sanity
Lists all Sanity projects associated with your account
Retrieves all studio applications linked to a specific Sanity project
Creates a new Sanity project and initializes it with a dataset and API tokens
Lists all CORS origins configured for a Sanity project
Adds CORS origin(s) to allow client-side requests to a Sanity project
Deletes a CORS origin from a Sanity project
Returns the currently authenticated Sanity account. Use it first for access or account troubleshooting and report the returned name, email, provider, and MCP authentication method so the user can verify which identity is active.
Lists all datasets in your Sanity project
Creates a new dataset with specified name and access settings
Modifies a dataset's name or access control settings
Create a new release for grouping content changes. Optionally provide releaseId; if omitted, one is generated. Does not schedule the release: releaseType and intendedPublishAt are recorded as metadata only. Scheduling, publishing, archiving and deleting a release are not available here and must be done in Sanity Studio or via the HTTP Actions API.
List releases in a dataset. By default returns active and scheduled releases. Use the state filter to find published or archived releases.
List all available embeddings indices for a dataset
Perform a semantic search on an embeddings index
Lists the Sanity Media Libraries in an organization. Call `list_organizations` first to get an organization ID. Returns library IDs to pass as `mediaLibraryId` to the other `media_library_*` tools.
Get the document types of a Media Library, or the full field definitions for one type. Call this before querying or editing: the library schema is fixed (assets, collections, folders, aspects), and the organization's own asset aspects are merged onto `sanity.asset` under `aspects`.
Query a Media Library using GROQ. Assets, collections, folders, and aspect definitions are all queryable. The result count reflects the query result set, not the library total; use a `count()` query for totals.
Fetch a single Media Library document by its exact ID. This is a direct ID lookup only - it does not search, filter, or query.
Create documents in a Media Library. Only `sanity.asset.collection` can be created — assets themselves come from uploading a binary, which is not supported here. Documents are created directly, not as drafts.
Edit Media Library documents. Edits are limited to the safe subset: an asset's `title` and `aspects.*`, its `cdnAccessPolicy`, and collection metadata/membership. Asset `title`/`aspects.*` edits are saved to a draft — publish them with `media_library_publish_documents`. `cdnAccessPolicy` is published-only and takes effect immediately: address it by the published id (a `drafts.` id is refused, since it cannot be staged) and patch it separately from title/aspects. Collections are edited directly. Folder placement, the version graph, and other system fields are rejected and must be managed in the Media Library app; custom metadata belongs in aspects. Every value an edit writes must be valid against the library's schema afterwards, on a draft or a published document alike; the edit is refused with the reasons otherwise. Problems the document already had elsewhere are reported as warnings, not enforced, and will stop publish until fixed. Array items without a `_key` are keyed by Content Lake on write, so re-read before addressing them by key.
Publish asset drafts to make unpublished metadata edits (`title`, `aspects.*`) live, preserving published-only and system-managed fields. The draft is validated against the current aspect definitions first, as the Media Library app does: any error in `title` or `aspects` refuses the publish, an aspect whose definition has since been deleted is kept as it stands, and root fields outside the schema are preserved and listed. Only assets have a draft/publish flow. Fails for an asset that has no draft.
Discard asset drafts, throwing away unpublished metadata edits and leaving the published asset intact.
Lists documents (across project datasets) that reference a Media Library asset. Use this before replacing an asset to see what depends on it.
Make one or more Media Library assets usable in project documents. For image/file assets this creates a local deliverable copy and returns a field value referencing it, plus a weak `media` global document reference back to the library; for video assets it returns a `sanity.video` value with global document references only (no local copy). Returns per-asset ready-to-use field values to apply with `patch_documents` against the target dataset. Each field type must match its asset type. Pairs with `media_library_list_asset_references`.
Run a limited subset of Sanity CLI commands and return their output. Use `--help` to list available commands or `<command> --help` for command details. Commands run without a shell and cannot access the filesystem, prompt for input, run in the background, or change authentication. Dedicated Sanity MCP tools may provide more structured responses, but equivalent CLI commands are also available.
Search Sanity docs
Fetch a specific documentation article.
List available best-practice development rules.
Load specific best-practice development rules.
Submit feedback about Sanity when you encounter issues while working with a Sanity codebase or project.
Use this when:
- A Sanity MCP tool returned an unexpected error or confusing result
- You needed a Sanity capability that doesn't exist or is hard to use
- Sanity docs, MCP tool descriptions, or examples were unclear or incorrect
- Common Sanity surfaces such as @sanity/client, the HTTP API, schemas, Studio, or deployment were confusing or blocked progress
- You had to use a workaround for something in Sanity that should be simpler
Provide a specific, detailed message about what you were trying to do,
what happened, and what you expected instead. If the feedback concerns a
Media Library, include its `mediaLibraryId` (and `organizationId` if known).
AI credit usage
Most MCP tools are standard API calls and don't consume AI credits. The following tools invoke Sanity's AI inference endpoints and consume AI credits:
generate_imagetransform_image
You can disable these tools in your MCP client if you want to avoid credit usage.
Learn more about pricing and quotas in How AI credits work.
Troubleshooting
Authentication issues
If you encounter authentication errors (e.g., 401 Unauthorized), the solution depends on how you installed the server:
Installed via CLI (using token auth)
If you installed the MCP via the Sanity CLI, your authentication relies on a generated token that may have expired or been revoked. To fix this, simply run the configuration command again and re-select your code editor with space:
npx sanity@latest mcp configure
pnpm dlx sanity@latest mcp configure
yarn dlx sanity@latest mcp configure
bunx sanity@latest mcp configure
This will generate a fresh auth token and update your editor's configuration file automatically.
Manually configured (using OAuth)
If you configured the server manually, you are likely using OAuth. Sessions typically expire after 7 days. Your client should prompt you to re-authenticate, but if it gets stuck:
- VS Code: Run
Authentication: Remove Dynamic Authentication Providersfrom the Command Palette, select the Sanity provider, and restart the server. - Cursor: Run
Cursor: Clear All MCP Tokensfrom the Command Palette to reset your session.
Tool availability
If specific tools (like query_documents) are missing or failing, verify that your account has the correct permissions for the project and dataset you are trying to access. The set of available tools may also vary as we release updates to the MCP server.
Support
Join us in the Sanity community to ask questions and discuss our MCP server with other developers in the #mcp-server channel.