When eve doesn’t ship a channel for your surface, you build one. Custom channels expose HTTP or WebSocket endpoints, parse incoming requests, start or resume sessions, observe runtime events, and deliver responses back to your platform.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/vercel/eve/llms.txt
Use this file to discover all available pages before exploring further.
File location and identity
Custom channels live inagent/channels/ at the root agent. The file stem becomes the channel id, so agent/channels/internal-webhook.ts is addressed as internal-webhook. Export the channel definition as the module’s default export.
Defining a channel
ImportdefineChannel and the route verb helpers from eve/channels:
agent/channels/my-channel.ts
Route verbs
The following route verb helpers are available fromeve/channels:
| Verb | Helper | Use case |
|---|---|---|
GET | GET() | Streaming endpoints, health checks |
POST | POST() | Webhook receivers, message ingestion |
PUT | PUT() | Full-replace update webhooks |
PATCH | PATCH() | Partial-update webhooks |
DELETE | DELETE() | Deletion notifications |
WS | WS() | Real-time bidirectional connections |
Request and a helpers object:
| Helper | Description |
|---|---|
send() | Starts or resumes a session. Returns a Session. |
getSession() | Looks up an existing session by id. The returned Session exposes getEventStream(). |
receive() | Hands inbound work to a different channel (cross-channel hand-off). |
params | Route parameters extracted from the path pattern. |
waitUntil() | Extends the request lifetime for background work. |
requestIp | The client IP address, or null when the host cannot provide it. |
The events map
Event handlers are declared under the events key and receive (eventData, channel, ctx):
eventData— the event payloadchannel— platform handles and session continuation operationsctx— the eveSessionContext
session.failed, which receives only (eventData, channel) with no ctx.
WebSocket routes
UseWS() when a custom channel needs a WebSocket endpoint. The route handler runs once per upgrade request and returns lifecycle hooks for that connection:
agent/channels/voice.ts
WS() handlers receive the same helpers as HTTP route handlers: send, getSession, receive, params, waitUntil, and requestIp. The returned hooks are compatible with Nitro/H3 websocket routing and include upgrade, open, message, close, and error.
Node upgrade server escape hatch
When a third-party SDK expects to bind directly to a Nodehttp.Server via server.on("upgrade", ...), use createWebSocketUpgradeServer():
agent/channels/vendor.ts
The bridge server does not listen on its own port. It receives only upgrade
events that matched the eve route. Treat it as a compatibility adapter for
libraries with server-binding APIs, not the primary way to build WebSocket
channels in eve.
Cross-channel hand-off
Route handlers can start a session on a different channel viaargs.receive(channel, ...). Use this when an inbound request on one channel should pivot the conversation onto another — for example, an incident webhook that opens an investigation thread in Slack:
agent/channels/incident-webhook.ts
- The first argument to
args.receive(...)is the target channel module’s default export — import it directly fromagent/channels/<name>.ts. authflows through tosession.auth.initiatorso the target’s handlers and the agent’s tools can read who started the session.- Calling
args.receive(...)does not also start a session on the current channel.
Channel metadata
A channel can project a subset of its adapter state as metadata, available to instrumentation resolvers, dynamic tool resolvers, and dynamic skill or instruction resolvers. Define ametadata(state) function on the channel config:
agent/channels/my-channel.ts
ctx.channel.metadata and narrow it with isChannel. When a parent agent dispatches a subagent, the framework forwards the parent’s channel metadata projection to the child.
Continuation tokens
Each call tosend(message, { auth, continuationToken }) addresses a session by its channel-local raw token. The framework prepends the channel name (derived from the file stem) before handing the token to the runtime.
Built-in channels export helpers that construct the correct format:
Late-bound continuation tokens
When the identity that should address a session is not known until later, re-key the parked session by callingsession.setContinuationToken(...). Pass the channel-local raw token; the runtime preserves the current channel namespace:
agent/channels/my-channel.ts
File uploads
send() accepts string | UserContent. To include file attachments, pass a UserContent array mixing text and file parts:
agent/channels/my-channel.ts
Authenticated file URLs
For platforms like Slack where files sit behind authenticated URLs, put aURL object in FilePart.data and declare fetchFile on the channel config. The staging pipeline calls fetchFile with the URL serialized as a string (url.href):
agent/channels/my-channel.ts
null to let the URL pass through to the model provider. The framework handles staging, enforcing upload policy, hydrating files for the model call, and reconstituting URL objects after queue serialization.
Auth helpers
Theeve/channels/auth module provides helpers for the eve HTTP channel’s route auth policy:
agent/channels/eve.ts
| Helper | Description |
|---|---|
localDev() | Accepts requests during local development |
vercelOidc() | Allows the local CLI and Vercel-issued deployment tokens from the same team |
placeholderAuth() | Returns a setup-focused 401 in production until replaced with real auth |
localDev() and vercelOidc() are for trusted infrastructure only. For
browser users or external clients, wire in your own auth (Clerk, Auth.js,
OIDC/JWT, API-key verifier, or a custom AuthFn).Channels Overview
Understand the channel contract, the eve HTTP channel default, and how to scaffold channel files.
Platform Channels
Ready-made adapters for Slack, Discord, Teams, Telegram, Twilio, and GitHub.