# Quickstart

> Scaffold with eve init, verify discovery with eve info, iterate with eve dev, and create/stream/continue an HTTP session against /eve/v1/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

- `docs/getting-started.mdx`
- `packages/eve/src/cli/commands/init.ts`
- `apps/fixtures/weather-agent/agent/agent.ts`
- `apps/fixtures/weather-agent/agent/tools/get_weather.ts`
- `apps/fixtures/weather-agent/agent/instructions.md`
- `packages/eve/src/protocol/routes.ts`

---

---
title: "Quickstart"
description: "Scaffold with eve init, verify discovery with eve info, iterate with eve dev, and create/stream/continue an HTTP session against /eve/v1/session."
---

The shortest path from zero to a running agent is four CLI surfaces and one HTTP contract: `eve init` writes `agent/` and installs dependencies, `eve info` reports compiled discovery and the active message routes, `eve dev` starts the Nitro dev host (default port `2000`, overridable via `$PORT` or `--port`), and the built-in Eve channel at `agent/channels/eve.ts` serves `POST /eve/v1/session`, `POST /eve/v1/session/:sessionId`, and `GET /eve/v1/session/:sessionId/stream`.

## Prerequisites

<Note>
See [Installation](/installation) for Node version requirements, package-manager install paths, and model credential setup.
</Note>

- Node 24 or newer
- A package manager (`npm`, `pnpm`, `yarn`, or `bun`)
- A model credential for the scaffold's default model (`anthropic/claude-sonnet-4.6`)

Gateway-routed model ids need `AI_GATEWAY_API_KEY` or a `VERCEL_OIDC_TOKEN` from `vercel link`. Direct provider ids need that provider's key (for example, `anthropic/claude-...` → `ANTHROPIC_API_KEY`). Place keys in `.env.local` or another file from Eve's development env load order (`.env.development.local` → `.env.local` → `.env.development` → `.env`).

## Scaffold an agent

<Steps>
<Step title="Create a new project">

Run `eve init` without a global install:

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

The command:

- Creates a child directory with `agent/agent.ts`, `agent/instructions.md`, and `agent/channels/eve.ts`
- Pins `eve`, `ai`, `zod`, and `@vercel/connect` in `package.json`
- Adds `dev`, `build`, and `start` scripts that call the `eve` binary
- Installs dependencies and initializes Git (fresh scaffolds only)
- Starts `eve dev --input /model` in an interactive terminal (unless a coding agent launched the CLI)

Pass `--channel-web-nextjs` to also scaffold a Next.js Web Chat app. Every scaffold ships the HTTP channel regardless.

<Warning>
`eve init` holds the terminal while the dev TUI runs. Press Ctrl+C to return to your shell before editing files. The command does not create a Vercel project or deploy.
</Warning>

</Step>

<Step title="Or add to an existing project">

From a directory that already has `package.json` and no conflicting `agent/` files:

```bash
npx eve@latest init .
```

Eve writes only the `agent/` tree and adds missing runtime dependencies. It does not modify unrelated host configuration. `--channel-web-nextjs` is not supported for in-place init; run `eve channels add web` afterward instead.

</Step>
</Steps>

### Scaffold layout

:::files
my-agent/
├── agent/
│   ├── agent.ts          # defineAgent({ model })
│   ├── instructions.md   # always-on system prompt
│   └── channels/
│       └── eve.ts        # HTTP ingress (POST/GET /eve/v1/session*)
├── package.json          # dev / build / start scripts
├── tsconfig.json
└── .gitignore            # ignores .eve, .env*, node_modules
:::

The default `agent/agent.ts` sets `model: "anthropic/claude-sonnet-4.6"`. Instructions start as a minimal markdown prompt. The default harness already exposes file, shell, web, and delegation tools before you author any custom tools.

## Verify discovery

Run `eve info` from the app root after scaffolding or any edit under `agent/`:

```bash
npx eve info
```

Human output reports app paths, compile status, discovery diagnostics (errors and warnings), discovered instructions/skills/tools/channels, and the active messaging contract:

| Label | Example value |
| --- | --- |
| Create | `POST /eve/v1/session` |
| Continue | `POST /eve/v1/session/:sessionId` |
| Stream | `GET /eve/v1/session/:sessionId/stream` |

For machine-readable output:

```bash
npx eve info --json
```

The JSON document includes `status`, `model`, `tools`, `channels`, `messaging` route paths, and `.eve/` artifact paths (`compiledManifest`, `discoveryManifest`, `diagnostics`, `moduleMap`, `metadata`). Fix discovery errors before starting the dev server; diagnostics also land in `.eve/discovery/diagnostics.json` after compile.

<Check>
A healthy quickstart run shows compile status `ready` and zero discovery errors.
</Check>

## Add a first tool

Tool names are derived from filenames under `agent/tools/` — no `name` field. Use snake_case ASCII. Create `agent/tools/get_weather.ts`:

```ts
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 }) {
    return { city, condition: "Sunny", temperatureF: 72 };
  },
});
```

Tools execute in the app runtime with access to `process.env`, not inside the sandbox. Re-run `eve info` to confirm `get_weather` appears in the tools list.

## Run locally

From the app root:

```bash
npm run dev
```

Equivalent direct invocation:

```bash
npx eve dev
```

<ParamField body="--port" type="number">
Listen port. Defaults to `$PORT`, then `2000`.
</ParamField>

<ParamField body="--no-ui" type="boolean">
Start the server without the interactive terminal UI.
</ParamField>

<ParamField body="--url" type="string">
Connect the TUI to an existing server URL instead of starting a local host (for example, `eve dev https://your-app.vercel.app`).
</ParamField>

The dev server loads environment files from the app root, compiles `agent/` into `.eve/`, and serves the Eve channel. In the TUI, type a message and observe tool calls, results, and the assistant reply in order.

<Tip>
Recommended iteration loop: edit `agent/` → `eve info` → `eve dev` → `eve build` → `eve start` for production-shaped verification.
</Tip>

## Create an HTTP session

Every Eve app exposes the same stable routes through the built-in Eve channel. With the dev server running on port `2000`:

:::endpoint POST /eve/v1/session
Create a durable session and enqueue the first user turn.
:::

<ParamField body="message" type="string | UserContent" required>
Plain text or multimodal AI SDK user content.
</ParamField>

<ParamField body="clientContext" type="string | string[] | object">
One-turn client context converted into model context by the channel.
</ParamField>

<ParamField body="outputSchema" type="object">
JSON schema for structured assistant output on this turn.
</ParamField>

<RequestExample>

```bash
curl -s -D - -X POST http://127.0.0.1:2000/eve/v1/session \
  -H 'content-type: application/json' \
  -d '{"message":"What is the weather in Brooklyn?"}'
```

</RequestExample>

<ResponseExample>

```json
{
  "continuationToken": "eve:…",
  "ok": true,
  "sessionId": "session_…"
}
```

Response headers include `x-eve-session-id` (same value as `sessionId`). Status is `202 Accepted`.

</ResponseExample>

<ResponseField name="continuationToken" type="string">
Namespaced token required to continue the conversation. Store it with `sessionId`.
</ResponseField>

<ResponseField name="sessionId" type="string">
Durable session identifier for stream attachment and follow-up posts.
</ResponseField>

Local development accepts loopback requests without extra auth headers. Deployed targets use the Eve channel's route-auth chain (see [Security model](/security-model)).

## Stream the session

:::endpoint GET /eve/v1/session/:sessionId/stream
Attach to the durable NDJSON event stream for one session.
:::

<ParamField query="startIndex" type="number">
Non-negative event index to resume from. Omit to receive the full stream from the beginning.
</ParamField>

<RequestExample>

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

</RequestExample>

The response uses `Content-Type: application/x-ndjson; charset=utf-8` with `x-eve-stream-format: ndjson` and `x-eve-stream-version: 15`.

A tool-using run typically emits:

| Event | When |
| --- | --- |
| `session.started` | Workflow session begins |
| `turn.started` | Turn boundary |
| `message.received` | User message accepted |
| `actions.requested` | Harness requests tool calls (for example `get_weather`) |
| `action.result` | Tool result projected back |
| `message.completed` | Final assistant text for the step |
| `session.waiting` | Session parked for the next user message |
| `session.completed` | Terminal success |

`message.appended` and `reasoning.appended` are optional incremental events; clients that only need final text can wait for `message.completed`. Human-in-the-loop, authorization, and failure events (`input.requested`, `authorization.required`, `turn.failed`, `session.failed`) appear when the harness parks for external input.

```mermaid
sequenceDiagram
  participant Client
  participant EveChannel as agent/channels/eve.ts
  participant Runtime as Durable workflow

  Client->>EveChannel: POST /eve/v1/session {message}
  EveChannel->>Runtime: send(turn, continuationToken)
  EveChannel-->>Client: 202 {sessionId, continuationToken}
  Client->>EveChannel: GET /eve/v1/session/:id/stream
  Runtime-->>EveChannel: NDJSON events
  EveChannel-->>Client: session.started … message.completed
  Client->>EveChannel: POST /eve/v1/session/:id {continuationToken, message}
  EveChannel->>Runtime: send(follow-up)
  EveChannel-->>Client: 200 {ok, sessionId}
```

## Continue the conversation

When the stream shows `session.waiting` (or after `message.completed` on the first turn), post a follow-up:

:::endpoint POST /eve/v1/session/:sessionId
Deliver the next user message or HITL input to an existing session.
:::

<ParamField body="continuationToken" type="string" required>
Token from the create response (or the latest turn boundary). Requests without it return `400`.
</ParamField>

<ParamField body="message" type="string | UserContent">
Next user message. Required unless `inputResponses` is supplied.
</ParamField>

<ParamField body="inputResponses" type="InputResponse[]">
Human-in-the-loop responses when the harness emitted `input.requested`.
</ParamField>

<RequestExample>

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

</RequestExample>

<ResponseExample>

```json
{
  "ok": true,
  "sessionId": "session_…"
}
```

</ResponseExample>

Re-attach to the stream (same `sessionId`) to observe the next turn. The continue route returns `200`; it does not echo a new `continuationToken` in the JSON body — reuse the token from session creation until the harness re-keys it at a turn boundary.

## What you have now

| Surface | Role |
| --- | --- |
| `agent/instructions.md` | Always-on behavior |
| `agent/tools/*.ts` | Typed capabilities the model invokes |
| `agent/channels/eve.ts` | HTTP ingress for sessions |
| `eve dev` | Local host + optional TUI |
| `/eve/v1/session*` | Create, stream, and continue durable conversations |

The agent already runs with the default harness (bash, file ops, `web_fetch`, `todo`, `ask_question`, `agent`, `load_skill`, `connection_search`). Override or disable built-ins under `agent/tools/` when you need tighter control.

## Next

<CardGroup>
<Card title="Project layout" href="/project-layout">
Authored slots under `agent/`, path-derived naming, and what compiles into `.eve/`.
</Card>
<Card title="Sessions and streaming" href="/sessions-and-streaming">
`continuationToken` contracts, NDJSON vocabulary, reconnect behavior, and subagent streams.
</Card>
<Card title="Default harness" href="/default-harness">
Built-in tools, compaction defaults, and override patterns.
</Card>
<Card title="Client integration" href="/client-integration">
`eve/client` `Client` and `ClientSession`, plus React/Vue/Svelte hooks.
</Card>
<Card title="HTTP API reference" href="/http-api">
Full `/eve/v1` route inventory, request shapes, and error codes.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Discovery diagnostics, dev-server conflicts, and runtime failure codes.
</Card>
</CardGroup>
