# Eve quickstart

> Run `eve init`, start `eve dev`, inspect discovery with `eve info`, and send the first session message to the stable HTTP API.

- Repository: withastro/flue-with-vercel-eve
- GitHub: https://github.com/withastro/flue
- Human docs: https://grok-wiki.com/public/docs/withastro-flue-with-vercel-eve-f4b79875fff6
- Complete Markdown: https://grok-wiki.com/public/docs/withastro-flue-with-vercel-eve-f4b79875fff6/llms-full.txt

## Source Files

- `vercel-eve:README.md`
- `vercel-eve:docs/getting-started.mdx`
- `vercel-eve:docs/reference/cli.md`
- `vercel-eve:docs/concepts/sessions-runs-and-streaming.md`
- `vercel-eve:apps/fixtures/weather-agent/agent/agent.ts`
- `vercel-eve:apps/fixtures/weather-agent/agent/tools/get_weather.ts`

---

---
title: "Eve quickstart"
description: "Run `eve init`, start `eve dev`, inspect discovery with `eve info`, and send the first session message to the stable HTTP API."
---

Eve scaffolds a filesystem-first agent under `agent/`, compiles discovery into `.eve/`, and serves a stable HTTP channel at `/eve/v1/session*` on port `3000` during local development. The `eve` CLI owns project bootstrap, discovery inspection, and the dev runtime; every app exposes the same session create, continue, and NDJSON stream routes whether you call them from `curl`, a client SDK, or the terminal UI.

## Prerequisites

| Requirement | Detail |
| --- | --- |
| Node.js | `24.x` or newer (`engines.node` is pinned on scaffold) |
| Package manager | npm (bundled with Node), or pnpm/yarn/bun if that manager launched the CLI |
| Model credential | Provider-neutral: gateway model ids need `AI_GATEWAY_API_KEY` or `VERCEL_OIDC_TOKEN`; direct provider ids need that provider's env key (for example `ANTHROPIC_API_KEY` for `anthropic/...`) |

<Note>
`eve init` does not create or link a Vercel project. Use `eve link` later to pull gateway credentials into `.env.local`. A running `eve dev` reloads env files automatically after linking.
</Note>

## Scaffold a project

<Steps>
<Step title="Run eve init">

<Tabs>
<Tab title="New directory">

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

Creates `my-agent/` with `agent/agent.ts`, `agent/instructions.md`, `agent/channels/eve.ts`, `package.json` scripts (`dev`, `build`, `start`), installs `eve`, `ai`, and `zod`, initializes Git, and starts the dev server.

</Tab>
<Tab title="Current directory">

```bash
mkdir my-agent && cd my-agent
npx eve@latest init .
```

Requires an empty directory (only `.git` and similar dotfiles allowed). Same scaffold as a named target, written in place.

</Tab>
<Tab title="Existing app">

```bash
cd existing-app
npx eve@latest init .
```

Requires an existing `package.json` and no `agent/` directory yet. Adds only the agent files and missing `eve`, `ai`, and `zod` dependencies.

</Tab>
</Tabs>

Pass `--channel-web-nextjs` on a **new** scaffold to add the Web Chat Next.js app. That flag is rejected when adding to an existing project; run `eve channels add web` there instead.

</Step>

<Step title="Stop the dev server to edit files">

`eve init` holds the terminal while `eve dev` runs. Press **Ctrl+C** to return to the shell before editing `agent/`.

On a fresh scaffold, init launches `eve dev --input /model`, which opens the TUI model setup flow. Configure credentials there or in `.env.local` before sending HTTP requests that hit the model.

</Step>

<Step title="Verify the scaffold layout">

:::files
my-agent/
├── package.json
├── tsconfig.json
├── agent/
│   ├── agent.ts
│   ├── instructions.md
│   └── channels/
│       └── eve.ts
└── .eve/          # created after first compile/dev
:::

The default `agent/agent.ts` sets `model: "anthropic/claude-sonnet-4.6"`. Tool names are path-derived: `agent/tools/get_weather.ts` becomes tool `get_weather` for the model.

</Step>
</Steps>

## Start the local runtime

From the project root:

```bash
npm run dev
```

Equivalent to `eve dev`. With no subcommand, `eve` alone also runs `eve dev`.

| Flag | Default | Effect |
| --- | --- | --- |
| `--port` | `$PORT`, then `3000` | Listen port |
| `--host` | all interfaces | Bind address |
| `--no-ui` | UI on | Server only, no terminal UI |
| `--url <url>` | none | Connect UI to a remote deployment instead of starting locally |

<Check>
A healthy local server answers `GET http://127.0.0.1:3000/eve/v1/health` without credentials. Eve writes the active dev PID to `.eve/dev-process.pid`; a second `eve dev` for the same agent exits if that process is still running.
</Check>

## Inspect discovery with eve info

Run discovery and compile without starting the server:

```bash
eve info
```

Human output includes app root, agent root, compile status, diagnostics summary, discovered skills and tools, artifact paths under `.eve/`, and the active messaging contract:

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

Machine-readable output:

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

<ParamField body="--json" type="flag">
Emit the stable JSON contract: `appRoot`, `agentRoot`, `status`, `model`, `tools`, `channels`, `messaging`, `artifacts`, and `diagnostics` counts.
</ParamField>

<Tip>
Run `eve info` after editing files under `agent/` to confirm discovery before debugging runtime behavior. On compile failure, `eve build` prints the full diagnostics report and the path to `.eve/discovery/diagnostics.json`.
</Tip>

## Send the first session message

Every Eve app mounts the Eve HTTP channel. Session routes are enabled by default even when you omit `agent/channels/eve.ts`; the scaffold includes `agent/channels/eve.ts` with `localDev()` and a production auth placeholder.

### Create a session

:::endpoint POST /eve/v1/session
Start a durable session with a user message. Returns immediately with handles for streaming and follow-ups.
:::

<ParamField body="message" type="string | UserContent" required>
Non-empty user message. Plain strings are the common case.
</ParamField>

<RequestExample>

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

</RequestExample>

<ResponseExample>

```json
{
  "continuationToken": "eve:7f3c…",
  "ok": true,
  "sessionId": "ses_01h…"
}
```

Response headers include `x-eve-session-id` (same session id) and `cache-control: no-store`. Status is **202 Accepted**.

</ResponseExample>

<ResponseField name="continuationToken" type="string">
Resume handle for the next user message on this conversation. Owned by the channel.
</ResponseField>

<ResponseField name="sessionId" type="string">
Stream-and-inspect handle. Attach to `GET /eve/v1/session/:sessionId/stream`.
</ResponseField>

<Warning>
Do not conflate the two handles. `continuationToken` resumes the conversation; `sessionId` identifies the run for streaming and inspection.
</Warning>

### Stream session events

:::endpoint GET /eve/v1/session/:sessionId/stream
Replay and follow the durable NDJSON event stream for one session.
:::

<RequestExample>

```bash
curl -N http://127.0.0.1:3000/eve/v1/session/ses_01h…/stream
```

</RequestExample>

The response content type is `application/x-ndjson; charset=utf-8`. Each line is one JSON event. A typical tool-using turn emits:

| Event | Meaning |
| --- | --- |
| `session.started` | Durable session created |
| `turn.started` | New turn began |
| `actions.requested` | Model requested tool calls |
| `action.result` | Tool returned |
| `message.completed` | Finalized assistant text |
| `session.waiting` | Session parked, ready for follow-up |
| `session.completed` | Terminal session end |

`reasoning.appended` and `message.appended` are optional incremental deltas; clients that do not render streaming can wait for `reasoning.completed` and `message.completed`.

Reconnect or rewind with `?startIndex=<count>` on the stream URL.

### Send a follow-up

After `session.waiting`, post to the session-specific route with the stored token:

:::endpoint POST /eve/v1/session/:sessionId
Continue an existing session. Requires the current `continuationToken`.
:::

<ParamField body="continuationToken" type="string" required>
Token from the create response (or the latest valid token for this session).
</ParamField>

<ParamField body="message" type="string" required>
Next user message.
</ParamField>

<RequestExample>

```bash
curl -X POST http://127.0.0.1:3000/eve/v1/session/ses_01h… \
  -H 'content-type: application/json' \
  -d '{"continuationToken":"eve:7f3c…","message":"Now check Queens."}'
```

</RequestExample>

<ResponseExample>

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

Status **200**. Reattach to the same stream URL to observe the new turn.

</ResponseExample>

Send one follow-up at a time and wait for `session.waiting` before posting another message to the same session.

## Optional: add a typed tool

The scaffold ships with the default harness (file, shell, web, and delegation tools). For a concrete tool call in the stream, add `agent/tools/get_weather.ts`:

```ts title="agent/tools/get_weather.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 };
  },
});
```

Run `eve info` to confirm `get_weather` appears under tools, then repeat the HTTP flow. The `weather-agent` fixture in the Eve repo is a fuller example with instructions, skills, and model options.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| Model errors on first message | Credential in `.env.local`; default model `anthropic/claude-sonnet-4.6` needs gateway or Anthropic key. TUI `/model` walks through setup. |
| Tool not called | `eve info` lists discovered tools; filename must be snake_case (`get_weather.ts` → `get_weather`). |
| `400` on follow-up | Body must include non-empty `continuationToken`; stale tokens are rejected. |
| `404` on stream | `sessionId` from create response or `x-eve-session-id` header; server must still be running. |
| Port already in use | Another `eve dev` may be active; check `.eve/dev-process.pid` or pass `--port`. |
| Discovery warnings | `eve info` diagnostics row; inspect `.eve/discovery/diagnostics.json`. |

<AccordionGroup>
<Accordion title="Auth during local development">

`localDev()` on the scaffolded `agent/channels/eve.ts` accepts loopback requests during development. Deployed targets require OIDC or your own auth policy. `GET /eve/v1/health` is always public.

</Accordion>
<Accordion title="Smoke-test a deployment from the CLI">

```bash
eve dev https://your-app.vercel.app
```

Connects the terminal UI to a remote server instead of booting locally.

</Accordion>
</AccordionGroup>

## Related pages

<CardGroup>
<Card title="Installation" href="/installation">
Prerequisites, Node engine requirements, and first-install commands for Eve projects.
</Card>
<Card title="Eve project layout" href="/eve-project-layout">
Authored slots under `agent/`, path-derived naming, and discovery boundaries.
</Card>
<Card title="Eve sessions and streaming" href="/eve-sessions-streaming">
Full NDJSON event set, `continuationToken` lifecycle, HITL, and reconnect rules.
</Card>
<Card title="Eve HTTP protocol reference" href="/eve-http-protocol-reference">
Session routes, event types, and client integration entry points.
</Card>
<Card title="Eve CLI reference" href="/eve-cli-reference">
Flags and defaults for `eve init`, `info`, `dev`, `build`, and related commands.
</Card>
<Card title="Eve weather fixture" href="/eve-weather-fixture">
End-to-end walkthrough of the `weather-agent` fixture with tool and skill authoring.
</Card>
</CardGroup>
