How to Build an AI Agent with Custom Tools in 15 Minutes Using Vercel's Eve Framework
A step-by-step guide to initializing a project, configuring system prompts, registering Zod-validated tools, and running your first local AI Agent using Vercel's file-driven Eve framework.

Last month, while evaluating tech stacks for my team, a recurring need kept popping up: everyone wants to add an AI assistant to internal business systems, but writing Prompt management, tool calling, and session state from scratch every time scatters the code. Then I tried eve, a framework recently launched by Vercel. It places all Agent configurations in the file system, using directory structures instead of config panels. You write it, run it, and extending it is intuitive.
In this tutorial, I'll walk you through building an AI Agent from scratch that can check the "weather" (simulated data). By the end, you'll master Eve's core workflow: initializing a project, writing system instructions, registering custom tools, launching, and interacting. Perfect for backend devs, full-stack engineers, or anyone looking to quickly embed AI capabilities into their services.
Prerequisites
- Node.js 18+ (Eve is built on the TypeScript ecosystem)
- OpenAI API Key (or credentials for other supported models, covered later)
- Basic terminal proficiency, familiarity with
npmis enough
Eve defines Agents in files, so you don't need to write glue code. The more comfortable you are with file directory operations, the faster you'll pick this up.
Step 1: Initialize the Project in One Go
Open your terminal and run:
bash
npx eve@latest init my-first-agent
This command does four things:
- Creates the
my-first-agentdirectory - Installs dependencies (including Eve itself and Zod)
- Initializes a Git repository
- Automatically launches an interactive terminal UI
To specify a model (e.g., if you don't want the default OpenAI), add the --model flag:
bash
npx eve@latest init my-first-agent --model openai/gpt-5.6-terra
Why design it this way? Many frameworks scatter models, tools, and Prompts across different files or even databases, making debugging a nightmare ("Where's the config?"). Eve flips the script: it consolidates all Agent assets into an
agent/directory, using the file system as the authoring interface. Change a file, save it, and it takes effect immediately.
Step 2: Understand the Generated Project Structure
After initialization, you'll see a structure like this:
my-first-agent/
└── agent/
├── agent.ts # Model and runtime configuration
├── instructions.md # System prompt (required)
├── tools/ # Callable tool functions for the Agent
│ └── get_weather.ts
└── ... # skills/ channels/ schedules/ added as needed
Three core files to focus on:
agent.ts: Tells the Agent which model and runtime parameters to useinstructions.md: Acts as the System Prompt, always loaded at startup.tsfiles undertools/: External capabilities the Agent can call, each exporting a single tool
Step 3: Write System Prompt & Register Tools
3.1 Edit instructions.md
Open agent/instructions.md and replace the content with:
md
You are a concise weather demo assistant. When responding to users, first clarify that the weather data provided is simulated, then give the result. Keep answers short; avoid long paragraphs.
Why Markdown? Eve loads it as a raw text Prompt. Using
.mdmakes it easy to add formatting, lists, and example conversations later, which is far more maintainable than cramming everything into a JSON string.
3.2 Add the Weather Tool
Create (or edit) get_weather.ts under agent/tools/:
ts
import { defineTool } from "eve/tools";
import { z } from "zod";
export default defineTool({
description: "Returns simulated weather data for a specified city.",
inputSchema: z.object({
city: z.string().min(1, "City name cannot be empty")
}),
async execute({ city }) {
// In a real project, this would call a weather API
return {
city,
condition: "Clear",
temperatureC: 22,
humidity: 65
};
},
});
What this code does:
defineTool: Eve's tool registry, wrapping a regular function into an Agent-recognizable toolinputSchema(Zod): Defines validation rules for parameters passed by the Agent. Before the model calls the tool, Eve validates the parameters to prevent dirty data from enteringexecuteasync execute: The actual execution logic. Here it returns mock data; in production, replace it with afetchcall to a real API.
Under the hood: An Agent "calls tools" essentially by having the LLM output structured JSON → framework parses it → executes the corresponding function → feeds the result back to the model. The Zod schema acts as the type-safe gateway in this pipeline.
3.3 Verify Model Configuration in agent.ts
Open agent/agent.ts and confirm the model ID is correct. If you have an OpenAI key, it should look like this:
ts
import { defineAgent } from "eve";
export default defineAgent({
model: "openai/gpt-5.6-luna-fast",
});
If you're using a provider other than OpenAI, Eve supports connecting to other models via AI Gateway. Simply change the model string to the corresponding identifier and ensure your environment variables are configured.
Step 4: Start the Agent & Test
In the project root, run:
bash
npm run dev
The terminal will launch an interactive UI. You can now input natural language, for example:
"What's the weather like in Beijing today?"
The Agent will:
- Load the system instructions from
instructions.md - Analyze your intent and realize it needs weather data
- Call the
get_weathertool, passing{ city: "Beijing" } - Generate a response based on the simulated result and system instructions
You don't need to write any routing, session management, or Prompt stitching code. The file-driven approach means: change config = change file = hot reload.
Troubleshooting Tips
- Missing Environment Variables: Eve relies on the model's API Key (e.g.,
OPENAI_API_KEY). If you get an auth error on startup, check your.envfile or terminal environment variables. - Tool Not Recognized: Ensure the tool file is inside
agent/tools/and defaults exportsdefineTool(...). Wrong directory or missingexport defaultmeans the Agent can't see the capability. - Zod Validation Fails: If the model passes parameters that don't match the
inputSchema, Eve will intercept and warn you. Addconsole.loginside the tool during debugging to inspect actual inputs. - Currently in Beta: Vercel explicitly labels Eve as beta in the README, so APIs may change. Check official release notes before using it in production.
Summary & Next Steps
This tutorial walked you through Eve's minimal closed loop:
- Initialize with
npx eve@latest init - Write
instructions.mdfor system prompts - Register Zod-validated tools using
defineTool - Launch and interact via
npm run dev
Next steps you can try:
- Add on-demand flow docs under
agent/skills/so the Agent reads them only in specific scenarios - Connect HTTP, Slack, or Discord under
agent/channels/to expose the Agent to more users - Write scheduled tasks in
agent/schedules/for automated periodic Agent workflows
Eve's philosophy is "file system as the authoring interface." Once you get used to it, managing an Agent feels as natural as building a standard project. If you have existing backend services, your next step is wrapping real APIs into tools/ and letting the Agent handle your business logic.
Feel free to discuss in the comments or check the official Eve docs for advanced patterns. Happy building your first Agent!