---
title: How to add skills to your eve agent
description: Add skills to an eve agent by creating a file under agent/skills/ or installing a published skill with the npx skills add CLI.
url: /kb/guide/how-to-add-eve-skills
canonical_url: "https://vercel.com/kb/guide/how-to-add-eve-skills"
last_updated: 2026-07-29
authors: Ben Sabic
related: []
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Skills give an [eve](https://vercel.com/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](https://agentskills.io/home), 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.

## Prerequisites

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](https://eve.dev/docs/getting-started#quick-start).
  

## Quick start with an AI coding agent

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:

### Agent prompt

```txt
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.
```

## How eve loads skills

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.

## Three ways to add a skill

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.
  

## Add a skill by creating a file

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`:

`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:

`--- 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:

`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.

## Install a published skill with `skills`

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

`npx skills add <owner>/<repo>`

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

`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.

## Load a per-user skill at runtime

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.

### Resolve the skill from the caller

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:

`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.

### What happens at runtime

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.

### Choose the resolver event

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.

### Verify the right skill loads

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.

### Beyond skills

`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](https://eve.dev/docs/guides/dynamic-capabilities) goes deep on the resolver events, return shapes, and the tool and instruction forms, and the [auth and route protection guide](https://eve.dev/docs/guides/auth-and-route-protection) shows exactly how `principalId` and the caller snapshot get set.

## Verify the skill loads

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](https://vercel.com/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fobservability%2Fagent-runs) in the Vercel dashboard.

* * *

## Learn more about building with eve