惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
W
WeLiveSecurity
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
S
SegmentFault 最新的问题
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
F
Full Disclosure
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Register - Security
The Register - Security
G
Google Developers Blog
C
Check Point Blog
GbyAI
GbyAI
A
About on SuperTechFans
V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
T
Tor Project blog
AWS News Blog
AWS News Blog
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
MongoDB | Blog
MongoDB | Blog
Latest news
Latest news
aimingoo的专栏
aimingoo的专栏
U
Unit 42
Y
Y Combinator Blog
P
Privacy International News Feed
Cisco Talos Blog
Cisco Talos Blog
S
Securelist
S
Schneier on Security
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Attack and Defense Labs
Attack and Defense Labs
P
Proofpoint News Feed
C
Cisco Blogs
Webroot Blog
Webroot Blog
T
Troy Hunt's Blog
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
P
Privacy & Cybersecurity Law Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
罗磊的独立博客
Cloudbric
Cloudbric
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News: Ask HN
Hacker News: Ask HN
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Security Blog
Microsoft Security Blog

Sanity.io

A Board Game agent built using Sanity Context and Vercel's AI SDK | Sanity Build a prototype with Claude Code that your whole team can edit | Sanity What’s New - May 2026 | Sanity I built a London pub guide with v0 and the Sanity MCP in six hours. Here's what I learned. | Sanity Build a content-aware Telegram agent with Vercel AI SDK and Chat SDK | Sanity How I used Agent API to generate photos for my family’s recipes | Sanity What’s New April - 2026 | Sanity Better context, better matches: An AI love story (for dogs) | Sanity How to write for an agent | Sanity Content Agent, meet Slack: AI content operations in your workflow | Sanity Structure powers intelligence | Sanity Your agent needs better content. Here's how to give it. | Sanity How to serve content to agents (a field guide) | Sanity Sanity TypeGen GA: Automatic TypeScript types for content and GROQ | Sanity Sanity is now available on the Vercel Marketplace | Sanity The logo soup problem (and how to solve it) | Sanity Content Releases: From scattered updates to coordinated publishing | Sanity What's New - February 2026 | Sanity How we solved the agent memory problem | Sanity v0 Builder Challenge: The winners | Sanity Introducing: Sanity Agent Skills | Sanity Content Agent: Days of work in one conversation | Sanity Our Sanity Values | Sanity Open Source Pledge 2025: Stepping up when it matters | Sanity v0 builder challenge: $3000 in prizes | Sanity Why AI Breaks Without Structured Content Operations | Sanity What’s New January - 2026 | Sanity BFCM 2025: What teams built when infrastructure stopped being the problem | Sanity How AI shaped holiday shopping and what it means for content in 2026 | Sanity Sanity Studio v5: Embracing React 19 | Sanity You’ll need a CMS eventually. Let your agent set it up. | Sanity “You should never build a CMS” | Sanity AI Content Operations: A 30-Day Implementation Guide | Sanity What’s New December - 2025 | Sanity Scheduled Drafts: Stop manually publishing content at midnight | Sanity What’s New November - 2025 | Sanity Everything *[NYC] 2025 recap: A day of AI, Content Operations, and Culture | Sanity Clankers and content operations | Sanity Content Agent: AI that understands your structured content is here | Sanity Why design-driven content modeling creates technical debt, not velocity | Sanity What's New October - 2025 | Sanity From studio to inbox: How Kevin Green eliminated email campaign friction | Sanity The content editor's guide to content operations [E-commerce edition] | Sanity styled-components maintenance mode: A 40% faster fork | Sanity From zero code to a live website in 7 hours (thanks, Cursor!) | Sanity First attempt will be 95% garbage: A staff engineer's 6-week journey with Claude Code | Sanity Internationalization is more than translating words | Sanity What's New - September 2025 | Sanity We just deleted our 35k-member community Slack | Sanity What's New - August 2025 | Sanity The engineer's guide to content operations [E-commerce edition] | Sanity SEO for AI: Evolving from Web Pages to the Content Lake | Sanity What's New - July 2025 | Sanity Sanity Studio v4: A major version bump for a minor reason | Sanity What's New - June 2025 | Sanity Dashboard and Insights: Your New Content HQ | Sanity Canvas: AI-accelerated, context-aware, freeform authoring | Sanity Agent Actions: AI building blocks for structured content | Sanity Functions: Life beyond pressing publish | Sanity A new era for content applications with Sanity App SDK | Sanity The end of CMS era and our $85M Series C. | Sanity What's New – May 2025 | Sanity Introducing the Sanity Model Context Protocol (MCP) server | Sanity What's New – April 2025 | Sanity Pushing all the envelopes with ambitious content | Sanity Self-hosting is only free if your time is worth nothing | Sanity Content that lasts: Scaling beyond your frontend | Sanity The Live Content API is now Generally Available | Sanity The future beyond AI chat bots | Sanity Learning the new skill of working with AI | Sanity What's New - March 2025 | Sanity Give it in plain text: Making your content AI-Ready | Sanity No More 'DO NOT PUBLISH': Introducing Content Releases | Sanity React in 2025, what's next? | Sanity The final boss of front-end: block editors | Sanity Introducing Sanity for Startups | Sanity A block content editor that loves you back | Sanity A Black Friday Snooze Fest: Massive Traffic, No Drama | Sanity How to make a recipe site that scales well | Sanity The Sanity Winter Release 2024 | Sanity AVIF Arrives, Sanity’s Promise Fulfilled | Sanity Sanity joins the Open Source Pledge | Sanity Your content is now Live by default | Sanity Begin Team to Join Sanity | Sanity Sanity Digest - September '24 Edition | Sanity Sanity partners with Google. Now live on the Google Cloud Marketplace. | Sanity Sanity Digest - August ‘24 Edition | Sanity Now playing: the latest Mux Video Input plugin for Sanity | Sanity Community Digest - June ‘24 Edition | Sanity Community Digest - May ‘24 Edition | Sanity Guide to Sanity's newest product announcements | Sanity AI and Content Creation: A Leader's Guide | Sanity Of course, you should be able to type your content quickly! | Sanity New to AI Assist: translation, reference suggestions, image generation | Sanity Speak the language of your editors: Sanity Studio UI localization | Sanity Introducing the new Sanity Growth plan to serve collaborative teams | Sanity Presentation: Work faster than ever with structured content | Sanity Goodbye Feedback Frenzy, Hello Sanity Studio Comments! | Sanity Easing into the App Router with the Sanity Toolkit for Next.js | Sanity Making website updates easier with structured content | Sanity
Build a conference concierge with Agent Context and Anthropic | Sanity
Knut Melvær · 2026-04-23 · via Sanity.io

You're at a conference. You want to see the AI talks, but the schedule is a 47-row spreadsheet organized by time slot, not by topic. You open the conference app and scroll. And scroll. You find one that looks right, but it's in "Room C" and you have no idea where Room C is. You check the venue map (a PDF, naturally). By the time you've figured it out, the talk has started.

Conference attendees have questions that don't fit neatly into a search box. "What talks about AI are on Thursday afternoon?" requires joining sessions, tracks, schedule slots, and rooms. "Is there anything for people new to design systems?" requires understanding topic relationships across the content model. A schedule page can list sessions. It can't understand intent.

For the fictive ContentOps Conf, I built a Telegram bot that attendees can message with exactly these kinds of questions. "What's happening in Room B right now?" "Tell me about the keynote speaker." "Are there any workshops I can still sign up for?" The bot has read access to the full conference content model and answers in natural language. Telegram because that's where conference attendees already are (the group chat, the hallway conversations, the "where are we meeting for dinner?" threads).

The whole thing is about 60 lines of application code across two files. And you can repurpose it to surface the agent on the website, or any other channel supported by Chat SDK. Agent Context also ships with a skill to make it even more effortless to add it to your code base.

This is the attendee side of a two-bot setup. The same Telegram app also has an ops bot for organizers that can read and write content using Sanity's Content Agent API. That bot is covered in a separate post. The two bots share a codebase but use different integration patterns, and the routing between them is a single if statement.

Two patterns, one decision

Before getting into the code, it's worth explaining why the attendee bot uses a different pattern than the organizer bot.

The organizer bot uses Content Agent API. That's a language model provider that bundles content access directly into the model. You call it like any Vercel AI SDK model, but it queries your Content Lake (Sanity's hosted content API) as part of inference. You don't choose the underlying model. You don't manage tools. It's opaque by design, and that's fine for an internal tool where you want simplicity and write access.

The attendee bot uses Agent Context. Agent Context is a different approach: it exposes your Sanity content as MCP (Model Context Protocol, a standard for connecting AI models to external tools) tools, and you bring your own LLM. You create an Agent Context document in Studio, get an MCP endpoint URL, and connect any model to those tools via @ai-sdk/mcp. The model can query your content through the tools but cannot write anything. The access boundary is structural, not prompt-based.

I chose Agent Context for the attendee bot for three reasons:

  1. Attendees only need read access. There's no reason to use a pattern that supports writes.
  2. I wanted to use Claude Sonnet 4.6 specifically. Content Agent API doesn't give you model choice.
  3. I wanted explicit control over the conversation flow, history management, and streaming behavior.

The routing in bot.ts makes the split visible:

Same bot, same Telegram app, two completely different integration patterns depending on who's asking.

Setting up Agent Context

Using the skill

If you're using Claude Code, Cursor, or a similar agent-capable tool, there's a faster path for existing projects. Install the Sanity Agent Context skills:

Then prompt at the root of your repo: "Use the create-agent-with-sanity-context skill to help me build an agent." It handles Studio setup, MCP connection, and scaffolding for your stack. Two companion skills, dial-your-context and shape-your-agent, help you refine the Instructions field on your Agent Context document and craft the system prompt respectively. The manual steps below cover the same ground if you'd rather wire it up yourself.

The manual old-school way

Three things to do before writing any application code.

1. Add the plugin to Studio

Install @sanity/agent-context and add agentContextPlugin() to your sanity.config.ts:

2. Create an Agent Context document in Studio

Once the plugin is installed, you'll see an "Agent Context" section in your Studio. Create a new document there. Give it a name and configure which document types the model can access. When you save, Studio generates an MCP endpoint URL in the format:

That URL is your SANITY_CONTEXT_MCP_URL environment variable.

3. Create a read-only API token

In your Sanity project settings, create a new API token with the Viewer role. This is your SANITY_API_READ_TOKEN. The MCP endpoint requires this token in the Authorization header on every request.

That's three environment variables total for the attendee bot:

  • ANTHROPIC_API_KEY — your Anthropic API key
  • SANITY_CONTEXT_MCP_URL — the MCP endpoint from the Agent Context document
  • SANITY_API_READ_TOKEN — the Viewer role token

The implementation

The application code splits into two files. The first creates the MCP client. The second handles the full message lifecycle.

createMCPClient from @ai-sdk/mcp connects to the Agent Context endpoint over HTTP. mcpClient.tools() fetches the available content tools. These are generated from your Agent Context document configuration and give the model the ability to query your content using GROQ (Sanity's query language). The function returns both the client (needed for cleanup) and the tools (passed to the model).

A few things worth noting here.

fetchSystemPrompt('prompt.botAttendee') fetches the system prompt from the Content Lake at runtime, not from a hardcoded string. This means conference organizers can adjust how the bot behaves without a code change or deploy. That pattern is covered in detail in a separate post on editable AI prompts.

loadConversationHistory(chatId, MAX_HISTORY_MESSAGES) loads the last 10 message pairs for this Telegram thread. The chatId is derived from the Telegram thread ID, so each conversation has its own history. The bot remembers context within a session.

streamText from Vercel AI SDK takes the model, system prompt, message history, and tools together. The stopWhen: stepCountIs(10) guard prevents runaway tool-calling loops. The model gets at most 10 steps to use tools and generate a response. In practice, answering "What talks about AI are on Thursday afternoon?" takes two or three tool calls: one to fetch sessions, one to filter by track or time slot.

The finally block calls mcpClient.close(). This is important. The MCP client holds an open connection to the Agent Context endpoint, and you need to close it explicitly when the request is done. Forgetting this will leak connections.

cleanMarkdownStream and stripMarkdown are Telegram-specific formatting utilities. Telegram's message format doesn't accept raw Markdown, so the stream gets cleaned before posting and the saved version gets stripped for storage.

System prompt from the Content Lake

The fetchSystemPrompt('prompt.botAttendee') call deserves a bit more explanation. Rather than hardcoding the system prompt in the application, it's stored as a prompt document in the Content Lake with the ID prompt.botAttendee. The function fetches it at runtime on every request.

This means the system prompt is editable content. A conference organizer can open Studio, find the "Bot Attendee" prompt document, and change how the bot introduces itself, what topics it declines to answer, or what tone it uses. No PR, no deploy. The change takes effect on the next message.

The full pattern for this, including the schema and the fetchSystemPrompt function, is in Store AI prompts in the CMS, not the codebase.

When to use Agent Context vs Content Agent API

Yes, Agent Context requires more setup than Content Agent API. Three environment variables instead of two, an explicit MCP client, manual lifecycle management. That's a real tradeoff. But the control you get in return is meaningful for public-facing interfaces.

Content Agent API bundles the LLM and content access together. You don't choose the model. It has read and write permissions, and setup is simpler (two environment variables). Best for internal tools and write operations.

Agent Context separates them. You bring your own LLM and get content access as MCP tools. Read-only permissions, full model control, but more setup (three environment variables plus an MCP client). Best for public-facing, read-only interfaces.

The read-only constraint is the most important difference for public-facing bots. With Agent Context, the model literally cannot write to your content. That's not a system prompt instruction that a clever user might talk the model out of. It's a structural boundary enforced by the MCP endpoint. For an attendee-facing bot, that's exactly what you want.

The model choice matters too. Different models have different strengths for conversational tasks, and you may have existing API agreements or cost structures that make one provider preferable. Agent Context doesn't lock you in.

Get started

The full implementation is in the conference-starter repo. The attendee bot code lives in apps/bot/src/handler-attendee.ts and apps/bot/src/ai/agent-context.ts.

To use Agent Context in your own project:

  1. Install @sanity/agent-context and add the plugin to your Studio config
  2. Create an Agent Context document in Studio and copy the MCP URL
  3. Create a Viewer role API token
  4. Install @ai-sdk/mcp and @ai-sdk/anthropic (or your preferred provider)
  5. Use createMCPClient to connect, mcpClient.tools() to get the tools, and pass them to streamText

The Agent Context documentation covers the Studio configuration in more detail, including how to scope which document types the model can access and how to configure the GROQ filters that control what content is visible.

If you need write access or want the simplest possible setup, the Content Agent API post covers that pattern. The two approaches complement each other, and the conference-starter repo shows both running side by side in the same application.

Don't have a Sanity project yet? Create one free and try Agent Context with the conference-starter repo.