Model or dataset
open-multi-agent/open-multi-agent avatar
open-multi-agent/open-multi-agent

open-multi-agent orchestration: a coordinator plans the task graph, and you own the approvals and the audit trail

TypeScript AI agent orchestration framework with dynamic workflows. Describe the goal, not the graph: a coordinator plans the task DAG at runtime and runs it on any LLM (Claude, ChatGPT, Gemini, DeepSeek, or local models).

7,059 stars2,437 forksTypeScriptMIT

At a glance

What is it?
OMA (Open Multi-Agent) is a self-hosted TypeScript runtime where runTeam() turns a goal into a task DAG at runtime. Its approval gates, run journal and governance checks are real, but each one stops short in a way the documentation states plainly.
Who is it for?
Use open-multi-agent if you run a Node.js backend, want agents planned from a goal rather than a hand-drawn graph, and need approval pauses and an offline run record without a hosted control plane. Skip it if you need a tamper-proof audit log, since verifyRun() does not prove the journal was never edited, or if you want an approval UI out of the box.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • open-multi-agent/open-multi-agent7,059 ★ · +383
Star history
Repository2026-07-292026-11-14
open-multi-agent/open-multi-agent6.7k7.1k

383 Stars in the last 108 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

runTeam() plans the task DAG at runtime instead of asking you to draw it

The core idea is in the project's tagline: describe the goal, not the graph. OMA exposes three entry points. runAgent() runs a single agent, runTasks() executes an explicit pipeline you define, and runTeam() hands a goal to a coordinator that plans the task DAG at runtime and dispatches it to the team's agents. This is the opposite of graph-first frameworks such as LangGraph, where you declare nodes and edges in code before anything runs. With OMA you keep that option through runTasks(), but the headline mode is planning on the fly.

The example below creates a two-agent team with shared memory and passes it a goal. Nothing in it declares a task graph.

typescript
import { OpenMultiAgent } from '@open-multi-agent/core'

const oma = new OpenMultiAgent({ defaultProvider: 'openai', defaultModel: 'gpt-5.4' })

const team = oma.createTeam('research-team', {
  name: 'research-team',
  agents: [
    { name: 'researcher', systemPrompt: 'Find the relevant facts.' },
    { name: 'analyst', systemPrompt: 'Compare evidence and identify tradeoffs.' },
  ],
  sharedMemory: true,
})

const result = await oma.runTeam(team, 'Compare three approaches and recommend one.')

Running it requires OPENAI_API_KEY in the environment. The trade-off of runtime planning is that the graph your agents follow is decided by a model on each run, so two runs of the same goal can take different shapes. When you need a fixed sequence, runTasks() is the tool.

npm create oma-app runs a scripted demo with no API key and no model request

OMA requires Node.js 20 or newer, and the engines field in the root package.json says the same: "node": ">=20.0.0". That floor is about to move. Node.js 20 is upstream end-of-life, kept only as a migration window, and the project says it will drop it in the next major release, no earlier than 2026-10-31. If your servers still run Node.js 20, plan the runtime upgrade before you plan the OMA upgrade.

The fastest first contact is the scaffolder:

bash
npm create oma-app@latest my-oma

In an interactive terminal it asks you to pick a starter (a PR review agent, a security analysis agent or a teaching DAG) and a runtime, installs dependencies, and runs a deterministic local demo. Scripted model responses drive the real scheduler, result aggregation and offline dashboard, so you see the orchestration machinery without spending tokens or handing over a key. For an existing backend, the package installs directly:

bash
npm install @open-multi-agent/core

The demo proves the plumbing, not the planning quality. Because its responses are scripted, it tells you nothing about how a real coordinator model will decompose your goals.

Durable approvals pause the run, but your application has to build the approval screen

OMA can stop before executing a plan, before dispatching a task, or before calling a tool, and wait for a human to approve. With persistent storage configured, a process that restarts while waiting can continue from the content that was reviewed, so an approval does not die with a crashed worker.

What OMA does not ship is the human side. The README is explicit that your application supplies the approval interface and the notifications. There is no built-in review page and no email or chat alert in the core description. For a team expecting a turnkey approval inbox, that is real work: you need a place for reviewers to see the pending plan or tool call, a way to tell them something is waiting, and storage wired up so the paused run survives a restart. The design keeps OMA a library rather than a hosted product, and the cost of that choice lands in your codebase. The durable-approvals guide in docs/ is the next thing to read.

verifyRun() checks a journal for consistency but cannot prove it was never edited

Enabling the run journal records model inputs, tool calls and results so a run can be inspected later, offline. verifyRun() then checks the recorded sources and content for consistency without a network connection.

The limit is stated in the project's own words: verifyRun() "does not prove the journal was never edited." That distinction matters if you are buying OMA for compliance. A consistency check catches a journal that contradicts itself. It does not stop someone with write access to the storage from rewriting a run cleanly and producing a journal that still verifies. If your auditors need tamper evidence, you will have to put the journal somewhere append-only or signed yourself, outside OMA. If you only need to answer "what did the agent see and which tool did it call" after an incident, the journal covers that use case as described, and the run-journal guide in docs/ explains how to turn it on.

A run can succeed while governanceConclusion says the required roles never ran

The governance floor lets you declare required roles and the order they must execute in, then check whether an actual run met those requirements. This is aimed at policies like "a reviewer agent must run after the writer and before anything is published".

The catch is that run success and governance success are two separate signals. A run that completes without error can still leave governance requirements unmet, and applications must check governanceConclusion on their own. Code that only looks at whether runTeam() resolved will happily ship output that skipped a mandatory role. Because runTeam() plans the graph at runtime, this is the safety net for a coordinator that decides a step was unnecessary. Treat a missing governanceConclusion check as a bug in your integration, and put that check next to every call that consumes a team result. The tool-configuration guide in docs/ covers declared governance roles for runTeam.

The offline and allowlist egress policy stops at process and ACP backends

OMA positions itself as a library with no OMA backend, no account and no hosted control plane. It makes no analytics, license, update or phone-home request. Model access goes through built-in adapters for Anthropic, OpenAI, Azure OpenAI, Bedrock and Gemini among others, plus DeepSeek and other Chinese providers, local servers such as Ollama, vLLM and llama-server through baseURL, any OpenAI-compatible endpoint, and Vercel AI SDK providers.

Outbound model traffic can be restricted with an egress policy set to offline or allowlist. The policy is checked before a built-in adapter connects, a child policy can only tighten its parent, and an unenforceable transport fails closed rather than open. Two backends are outside it: process and ACP backends sit outside the egress policy. If you route agents through either one, an offline policy will not prevent those connections, and you need network controls at the host or container level to cover the gap.

A workspaces monorepo shipping a minor release roughly every week

The repository root is a private npm workspace named open-multi-agent with version 0.0.0. The published code lives under packages/, with @open-multi-agent/core as the main package and its examples in packages/core/examples/. A bench/ directory holds an A/B harness: bench:ab:mock runs it against a mock with no model calls, and the root test script runs bench:ab:test after the workspace tests. A pretest step validates the example catalog, so a broken example fails the suite.

Releases are frequent. v1.21.3 shipped on 2026-10-16, v1.22.0 on 2026-10-23 and v1.23.0 on 2026-10-29, the same day as the last push. The project says it launched on 2026-04-01 under the MIT license. That pace means features arrive quickly, and it also means a pinned version ages fast. With the Node.js 20 removal tied to the next major release, read CHANGELOG.md before each bump rather than letting a caret range pull in a new major line unattended.

Editorial conclusion

Use open-multi-agent if you run a Node.js backend, want agents planned from a goal rather than a hand-drawn graph, and need approval pauses and an offline run record without a hosted control plane. Skip it if you need a tamper-proof audit log, since verifyRun() does not prove the journal was never edited, or if you want an approval UI out of the box. Before adopting, run npm create oma-app@latest to see the offline demo, confirm your Node.js version against the planned removal of Node.js 20, and decide how your code will read governanceConclusion after every run.

Frequently asked questions

How do I run multiple agents at once with open-multi-agent?

Create a team with oma.createTeam() listing several agents, then call oma.runTeam() with a goal. A coordinator plans the task DAG at runtime and dispatches work to the agents, while runTasks() runs an explicit pipeline you define instead.

Does open-multi-agent need an API key to try it?

Not for the starter demo. npm create oma-app@latest my-oma runs a deterministic local demo driven by scripted model responses, with no API key and no model request; the runTeam example with an OpenAI model needs OPENAI_API_KEY.

Which Node.js version does open-multi-agent require?

It requires Node.js 20 or newer. Node.js 20 is kept only as a migration window, and OMA plans to remove it in the next major release, no earlier than 2026-10-31.

Does open-multi-agent send telemetry?

No. The project describes it as a library with no OMA backend or account, and says it makes no analytics, license, update or phone-home request.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-multi-agent-open-multi-agent.svg)](https://hysenlabs.com/projects/open-multi-agent-open-multi-agent)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/open-multi-agent-open-multi-agent.svg)](https://hysenlabs.com/projects/open-multi-agent-open-multi-agent)

Was this useful?