One directory, one agent
eve is an open-source agent framework built around a simple premise: an agent should be defined by what it does, not by the plumbing required to run it in production. Every agent is a directory where each file describes one component — its identity, tools, and behavior are readable at a glance.
agent/
agent.ts # the model it runs on
instructions.md # who it is
tools/
run_sql.ts # what it can do
post_chart.ts
skills/
revenue-definitions.md # what it knows
subagents/
investigator/ # who it delegates to
channels/
slack.ts # where it lives
schedules/
monday-summary.ts # when it acts on its own
That structure means an agent's definition starts with two files. agent.ts configures the model (with provider fallbacks via AI Gateway) and optional fields for compaction and model options. An instructions.md file serves as the system prompt, prepended to every model call.
import { defineAgent } from "eve";
export default defineAgent({
model: "anthropic/claude-opus-4.8",
});
You are a senior data analyst. You answer questions about the team's data.
- Prefer exact numbers to hand-waving. If you can compute it, compute it.
- State the assumptions behind any number you report (date range, filters, grain).
- Use the tools available to you rather than guessing. If you cannot answer from
the data, say so plainly.
Additional files in the directory — for tools, skills, or connections — get picked up automatically at build time. No registration boilerplate, no wiring. eve owns the agent loop the way Next.js owns routing.
Why eve exists
The team behind eve spent years shipping agents at Vercel, including v0. Once coding agents made building one accessible, hundreds of internal agents followed — and so did a recurring pattern. Every team built the same harness: durable execution, sandboxing, approvals, tracing. Each agent solved the same infrastructure problems from scratch, and none of it carried over.
Agents have a shape. eve is that shape turned into a framework, the same way Next.js standardized web application structure.
Production features included
Rather than assembling infrastructure, eve ships with it.
Durable sessions
Every conversation is a durable workflow backed by the open-source Workflow SDK. Each step is checkpointed, so sessions survive crashes and deploys and resume exactly where they stopped — even after waiting on a human for hours or days.
Sandboxed compute
Agent-generated code is untrusted by default. Each agent runs in an isolated sandbox for shell commands, scripts, and file I/O, separate from the harness controlling it. The sandbox backend is an adapter: Vercel Sandbox in production, Docker, microsandbox, or just-bash locally, with support for custom providers.
Human approval
Any action can require approval. The agent pauses at that step and waits without consuming compute, then resumes from the same checkpoint once approved.
Secure connections
A connection is a file pointing at an MCP server or an API with a compatible OpenAPI document. eve discovers remote tools and brokers authentication via Vercel Connect, with OAuth consent and token refresh built in. The model never sees URLs or credentials. Launch integrations include Slack, GitHub, Snowflake, Salesforce, Notion, and Linear.
import { defineMcpClientConnection } from "eve/connections";
export default defineMcpClientConnection({
url: "https://mcp.linear.app/sse",
description: "Linear workspace: issues, projects, cycles, and comments.",
auth: {
getToken: async () => ({ token: process.env.LINEAR_API_TOKEN! }),
},
});
Multi-channel by default
The same agent serves every surface. The HTTP API is on by default; Slack, Discord, Teams, Telegram, Twilio, GitHub, and Linear arrive as adapter files. Channels can hand off to each other — an incident webhook can spawn a Slack investigation thread.
Tracing and evals
Every run produces an OpenTelemetry span tree showing model calls, tool calls, and sandbox commands in order. These export to any tracing backend: Braintrust, Raindrop, Arize, Honeycomb, Datadog, Jaeger, or Vercel's Agent Runs tab. Evals run scored test suites locally or in CI.
ai.eve.turn # one span per turn
├── ai.streamText # the model call
│ └── ai.streamText.doStream
└── ai.toolCall # run_sql, with inputs and outputs
Extending agents
Tools are TypeScript files; skills are markdown files. The filename becomes the tool name, and the skill is loaded only when relevant. Both are described to the model automatically.
import { defineTool } from "eve/tools";
import { z } from "zod";
import { runReadOnlySql } from "../lib/sample-db";
export default defineTool({
description: "Run a read-only SQL query against the orders and customers tables.",
inputSchema: z.object({
sql: z.string().describe("A single read-only SELECT statement."),
}),
async execute({ sql }) {
const { columns, rows } = await runReadOnlySql(sql);
return { columns, rows: rows.slice(0, 500), truncated: rows.length > 500 };
},
});
---
description: How this team defines revenue. Load before answering any revenue question.
---
Revenue is recognized net of refunds, over the subscription term.
Weeks are Monday-anchored, in UTC.
Exclude trial and internal accounts from every number.
Approval requirements are a single field on a tool definition — say, guarding any SQL query that would scan more than 50GB.
export default defineTool({
description: "Run a read-only SQL query against the warehouse.",
inputSchema: z.object({ sql: z.string() }),
needsApproval: ({ toolInput }) => estimateScanGb(toolInput.sql) > 50,
async execute({ sql }) {
// unchanged
},
});
Tools aren't the ceiling. Agents get a real shell in their sandbox and can write and run their own code to reshape data or run one-off analyses.
> Break last week's revenue down by region and chart it
⦿ write_file analysis/by_region.py
⦿ bash
python analysis/by_region.py
Revenue by region for the week of June 1. AMER $2.1M, EMEA $1.6M, APAC
$0.5M. Chart saved to analysis/by_region.png.
Agents can delegate too. A subagent is a directory inside subagents/ with its own instructions, tools, and sandbox. The parent calls it like a tool; the child gets a clean context window and returns a result.
import { defineAgent } from "eve";
export default defineAgent({
description: "Investigates anomalies in the data before the analyst reports them.",
model: "anthropic/claude-opus-4.8",
});
Developing and testing
The dev loop is a single command that starts a server with a terminal UI. Every step — skill loads, tool calls, model responses — appears as it happens, each line a checkpointed step in the durable session. The same structured events are served over HTTP, so curl, scripts, or CI can drive the agent and inspect its actions.
eve dev
> What was revenue last week?
⦿ load_skill revenue-definitions
⦿ run_sql
SELECT date_trunc('week', created_at) ...
Revenue for the week of June 1 was $4.2M net of refunds, up 6% from the
prior week.
For repeatable verification, evals run scored checks written as files in the project. Run them locally with eve eval or point them at a deployed app to catch regressions from prompt changes or model swaps.
import { defineEval } from "eve/evals";
import { includes } from "eve/evals/expect";
export default defineEval({
description: "The analyst answers revenue questions by the team's rules.",
async test(t) {
await t.send("What was revenue last week?");
t.completed();
t.calledTool("run_sql");
t.check(t.reply, includes("net of refunds"));
},
});
Deployment
An eve agent deploys as an ordinary Vercel project. There's nothing to provision — the sandbox swaps to Vercel Sandbox without code changes, and the same directory runs in production as it did locally. Deploys don't interrupt in-flight sessions; a task mid-execution finishes on the version it started with. No dashboard steps are required — the coding agent that built yours can ship and verify it.
vercel deploy
Channels make an agent reachable in one step
Putting an agent in Slack previously meant assembling a whole app first: configuration, bot token, event subscriptions, a webhook endpoint, and a signing secret, all before the agent could say a word. With eve, that same channel is a single command.
eve channels add slack
That command writes channels/slack.ts, a single file that ships like any other code change, and your deployed agent is immediately answering in Slack. The channel brings the platform affordances with it: approvals render as Slack buttons, questions become select menus, and the agent shows typing indicators while working. If credentials are routed through Vercel Connect, there's no bot token to manually copy into a .env file. Rerun the command with discord or teams, and the same agent works there too—one file per channel.
Since channels are the agent's user interface, sessions can move fluidly between them. A conversation started in Slack can continue on the web, and an incident webhook arriving over HTTP can open an investigation thread in Slack, finishing the work where the team is already active.
Put the agent on a schedule
The Monday revenue report shouldn't wait for someone to ask for it. A schedule is just another file, defining a cron expression and a handler that starts the agent on its own clock.
agent/schedules/monday-summary.ts
import { defineSchedule } from "eve/schedules";
import slack from "../channels/slack.js";
export default defineSchedule({
cron: "0 9 * * 1",
async run({ receive, waitUntil, appAuth }) {
waitUntil(
receive(slack, {
message: "Summarize last week's revenue and post it to the team channel.",
target: { channelId: "C0123ABC" },
auth: appAuth,
}),
);
},
});
On Vercel, each schedule deploys as a Vercel Cron Job, so the report posts automatically every Monday without anyone needing to remember.
Managing agents like production software
An agent your team depends on is production software, and a change to its instructions can fail as critically as a code change. Because an eve agent is just files in a directory, it lives in Git like everything else; a new prompt, tool, or skill becomes a commit with a diff, a review, and full history.
Wire eve eval into CI and your suites serve as the deploy gate, scoring every commit so regressions stop in CI rather than in production.
Every commit gets its own preview deployment that carries the agent's channels along. Team members can test the next version of your Slack bot before it replaces the one they use daily. And if a change breaks in a way no eval foresaw, you can roll production back to a previous version instantly.
How Vercel runs on eve
Vercel runs more than a hundred agents in production, each taking on a business role and helping the company operate daily. A few stand out.
The data analyst
Vercel's most-used internal tool is an agent handling over 30,000 questions per month. Anyone can ask d0 anything in Slack and receive answers from the warehouse. Every query is scoped to the asker's own permissions, so d0 can never expose a table that user couldn't already see.
The autonomous SDR
Lead Agent runs the playbook of the company's best rep around the clock. It works every new lead the moment it arrives and follows up independently, so no lead goes cold overnight. It costs about $5,000 a year to run, returns 32 times that amount, and requires just one part-time engineer to maintain.
The sales cockpit
RevOps built Athena in six weeks without engineers. It answers pipeline and forecast questions from Snowflake and Salesforce in plain language, and pipeline coverage nearly doubled after its launch.
The support engineer
Vertex is the support agent handling tickets across the help center, docs, and Slack around the clock. It reads each ticket, locates the right answer, and responds, solving 92% of tickets on its own and escalating the rest so the support team can focus on problems needing human attention.
The content agent
Anyone at Vercel can write, not just the content team. draft0 runs a full review pipeline that catches glaring issues and builds an analysis of what a piece is actually about, all before it reaches the editors. By then the obvious work is done, leaving a much clearer picture of what the piece needs. Smaller content moves fast, and full attention goes to pieces that demand it.
The routing agent
With hundreds of agents in daily use, manually tracking which handles what isn't efficient. Instead, everything goes to V in Slack first. V determines which agent can actually answer the task and routes it there, making the whole fleet function as one agent rather than a hundred separate options.
Each of these agents began as a separate project on its own stack, with distinct ways of holding state, brokering credentials, and emitting logs—exactly where most teams land after their second or third agent. Today they share one monorepo and are built, observed, and upgraded the same way, regardless of which team owns them. Sharing the same shape means a hundred agents run with consistent tools and conventions.
Get started
A year ago, agents triggered less than 3% of deployments on Vercel. Now they trigger around 29%, with expectations that half of all deployments will soon come from agents. You've likely already built an agent, and the next one doesn't have to start from scratch.
The public preview is open now, and the CLI wizard guides you from picking a model to running a dev server in under a minute.
npx eve@latest init my-agent
Coding agents only need a prompt:
Set up an Eve agent for the user. Eve is a filesystem-first TypeScript framework for durable agents, published as the npm package eve. Read its docs: once eve is installed they are bundled in the package at node_modules/eve/docs; before eve is installed, read the published Introduction and Getting Started pages. If the project has no Eve app, scaffold one with `npx eve@latest init <name>`; add `--channel-web-nextjs` only when the user wants Web Chat. The init command installs dependencies, initializes Git, and starts the dev server, so run it in a controllable process and stop it before editing. To add Eve to an existing app, run `npm install eve@latest`. Make sure agent/agent.ts and agent/instructions.md exist, then add a first typed tool at agent/tools/get_weather.ts using defineTool from eve/tools with a Zod inputSchema and an inline execute. Start the dev server again, then exercise the HTTP API: create a session with POST /eve/v1/session, attach to GET /eve/v1/session/:id/stream, and send a follow-up with the returned continuationToken. Verify with the project's typecheck, adapt model and provider choices to the project, and do not commit unless the user asks.
Full eve documentation is available at eve.dev/docs, with development happening openly at github.com/vercel/eve where issues, discussions, and contributions are welcome.
Hundreds of agents already run on eve at Vercel. What will you build?



