{"slug": "your-slack-bot-s-database-is-now-a-claude-session", "title": "Your Slack Bot's Database Is Now a Claude Session", "summary": "Vercel's new template, vercel-labs/cma-chat-sdk, wires Claude Managed Agents into Chat SDK for Slack bots, storing only a session ID in Redis instead of message history. The roughly 300-line TypeScript bridge creates an Anthropic session per Slack thread, streams agent events via SSE, and disables bash to prevent prompt-injection exfiltration. The template pins agent versions and checks session ownership, but long-lived SSE on serverless is limited to five minutes per turn.", "body_md": "[AI](https://sourcefeed.dev/c/ai)Article\n\n# Your Slack Bot's Database Is Now a Claude Session\n\nVercel's template wires Claude Managed Agents into Chat SDK, and the thin bridge is the point.\n\n[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)\n\nEvery Slack bot I've built with an LLM has the same ugly middle: a table of thread IDs mapped to message arrays, a job that replays that history into each model call, and a growing pile of code to keep the two in sync. Vercel's new template for running [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview) behind [Chat SDK](https://chat-sdk.dev) deletes that middle. The transcript lives in an Anthropic session. Your Redis holds one string per thread: the session ID.\n\nThat's the whole idea, and it's a better one than the \"Slack research bot\" framing suggests.\n\n## What the bridge is\n\nChat SDK is Vercel's `npm i chat`\n\nlibrary, open-sourced in February as a public beta: one handler, adapters for Slack, Teams, Google Chat, Discord, GitHub, Linear, Telegram and WhatsApp. Its `thread.post()`\n\naccepts any `AsyncIterable<string>`\n\n, which is the hook everything hangs on.\n\nManaged Agents went into public beta in April. You create an agent (model, system prompt, tool policy) once, then open sessions against it. Anthropic runs the loop, the sandbox, and the web search and fetch tools, and streams events back over SSE.\n\nThe template ([vercel-labs/cma-chat-sdk](https://github.com/vercel-labs/cma-chat-sdk)) is roughly 300 lines of TypeScript connecting the two. On a new mention it creates a session with the Slack thread ID in the metadata, stores the session ID in thread state, then for every turn it opens the event stream with `event_deltas: [\"agent.message\"]`\n\n, sends a `user.message`\n\n, and feeds the deltas through the SDK's `accumulateManagedAgentsEvent`\n\nhelper into an async generator that `thread.post()`\n\nconsumes. On Slack that lands as native streaming. Swap the adapter and the same generator becomes post-and-edit on Discord, or a single buffered message on WhatsApp.\n\nAnthropic ships a browser version of the same analyst in its quickstarts using Chat SDK's web adapter, alongside assistant-ui and CopilotKit variants. Vercel's version is the Slack port with Redis and Vercel Connect wired in.\n\n## The parts that earn attention\n\nA few decisions in the template are worth stealing even if you never deploy it.\n\nBash is off. The agent gets `agent_toolset_20260401`\n\nwith `permission_policy: always_allow`\n\nfor web search and fetch, and `bash`\n\nexplicitly disabled. The README says why: the analyst reads untrusted web pages, and an auto-approved shell with open networking is a prompt-injection exfiltration path. An always-allow policy plus a read-only tool surface is the right trade for an unattended bot. If you ever flip bash on, you need a confirmation flow, and the template's own error message tells you it doesn't have one.\n\nSession ownership is checked, not assumed. Before each turn the code retrieves the session and verifies `session.agent.id`\n\nmatches the configured agent and the session isn't archived or terminated. Thread state is untrusted input.\n\nTurns are anchored. The bridge records the ID of the `user.message`\n\nit just sent and ignores stream events until it sees that ID echoed back. That's what makes the design survive multiple serverless instances handling the same thread; the process-local queue only orders turns within one instance.\n\nAgent versions are pinned. Editing the prompt and running `npm run cma:update`\n\npublishes a new version, but existing sessions keep the version they started on. Old Slack threads won't change behavior under you. That's a feature, and it's also a thing to remember when a \"fixed\" prompt doesn't seem fixed in a week-old thread.\n\n## Where it hurts\n\nLong-lived SSE on serverless is still awkward. The webhook route sets `maxDuration = 300`\n\nand uses Next.js `after()`\n\nas `waitUntil`\n\n, so a turn has five minutes. The stream can drop, and the template's answer is a Slack message asking you to wait and not resend. Vercel's own April guide for Managed Agents took the opposite approach: Vercel Workflow polling the events API every three seconds and releasing the function between polls. Polling is uglier and more durable. Pick based on how often your research turns run past a couple of minutes.\n\nToken streaming may not stream. Anthropic's quickstart README notes that `event_deltas`\n\npreviews are gated per organization; without them, replies arrive whole when the turn finishes. The bridge handles both paths, but test what your org gets before promising \"token-by-token\" to anyone.\n\nData residency rules you out or it doesn't. Sessions are stateful by design, and Anthropic's docs say Managed Agents isn't eligible for Zero Data Retention or a HIPAA BAA. If your Slack workspace is where regulated conversations happen, this isn't your architecture yet.\n\nThe cost model is fine for chat and worth checking for anything else. Runtime is $0.08 per session-hour, billed only while the session is `running`\n\n; idle threads cost nothing. Web search adds $10 per 1,000 searches; fetch is token cost only. A research turn on `claude-sonnet-5`\n\n(the template's default) that takes 90 seconds and runs a handful of searches is pennies. The number to watch is input tokens, since the session replays context every model request. The template's debug mode posts per-turn token and cache-hit stats to the thread, which is the right way to find out.\n\n## Adopting it\n\nIf you're on Vercel with an Anthropic key, the setup is short: `pnpm install`\n\n, `vercel connect create slack`\n\n, add Upstash Redis, `npm run cma:setup -- --vercel`\n\nto provision the agent and environment and push both IDs into the project, then `vercel deploy --prod`\n\n. Node 24, Next.js 16, Chat SDK 4.38, Anthropic SDK 0.120.\n\nIf you already have a Chat SDK bot running on AI SDK, this is a different contract, not a drop-in. You give up your own tool loop, your own context management, and your own storage of the transcript. In return you stop owning three things that break. Whether that's a win depends on whether your bot needs tools that must run on your side of the wall. Managed Agents supports custom tools and MCP servers, but this template uses neither, and once you're hosting tool execution yourself you've lost a chunk of the \"no infrastructure\" argument.\n\n## Verdict\n\nThe integration itself is glue. The pattern is the news: chat thread equals agent session, and the bot becomes a stateless adapter between a messaging platform and a hosted harness. That's where most \"agent in Slack\" products will end up, because the alternative is every team rebuilding the same history table and replay loop.\n\nShip it for internal research and ops bots today, with bash off and a Redis you trust. Don't ship it for regulated data, and don't call the streaming token-level until you've watched your own org's stream. Both products are still beta, and the Anthropic session is now the system of record for your conversations, which is a dependency you should name in your architecture doc before someone asks where the transcripts went.\n\n## Sources & further reading\n\n-\n[Run Claude Managed Agents with Chat SDK](https://vercel.com/changelog/claude-managed-agents-with-chat-sdk)— vercel.com -\n[vercel-labs/cma-chat-sdk: Build with Claude Managed Agents and Chat SDK](https://github.com/vercel-labs/cma-chat-sdk)— github.com -\n[Claude Managed Agents quickstart: Chat SDK research analyst](https://github.com/anthropics/claude-quickstarts/tree/main/managed-agents/chat-sdk)— github.com -\n[Claude Managed Agents overview](https://platform.claude.com/docs/en/managed-agents/overview)— platform.claude.com -\n[Session event stream and event deltas](https://platform.claude.com/docs/en/managed-agents/events-and-streaming)— platform.claude.com -\n[Claude pricing, including Managed Agents session runtime](https://platform.claude.com/docs/en/about-claude/pricing)— platform.claude.com -\n[Chat SDK streaming](https://chat-sdk.dev/docs/streaming)— chat-sdk.dev -\n[Introducing npm i chat: One codebase, every chat platform](https://vercel.com/changelog/chat-sdk)— vercel.com\n\n[Rachel Goldstein](https://sourcefeed.dev/u/rachel_goldstein)· Dev Tools Editor\n\nRachel has been embedded in the developer tooling ecosystem for nearly eight years, covering everything from IDE wars and package-manager drama to the quiet rise of AI-assisted coding. She has a soft spot for open-source maintainers and an unhealthy number of terminal emulators installed on a single laptop.\n\n## Discussion 0\n\nNo comments yet\n\nBe the first to weigh in.", "url": "https://wpnews.pro/news/your-slack-bot-s-database-is-now-a-claude-session", "canonical_source": "https://sourcefeed.dev/a/your-slack-bots-database-is-now-a-claude-session", "published_at": "2026-08-27 17:09:09+00:00", "updated_at": "2026-08-27 17:21:31.589418+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["Vercel", "Claude Managed Agents", "Chat SDK", "Anthropic", "Redis", "vercel-labs/cma-chat-sdk"], "alternates": {"html": "https://wpnews.pro/news/your-slack-bot-s-database-is-now-a-claude-session", "markdown": "https://wpnews.pro/news/your-slack-bot-s-database-is-now-a-claude-session.md", "text": "https://wpnews.pro/news/your-slack-bot-s-database-is-now-a-claude-session.txt", "jsonld": "https://wpnews.pro/news/your-slack-bot-s-database-is-now-a-claude-session.jsonld"}}