Connect Sanity Context with LangChain
Connect Sanity Context to a Python agent using LangChain and langchain-mcp-adapters.
This example connects Sanity Context to a Python agent using LangChain and langchain-mcp-adapters. The adapter library converts MCP tools to LangChain tools automatically.
Before you start
You need a Sanity Context MCP endpoint. If you haven't set one up yet, start with Sanity Context. You'll need:
- MCP endpoint URL: Shown in the Sanity Context document in Studio.
- Sanity API read token: Create one at sanity.io/manage.
- Anthropic API key:
ChatAnthropicreads it fromANTHROPIC_API_KEY. - Python 3.10 or later.
Install dependencies
pip install langchain langchain-mcp-adapters langchain-anthropic httpx python-dotenv
Set environment variables
Create a .env file next to agent.py. load_dotenv() reads it. Replace each placeholder with your own value:
SANITY_CONTEXT_MCP_URL=YOUR_MCP_ENDPOINT_URL SANITY_API_READ_TOKEN=YOUR_SANITY_READ_TOKEN ANTHROPIC_API_KEY=YOUR_ANTHROPIC_API_KEY
Full example
Connect to the MCP endpoint, fetch initial context, and run the agent:
import asyncio
import os
from urllib.parse import urlparse, urlunparse
import httpx
from dotenv import load_dotenv
from langchain.agents import create_agent
from langchain_anthropic import ChatAnthropic
from langchain_mcp_adapters.client import MultiServerMCPClient
load_dotenv()
MCP_URL = os.environ["SANITY_CONTEXT_MCP_URL"]
API_TOKEN = os.environ["SANITY_API_READ_TOKEN"]
async def main():
# 1. Fetch initial context via HTTP
parsed = urlparse(MCP_URL)
initial_context_url = urlunparse(
parsed._replace(path=parsed.path.rstrip("/") + "/initial-context")
)
async with httpx.AsyncClient() as http:
resp = await http.get(
initial_context_url,
headers={"Authorization": f"Bearer {API_TOKEN}"},
)
resp.raise_for_status()
initial_context = resp.text
# 2. Connect to Sanity Context MCP and load tools
mcp_client = MultiServerMCPClient({
"sanity": {
"transport": "http",
"url": MCP_URL,
"headers": {"Authorization": f"Bearer {API_TOKEN}"},
},
})
tools = [t for t in await mcp_client.get_tools() if t.name != "initial_context"]
# 3. Create the agent and call the LLM
system_prompt = (
"You are a helpful assistant.\n\n"
"# Data reference\n\n"
"Use this to understand what's available and write better queries.\n\n"
+ initial_context
)
llm = ChatAnthropic(model="claude-sonnet-4-6")
agent = create_agent(llm, tools, system_prompt=system_prompt)
result = await agent.ainvoke(
{"messages": [("user", "What content do we have?")]}
)
print(result["messages"][-1].content)
asyncio.run(main())How it works
Every Sanity Context integration follows three steps:
- Fetch initial context via the
/initial-contextHTTP endpoint and inject it into your system prompt. This gives the agent a compressed schema overview so it can write accurate queries from the start — and saves a tool call on every conversation. - Connect to MCP and get tools: Authenticate with your Sanity API read token.
MultiServerMCPClienthandles the MCP-to-LangChain tool conversion. Filter out theinitial_contexttool since you've already fetched it. - Create the agent and call the LLM using
create_agentfrom LangChain. The agent will make tool calls as it explores your content.
Common errors
Three failures account for most first runs:
KeyError: 'SANITY_CONTEXT_MCP_URL': The.envfile is missing, or isn't in the directory you run the script from.load_dotenv()returns without error when it finds no file.httpx.HTTPStatusError: Client error '401 Unauthorized'raised byresp.raise_for_status(): The value inSANITY_API_READ_TOKENisn't a valid Sanity API read token.Anthropic authentication failed: no API key or authorization credentials were provided.: SetANTHROPIC_API_KEYin the.envfile.ChatAnthropicconstructs without a key and fails on the first call instead.
Next steps
- Sanity Context patterns and best practices: Production patterns for public assistants, personalized agents, and multi-backend setups.
- Add insights to Sanity Context: Track and analyze agent conversations.
- AI shopping assistant walkthrough: A full reference implementation using Next.js and the Vercel AI SDK.