Skip to content
Docs

Build your first Slack agent with Eve

Deploy the Eve Slack agent template: a starter Slack bot built on the Eve framework with an example tool and skill, deployed to Vercel with Vercel Connect and no API keys.

8 min read
Last updated June 17, 2026

Stand up a Slack bot powered by an AI agent, then make it your own. This template is the minimal Eve starter: a single agent that answers @mentions in Slack, calls a tool when it needs live data, and follows a skill for multi-step tasks. It's the smallest complete example to learn the framework from.

The bot is built on Eve, a filesystem-first framework for durable backend agents from Vercel. Slack authenticates through Vercel Connect, and the model runs through the Vercel AI Gateway using your linked project, so there are no API keys or secrets to set.

Deploy the template now, or read on for how it works.

Eve Slack Agent Template

A starter Slack bot built on Eve, with one example tool and one skill. Deploy it, @mention it, and start building.

Deploy Template

If you're working with an AI coding agent like Claude Code or Cursor, you can clone the template and hand it off with this prompt:

AI Prompt
I want to build a Slack agent with the Eve framework.
Clone the repo at https://github.com/vercel-labs/eve-slack-agent-template, read the AGENTS.md and README.md files to understand how it works.
Install dependencies with pnpm, then help me run it locally with `pnpm dev` and deploy with `eve deploy`.
The example tool is agent/tools/get_weather.ts and the example skill is agent/skills/plan_a_trip.md; help me add my own tool and skill. When searching for information, check for applicable skill(s) first and review the local Eve docs under node_modules/eve.

Turn your agent into a Vercel expert with this plugin. It provides your coding agent with up-to-date knowledge of the Vercel products this template uses, including Vercel Connect and AI Gateway. The plugin is optional; it's not required to use Eve or for this guide.

Terminal
npx plugins add vercel/vercel-plugin

You need two accounts to deploy and run the agent:

  • A Vercel account.
  • A Slack workspace where you can install an app. The Deploy button installs a Vercel-managed Slack app for you.

For local development, you also need Node.js 24 or newer, pnpm, and the Vercel CLI.

Deploying with the button provisions the one service this agent needs and wires it up:

The Slack connector, with its event trigger pointed at the route Eve serves (/eve/v1/slack) and the connector UID stored in SLACK_CONNECTOR. The connector uses Vercel Connect, so you authorize Vercel's managed Slack app in the browser instead of registering an OAuth client or copying secrets.

When the deployment finishes, your agent is live. All that's left is to bring it into Slack.

Invite the bot to a channel in your workspace, then @mention it to start a thread. Try a question that exercises the example tool, such as "what's the weather in Lisbon?", or a multi-step request that triggers the skill, such as "help me plan a weekend in Lisbon." The agent replies in the thread, keeping the conversation's context as you go back and forth.

You can't test the Slack surface locally, because Slack forwards events to Vercel Connect, which delivers them to your deployed project rather than to a local URL. Test the inbound Slack path against a preview or production deployment; everything else runs in the local dev terminal UI (TUI).

You can run the full agent locally in a TUI, with one exception: the Slack surface only runs against a deployment. Link the project you deployed and pull its environment first:

Terminal
vercel link
vercel env pull

Then start the dev server and link a model provider with /model in the TUI:

Terminal
pnpm dev

Chat with the agent directly in the TUI to exercise its instructions, the get_weather tool, and the plan_a_trip skill. Ship changes to production with eve deploy:

Terminal
eve deploy

Use eve deploy rather than vercel deploy. Eve is an experimental framework that Vercel's default deploy can't auto-detect; eve deploy wraps vercel deploy --prod, installs dependencies, and pulls environment variables.

The agent runs a short loop on every @mention: read the message, decide whether a tool or skill helps, and reply in the thread.

  1. @mention in Slack. A writer @mentions the bot or DMs it. The Slack channel turns the message into a session and threads every reply.
  2. The model reads its instructions. Claude Haiku 4.5 runs with the system prompt in agent/instructions.md, which tells it to stay concise and use tools when they help.
  3. It calls a tool or loads a skill when useful. For a weather question or a weather-dependent plan, it calls the get_weather tool. For a trip-planning request, it loads the plan_a_trip skill, which adds step-by-step guidance to the turn.
  4. It replies in the thread. The answer goes back to Slack, and the thread's context carries into the next message.

Tools run in your app runtime with full access to process.env, so they can call real APIs and read configuration. Skills are loaded on demand and only add instructions to the turn; they never add a new action the agent can take.

The whole agent is defined under agent/, and Eve discovers each capability from the filesystem. A tool's, skill's, or channel's filename is its name, so there's no central registry to wire up. The starter is five short files.

The model is one line:

agent/agent.ts
import { defineAgent } from "eve";
export default defineAgent({
model: "anthropic/claude-haiku-4.5",
});

The id routes through the Vercel AI Gateway, which authenticates through your linked project, so there's no provider API key to set. Claude Haiku 4.5 is a fast model that's a sensible default for a starter agent. To use a more capable model for harder tasks, change the string to another Gateway id such as anthropic/claude-opus-4.8, or run /model in the dev TUI.

instructions.md is the agent's always-on system prompt. Eve prepends it to every model call, and in this template it's deliberately small:

agent/instructions.md
# Identity
You are a concise assistant. Use tools when they are available.
Use `get_weather` before answering questions about current weather or suggesting
weather-dependent plans.

This is where you shape the agent's personality and rules. Naming a tool here, as it does with get_weather, nudges the model to reach for it at the right time.

The Slack surface is one file. It hands Eve a set of Slack credentials brokered by Vercel Connect:

agent/channels/slack.ts
import { connectSlackCredentials } from "@vercel/connect/eve";
import { slackChannel } from "eve/channels/slack";
export default slackChannel({
credentials: connectSlackCredentials(
process.env.SLACK_CONNECTOR ?? "slack/my-agent"
),
});

connectSlackCredentials reads the connector UID from SLACK_CONNECTOR (the value the Deploy button sets) and lets Vercel Connect handle token rotation and webhook verification, so none of that lives in your code. Because the file is slack.ts, Eve registers it as the slack channel and serves its events at /eve/v1/slack. The "slack/my-agent" fallback is only a default for when the environment variable isn't set.

A tool is a typed action the model can call. This one takes a city and returns the weather:

agent/tools/get_weather.ts
import { defineTool } from "eve/tools";
import { z } from "zod";
export default defineTool({
description: "Get the current weather for a city.",
inputSchema: z.object({ city: z.string().min(1) }),
async execute({ city }) {
return { city, condition: "Sunny", temperatureF: 72 };
},
});

Three things make this a complete tool: a description the model uses to decide when to call it, a Zod inputSchema that validates and types the arguments, and an execute function that does the work. The filename is the tool name, so the model sees this as get_weather. Tool filenames must be snake_case ASCII. This starter returns fixed data; replacing the body with a real API call is the first change most people make.

A skill is a procedure the model loads on demand instead of carrying on every turn. This one guides trip planning:

agent/skills/plan_a_trip.md
---
description: Use when the user wants help planning a trip or deciding what to do in a destination.
---
When planning a trip:
1. Ask for the destination and dates if the user has not given them.
2. Check the destination's weather with the `get_weather` tool before suggesting activities.
3. Suggest a short itinerary that fits the weather: outdoor activities when it is clear, indoor alternatives otherwise.
4. Keep the plan concise — a few bullet points per day, not an essay.

The description in the frontmatter is a routing hint, not a label. Eve exposes it to the model alongside a built-in load_skill tool, and the model loads the skill only when a request matches the description. This is a flat-file skill: a single markdown document. For a larger procedure, a skill can also be a folder with supporting files.

Because Eve discovers everything from the filesystem, extending the agent is mostly adding files:

  • Add a tool. Create a new file in agent/tools/ that default-exports a defineTool. The snake_case filename becomes the tool name, and Eve picks it up with no registration step. Mention it in agent/instructions.md if you want the model to prefer it.
  • Call a real API. Replace the body of agent/tools/get_weather.ts with a real request. Tools run in your app runtime with full process.env, so read any provider key from the environment (set it on your Vercel project) rather than hardcoding it.
  • Add a skill. Drop a markdown file in agent/skills/ with a description frontmatter. Eve loads it on demand when a request matches the description.
  • Change the model. Edit agent/agent.ts (any AI Gateway model id works) or run /model in the dev TUI.
  • Change behavior. Edit agent/instructions.md to reshape the agent's tone and rules.

The agent auto-updates as you edit these files, so you can iterate in the dev TUI and see changes immediately.

Each item below lists a symptom, its cause, and the fix.

Symptom: You @mention the bot in Slack, but it doesn't reply.

Cause: The bot isn't in the channel yet, or the deployment that registered the Slack trigger hasn't finished.

Fix: Invite the bot to the channel and confirm the deployment succeeded, then @mention it again. The Deploy button points Slack's events at the route the agent serves (/eve/v1/slack), so the path is already correct.

Symptom: A turn shows "Working…" in the dev TUI with no visible progress.

Cause: The TUI hides logs by default, so a normal multi-step turn can look stalled.

Fix: Show logs with npx eve dev --logs all, or run /loglevel all in the session.

Symptom: get_weather returns the same result for every city.

Cause: The example tool returns hardcoded data; it doesn't call a real weather service.

Fix: This is expected for the starter. Replace the body of agent/tools/get_weather.ts with a call to a real weather API.

No. The Slack channel authenticates through Vercel Connect, and the model runs through the Vercel AI Gateway using your linked project, so there are no keys to store in code. If you wire the example tool up to a real third-party API, that provider's key is the one exception, and it lives in your environment rather than in code.

Not the Slack surface. Slack forwards events to Vercel Connect, which delivers them to your deployed project rather than to a local URL, so test Slack against a preview or production deployment. You can chat with the agent and exercise its tool and skill in the local dev TUI with pnpm dev.

The get_weather tool ships with stub data so the template runs with no external setup. Replace its body with a real API call to get live results.

Add a file under agent/tools/ (a defineTool default export, where the filename is the tool name) or a markdown file under agent/skills/ (with a description frontmatter). Eve discovers both from the filesystem, with no registration step.

Claude Haiku 4.5, set in agent/agent.ts and routed through the Vercel AI Gateway. Change the string to any Gateway model id (for example, anthropic/claude-opus-4.8) or run /model in the dev TUI.

Was this helpful?

supported.