# Overview

> Filesystem-first agent model, channel/harness/runtime split, public entry points (eve CLI, /eve/v1 HTTP routes, define* authoring), and the shortest path from init to a running session.

- Repository: vercel/eve
- GitHub: https://github.com/vercel/eve
- Human docs: https://www.grok-wiki.com/public/docs/vercel-eve-759e1d74a10f
- Complete Markdown: https://www.grok-wiki.com/public/docs/vercel-eve-759e1d74a10f/llms-full.txt

## Source Files

- `README.md`
- `docs/introduction.md`
- `docs/README.md`
- `packages/eve/package.json`
- `packages/eve/src/public/index.ts`
- `packages/eve/src/protocol/routes.ts`

---

---
title: "Overview"
description: "Filesystem-first agent model, channel/harness/runtime split, public entry points (eve CLI, /eve/v1 HTTP routes, define* authoring), and the shortest path from init to a running session."
---

Eve is a filesystem-first framework for durable backend agents. You author capabilities as files under `agent/`, Eve compiles them into inspectable `.eve/` artifacts, and a Nitro-hosted runtime serves a stable `/eve/v1` HTTP protocol plus optional platform channels. The published npm package is `eve`; the CLI binary is `eve`. Node 24 or newer is required.

## Filesystem-first agent model

An Eve app is a TypeScript project whose agent contract is a directory tree, not a monolithic config object. Eve walks `agent/` at build time, derives names from paths (no `name` fields on `define*` calls), and serializes the discovered surface into `.eve/compile/compiled-agent-manifest.json` and `.eve/compile/module-map.mjs`.

:::files
```text
my-agent/
├── package.json
├── tsconfig.json
├── agent/
│   ├── agent.ts              # defineAgent — model, compaction, build
│   ├── instructions.md       # always-on system prompt (required on root)
│   ├── tools/                # defineTool integrations
│   ├── skills/               # on-demand procedures
│   ├── connections/          # MCP and OpenAPI connections
│   ├── sandbox/              # optional sandbox override + workspace seed
│   ├── channels/             # HTTP and messaging ingress (root-only)
│   ├── subagents/            # specialist child agents
│   ├── schedules/            # recurring jobs (root-only)
│   ├── hooks/                # stream-event subscribers
│   └── lib/                  # shared import-only code
└── evals/                    # defineEval suites (sibling of agent/)
```
:::

| Path | Resolves to | Author with |
| --- | --- | --- |
| `agent/tools/get_weather.ts` | tool `get_weather` | `defineTool` from `eve/tools` |
| `agent/connections/linear.ts` | connection `linear` | `defineMcpClientConnection` or `defineOpenAPIConnection` from `eve/connections` |
| `agent/skills/summarize.md` | skill `summarize` | markdown file (loaded via `load_skill`) |
| `agent/channels/slack.ts` | channel `slack` | `defineChannel` or platform factory from `eve/channels/*` |
| `agent/subagents/researcher/` | subagent `researcher` | nested `agent.ts` + authored slots |

The root agent name comes from `package.json` `name`, falling back to the app-root directory name. Local subagents take their name from their directory. Add a file and Eve discovers it; rename or move it and its identity moves with it. Run `eve info` to inspect the resolved surface and `.eve/discovery/diagnostics.json` when discovery fails.

<Info>
Only two authored sources reach the sandbox workspace at runtime: `agent/skills/` files seed to `/workspace/skills/...`, and `agent/sandbox/workspace/**` seeds to `/workspace/...` at session bootstrap. Everything in `lib/` stays import-only.
</Info>

## Channel, harness, and runtime

Eve separates transport, AI work, and durable orchestration. That split drives the public HTTP contract: channels own `continuationToken`; the runtime owns `sessionId` and the event stream.

```mermaid
flowchart TB
  subgraph ingress["Ingress (channels)"]
    HTTP["Eve HTTP channel<br/>/eve/v1/session"]
    Slack["Platform channels<br/>agent/channels/*"]
  end

  subgraph harness["Harness (one unit of AI work)"]
    Loop["Default agent loop"]
    Tools["Built-in + authored tools"]
    Model["Model call + compaction"]
  end

  subgraph runtime["Runtime (durable orchestration)"]
    WF["Workflow SDK checkpoints"]
    Stream["NDJSON event stream"]
    State["Session state + hooks"]
  end

  HTTP --> Loop
  Slack --> Loop
  Loop --> Tools
  Loop --> Model
  Loop --> WF
  WF --> Stream
  WF --> State
  Stream --> HTTP
  Stream --> Slack
```

| Layer | Responsibility | Owns |
| --- | --- | --- |
| **Channel** | Normalize inbound transport, apply auth and delivery policy, start or resume sessions | `continuationToken` |
| **Harness** | Run one unit of AI work (model step, tool calls, compaction) and return `{ session, next }` | Turn/step execution inside the agent loop |
| **Runtime** | Persist session state, follow `next`, stream events, orchestrate workflow primitives | `sessionId`, NDJSON stream, durable checkpoints |

Sessions nest as **session → turn → step**. Turns checkpoint at step boundaries via the Workflow SDK, so crash, timeout, and redeploy resume from the last completed step. Parked work (HITL approval, OAuth, subagents) suspends the workflow until input arrives. The default harness ships built-in tools (`bash`, file ops, `web_fetch`, `todo`, `ask_question`, `agent`, `load_skill`, `connection_search`) without any imports.

## Public entry points

Eve exposes three surfaces for authoring, operating, and integrating agents.

### `eve` CLI

The `eve` binary runs from the app root and loads `.env`/`.env.local` before every command. Running `eve` with no subcommand starts `eve dev`.

| Command | Purpose |
| --- | --- |
| `eve init [target]` | Scaffold a new agent or add one to an existing project |
| `eve info` | Print discovered tools, skills, routes, artifacts, and diagnostics |
| `eve build` | Compile `.eve/` artifacts and build host output |
| `eve start` | Serve the built `.output/` app |
| `eve dev` | Start local runtime and open the interactive terminal UI |
| `eve link` / `eve deploy` | Link to Vercel and deploy |
| `eve eval` | Run evals locally or against a remote URL |
| `eve channels add/list` | Scaffold or list authored channels |

Recommended loop: edit authored files → `eve info` to verify discovery → `eve dev` to iterate → `eve build` → `eve start` for production.

### `/eve/v1` HTTP routes

All stable runtime transport routes share the `EVE_ROUTE_PREFIX` of `/eve/v1`.

| Method | Route | Purpose |
| --- | --- | --- |
| `GET` | `/eve/v1/health` | Health check |
| `GET` | `/eve/v1/info` | JSON inspection payload for the current agent |
| `POST` | `/eve/v1/session` | Create a new durable session |
| `POST` | `/eve/v1/session/:sessionId` | Continue a session with `continuationToken` |
| `GET` | `/eve/v1/session/:sessionId/stream` | NDJSON event stream |
| `GET` | `/eve/v1/connections/:name/callback/:token` | OAuth callback (unguessable token) |
| `GET` | `/eve/v1/callback/:token` | Terminal session callback |

Dev-only routes (`/eve/v1/dev/schedules/:scheduleId`, `/eve/v1/dev/runtime-artifacts`) register only when Nitro runs in dev mode.

:::endpoint POST /eve/v1/session
Create a durable session. Returns `sessionId` and `continuationToken` in the JSON body; the `x-eve-session-id` header names the session to stream.
:::

### `define*` authoring API

Authoring helpers live in `packages/eve/src/public/` and ship through the `eve` package exports.

| Import path | Helper | Authored slot |
| --- | --- | --- |
| `eve` | `defineAgent`, `defineRemoteAgent` | `agent/agent.ts` |
| `eve/instructions` | `defineInstructions`, `defineDynamic` | `agent/instructions.ts` or `agent/instructions/` |
| `eve/tools` | `defineTool`, `defineBashTool`, `defineReadFileTool`, … | `agent/tools/*.ts` |
| `eve/skills` | `defineDynamic` | dynamic skill modules |
| `eve/connections` | `defineMcpClientConnection`, `defineOpenAPIConnection` | `agent/connections/*.ts` |
| `eve/channels` | `defineChannel` | `agent/channels/*.ts` |
| `eve/sandbox` | `defineSandbox` | `agent/sandbox.ts` or `agent/sandbox/sandbox.ts` |
| `eve/schedules` | `defineSchedule` | `agent/schedules/*.ts` or `*.md` |
| `eve/hooks` | `defineHook` | `agent/hooks/*.ts` |
| `eve/context` | `defineState` | session-scoped durable state |
| `eve/instrumentation` | `defineInstrumentation` | `agent/instrumentation.ts` (root-only) |
| `eve/evals` | `defineEval`, `defineEvalConfig` | `evals/` at app root |

Tool and connection handlers receive a `ctx` with `ctx.session`, `ctx.getSandbox()`, `ctx.getSkill()`, `ctx.getToken()`, and `ctx.requireAuth()`. Client integration ships separately via `eve/client`, `eve/react`, `eve/vue`, `eve/svelte`, and framework plugins `eve/next`, `eve/nuxt`, `eve/sveltekit`.

## Shortest path to a running session

<Steps>
<Step title="Scaffold">

```bash
npx eve@latest init my-agent
```

Creates the project, installs `eve`, `ai`, and `zod`, initializes Git, and starts `eve dev` with the interactive terminal UI. Stop with Ctrl+C before editing. Pass `--channel-web-nextjs` to add the Web Chat application.

</Step>

<Step title="Verify discovery">

```bash
cd my-agent
npx eve info
```

Confirms `instructions.md`, `agent.ts`, the built-in HTTP channel, and compiled artifact paths under `.eve/`.

</Step>

<Step title="Run locally">

```bash
npx eve dev
```

Starts the dev server (default port 2000) and opens the terminal UI. Set a model credential before prompting: gateway model ids need `AI_GATEWAY_API_KEY` or `VERCEL_OIDC_TOKEN`; direct provider ids need the matching provider key (for example `ANTHROPIC_API_KEY` for `anthropic/...`).

</Step>

<Step title="Create and stream a session">

<RequestExample>
```bash
curl -X POST http://127.0.0.1:2000/eve/v1/session \
  -H 'content-type: application/json' \
  -d '{"message":"Hello"}'
```
</RequestExample>

<ResponseExample>
```json
{
  "sessionId": "ses_…",
  "continuationToken": "ct_…"
}
```
</ResponseExample>

Attach to the stream:

```bash
curl http://127.0.0.1:2000/eve/v1/session/<sessionId>/stream
```

The response is NDJSON (`application/x-ndjson`). Expect lifecycle events such as `session.started`, `turn.started`, `step.started`, `message.completed`, and `session.waiting` or `session.completed`.

</Step>

<Step title="Send a follow-up">

When the session parks (`session.waiting`), POST the next message with the stored token:

```bash
curl -X POST http://127.0.0.1:2000/eve/v1/session/<sessionId> \
  -H 'content-type: application/json' \
  -d '{"continuationToken":"<token>","message":"Follow up"}'
```

</Step>
</Steps>

<Warning>
`continuationToken` is a resume handle for the session's current workflow hook, not a general message-queue address. Send one user turn at a time and wait for `session.waiting` before delivering the next message to the same session.
</Warning>

## Compiled artifacts

`eve build` and `eve dev` write inspectable output under `.eve/`:

| Artifact | Contents |
| --- | --- |
| `.eve/discovery/agent-discovery-manifest.json` | Filesystem discovery results |
| `.eve/discovery/diagnostics.json` | Authored-shape errors and warnings |
| `.eve/compile/compiled-agent-manifest.json` | Serialized surface Eve loads at runtime |
| `.eve/compile/module-map.mjs` | Compiled module entrypoints |

On Vercel (`VERCEL=1`), `eve build` also writes `.vercel/output`. Local `eve build` skips that bundle but still produces `.eve/` artifacts.

## Next

<CardGroup>
<Card title="Installation" href="/installation">
Node 24+ prerequisites, install paths, model credentials, and environment file loading.
</Card>
<Card title="Quickstart" href="/quickstart">
Scaffold, verify with `eve info`, iterate with `eve dev`, and exercise `/eve/v1/session`.
</Card>
<Card title="Project layout" href="/project-layout">
Every authored slot under `agent/`, path-derived naming, and what compiles into `.eve/`.
</Card>
<Card title="Execution model" href="/execution-model">
Session/turn/step nesting, durable checkpoints, and parked work semantics.
</Card>
<Card title="Sessions and streaming" href="/sessions-and-streaming">
`continuationToken` vs `sessionId`, NDJSON events, and reconnect behavior.
</Card>
<Card title="CLI reference" href="/cli-reference">
All `eve` commands, flags, and the edit-info-dev-build-start loop.
</Card>
</CardGroup>
