Tools, skills & subagents

Instructions and the model decide how an agent thinks. Capabilities decide what it can do. Eve gives you three, each with a different job:

  • Tools: typed actions the agent calls (hit an API, run a query, write a file).
  • Skills: load-on-demand instructions the model pulls in only when relevant.
  • Subagents: specialist child agents the root agent delegates work to.

Studio groups all three (plus Hooks) under the Capabilities tab, with a sub-tab for each. Every sub-tab lists the discovered items, a New button to scaffold one, and an in-app editor that opens the real source file when you click a row. Nothing is stored in a Studio database; the files under agent/ are the capabilities.

Capabilities that come from a mounted extension (for example Arcana's arcana__recall skill) are badged with the extension's namespace (arcana); their source lives in the package, not under agent/, so those rows don't open the editor. Eve's own defaults (bash, read_file, web_search, …) are badged built-in.

New to the folder model? Read The agent, explained first.

Tools

A tool is a typed action, and the action stays in code you control. Tools run in the app runtime with full access to process.env, not in the sandbox, so they can read secrets, import shared lib/ code, and call your own services.

The filename is the tool name the model sees: agent/tools/get_weather.ts is the tool get_weather.

import { defineTool } from "eve/tools";
import { z } from "zod";

export default defineTool({
  description: "Get the current weather for a city.",
  inputSchema: z.object({ city: z.string().min(1) }),
  async execute({ city }, ctx) {
    return { city, condition: "Sunny", temperatureF: 72 };
  },
});

A tool definition needs:

  • a filename slug under agent/tools/: the model-facing name (snake_case ASCII).
  • description: what the tool does, written for the model.
  • inputSchema: a Zod schema (or any Standard/JSON Schema). Use z.object({}) for no input.
  • execute(input, ctx): the implementation, sync or async.

Approval: human-in-the-loop

Any tool can require a person to sign off before it runs. Set approval with the helpers from eve/tools/approval:

import { defineTool } from "eve/tools";
import { always } from "eve/tools/approval";
import { z } from "zod";

export default defineTool({
  description: "Refund a charge.",
  inputSchema: z.object({ chargeId: z.string(), amount: z.number() }),
  approval: always(),
  async execute(input) {
    return refund(input);
  },
});

| Helper | Behavior | | ---------- | -------------------------------------------------------------------- | | never() | Never require approval (the default when approval is omitted). | | once() | Require approval the first time in a session; auto-allow after. | | always() | Require approval before every call. |

When a gated tool is called, the run parks durably and Studio's Chat surfaces an approval prompt; the turn resumes exactly where it left off once you approve or deny. Gate anything sensitive, irreversible, or external-side-effecting. (For input-dependent decisions you can pass a policy function instead of a helper.) Studio marks approval-gated tools in the list.

Create and edit tools in Studio

Capabilities → Tools. The sub-tab lists every discovered tool; approval-gated tools carry an approval badge. Click New and give it a Name (snake_case), a Description written for the model, and an Approval gate (never, once, or always); Studio scaffolds agent/tools/<name>.ts with an empty Zod schema and a stub execute. Click any row to open the in-app editor, a modal over that tool's .ts source, where you read, edit, and Save, or Delete the file (with a confirm step).

Agents set up with an earlier Studio may still carry files from the retired Evolve feature, such as agent/tools/propose_change.ts. Studio badges these legacy Eve Studio (Evolve) tool and notes that they are safe to delete; open the row and Delete to remove them.

Skills

A skill is a procedure the model loads on demand, rather than carrying on every turn: progressive disclosure. Eve advertises each skill's description to the model and pulls the full body into context only when a request matches (or you name the skill outright). Loading a skill adds instructions, never a new execution surface; if you need typed runtime behavior, that's a tool.

A packaged skill is a directory with a SKILL.md and optional sibling files:

agent/skills/release-notes/
├── SKILL.md
└── references/
    └── checklist.md
---
description: Use when the user needs a release checklist or changelog workflow.
---

Gather the merged PRs since the last tag, group them by area, and draft the
changelog in the house voice. See references/checklist.md for the full list.

The description frontmatter is the routing hint. Write it as the task that should trigger the skill, not as a label. A packaged SKILL.md must carry it; a flat single-file skill (agent/skills/forecast.md) can infer one from its first line but is a weaker hint. Sibling files under references/ are read relative to the SKILL.md.

Skills are scoped to the agent that declares them: a subagent's skills are invisible to the root, and vice versa.

Create and edit skills in Studio

Capabilities → Skills. The sub-tab lists discovered skills. Click New and provide a Name, the Description that acts as the routing hint, and an optional Markdown Body; Studio scaffolds skills/<name>/SKILL.md. Click a row to open the in-app editor on that skill's SKILL.md, where you edit the description and body and Save, or Delete the skill.

Subagents

A subagent is a specialist child agent the root delegates to. Use one to run independent work in parallel, narrow the tool surface, or give a task to a purpose-built role. A declared subagent lives under agent/subagents/<id>/ and is its own agent root: it inherits nothing from the parent.

agent/subagents/research/
├── agent.ts            # required: must export a description
├── instructions.md     # optional, its own system prompt
├── tools/              # optional, its own tools
├── skills/             # optional, its own skills
├── hooks/              # optional, its own hooks
├── memory/             # optional, its own memory slots
└── extensions/         # optional, its own extension mounts (e.g. a separate Arcana brain)
import { defineAgent } from "eve";

export default defineAgent({
  description: "Investigate ambiguous questions before the parent responds.",
  model: "anthropic/claude-opus-4.8",
});

The description is required: the parent reads it to decide whether to delegate, and the build fails without it. The subagent's directory name is its tool name (research), which the parent calls with a message (the child never sees the parent's history). Because it's a separate agent root, anything the child needs (instructions, tools, skills, hooks, memory) must live under its own directory. Schedules and channels are root-only and can't be declared inside a subagent.

Reach for a subagent when the task needs a different prompt, role, or narrower tool set; reach for a skill when the agent can keep its identity and just needs an optional procedure.

Create and edit subagents in Studio

Capabilities → Subagents. The sub-tab lists declared subagents. Click New and provide a Name, the Description the parent uses to decide when to delegate, and optional Instructions; Studio scaffolds subagents/<id>/ with its agent.ts and instructions.md. Click a row to open the in-app editor on both files, where you edit and Save, or Delete the subagent. A subagent's own tools, skills, and hooks are authored inside its directory the same way the root's are.

Enable self-modification (experimental, dev only)

Eve ships a development-only subagent that can edit the agent's own source. A Self-modification card, badged experimental · dev only, sits below the subagent list; its Enable button installs it from the registry:

eve add experimental/self-modification --non-interactive --yes

That installs @eve/self-modification and writes agent/subagents/self-modification/ (its agent.ts, a sandbox that mounts agent/ read-write, and an extension mount). Under eve dev, the root agent can then delegate "change your own source" requests to it: it inspects and edits files with structured file tools, and can install registry items through its own selfmod__registry_add tool. It does nothing in production builds, so a deployed agent stays read-only.

Once installed the card is badged enabled and shows the subagent's path. Ask the agent in Studio's local Chat to add a tool or rewrite a skill, watch the delegation in the transcript, then review the resulting files in the Capabilities tab (or git diff) before you deploy. Remove the subagent directory to turn it off.

The package is pinned to the eve 0.49 line. On an agent running an older eve the card reads needs eve 0.49.0+ instead of offering Enable, because installing it there produces a discovery error rather than a working subagent. Upgrade the agent first; see Keep eve current.

Hooks

The fourth Capabilities sub-tab is Hooks: observe-only subscribers to the runtime event stream (audit logging, metrics, alerting). Like tools, a hook is a single .ts file you open in the in-app editor. They're covered on their own page.

→ Hooks

Where to go next