Slack Channel

Purpose and Scope

The Slack channel is the first-party integration for putting an eve agent inside a Slack workspace. It is intended for teams that want agent conversations to happen in the place where work is already coordinated: app mentions, direct messages, and threaded replies. The channel handles Slack-specific conversation mechanics while preserving eve's channel contract, so inbound Slack events become agent turns and completed agent output is delivered back to Slack in the correct place.

Sources: docs/channels/slack.mdx

This page focuses on setup and operational behavior rather than general channel authoring. A Slack app mention or direct message is the user-facing trigger, but the deployed eve application receives the event at its Slack route, verifies it through Vercel Connect, and dispatches a session turn only when the configured hooks allow it. That means Slack is not just a transport: it also contributes identity, thread placement, interaction callbacks, and human-in-the-loop controls that shape how the agent behaves in a collaborative workspace.

Sources: docs/channels/slack.mdx

Use Slack when the important context is a team conversation, not a standalone browser chat. The channel replies in threads, shows typing indicators, and converts human-in-the-loop prompts into Slack buttons. Those details matter because they keep agent work anchored to the original Slack conversation and make approval requests feel native to Slack users. The documentation also emphasizes that credentials flow through Vercel Connect, so the application does not manage raw Slack bot tokens or signing secrets directly.

Sources: docs/channels/slack.mdx

Relevant Source Files

  • docs/channels/slack.mdx - First-party Slack channel documentation covering the Connect setup flow, the agent/channels/slack.ts example, dispatch hooks, thread context behavior, typing indicators, and HITL interaction behavior.

Setup Flow

Slack setup starts with Vercel Connect because the Slack channel relies on Connect for both outbound bot credentials and inbound webhook verification. Create a Slack Connect client, copy its UID such as slack/my-agent, and attach the project as the trigger destination for eve's Slack route. The documented route is /eve/v1/slack; the Connect trigger must point there because eve does not serve the default Connect path.

Sources: docs/channels/slack.mdx

npm install -g vercel@latest && export FF_CONNECT_ENABLED=1
vercel connect create slack --triggers
vercel connect detach <uid> --yes
vercel connect attach <uid> --triggers --trigger-path /eve/v1/slack --yes

The FF_CONNECT_ENABLED=1 environment variable enables the feature-flagged Connect commands in the Vercel CLI. The create command provisions a Slack Connect client, while detach followed by attach --trigger-path /eve/v1/slack moves the trigger destination to eve's Slack endpoint. The --triggers flag is essential because it turns on Slack Event Subscriptions; without those subscriptions, Slack will not deliver the app_mention and message.im events that the channel expects.

Sources: docs/channels/slack.mdx

After Connect is prepared, add the channel file. The documentation recommends eve channels add slack for scaffolding, but also shows the manual setup: install @vercel/connect, import connectSlackCredentials from @vercel/connect/eve, import slackChannel from eve/channels/slack, and export the configured channel from agent/channels/slack.ts. The Connect UID is passed to connectSlackCredentials, which returns the credential object that the Slack channel consumes.

Sources: docs/channels/slack.mdx

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

Deploy after the Connect trigger and channel file are both ready. The documented deployment command sets VERCEL_USE_EXPERIMENTAL_FRAMEWORKS=1, allowing the Vercel CLI to recognize eve as a framework during the build. The docs note that eve's setup commands set the same flag, so manual deployment needs to preserve the same environment expectation when moving the Slack-enabled agent into production.

Sources: docs/channels/slack.mdx

VERCEL_USE_EXPERIMENTAL_FRAMEWORKS=1 vercel deploy --prod

Message Handling and Dispatch

The Slack channel exposes dispatch hooks that decide whether an inbound Slack event becomes an eve turn and what authorization context accompanies it. Returning { auth } dispatches the turn, returning null drops it, and returning { auth, context } dispatches while injecting background context into the conversation history. This keeps policy decisions close to the Slack integration while still feeding eve the normalized session input it needs to run the agent.

Sources: docs/channels/slack.mdx

onAppMention(ctx, message) handles app_mention events. The default behavior derives workspace-scoped authorization and posts a Thinking… indicator so users see that the agent is working. onDirectMessage(ctx, message) handles message.im events and requires Slack direct-message history access. Before dispatching direct messages, bot-authored messages and edits are filtered out, which avoids common feedback loops and accidental reprocessing of changed Slack messages.

Sources: docs/channels/slack.mdx

onInteraction(action, ctx) handles Slack block_actions callbacks that are not already consumed by human-in-the-loop flows. This gives applications a channel-specific escape hatch for interactive Slack UI while preserving the built-in HITL behavior. For approval prompts, the Slack channel turns the agent's human-input request into Slack buttons, letting a reviewer respond from the same workspace surface rather than switching to a separate approval console.

Sources: docs/channels/slack.mdx

Speaker attribution is handled deliberately. The docs state that eve attaches the triggering Slack user id to the same model message as the message text. That is important in shared threads because several people can mention the same agent in one conversation. Stable Slack user identifiers preserve who said what without forcing profile lookup requests before the model turn is built.

Sources: docs/channels/slack.mdx

Thread Context

By default, the Slack channel gives the agent the triggering mention but not the earlier replies in the Slack thread. That default keeps each turn focused and avoids automatically expanding context with every historical message. When a threaded conversation itself is the relevant source of truth, enable threadContext so the channel fetches replies and injects them into the turn, with each message attributed by stable Slack user id.

Sources: docs/channels/slack.mdx

import { slackChannel } from "eve/channels/slack";
import { connectSlackCredentials } from "@vercel/connect/eve";
 
export default slackChannel({
  credentials: connectSlackCredentials("slack/my-agent"),
  threadContext: { since: "last-agent-reply" },
});

The documented since: "last-agent-reply" setting is a practical control for repeated mentions in long-running threads. Instead of reinjecting the entire thread on every mention, the channel adds only replies that are new since the agent last answered. That reduces duplicate context, lowers the chance of stale instructions dominating the turn, and keeps Slack threads usable as incremental collaborative workspaces rather than as ever-growing prompt dumps.

Sources: docs/channels/slack.mdx

API Components

The public configuration surface shown by the documentation is intentionally compact. slackChannel() defines the channel, credentials supplies Slack access through Connect, and connectSlackCredentials("slack/my-agent") binds the channel to a Connect client UID. The route target for inbound Slack events is /eve/v1/slack, and the project file convention is agent/channels/slack.ts, matching eve's filesystem-first approach to channel discovery.

Sources: docs/channels/slack.mdx

ComponentPurpose
slackChannel({ ... })Creates the Slack channel definition exported from agent/channels/slack.ts.
credentialsSupplies { botToken, webhookVerifier } through Vercel Connect.
connectSlackCredentials("slack/my-agent")Resolves Slack credentials and verification behavior from a Connect UID.
onAppMention(ctx, message)Decides whether to dispatch Slack app_mention events.
onDirectMessage(ctx, message)Decides whether to dispatch Slack message.im direct-message events.
onInteraction(action, ctx)Handles Slack block_actions callbacks not consumed by HITL.
threadContext: { since: "last-agent-reply" }Fetches and injects newer thread replies for context-aware turns.
/eve/v1/slackInbound Slack trigger route used by Vercel Connect.

Operational Notes and Next Steps

The most common setup mistakes are routing and subscription related. The Connect client must be attached to /eve/v1/slack, not the default Connect trigger path, and the --triggers option must be enabled so Slack delivers event subscriptions. If mentions or DMs do not reach the agent, verify the Connect UID used in connectSlackCredentials, confirm that the trigger destination was reattached, and check that Slack Event Subscriptions include the event types the channel handles.

Sources: docs/channels/slack.mdx

After the basic channel works, decide how much Slack context the agent should see and what authorization object should represent a Slack user or workspace. Start with the default dispatch behavior for a workspace-scoped prototype, then customize the hooks when your app needs tenant-specific authorization, channel allowlists, or different handling for DMs versus shared channels. For broader channel behavior, read Channels Overview and Custom Channels next; for production access decisions, read Auth and Route Protection.