Self-hosted service
desplega-ai/agent-swarm avatar
desplega-ai/agent-swarm

Extensions run inside the API process, and a Python file exists for GitHub Actions

Your Company Agentic Operating System

858 stars110 forksTypeScriptMIT

At a glance

What is it?
Agent Swarm is a TypeScript orchestrator where a lead agent splits goals into tasks and hands them to workers such as Claude Code or Codex inside Docker containers, with memory and review gates that survive sessions. Its configuration files are where the design shows: extensions execute in the API process, an empty API key disables authentication, and a pyproject.toml exists only to satisfy a deployment action.
Who is it for?
Judgment: Agent Swarm is a serious operational project whose configuration is more informative than its feature list, and that is a compliment with a caveat. The parts a self-hoster needs are all written down: which harness credential goes with which provider, what breaks on Bedrock, how to generate the encryption key, why the compose file is the one to use, and how the MCP surface reports results.
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 received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

Editorial analysis

Extensions execute trusted code inside the API server process

Extensions are TypeScript hooks, and the environment template says plainly where they run: inside the API server process. That is a meaningful difference from a plugin system that loads code into a worker or a container, because a bad extension has the same reach as the server itself. The flag that governs it is `EXTENSION_ALLOW_LEAD_ACTIVATION`, which defaults to true and, when set false, reserves enabling, disabling and version activation for operators and dashboard users. Two more constraints come with it: it is a deployment-only setting, and every API replica has to be restarted after you change it. The README's own description of the lifecycle matches that model, with extensions installed as agent-owned inert drafts and then activated by a trusted lead, an operator or a dashboard user. So a fresh deployment lets a lead agent turn its own hooks on, which is convenient and worth revisiting before the deployment is reachable by anyone else.

An empty API_KEY turns authentication off entirely

The first line of the environment template is the one to read first. `API_KEY=` with the comment Define your API key or leave empty for no auth means an unset key is not a degraded mode, it is no authentication at all on the REST surface. Next to it, `RBAC_ENABLED=true` gates requests authenticated with `aswt_` user tokens against role grants, and the comment is explicit that the operator API key and agent calls are unaffected by that gate. Those are three different identity paths in one file: the operator key, user tokens under RBAC, and agent traffic. Turning RBAC on does nothing for the first and third, so a deployment that sets only that flag is not what the flag name suggests. The self-hosted compose example asks for an API key, a harness credential and all eight agent UUIDs, which is the point at which these settings start to matter.

Bedrock is alpha, and the env file names what is missing

Four provider combinations are documented in the template, and the table is the clearest statement of what the project supports. HARNESS_PROVIDER=claude uses CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY. codex uses OPENAI_API_KEY. pi covers OpenRouter with OPENROUTER_API_KEY plus MODEL_OVERRIDE. And AWS Bedrock is marked alpha, also routed through pi, needing AWS_REGION, MODEL_OVERRIDE and AWS credentials or a profile, with a note to uncomment the `~/.aws` mounts in Docker. The alpha warning is the useful part: session summaries, memory rating, spend tracking and model tiers may be missing on Bedrock, which is four of the features the project advertises. There is also a transport switch for Claude, `CLAUDE_TRANSPORT`, cli by default or sdk, with the note that sdk still starts Claude Code and cannot be combined with claude-bridge.

The self-host path starts with a key you generate and permissions you set

The examples route in the README is a copy-and-paste sequence rather than a package install:

bash
git clone https://github.com/desplega-ai/agent-swarm.git && cd agent-swarm
cp .env.docker.example .env  # Set API_KEY, a harness credential, and all eight agent UUIDs.
openssl rand -base64 32 > encryption_key
chmod 600 .env encryption_key
docker compose -f docker-compose.example.yml --env-file .env up -d

The encryption key is generated locally, not fetched, and both files are then locked to owner-only access. The API comes up on port 3013 with `/docs` and `/openapi.json`, and the hosted dashboard can be pointed at your own API, which is how the self-hosted software and the hosted control panel relate. A Compose checklist exists under the operator skill's references and the README asks you to read it before starting. Kubernetes goes through an OCI Helm chart under charts/agent-swarm. There are three compose files in the tree, example, local and scripts-only, and the quick start names the first one.

Bun's isolated linker would hide dependencies and break the compile

The server Dockerfile is a Bun multi-stage build, and its comments explain the two non-obvious decisions in it. The first is that the workspace manifests have to be present before the frozen install runs: the root package declares Bun workspaces for apps/ui, apps/templates-ui and apps/evals, and bunfig.toml pins the linker to `hoisted`, because Bun defaults workspaces to `isolated`, which would hide the root's phantom transitive dependencies and break the compile. The member manifests are copied in for that reason and nothing else, since the final image takes only the compiled binary. The second is that slack-manifest.json is copied into the build at all, because it is bundled into the binary by the Slack manifest module, which runs during onboarding. The builder is pinned to oven/bun:1.4.0 to match the packageManager field in the manifest, so the toolchain has one version and not two.

The compiled binary cannot share its virtual filesystem with subprocesses

The reason script runtimes are pre-bundled is specific and worth knowing before you write a custom script. A compiled Bun binary has its own virtual filesystem, and a subprocess it spawns cannot reach it: running a script through that path fails inside the harness subprocess rather than in the parent. The workaround is to pre-bundle the script runtime files into self-contained JavaScript bundles during the build, so the subprocess loads a real file instead of reaching into the parent image. The same reasoning explains why the image copies a small set of individual paths, including one plugin library file under plugin/opencode-plugins/lib, the templates directory, tsconfig.json and the Slack manifest. There is a second Dockerfile, Dockerfile.worker, and its builder stage is expected to stay in sync with this one, which is a manual instruction rather than an enforced one.

A pyproject.toml exists only to satisfy a deployment action

The repository ships a Python manifest in a TypeScript project, and its own first line explains why. The comment says it is a minimal pyproject.toml to satisfy the GitHub Actions setup-python cache requirement, and names the workaround: the dokploy-deploy-action uses setup-python with pip caching, which requires a pyproject.toml or a requirements.txt even though the project is Node and TypeScript. The file is named agent-swarm-deploy-workaround at version 0.0.0 with the description Workaround file for GitHub Actions deployment. It is not a dependency manifest and nothing installs from it. It is worth flagging for two reasons: a Python file in a Bun repository will trip tooling that scans for one, and anyone auditing dependencies should know this file declares no dependencies on purpose.

Version 1.161.0, a minor release every day or two, and React pinned exactly

The release cadence is the loudest fact about the project. v1.159.0 on 30 September 2026, v1.160.0 on 1 October, v1.161.0 on 2 October, with the last push also on 2 October, and the README says outright that the repository evolves every single day. The manifest version matches the newest tag exactly, so there is no drift there. Two details in the manifest are unusual. React and react-dom are pinned through overrides to 19.2.3 with no caret, which freezes two transitive trees at an exact version across every workspace. And the package lists itself as its own dependency through a link to its own name, alongside a files array that publishes dist/, src/, tsconfig.json, plugin subdirectories, templates, vendored-openapi and openapi.json, so the published artifact carries source and typechecking configuration rather than only build output. The tree also holds six plugin directories, one each for Claude, Codex, Cursor, Devin, Kimi and the shared agent skills.

Editorial conclusion

Judgment: Agent Swarm is a serious operational project whose configuration is more informative than its feature list, and that is a compliment with a caveat. The parts a self-hoster needs are all written down: which harness credential goes with which provider, what breaks on Bedrock, how to generate the encryption key, why the compose file is the one to use, and how the MCP surface reports results. The parts to slow down on are the ones that grant power rather than describe it. Extensions execute trusted code in the API server process, the lead can activate them by default, and an empty API_KEY means no authentication at all, so the three settings to change before anyone else can reach the port are EXTENSION_ALLOW_LEAD_ACTIVATION, API_KEY and RBAC_ENABLED. Anyone adopting it should also expect the file layout to move, given a minor release every day or two.

Frequently asked questions

What is agent-swarm?

An MIT licensed TypeScript operating system for AI work. A lead agent breaks goals into tasks, routes them to specialised workers such as Claude Code or Codex, runs each worker in an isolated Docker container, and keeps shared memory, tools, schedules and review gates so delegated work compounds across sessions. It is published as @desplega.ai/agent-swarm.

Which harnesses and models can agent-swarm use?

Claude Code, Codex, pi, opencode, Devin and ACP agents. The environment template maps HARNESS_PROVIDER=claude to CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY, codex to OPENAI_API_KEY, and pi to OpenRouter or to AWS Bedrock, which is marked alpha and may be missing session summaries, memory rating, spend tracking and model tiers.

How do I self-host agent-swarm?

Clone the repository, copy .env.docker.example to .env, set an API key, a harness credential and all eight agent UUIDs, generate an encryption key with openssl rand -base64 32, chmod 600 both files, then bring it up with docker compose -f docker-compose.example.yml --env-file .env up -d. The API listens on port 3013 with /docs and /openapi.json.

What does EXTENSION_ALLOW_LEAD_ACTIVATION control?

Extensions execute trusted code inside the API server process. With the flag at its default of true, a lead agent can activate them; setting it false reserves enable, disable and version activation for operators and dashboard users. It is a deployment-only setting and every API replica must be restarted after a change.

Why does agent-swarm have a pyproject.toml?

It is a workaround, and the file says so. It is named agent-swarm-deploy-workaround at version 0.0.0 because the dokploy-deploy-action uses GitHub Actions setup-python with pip caching, which requires a pyproject.toml or requirements.txt even though this is a Node and TypeScript project. It declares no dependencies.

Official sources

  1. desplega-ai/agent-swarm on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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/desplega-ai-agent-swarm.svg)](https://hysenlabs.com/projects/desplega-ai-agent-swarm)