Sanity Context

Connect Sanity Context with LangChain

Connect Sanity Context to a Python or TypeScript agent using LangChain and its MCP adapters.

LangChain is a framework for building LLM agents in Python and TypeScript. This guide shows you how to connect a LangChain agent to Sanity Context with LangChain's MCP adapters: langchain-mcp-adapters for Python and @langchain/mcp-adapters for TypeScript. The adapters convert MCP tools to LangChain tools. You'll build a script that loads your schema or Knowledge Base outline into the system prompt, connects to your Context MCP endpoint, and answers a question about your content.

The same code works whether the endpoint uses Knowledge Base sources, a dataset source, or both. With Knowledge Base sources only, the tools are knowledge_base_search and knowledge_base_read instead of the dataset source tools, and the initial context is the Knowledge Base outline instead of your schema. With both source types, the endpoint serves the dataset source tools and the Knowledge Base source tools, and its initial context contains both the schema overview and the Knowledge Base outline. See Context MCP source types.

Prerequisites

To follow this guide, you need:

  • Context MCP endpoint URL: Shown on the MCP endpoint in the Context app in the Sanity Dashboard. To create an MCP endpoint, see Configure a Context MCP endpoint, or expand Create the endpoint with the Sanity CLI (optional) at the end of this section.
  • Organization API token: Create one in Manage under API > Tokens at the organization level. Under Organization permissions, select Context with the Viewer role. Project tokens are refused.
  • Anthropic API key: ChatAnthropic reads it from ANTHROPIC_API_KEY.
  • Python 3.10 or later for Python, or Node.js 22.18 or later for TypeScript. Node.js 22.18 and later run .ts files directly.
Create the endpoint with the Sanity CLI (optional)

You can create a Knowledge Base and an MCP endpoint from the Sanity CLI instead of the Dashboard. If you haven't signed in, run npx sanity@latest login. You still create the organization token in Manage. Replace ORGANIZATION_ID, PROJECT_ID, and KNOWLEDGE_BASE_ID with your own values:

mcp create prints the endpoint URL to use as SANITY_CONTEXT_MCP_URL. To serve a live dataset through a dataset source instead, replace --knowledge-base KNOWLEDGE_BASE_ID with -p PROJECT_ID -d production. See the Context CLI command reference for every flag.

Install dependencies

In a new project directory, install LangChain, the MCP adapters, and the Anthropic provider for your language:

The example uses version 2 of @langchain/mcp-adapters, which includes its own MCP client, so you don't install the MCP SDK separately. Set the module type in package.json so Node.js loads agent.ts as an ES module:

If you type-check with tsc, set "skipLibCheck": true in tsconfig.json. Recent @langchain/anthropic releases fail library checks against newer @anthropic-ai/sdk types.

Set environment variables

Create a .env file next to agent.ts or agent.py. In TypeScript, Node.js reads it with --env-file; in Python, load_dotenv() reads it. Replace each placeholder with your own value:

Create the agent

Create agent.ts or agent.py next to .env. The script works in three stages:

  • Fetch initial context from the /initial-context HTTP endpoint and add it to the system prompt. The agent starts with a compressed schema or Knowledge Base outline, which saves a tool call on every conversation. For details, see Inline initial context into your system prompt.
  • Connect to the MCP endpoint and load its tools, authenticating with your organization API token. MCPAdapter (TypeScript) or MultiServerMCPClient (Python) converts the MCP tools to LangChain tools. The script removes the initial_context tool, since its content is already in the system prompt.
  • Create the agent and call the model with createAgent (TypeScript) or create_agent (Python). The agent calls tools as it explores your content, then writes its answer.

A few details differ in LangChain.js:

  • MCPAdapter replaces MultiServerMCPClient, which is now a deprecated alias, and listTools() replaces getTools().
  • Version 2 of @langchain/mcp-adapters prefixes tool names with the server key by default (sanity_groq_query). The example sets prefixToolNameWithServerName: false so the names match the server's and the initial_context filter works. If you keep the prefix, filter on sanity_initial_context instead.
  • If the initial context fetch fails, the TypeScript example logs a warning and keeps the initial_context tool, so the model can still load the schema or outline itself. The Python example stops with an error instead.

Run it with a question. Node.js reads the .env file with --env-file:

The agent calls the Context MCP tools to explore your content, then prints its answer to the terminal. If the run fails, match the message against the list in Troubleshoot common errors.

Remember the conversation with LangGraph

createAgent runs on LangGraph, so a LangGraph checkpointer gives the agent memory across turns. @langchain/langgraph is already installed as a dependency of langchain. Add it to your own dependencies, since the example imports it directly:

Then replace the agent and the invoke call in the try block:

The second question works because the checkpointer carries the first answer forward on the same thread_id. MemorySaver keeps state in memory; use a persistent checkpointer, such as Postgres, in production.

To use the agent inside a larger graph, add agent.graph as a node, for example new StateGraph(MessagesAnnotation).addNode('sanity', agent.graph). Put the checkpointer on the parent graph, not on the agent.

Troubleshoot common errors

These are the most common errors and how to fix them:

  • [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///…/agent.ts is not specified and it doesn't parse as CommonJS.: The agent still runs, but package.json doesn't set the module type. Run npm pkg set type=module. Editors and tsc report the same cause as error TS1309: The current file is a CommonJS module and cannot use 'await' at the top level.
  • Error: Set SANITY_CONTEXT_MCP_URL and SANITY_ORGANIZATION_TOKEN: The environment variables aren't loaded. Run with --env-file=.env.
  • MCPClientError: Authentication failed for HTTP server "sanity", after Could not fetch initial context: Error: HTTP 401: The token is missing, invalid, or belongs to another organization.
  • 403 from the MCP connection with JSON-RPC error -32007 on an endpoint with a dataset source, or -32006 on an endpoint with only Knowledge Base sources, or the same 403 from the /initial-context fetch with code contextGrantRequired or knowledgeBaseAccessDenied. The messages are "Serving a dataset requires an organization API token with Context access ('sanity.knowledge-base.read'). Create one under your organization's API settings in Manage." (dataset source) and "No access to knowledge base '<knowledge base ID>'. Requires one of: sanity.knowledge-base.read." (Knowledge Base sources only; <knowledge base ID> is a placeholder for the Knowledge Base's ID): On an endpoint with a dataset source, the token isn't an organization API token with Context Viewer permissions. On an endpoint with only Knowledge Base sources, the token has no read access to the Knowledge Base the message names. Project tokens are refused however broad their permissions. Create an organization token as described in Prerequisites.
  • Error: Anthropic API key not found: Add ANTHROPIC_API_KEY to the .env file. ChatAnthropic throws when it's created, before the agent runs.
  • A Zod error about unrecognized_keys from MCPAdapter: The config has an option from version 1, such as useStandardContentBlocks. Remove it.
  • Failed to put checkpoint ... missing a required "thread_id": Pass {configurable: {thread_id}} when the agent has a checkpointer.

Next steps

Was this page helpful?