Zero-to-One Multi-Agent AI System in TypeScript

This guide gives you a concrete, working architecture for a zero-to-one multi-agent AI system in TypeScript — covering agent orchestration, tool registration, memory persistence with Supabase, and a streaming Next.js frontend, so you ship something real instead of another demo.

◆ The Kit
Pantheon Starter Kit — Build your own autonomous AI workforce
Full Next.js + Supabase + Claude codebase. 9 PM2 agents wired up. Cost guardrails included. 43 SEO-ready topic pages with AdSense + affiliate slots already plumbed.
$39
buy on gumroad →
ADVERTISEMENT

What 'Multi-Agent' Actually Means in Practice

A multi-agent system is not just multiple API calls. It is a set of specialized agents — each with a defined role, tool access, and context window — coordinated by an orchestrator that routes tasks, aggregates results, and decides when the job is done.

For indie builders, the practical split is: one Orchestrator agent that breaks down the user goal, two or three Worker agents that execute discrete subtasks (web search, code execution, data retrieval), and a Critic agent that validates outputs before they surface to the user. This pattern keeps each agent's prompt focused and its failure surface small.

ADVERTISEMENT
Get the Pantheon Starter Kit$39
◇ no time to read?
Get one tight email when I publish something worth sharing — autonomous AI agents, cost engineering, post-mortems. No spam, no SaaS pitches.

Defining Agent Roles and Tool Schemas in TypeScript

Start by defining each agent as a typed object with a system prompt, an allowed tool list, and a max-token budget. TypeScript interfaces enforce this contract across your codebase and make it trivial to add agents later without breaking existing ones.

Tools follow Claude's tool-use schema: a name, a description the model reads at inference time, and a Zod-validated input schema. Keeping tool definitions co-located with their implementation functions prevents the common bug where the schema drifts from the actual handler.

// agent.types.ts
import { z } from 'zod';

export interface AgentTool<T extends z.ZodTypeAny> {
  name: string;
  description: string;
  inputSchema: T;
  handler: (input: z.infer<T>) => Promise<string>;
}

export interface AgentConfig {
  id: string;
  systemPrompt: string;
  tools: AgentTool<z.ZodTypeAny>[];
  maxTokens: number;
}

// Example worker agent
const searchAgent: AgentConfig = {
  id: 'search-worker',
  systemPrompt: 'You retrieve and summarize web content. Return only facts.',
  tools: [webSearchTool],
  maxTokens: 1024,
};

Orchestrator Loop and Claude API Integration

The orchestrator runs a loop: it calls Claude with the current task and tool list, checks whether Claude returned a tool_use block or a final text response, executes the tool if needed, appends the result to the message history, and loops until Claude returns a stop reason of 'end_turn'.

One critical detail: pass the full message history on every turn, not just the last message. Claude's tool-use reliability drops sharply when it loses context about what it already tried. Cap history at a rolling window of the last 20 messages to stay within token limits.

Persisting Agent Memory with Supabase

Short-term memory lives in the in-process message array. Long-term memory — summaries, user preferences, completed task records — lives in Supabase. A simple agent_runs table with a JSONB messages column and pgvector embeddings for semantic recall covers most indie-scale use cases.

Use Supabase Row Level Security from day one. Each agent run is scoped to a user_id, so you never accidentally leak one user's agent history to another. Adding RLS after the fact on a populated table is painful.

-- supabase/migrations/001_agent_runs.sql
create table agent_runs (
  id          uuid primary key default gen_random_uuid(),
  user_id     uuid references auth.users not null,
  goal        text not null,
  messages    jsonb not null default '[]',
  embedding   vector(1536),
  status      text check (status in ('running','complete','failed')),
  created_at  timestamptz default now()
);

alter table agent_runs enable row level security;

create policy "Users see own runs"
  on agent_runs for all
  using (auth.uid() = user_id);

Streaming Agent Output in a Next.js App Router Route

Wrap your orchestrator loop in a Next.js Route Handler that returns a ReadableStream. On the client, consume it with the Vercel AI SDK's useCompletion hook or a plain EventSource — both work. Stream each agent's intermediate reasoning steps, not just the final answer, so users see progress and trust the system.

Avoid the common mistake of awaiting the entire orchestrator run before responding. On long tasks, Vercel's 60-second function timeout will kill you. Stream early, flush often, and store the final result to Supabase so the client can poll for completion if the stream drops.

Open-Source Implementation: Pantheon

Pantheon is an open-source multi-agent starter kit built on exactly this stack — TypeScript, Claude, Next.js App Router, and Supabase. It ships with a working orchestrator loop, typed tool registration, Supabase migrations, and a streaming chat UI. You can clone it and have a running agent system in under an hour.

Find the repo, setup guide, and architecture notes at github.com/lewisallena17/pantheon. Issues and PRs are open — it is built for indie developers who want a real foundation, not a toy example.

Open-source implementation

Everything in this article runs in pantheon — a production-ready Next.js + Supabase + Claude starter. Clone it, deploy to Vercel, run PM2. The dashboard auto-commits every agent edit and reverts itself if TypeScript breaks.

◈ Tools mentioned

  • Supabase — open-source Firebase alt
  • Vercel — zero-config Next.js hosting
  • Claude — AI assistant by Anthropic
  • Gumroad — sell digital products

Some links may pay us a referral if you sign up. Never affects the price you pay.

Get the full starter kit

Clone the Pantheon starter kit at github.com/lewisallena17/pantheon, follow the README to wire up your Claude API key and Supabase project, and ship your first zero-to-one multi-agent AI system in TypeScript this week — not this quarter.