New Project
A Slack-based Sanity copilot built on eve. It queries and edits content with GROQ, shapes schemas, manages releases, and drafts into Notion.

A Slack-based Sanity copilot built on eve. Team members @mention it in Slack and it manages their Sanity project: querying and editing content with GROQ, inspecting and shaping schemas, creating and editing drafts, managing releases, and drafting content pieces into Notion. Long-form drafts are shared as Notion pages.
Deploying with the button provisions everything the agent needs and wires it up for you:
SLACK_CONNECTOR, with the event trigger pointed at /eve/v1/slack),SANITY_CONNECTOR),NOTION_CONNECTOR),Once deployed, @mention the bot in your Slack workspace to start working on your Sanity project.
| Layer | Technology |
|---|---|
| Agent framework | eve |
| Language | TypeScript (strict, ESM) |
| Chat surface | Slack, via Vercel Connect |
| Content management | Sanity (MCP), user-scoped OAuth via Vercel Connect |
| Drafting surface | Notion (MCP), user-scoped OAuth via Vercel Connect |
| File storage | Vercel Blob |
| Model access | Vercel AI Gateway |
| Sandbox | Vercel Sandbox |
| Lint & format | Ultracite (Biome) |
Zero static keys. Authentication runs entirely on Vercel Connect (Slack, Sanity, and Notion) and Vercel OIDC (Vercel Blob and AI Gateway). There are no API keys or client secrets to manage in code or .env files: Sanity and Notion are authorized per user in the browser, and Blob and the model authenticate with the project's OIDC token.
If you're working with an AI coding agent like Claude Code or Cursor, you can use this prompt to have it help you with building your agent:
I want to build a Slack agent with the eve framework, using the Sanity copilot template. Read the setup instructions at https://agent-resources.dev/sanity-copilot-eve-template.md and follow them. They will cover deploying the template, building with eve, how everything works overall, and more.
agent/agent.ts # model configuration, compaction, session token limitsinstructions.md # the agent's behaviorchannels/slack.ts # Slack surface (Vercel Connect credentials)eve.ts # dev TUI surface for local developmentconnections/sanity.ts # Sanity MCP, user-scoped OAuth; destructive tools require approvalnotion.ts # Notion MCP, user-scoped OAuth; page updates/moves require approvalsandbox.ts # Vercel Sandbox backendsubagents/researcher/ # fresh-context web researcher (own session, web tools only)reviewer/ # fresh-context draft reviewer (own session)skills/writing-quality/ # its own copy of the writing-quality rubricsandbox.ts # its own sandbox backendtools/upload_asset.ts # Vercel Blob: store text or binary contentlist_assets.ts # Vercel Blob: browse stored assetsget_asset_info.ts # Vercel Blob: metadata without downloadingdownload_asset.ts # Vercel Blob: read a stored file backdelete_asset.ts # Vercel Blob: delete (requires approval)get_user_preferences.ts # load this user's saved preferencessave_user_preferences.ts # save standing preferences (per-user, principal-scoped)clear_user_preferences.ts # clear this user's preferences (requires approval)lib/user-preferences.ts # principal-scoped Blob key + reserved-prefix guardskills/sanity-best-practices/ # schemas, GROQ, releases, framework integrationscontent-modeling-best-practices/ # designing and refactoring content typesportable-text-conversion/ # converting rich text into Portable Textportable-text-serialization/ # rendering Portable Text out to other formatsseo-aeo-best-practices/ # metadata, structured data, AI-answer readinesscontent-experimentation-best-practices/ # A/B tests and variantswriting-quality/ # prose rules for anything written for humans
All of the skills except writing-quality come from Sanity's Agent Toolkit; the sanity-best-practices references are also the canonical content behind the Sanity MCP server's rules tools.
The eve content agent template is a full content assistant: per-surface style skills (blog, LinkedIn, X, release notes, newsletters), a house voice, and a style lint. Instead of merging all of that into this copilot, you can deploy it as its own agent and let the copilot delegate to it through eve's remote agents feature.
vercelOidc() handles deployment-to-deployment auth with no shared secret:// agent/subagents/content_writer.tsimport { defineRemoteAgent } from "eve";import { vercelOidc } from "eve/agents/auth";export default defineRemoteAgent({url: () => process.env.CONTENT_AGENT_URL ?? "https://your-content-agent.vercel.app",description:"Drafts blog posts, LinkedIn and X posts, release notes, and newsletters in the house voice. " +"Pass the surface, the source material, and any constraints in the message.",auth: vercelOidc(),});
CONTENT_AGENT_URL in this project's environment and mention the new subagent in agent/instructions.md so the copilot knows when to hand off.The remote agent runs in its own deployment with its own skills and connections, and it never sees this copilot's conversation history, so the copilot packs everything the writer needs into the call message. The result comes back as a normal tool result, the same shape as the local researcher and reviewer subagents.
Link the project you deployed (or a fresh one) and pull its environment:
vercel linkvercel env pull
Then run the development server and link a model provider with /model in the TUI:
pnpm dev
You can chat with the agent directly in the dev TUI to test the Sanity, Notion, and Blob flows. The Slack surface itself only runs against a deployment. Ship changes with:
eve deploy
This project uses Ultracite (a Biome preset) for linting and formatting:
pnpm check # check formatting and lint rulespnpm fix # auto-fix what is fixablepnpm validate # lint + typecheck + eve discovery diagnostics
The Deploy button provisions these for you. To set them up manually (for a project you didn't create with the button), use the Vercel CLI:
# Sanity connector (note the printed UID, e.g. sanity/<name> -> SANITY_CONNECTOR)vercel connect create mcp.sanity.io --name sanity# Notion connector (note the printed UID, e.g. notion/<name> -> NOTION_CONNECTOR)vercel connect create mcp.notion.com --name notion# Slack connector (note the UID, e.g. slack/<name> -> SLACK_CONNECTOR), then point its# event trigger at the route the agent servesvercel connect create slack --name <name> --triggersvercel connect attach slack/<name> --triggers --trigger-path /eve/v1/slack# Blob store, connected to the project for all environmentsvercel blob create-store <name> --access public --yes
agent/instructions.md. It describes the whole workflow: load the right skill first, ground work in the real project with GROQ and schema reads, work in drafts and publish only on approval, draft long pieces into Notion, and get a fresh-eyes review before proposing a draft.APPROVAL_REQUIRED_TOOLS lists in agent/connections/sanity.ts and agent/connections/notion.ts to change which MCP tools pause for a human decision.agent/skills/. Each folder holds a SKILL.md plus its reference files. The reviewer subagent keeps its own copy of writing-quality under agent/subagents/reviewer/skills/.agent/agent.ts (or run /model in the dev TUI).agent/tools/. The filename is the tool name.The agent auto-updates as you edit these files.
writing-quality.