# Build your first Slack agent with eve

**Author:** Ben Sabic, Allen Zhou

---

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 responds to @mentions in Slack, invokes a tool when it needs live data, and follows a skill for multi-step tasks. It's the smallest complete example for learning the framework.

The bot is built on [eve](https://beta.eve.dev), a filesystem-first framework for durable backend agents from Vercel. Slack authenticates through [Vercel Connect](https://vercel.com/docs/connect), and the model runs through the [Vercel AI Gateway](https://vercel.com/docs/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.

## Quick start with an AI coding agent

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:

### Vercel Plugin

Turn your agent into a Vercel expert with this [plugin](https://vercel.com/docs/agent-resources/vercel-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 for this guide.

`npx plugins add vercel/vercel-plugin`

## Setup and deployment

### What you need before deploying

You need two accounts to deploy and run the agent:

- A [Vercel account](https://vercel.com/signup).
  
- 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](https://vercel.com/docs/cli).

### Deploy to Vercel

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.

### Use it in 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).

### Local development

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:

`vercel link vercel env pull`

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

`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`:

`eve deploy`

Use `eve deploy` rather than `vercel deploy`. The command wraps `vercel deploy --prod`, installs dependencies, and pulls environment variables.

## How the agent works

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.

## Code walkthrough

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, `agent/agent.ts`

The model is one line:

`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.

### Behavior, `agent/instructions.md`

`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:

``# 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, `agent/channels/slack.ts`

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

`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` and lets Vercel Connect handle token rotation, multi-workspace tenancy, 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, `agent/tools/get_weather.ts`

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

`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, `agent/skills/plan_a_trip.md`

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

``--- 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.

## Make it your own

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](https://vercel.com/ai-gateway/models) 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.

## Troubleshooting

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

### @mentions don't get a response

**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.

### The bot sits on "Working…"

**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.

### The weather is always "Sunny, 72°F"

**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.

## Related resources

- [eve Slack agent template](https://github.com/vercel-labs/eve-slack-agent-template)
  
- [eve documentation](https://eve.dev/docs)
  
- [Vercel Connect](https://vercel.com/docs/connect)
  
- [Vercel AI Gateway](https://vercel.com/docs/ai-gateway)

---

[View full KB sitemap](/kb/sitemap.md)
