How Sanity Context & MCP Supercharged AI Customer Support in Basegent & Bucket Space A developer built Basegent, an AI customer support platform, and integrated it with Sanity's Context MCP and Knowledge Base beta to replace traditional vector-search RAG with structured, live-queried policy documents. The integration uses a SanityContextSourceAdapter that calls Sanity's hosted MCP endpoint via JSON-RPC during chat sessions, paired with a multi-provider BYOK inference engine, and was piloted on the developer's Bucket Space bookmarking app. This is a submission for the Sanity Challenge, Path One: Ship an Agent That Queries Real Content https://dev.to/challenges/sanity-2026-09-16 Over the past few months, I have been building Basegent https://basegent.space , a modern AI customer support and operations platform. Basegent gives developers and SaaS teams an intelligent chat assistant that can resolve real customer problems, cite official documentation, and escalate smoothly to human operators when confidence drops. At the same time, I run Bucket Space https://mybucket.space —a modern web application built for smart bookmarking, content capture, and personal library organization. Naturally, I wanted Bucket to be the proving ground for Basegent. But as anyone who has deployed AI support bots in production knows, traditional Retrieval-Augmented Generation RAG has a dirty secret: Traditional vector search treats company documentation like a bag of text chunks. It slices policies into arbitrary paragraphs, calculates similarity embeddings, and hopes the LLM can resolve contradictions on the fly. In real-world customer support, this naive approach fails catastrophically: Free vs. Pro , geographical market US vs. EU , or deployment type standard vs. custom . Similarity search has no concept of conditional logic. When Sanity announced the Sanity Context MCP and Knowledge Base beta in Sanity Labs, it clicked immediately. Sanity wasn't just offering another vector database; it was treating context as a managed, structured, verifiable source of truth with built-in conflict resolution and an open protocol Model Context Protocol - MCP . I set out to connect the entire loop: SanityContextSourceAdapter directly into Basegent that talks to Sanity's hosted MCP endpoint, paired with a multi-provider Bring-Your-Own-Key BYOK inference engine. @basegent/react chat widget into Here is the story of how it works, how Sanity Context solved our hardest policy dilemmas, and how you can implement this pattern in your own stack. production . @basegent/client Instead of copying periodic data dumps or storing duplicate content, Basegent queries Sanity Context live during the chat conversation via MCP JSON-RPC: Customer on Bucket Space mybucket.space │ Authenticated Query + Signed Token ▼ @basegent/react Chat Widget │ ▼ SSE / WebSocket Basegent Platform basegent.space │ ┌─────────────┴──────────────────────────┐ │ Multi-Provider BYOI / BYOK Engine │ │ Groq / OpenAI / Anthropic / Google │ └─────────────┬──────────────────────────┘ │ 1. Discover Outline /initial-context 2. Select Virtual Paths 3. Live MCP Tool Call knowledge base read ▼ Sanity Context MCP Endpoint api.sanity.io │ ┌─────────────────┴──────────────────────────┐ │ Sanity Knowledge Base kb3NuTkXw21o │ │ - Reconciled Structured Policies │ │ - Durable Standing Instructions │ │ - Canonical Documentation Citations │ └────────────────────────────────────────────┘ │ ▼ Streamed Answer with Citations & 1-Click Human Escalation To power support for Bucket, I created a dedicated project in Sanity Labs under organization Miracle Onyenma oL4FZOkGh with project ID jk662cms and dataset production . Support policies shouldn't be plain blobs of text. In Sanity Studio, we modeled supportPolicy documents with explicit schema constraints: js // schemas/supportPolicy.ts import { defineType, defineField } from "sanity"; export const supportPolicy = defineType { name: "supportPolicy", title: "Support Policy & Guide", type: "document", fields: defineField { name: "policyKey", type: "string", title: "Policy Key" } , defineField { name: "title", type: "string", title: "Title" } , defineField { name: "claim", type: "text", title: "Core Claim / Rule" } , defineField { name: "appliesTo", type: "object", title: "Applies To", fields: { name: "plans", type: "array", of: { type: "string" } }, { name: "markets", type: "array", of: { type: "string" } }, { name: "productIds", type: "array", of: { type: "string" } }, , } , defineField { name: "effectiveFrom", type: "datetime", title: "Effective From" } , defineField { name: "effectiveUntil", type: "datetime", title: "Effective Until" } , defineField { name: "priority", type: "number", title: "Precedence Priority 0-100 " } , defineField { name: "authority", type: "string", options: { list: "canonical", "legacy", "advisory" }, } , defineField { name: "supersedes", type: "reference", to: { type: "supportPolicy" } } , defineField { name: "sourceUrl", type: "url", title: "Canonical Source URL" } , , } ; We populated this dataset with real Bucket documentation alongside intentional edge cases: priority: 100 , authority: canonical , effective 2026 . priority: 10 , authority: legacy , expired end of 2025 . priority: 90 . Next, in Sanity Context Lab, we built the Basegent Support Policies Knowledge Base kb3NuTkXw21o . This is where Sanity Context shines. Instead of silently averaging out conflicting statements, Sanity actively parsed the documents, analyzed the domain boundaries, and flagged critical ambiguities in the Issues Review dashboard. Sanity flagged a direct conflict between the custom deployment exception 7 days and the legacy global rule 14 days regarding custom products: Sanity highlighted that while the new policy claims to supersede the legacy policy, its applicability was strictly scoped to the US Pro tier, leaving free and non-US tiers potentially ambiguous: With one click in the Sanity interface, we resolved the issue by selecting the source-backed canonical claim. Sanity compiled this decision into a durable standing instruction that automatically survives future dataset rebuilds Once verified, we generated an organization-level Context Viewer token and pointed Sanity's hosted Context MCP endpoint https://api.sanity.io/v1/context/organizations/oL4FZOkGh/mcp/context to this Knowledge Base. In Basegent, every customer support environment lives in an isolated tenant called a Workspace . We created the dedicated Bucket workspace slug: bucket at basegent.space/Account : In Basegent's Sources dashboard /sources/new , we added Sanity Context as a first-party knowledge source, supplying: kb3NuTkXw21o Basegent's core runtime defines a provider-neutral ContentSourceAdapter . To query Sanity live, we implemented SanityContextSourceAdapter : /initial-context When Basegent compiles its retrieval registry, it asks Sanity Context for its virtual outline: // lib/sources/sanity-context-adapter.ts export interface SanityContextConfig { mcpUrl: string; knowledgeBaseId: string; organizationToken: string; } export async function fetchKnowledgeIndex config: SanityContextConfig, connectionId: string, : Promise