Crewlet
Run an AI agent company.
Crewlet is an open-source Python engine for orchestrating hierarchically organized AI agent companies. You describe a company in YAML — mission, org chart, roles, policies, integrations — and Crewlet runs it: one persistent agent per seat, planning and executing real work on Slack, your issue tracker, and your code host, learning from what it did, and escalating to the humans in the org chart when stuck.
Quickstart · Choosing your stack · Concepts · Documentation · Contributing
The org chart is the execution graph
Identity, delegation, communication, and knowledge are all scoped by where a seat sits in the hierarchy. The chart you draw is the graph the engine runs.
|
The org chart runs the work Departments, teams, and seats nest to any depth. Leads assign work by reasoning about their reports — not by a routing algorithm. |
Company as code The whole company is versioned YAML in PostgreSQL — live-editable through a REST API, with no restart for role, provider, or integration changes. |
Plan → Execute → Review Every turn is planned, executed against explicit success criteria, then judged — and looped back when the work isn't done. |
|
Agents that ship code An engineer seat runs a coding agent in an isolated sandbox and opens the merge request under its own identity — not yours. |
Memory that compounds Agents search the team knowledge base at query time, keep a private diary, recall similar past turns, and synthesize reusable skills. |
Humans hold seats too Put yourself in the chart. Human seats lead units and receive escalations on the surfaces you already use. |
How a turn works
A trigger — a Slack message, a work-item webhook, a schedule — wakes exactly one agent, which runs a three-phase turn:
flowchart LR
T["Trigger<br/><i>Slack · work item · schedule</i>"] --> P
P["<b>Plan</b><br/>decide the steps,<br/>pick the tools"] --> E["<b>Execute</b><br/>tool loop, or a<br/>coding agent in a sandbox"]
E --> R["<b>Review</b><br/>judge against the<br/>plan's success criteria"]
R -->|done| S["Work shipped:<br/>comments, MRs, docs"]
R -->|self_iterate| P
Each phase gets its own narrow prompt, its own tool surface, and can run on its own model — a frontier model to plan, a cheap one to summarize. See Turn Engine.
Quickstart
Bring up the infrastructure, describe a company, run it:
pip install "crewlet[postgresql,api]"
# PostgreSQL (TimescaleDB + pgvector) and Apache Pulsar
cp .env.example .env && docker compose up -d
export CREWLET_API_TOKEN_FOUNDER="$(openssl rand -hex 32)"
export ANTHROPIC_API_KEY="sk-ant-..." # or OpenAI, or any OpenAI-compatible endpoint
export OPENAI_API_KEY="sk-..." # embeddings
crewlet run config.yaml --import-company company.yaml
A four-agent company is about 40 lines of YAML:
name: "Acme AI"
mission: "Ship AI-powered products fast"
providers:
llm:
default:
type: anthropic
model: claude-sonnet-5
api_keys: ["${ANTHROPIC_API_KEY}"]
roles:
- name: CEO
goal: "Set product vision and make final calls"
manages: [CTO, PM]
units:
- name: Core Engineering
type: team
lead: CTO
roles:
- name: CTO
goal: "Set technical direction and unblock engineers"
manages: [Engineer]
- name: Engineer
goal: "Implement features, write tests, ship quality code"
The dashboard and webhook API come up with the engine. The full Quickstart walks through watching an agent's first turn with no integrations at all, then wiring in the real ones.
Want the full picture first?
examples/nimbus.company.yamlis a complete seven-seat reference company — Plane, GitLab, Slack, and a code sandbox wired end-to-end, with the reasoning for every setting in comments.
Rather not write it by hand? An AI assistant can interview you and author both files, checking its own work against the shipped JSON Schema — see Authoring with an AI assistant for a step-by-step walkthrough.
Plug in your stack
Crewlet is the engine; the surfaces your agents work on are yours to choose. Every one has a hosted and a self-hosted path — see Choosing your stack.
| Options | |
|---|---|
| LLM | Anthropic, OpenAI, or any OpenAI-compatible endpoint — including your own vLLM / LiteLLM gateway |
| Tracker + knowledge base | Plane (self-hosted, covers both) · Jira + Confluence |
| Code host | GitLab (gitlab.com or self-hosted) · GitHub |
| Chat | Slack — one bot identity per agent |
| Code sandbox | E2B cloud or self-hosted; Claude Code or OpenCode as the coding agent |
For Slack, Plane, and GitLab, one command provisions the whole fleet — a Slack app
or service account per seat, memberships, per-agent tokens minted into your config's
own ${VAR} references, and the webhooks:
crewlet slack provision company.yaml --base-url <url>
crewlet plane provision company.yaml --create-projects --webhook-url <url>
crewlet gitlab provision company.yaml --webhook-url <url>
Add --secret-store and the minted credentials go straight into the encrypted
secret store the engine reads ${VAR} from —
no env file to source, no shell to be in.
Architecture
flowchart LR
EXT["<b>External surfaces</b><br/>Slack · Jira / Plane<br/>GitHub / GitLab"]
API["<b>REST API + dashboard</b><br/><i>embedded, or its<br/>own process</i>"]
Q["<b>Apache Pulsar</b><br/><i>per-agent<br/>inbox topics</i>"]
ENG["<b>Engine</b><br/><i>one turn engine<br/>per seat</i>"]
DB[("<b>PostgreSQL</b><br/>TimescaleDB<br/>pgvector")]
EXT -->|webhooks| API
API <--> Q
Q <--> ENG
ENG -->|"MCP tools, as each agent"| EXT
ENG --> DB
API --> DB
Agents are callback-driven: messages on an agent's inbox topic invoke its handler, and events that piled up while it was busy are batched into a single digest turn. Config lives in two tiers — an ops-owned bootstrap file on disk, and a versioned, live-editable company document in PostgreSQL that can be encrypted at rest as a single opaque blob.
CLI
crewlet run config.yaml --import-company company.yaml # boot + import, idempotent
crewlet run api config.yaml # standalone API (split deployments)
crewlet validate company.yaml # check before importing
crewlet validate company.yaml --json # machine-readable errors
crewlet schema company # JSON Schema (editors, CI, agents)
crewlet config export | show | revisions | diff # inspect Tier B revisions
crewlet secrets keygen && crewlet config seal # encrypt the config at rest
crewlet secrets set LLM_API_KEY # store a secret the engine reads ${VAR} from
crewlet plane import company.yaml examples/ # publish docs + tool skills
crewlet confluence import company.yaml # ...on the Confluence backend
Full reference: CLI · API endpoints · Environment variables.
Documentation
|
Start here
Core concepts
Guides |
|
Contributing
Issues and pull requests are welcome. CONTRIBUTING.md covers the dev setup, conventions, and the checks CI runs:
uv sync --all-extras
uv run pytest
uv run ruff check src/ tests/ && uv run ruff format --check src/ tests/
Releases go to PyPI from a v* tag — see RELEASING.md.
Security issues: please report them privately — see SECURITY.md.
License
The dashboard's icon sprite is adapted from Feather Icons — MIT License, Copyright (c) 2013-2023 Cole Bemis.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file crewlet-0.1.0.tar.gz.
File metadata
- Download URL: crewlet-0.1.0.tar.gz
- Upload date:
- Size: 2.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
406254b3913094cada4e7e449c2653a6623a2d217395c0f8f82c657d644760c8
|
|
| MD5 |
3c48bb7ef2db644cdba3add8fd0e90f7
|
|
| BLAKE2b-256 |
2cc2be7a6e84ad02e6318b51eb36672bd708d08a59ac7dd071c9e06ad3e670fc
|
Provenance
The following attestation bundles were made for crewlet-0.1.0.tar.gz:
Publisher:
release.yml on crewlet/crewlet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
crewlet-0.1.0.tar.gz -
Subject digest:
406254b3913094cada4e7e449c2653a6623a2d217395c0f8f82c657d644760c8 - Sigstore transparency entry: 2427142623
- Sigstore integration time:
-
Permalink:
crewlet/crewlet@b40ea18e198d0ebeeebfd27c5b778c297a919d6f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/crewlet
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b40ea18e198d0ebeeebfd27c5b778c297a919d6f -
Trigger Event:
push
-
Statement type:
File details
Details for the file crewlet-0.1.0-py3-none-any.whl.
File metadata
- Download URL: crewlet-0.1.0-py3-none-any.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9238246f90f7a3c471964ee8680ab4ab655dc83ada54e68ad2fc91e19ef5cbc0
|
|
| MD5 |
d896a5554b4a3d36e1feb1e67736d8d7
|
|
| BLAKE2b-256 |
7faae8ddba019cae82b3a0c4377a94195b81792f919ec62eb125ba1c63657587
|
Provenance
The following attestation bundles were made for crewlet-0.1.0-py3-none-any.whl:
Publisher:
release.yml on crewlet/crewlet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
crewlet-0.1.0-py3-none-any.whl -
Subject digest:
9238246f90f7a3c471964ee8680ab4ab655dc83ada54e68ad2fc91e19ef5cbc0 - Sigstore transparency entry: 2427143039
- Sigstore integration time:
-
Permalink:
crewlet/crewlet@b40ea18e198d0ebeeebfd27c5b778c297a919d6f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/crewlet
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b40ea18e198d0ebeeebfd27c5b778c297a919d6f -
Trigger Event:
push
-
Statement type: