Skip to content
Docs

How to add skills to your eve agent

Add skills to an eve agent by creating a file under agent/skills/ or installing a published skill with the npx skills add CLI.

6 min read
Last updated June 22, 2026

Skills give an eve agent focused instructions that it loads only when a task calls for them, so the agent gets relevant guidance without carrying it in every prompt. eve loads any skill you place under agent/skills/, and because eve follows the open Agent Skills standard, a skill written for that standard works in eve without changes. You can add a skill in two ways: write the file yourself, or install a published skill with the skills CLI.

This guide walks you through both approaches and then shows you how to confirm that your agent loads the skill for the right requests.

Before you begin, you need an eve project and Node.js installed.

  • To create a new project, run npx eve@latest init my-agent.
  • To add eve to an existing app, follow the quickstart steps.

If you're using an AI coding agent like Claude Code or Cursor, give it this prompt, and it'll help you add a skill to your eve agent:

AI Assistance

I want to add a custom skill to my eve agent. Use this guide as your reference: https://vercel.com/kb/guide/how-to-add-eve-skills. First, two checks before we build anything custom. A skill is guidance you load when a task calls for it, not an action you run; if what I need is for you to call an API, run a query, or change something, that's a tool rather than a skill, so tell me and point me to the tools guide (/kb/guide/how-to-add-eve-tools). And if a published skill on skills.sh already covers what I want, mention it, since I can install one with `npx skills add <owner>/<repo>` instead of writing my own. Before writing anything, ask me what the skill should cover. Find out: - The procedure: the steps you should follow when the skill is active - When you should use it, so we can write a description that routes to it reliably - Whether the guidance is the same for everyone, or specific to each user or caller (their saved preferences, a team playbook, records on their account) - Whether it needs supporting files like references, examples, or scripts Once you have my answers, create the skill and follow these conventions: - Put it under `agent/skills/`. The name comes from the file path. - Start with plain markdown. Move to `defineSkill` from `eve/skills` only when markdown can't capture what's needed, such as typed values or generated content. - Give it a clear `description` in frontmatter. That's the routing hint the model uses to decide when to load the skill, so write it for that job rather than letting eve fall back on the first line of the file. - Write the body as the procedure itself: the steps to take once the skill loads. - For a simple skill with no extra files, a single markdown file is enough (for example, `agent/skills/plan_a_trip.md`). If it needs supporting files, make a directory with a `SKILL.md` plus `references/`, `assets/`, or `scripts/` siblings, and keep the `description` in the `SKILL.md` frontmatter. If the guidance is tied to the individual caller, resolve it at runtime with `defineDynamic` from `eve/skills` instead of a fixed file: read the caller off `ctx.session.auth` and return `null` when there's nothing to load. Resolve on `session.started` when each user has their own session, or `turn.started` when several callers share one. Keep it a static file when the skill is the same for everyone. When the skill is ready, tell me how to test it: start the dev server with `eve dev`, send a request that should match the skill's description, then open Agent Runs in the Vercel dashboard to confirm you called `load_skill` and loaded it. If any of my requirements are unclear, ask before you generate anything rather than guessing.

eve scans the files under agent/skills/ at build time and advertises each skill's description to the model, alongside a built-in load_skill tool. When a request matches a skill's description, or you name the skill directly, the model calls load_skill and eve adds that skill's markdown to the current turn. Loading a skill adds instructions, not new tools, so your agent's tools remain available whether or not a skill is loaded.

You add a skill in one of three ways, and which one you reach for depends on where the skill comes from:

  • Write it yourself: Author a markdown or TypeScript skill under agent/skills/, and eve loads it at build time.
  • Install a published one: Pull a skill from a GitHub repository with the skills CLI.
  • Resolve it at runtime: Return a different skill per caller with defineDynamic, keyed on the session.

The smallest skill is a single markdown file under agent/skills/. Its name comes from the file path, and its content is the procedure the agent follows.

Create agent/skills/plan_a_trip.md:

agent/skills/plan_a_trip.md
Use when the user wants to plan a trip or build an itinerary.
Gather the destination, dates, and budget first, then propose a day-by-day plan.

When a flat markdown file has no description frontmatter, eve advertises its first non-empty line as the routing hint. To route on intent reliably, add a description rather than relying on the first line.

For a skill that needs supporting files, create a directory with a SKILL.md and sibling files. The packaged SKILL.md must include a description in its frontmatter so eve knows when to load it:

agent/skills/research/SKILL.md
---
description: Research unfamiliar topics before answering with confidence.
---
When the task is novel or ambiguous, gather evidence first, then answer with the key facts and the remaining uncertainty.

Place supporting files (references/, assets/, and scripts/) next to the SKILL.md. eve picks up the skill at build time, with no registration step required.

When markdown can't capture what you need, such as typed values or generated content, author the skill in TypeScript with defineSkill from eve/skills. eve generates the SKILL.md from the object you export, and each files entry becomes a sibling in the package:

agent/skills/research.ts
import { defineSkill } from "eve/skills";
export default defineSkill({
description: "Research unfamiliar topics before answering with confidence.",
markdown:
"When the task is novel or ambiguous, gather evidence first, then answer with the key facts and the remaining uncertainty.",
files: {
"references/checklist.md": "# Checklist\n\n- Find primary sources.\n",
},
});

Start with plain markdown and move to defineSkill only when you hit its limits.

The skills CLI installs skills from a GitHub repository into your project. Run it from your eve project's root directory:

Terminal
npx skills add <owner>/<repo>

For example, to install Vercel's official skill collection:

Terminal
npx skills add vercel-labs/agent-skills

The skills CLI detects when you run this inside an eve project and prompts you to install the skills for eve before writing any files:

Detected an eve project. Install skills for eve?
ā— Yes / ā—‹ No

Select Yes to add the skills to your eve agent. The model can load them on the next run, the same way it loads skills you write by hand.

To give each caller a different skill, resolve it at runtime with defineDynamic from eve/skills instead of reading a fixed file from agent/skills/.

The dynamic skill file runs a resolver when a session starts, reads the authenticated caller off ctx.session.auth, and returns the skill that caller can load (or null for none). Each user gets a skill built from their own data.

Reach for a dynamic skill when the content is tied to the principal, such as a user's saved preferences, their team's playbook, or records on their account. If the skill is the same for everyone, keep it as a static file.

This file provides each user with a skill based on their saved writing preferences. It reads the user's principalId from the session, looks up their guide, and returns a skill only when there's something to load:

agent/skills/user_style.ts
import { defineDynamic, defineSkill } from "eve/skills";
import { getStyleGuide } from "../lib/users.js";
export default defineDynamic({
events: {
"session.started": async (_event, ctx) => {
const userId = ctx.session.auth.current?.principalId;
if (!userId) return null;
const markdown = await getStyleGuide(userId);
if (!markdown) return null;
return defineSkill({
description: "Apply this user's saved writing preferences and house style.",
markdown,
});
},
},
});

ctx.session.auth.current is the authenticated caller for the current turn, and its principalId is the stable user id set by route auth. Keeping the getStyleGuide lookup in lib/ lets other agent files reuse it. When there's no caller or no saved guide, the resolver returns null, and the user sees no extra skill.

When a session starts, eve runs the resolver and reads the caller's id to fetch that user's style guide.

If the lookup returns markdown, eve advertises it as a loadable skill named after the file slug (user_style). The model can then call load_skill for it on any turn in that session.

Dynamic skill files resolve on session.started or turn.started:

  • session.started: Runs once for the caller that starts the session. Use it when each user has their own session.
  • turn.started: Re-resolves each turn against ctx.session.auth.current, so the active caller gets their own skill. Use it when several callers share one session and a session.started result would stay pinned to whoever started it.

Dynamic skills don't resolve on step.started, which eve reserves for dynamic tools.

Send a request as a user who has a saved guide, then as one who doesn't, and confirm the agent advertises user_style for the first and nothing extra for the second.

defineDynamic resolves tools and instructions from the same session signal, so you can also give each caller their own tool set or system prompt.

From here, the dynamic capabilities guide goes deep on the resolver events, return shapes, and the tool and instruction forms, and the auth and route protection guide shows exactly how principalId and the caller snapshot get set.

Start your agent and send a request that matches the skill's description. If you scaffolded with init, the dev server is already running; otherwise start it with eve dev. When a request matches, the model calls load_skill and follows the skill's instructions.

To see which skills loaded, along with tools, timing, and token usage, open Agent Runs in the Vercel dashboard.


Was this helpful?

supported.