Flue Zero to Expert, Part 1: Your First Agent

Start from zero. Install Flue, learn the agent harness model, create one headless agent, and run it locally.

Series map

Part 1: Your First Flue Agent · Part 2: Typed Workflows · Part 3: Safe Tools · Part 4: Autonomous Agents · Part 5: Persistence and Durable Execution · Part 6: Production Routing and Deployment · Part 7: Operate Like an Expert

Tested with Flue 1.0.0-beta.9. Beta APIs and CLI behavior may change in later releases.

A Flue agent is a model running inside a harness.

The model reasons and generates text. The harness provides the environment around it: instructions, tools, a filesystem, context, skills, subagents, and a sandbox.

This split matters. A model call alone cannot keep files, run commands, or act on external systems. The harness gives it only the abilities you configure.

Flue agents are headless: they do not include a chat interface or terminal UI. Your application starts them through code, HTTP, or the Flue CLI.

In this part, you will create one Node.js agent and run one prompt against it.

Prerequisites

Flue 1.0.0-beta.9 requires Node.js 22.19.0 or newer.

Check your version:

node --version

You also need access to a supported model provider. This example uses Anthropic and anthropic/claude-sonnet-4-6.

Create a project:

mkdir flue-hello
cd flue-hello
npm init -y
npm install @flue/runtime
npm install --save-dev @flue/cli
echo 'ANTHROPIC_API_KEY="your-api-key"' > .env
echo '.env' >> .gitignore
npx flue init --target node

Replace your-api-key with a real provider key. Never commit .env: provider credentials are secrets. This file is for local development, not source control.

In beta.9, flue init creates flue.config.ts for the selected target.

Project layout

For beta.9, src/ is the recommended source directory for a new project. Flue discovers agents from src/agents/.

flue-hello/
├─ .env
├─ .gitignore
├─ flue.config.ts
├─ package.json
└─ src/
   └─ agents/
      └─ hello-world.ts

Create the directory:

mkdir -p src/agents

Keep discovered agent files flat inside src/agents/; nested files are not discovered as separate agents. The filename becomes the public name, so src/agents/hello-world.ts registers hello-world.

Beta.9 can instead use .flue/ or the project root as its source directory. It selects the first existing layout in this order:

  1. .flue/
  2. src/
  3. The project root

It does not merge these locations. If .flue/ exists, agents under src/agents/ are not discovered.

Define the agent

Create src/agents/hello-world.ts:

import { defineAgent } from '@flue/runtime';

export default defineAgent(() => ({
  model: 'anthropic/claude-sonnet-4-6',
  instructions: 'Tell a short, funny "hello world" engineering joke.',
}));

defineAgent describes the harness configuration:

  • model selects the provider and model.
  • instructions define the agent's role and behavior.

The default export registers this file as a discoverable agent. A named export alone does not register it.

This agent has no custom tools or external side effects. It cannot update a database, call a private service, or modify your application unless you explicitly add those capabilities. Any capability that crosses a trust boundary also needs authorization checks.

Run the headless agent

Invoke the discovered agent with JSON input:

npx flue run hello-world --input '{"message":"Tell me a joke."}'

In beta.9, Flue starts the configured runtime, finds hello-world, sends the prompt, prints the response, and exits.

The exact joke can change between runs. Model output is not deterministic; treat it as untrusted data before displaying, storing, or passing it to another system.

The CLI is only a convenient caller. The agent remains headless. A production application must decide how users reach it, how callers authenticate, and where state is stored.

You now have the smallest useful Flue agent: one model, one instruction, one discovered module, and one headless invocation.

Next, continue to Part 2: Typed Workflows to turn agent work into a finite, validated operation.

Sources