Skip to Content

Get Started

This guide walks you through installing Newnadoon, creating your first agent, adding tools, memory, multi-agent workflows, and running your agent in both development and production.


1. Install

Newnadoon packages are hosted on a private registry. Configure access once before installing.

Configure registry access

Option A — Add a .npmrc file to your project root (recommended for teams):

@newnadoon:registry=https://npm.newnadoon.com/ registry=https://npm.newnadoon.com/

Option B — Run the config command once on your machine:

Terminal
$ npm config set @newnadoon:registry https://npm.newnadoon.com/

Create a new project

Run the Newnadoon project scaffolder. It asks for a project name, an optional Next.js frontend, and an optional debug dashboard.

Terminal
$ npm create newnadoon@latest

The installer will:

  1. Prompt for a project name.
  2. Ask whether to scaffold a Next.js frontend (optional).
  3. Ask whether to install the debug dashboard (optional). Default is no.
  4. Install @newnadoon/ai-framework (runtime only: agents, API, MCP) and copy sample agents.

@newnadoon/ai-framework does not include the debugger UI. Say yes at the dashboard prompt, or add it later:

Terminal
$ npm install -D @newnadoon/ai-framework-dashboard

Existing project (runtime only)

Terminal
$ npm install @newnadoon/ai-framework

Update the framework package

When a new version of the framework is released, update it independently:

Terminal
$ npm install @newnadoon/ai-framework@latest

2. Create your first agent

A Staff Agent is the core execution unit in Newnadoon. It receives a task, reasons about it using an LLM, and returns a result. This is the right starting point before adding tools or memory.

Configure your model

Set your OpenAI API key in a .env or .env.local file:

OPENAI_API_KEY=sk-... OPENAI_MODEL=gpt-4o-mini

Define and run a Staff Agent

import 'dotenv/config' import { createStaffAgent, useOpenAIModel } from '@newnadoon/ai-framework' const llm = await useOpenAIModel( process.env.OPENAI_MODEL || 'gpt-4o-mini', process.env.OPENAI_API_KEY ) const agent = createStaffAgent({ llm, tools: [], name: 'My First Agent', systemPrompt: 'You are a helpful assistant. Keep your answers brief.', maxSteps: 5, streaming: true }) const result = await agent.execute({ task: 'What is the capital of France?' }) console.log(result)

createStaffAgent returns an executable workflow. Pass any task string via the task key in the initial state.


3. Add tools

Tools are functions that give your agent the ability to interact with the outside world — APIs, databases, calculations, file systems, or any custom logic. Each tool has a name, a description the LLM uses to decide when to call it, and an execute function.

Define tools

import type { Tool } from '@newnadoon/ai-framework' const calculatorTool: Tool = { name: 'calculator', description: 'Performs mathematical operations on two numbers', execute: async (args) => { const a = Number(args.a) const b = Number(args.b) switch (args.operation) { case 'add': return a + b case 'subtract': return a - b case 'multiply': return a * b case 'divide': return b !== 0 ? a / b : null default: throw new Error(`Unknown operation: ${args.operation}`) } } } const searchTool: Tool = { name: 'search', description: 'Searches for information on a topic', execute: async (args) => { // Replace with a real API call return `Search results for: ${args.query}` } }

Pass tools to your agent

const agent = createStaffAgent({ llm, tools: [calculatorTool, searchTool], name: 'Tool-Enabled Agent', systemPrompt: 'You are a helpful assistant that can calculate and search.', maxSteps: 10, streaming: true }) const result = await agent.execute({ task: 'What is 42 multiplied by 7?' }) console.log(result)

The agent will automatically determine which tool to call, invoke it, observe the result, and reason toward a final answer.


4. Add memory and persistence

By default, each agent run is stateless. Persistent memory lets agents remember conversation history and prior context across multiple runs or sessions.

Newnadoon provides pluggable Storage Adapters for this. The PostgresStorageAdapter persists run state, checkpoints, and agent memory to a Postgres database.

import 'dotenv/config' import { createStaffAgent, useOpenAIModel, PostgresStorageAdapter } from '@newnadoon/ai-framework' const llm = await useOpenAIModel(process.env.OPENAI_MODEL || 'gpt-4o-mini') const storageAdapter = new PostgresStorageAdapter({ connectionString: process.env.POSTGRES_URL || process.env.DATABASE_URL || 'postgresql://postgres:postgres@localhost:5432/newnadoon' }) const agent = createStaffAgent({ llm, storageAdapter, tools: [], name: 'Multi-Turn Assistant', systemPrompt: 'You are a friendly assistant. Keep your answers brief.', reasoning: false, maxSteps: 5, streaming: true }) // First turn await agent.execute({ task: 'My name is Alex.' }) // Second turn — agent remembers the conversation await agent.execute({ task: 'What is my name?' })

Storage adapters also record run tracking, step history, and checkpoints — all of which are visible in the debug dashboard (see section 6).

Available adapters: MemoryStorageAdapter (in-process, no config), PostgresStorageAdapter, MongoStorageAdapter.


5. Department Agents

A Department Agent acts as a supervisor. It receives a task, decides which Staff Agent is best suited for it, delegates, and collects the result. This is how you model team-like behavior — individual specialists coordinated by a manager.

The Department Agent routes intelligently using the LLM and the names and system prompts of each registered staff agent.

import 'dotenv/config' import { createDepartmentAgent, createStaffAgent, useOpenAIModel, type Tool } from '@newnadoon/ai-framework' const llm = await useOpenAIModel( process.env.OPENAI_MODEL || 'gpt-4o-mini', process.env.OPENAI_API_KEY ) const calculatorTool: Tool = { name: 'calculator', description: 'Performs basic arithmetic on two numbers', execute: async (args) => { const a = Number(args.a), b = Number(args.b) switch (String(args.operation).toLowerCase()) { case 'add': return a + b case 'subtract': return a - b case 'multiply': return a * b case 'divide': return b === 0 ? null : a / b default: throw new Error(`Unsupported operation: ${args.operation}`) } } } const researchTool: Tool = { name: 'research', description: 'Returns a research summary for a query', execute: async (args) => `Research summary for "${args.query}": TypeScript is a typed superset of JavaScript.` } const writerTool: Tool = { name: 'writer', description: 'Writes a concise response from provided content', execute: async (args) => { const content = String(args.content ?? args.summary ?? args.text ?? '') return content.length > 0 ? `Written response: ${content}` : 'Written response: (empty input)' } } const mathStaff = createStaffAgent({ llm, tools: [calculatorTool], name: 'Math Staff', systemPrompt: 'You are a math specialist. Use the calculator when needed.', maxSteps: 5 }) const researchStaff = createStaffAgent({ llm, tools: [researchTool], name: 'Research Staff', systemPrompt: 'You are a research specialist. Use the research tool for facts.', maxSteps: 5 }) const writingStaff = createStaffAgent({ llm, tools: [writerTool], name: 'Writing Staff', systemPrompt: 'You are a writing specialist. Use the writer tool to craft output.', maxSteps: 5 }) const department = await createDepartmentAgent({ name: 'Customer Success Department', systemPrompt: 'You are a department manager. Delegate to the best staff agent and return a concise final answer.', llm, llmOptions: { temperature: 0.2, maxTokens: 500 }, maxSteps: 10, streaming: true, staffAgents: { math: mathStaff, research: researchStaff, writing: writingStaff } }) const result = await department.execute({ task: 'What is 12 multiplied by 7?' }) console.log(result)

The manager agent selects math for calculation tasks, research for information tasks, and writing for output formatting — all without manual routing code.


6. Workflows

A Workflow is the orchestration layer for multi-step, deterministic business processes. Unlike agents (which reason freely), workflows run steps in a defined sequence with explicit transitions, conditional routing, and state passed between each step.

Use workflows when you need predictable execution order, branching logic, or a pipeline where each stage transforms and passes state to the next.

import 'dotenv/config' import { createWorkflowBuilder, createStep, useOpenAIModel } from '@newnadoon/ai-framework' const llm = await useOpenAIModel(process.env.OPENAI_MODEL || 'gpt-4o-mini') // Define individual steps const routeStep = createStep<any>({ fn: () => 'route', setResult: () => ({}) }) const addStep = createStep<any>({ fn: ({ a, b }) => a + b, getArgs: (state) => ({ a: Number(state.a), b: Number(state.b) }), setResult: (_state, result) => ({ result }) }) const multiplyStep = createStep<any>({ fn: ({ a, b }) => a * b, getArgs: (state) => ({ a: Number(state.a), b: Number(state.b) }), setResult: (_state, result) => ({ result }) }) // Build the workflow const workflow = createWorkflowBuilder() .addStep('route', routeStep) .addStep('add', addStep) .addStep('multiply', multiplyStep) .addConditionalTransition('route', async (state) => { // LLM decides which step to run next based on the request const operation = await llm( `Route this request to either "add" or "multiply": "${state.request}"`, { temperature: 0 } ) return operation.trim().toLowerCase() }) .setEntryPoint('route') .build() // Execute const result = await workflow.execute({ a: 12, b: 7, request: 'Multiply these two numbers.' }) console.log(result.result) // → 84

Workflows support sequential transitions, LLM-based conditional routing, and parallel step branches. They are the right choice for automating end-to-end business processes that require both logic and auditability.


7. Host and debug your agent

Development — API first

After installing, start the API + MCP server. This is the main runtime and does not download the dashboard.

Terminal
$ npx newnadoon-api --port 8080

Development — Debug dashboard (optional)

The debugger is a separate package. Install it only if you want the local UI:

Terminal
$ npm install -D @newnadoon/ai-framework-dashboard
Terminal
$ npx newnadoon dev

The dashboard launches at http://localhost:2024  so you can run agents, view state at each step, and stream events. Use this during development before deploying.

For a full explanation of how the dashboard works and how newnadoon.json registers agents, see Debugger visibility dashboard.

Voice — sample Voice Assistant

Scaffolded projects include a NewnaVoiceKit sample (lib/agents/voice-assistant.ts). To enable speech:

  1. npx newnadoon-voice setup && npx newnadoon-voice download-files
  2. Add NewnaVoiceKit, Deepgram, and Cartesia keys to .env
  3. Set NEWNAVOICEKIT_AGENT_RUN_URL=http://localhost:2024/api/voice/turn
  4. Run npx newnadoon-voice dev alongside npx newnadoon dev

Step-by-step guide: Voice agents.

Production — API and MCP server

Install @newnadoon/[email protected] or later from https://npm.newnadoon.com/. Then start the API + MCP server:

Terminal
$ npx newnadoon-api --port 8080

Cursor talks to POST http://localhost:8080/api/mcp (Streamable HTTP). Open http://localhost:8080/ for the default MCP client snippets. Add public/index.html to replace that HTML page; other files in public/ (favicon, assets) are served at /.

create-newnadoon copies Dockerfile.user and docker-compose.user.yml. Compose starts local Postgres (host 5433) and Redis (host 6380), runs npx newnadoon-db migrate deploy, then the API. The framework does not embed those databases. Traefik / Cloudflare should only expose the API (8080). Do not put Redis or Postgres on the public edge.

Override POSTGRES_URL / REDIS_URL to use your own database and remove those compose services.

The Kanban work-item sample uses the same Compose baseline (cards still live in Kanban; Postgres/Redis persist agent runs). From a scaffolded project:

docker compose -f docker-compose.user.yml up --build -d

Production — Host on Newnadoon cloud

To run on Newnadoon infra (public App / API / MCP URLs), subscribe to Newnadoon Agents in Portal, create a write:deploy API key (ndpub_…), then:

Terminal
$ npx newnadoon deploy --name my-agent --tag latest

Requires @newnadoon/ai-framework 1.0.31+, Docker, and Dockerfile.user + .npmrc in the project. Full guide: Host on Newnadoon cloud.


Next steps