GantryBuild AI employees that follow the rules you set.
Open-source software you run on your own servers, giving each AI employee approved tools, memory across conversations, a person to ask before risky actions, and a record you can review.
- Role
- Core contributor · first production adopter · fork maintainer
- Timeline
- Apr 2026 → present · v1.2.x
- Team
- Core team of 6 · MIT licence
- Focus
- Open-source, self-hosted agent harness: governed tools, channels, memory, audit
- Stack
- TypeScript·Node 24·Postgres·MCP·Slack·Teams·Telegram·DeepAgents·bubblewrap sandbox·OpenAPI SDK

- lines of TypeScriptRUNTIME, WEB CONSOLE, SDK, CONTRACTS
- 750K
- test filesUNIT, INTEGRATION, E2E, AGENT E2E
- 775
- decision recordsEVERY CONTRACT CHANGE WRITTEN DOWN
- 137
- channels, one permission modelSLACK · TEAMS · TELEGRAM · DISCORD · SDK
- 5
An agent needs a badge, boundaries and a record.
Teams were dropping agents into Slack and Teams with a bot token and a prayer: model keys in env files, tools with whatever access the developer had, no record of what the agent did, and state that evaporated on restart. Each agent was also welded to one model provider and one chat surface.
Gantry's brief was the opposite: treat an agent like a new hire. Give it a seat in the channels the team already uses, only the access it needs, a full audit trail, memory that survives model swaps, and offboarding in one command. And make risky actions visible and reviewable instead of silently allowed.
The first production workload to push on that design was a customer-facing WhatsApp sales agent (Boondi), with hard identity, grounding and concurrency requirements that a Slack helper never has.
Approve once. Audit everything.
Routine tools follow the agent’s grants and rules. When an action needs a human, a permission card arrives in the conversation with the exact command, a choice to approve or deny, and an audit record for every decision.
ops-helper wants to run a tool
shell · medium riskkubectl rollout restart deploy/apicapability: shell · rule: ask · conversation: #ops · turn 2,391
Audit log
Decisions appear here. Choose an action above.
Core contributor, first production customer, feedback loop.
Gantry is the work of a small core team, and I am one of its core contributors as well as its first production customer. That WhatsApp sales agent runs on Gantry's API mode, so I also integrated the runtime end to end: persona variants per channel, MCP servers with signed caller identity, memory digests, message caps, handoff hooks and the settings contract that Docker and ECS derive from.
Along the way I maintained the WhatsApp agent's fork of Gantry, repacked it as a vendored artifact so client builds never depended on a sibling checkout, and fed findings upstream: the global advisory lock and pool sizing the capacity ladder exposed, settings-parser limits, and what an agent needs from the runtime to answer a stranger safely.
Runtime
- Node 24 host process
- Worker agents in a bubblewrap sandbox
- Inline agents for chat-style loads
- Provider-neutral model gateway with catalog aliases
- DeepAgents harness for OpenAI-compatible providers, alongside the Anthropic SDK
Channels
- Slack, Microsoft Teams, Telegram, Discord and more
- Web and SDK clients
- Permission cards with one-tap durable approvals
- Conversation installs without editing settings
Tools
- Capability grants and per-agent tool_rules
- MCP servers over stdio and http/sse
- Skills, local CLIs, browser automation
- LLM auto-permission mode that never writes policy
State & surface
- Postgres: settings revisions, credentials, memory, jobs, audit
- Control API + typed Node SDK (OpenAPI)
- gantry CLI: setup, doctor, status, model, provider
- Lifecycle webhooks and /v1/usage
One host. Explicit grants. Durable state.
A host process sits between human channels and the model. Channels adapt Slack, Teams, Telegram, Discord and SDK traffic into conversations; the runtime routes each turn to a worker or inline agent, on the Anthropic SDK or DeepAgents harness, under a capability projection; tools are grants, not defaults; and Postgres holds the desired state, credentials, memory, jobs and the audit trail that makes all of it reviewable.
- 01
Channels
- Slack, Teams, Telegram, Discord
- Web / SDK clients
- Permission cards, progress, threads
- Guided conversation installs
- 02
Runtime
- Worker agents (sandboxed subprocess)
- Inline agents (host loop)
- Anthropic SDK or DeepAgents harness per model
- Model gateway, provider aliases
- Direct LLM API passthrough
- 03
Governance
- Capability grants
- Declarative tool_rules
- LLM auto-permission (never writes policy)
- One-tap durable approvals
- 04
State
- Postgres settings revisions
- Credential center
- Per-agent + shared memory
- Jobs, events, audit
- 05
Surfaces
- gantry CLI
- Control API + Node SDK
- Web console
- Webhooks, /v1/usage
What changes when the agent meets production.
- CHALLENGE 01
Autonomy without prompt fatigue
Ask a human to approve every tool call and they stop reading. Approve nothing and the agent is useless.
Capabilities are granted per agent, tool rules are declarative, and an optional LLM auto-permission mode classifies routine actions without ever being allowed to write policy itself. What still needs a human arrives as a card in the channel with one-tap approve, deny or allow-always, and every decision lands in the audit log. The WhatsApp agent's MCP tools ride the same model: read-only Shopify and CRM tools are auto-approved by pattern, and human_handoff is the one action the agent may take that changes the world.
- CHALLENGE 02
Provider neutrality that survives a model swap
Pinning an agent to sonnet-4.7 in code means a price and behaviour change on every catalog update.
Models are catalog aliases resolved by a gateway that owns the credentials; agent processes never see raw provider keys. The WhatsApp agent pins the exact catalog entry rather than the recommended alias, because an unpinned alias silently migrates the chat model, and its price, on a runtime upgrade. The same gateway exposes a provider-shaped direct LLM API, so official Anthropic or OpenAI SDKs can point at Gantry with a Control API key and inherit its budgets and audit. Non-Anthropic models run through the DeepAgents harness, with its raw shell, filesystem and MCP access replaced by Gantry's own approvals, sandbox and audit.
- CHALLENGE 03
Durable state under concurrency
Two workers, one conversation, and a customer who sends three messages in a row.
Runtime state is desired-state rows in Postgres, not memory. Workers hold leases with heartbeats; a reconciler reclaims what a dead task left behind; LISTEN/NOTIFY wakes the right process. The WhatsApp agent's capacity ladder found the runtime's first real knee here, a single global advisory lock in the event repository, and the follow-up ladder found the pool ceiling. Both went upstream with numbers attached.
- CHALLENGE 04
Sandbox the worker, not the developer
A worker agent can run shells, browsers and MCP servers over stdio, HTTP or SSE. It must not be able to reach what it was not granted.
Worker agents run in a bubblewrap sandbox with a reviewed capability projection: filesystem, shell, skills, browser automation and MCP servers appear only if granted. Inline agents skip the sandbox for lightweight chat loads and get core tools plus remote MCP servers. The host owns credentials, the audit log and the permission model in both cases, which is what made it possible to put a customer-facing agent on the same runtime as an internal Slack helper.
Fleet operations
Check the runtime, inspect model aliases and review pending approvals from one CLI. The fleet board puts channel installs, agent state and daily turns in the same view.
gantry — zsh
REPLAYAgent fleet
4 AGENTS / 5 CHANNELS| Agent | Slack | Teams | Telegram | Discord | SagePilot | State | 24h |
|---|---|---|---|---|---|---|---|
| boondi_support | Not installed | Not installed | Not installed | Not installed | Installed | ready | 1,842 |
| ops-helper | Installed | Installed | Not installed | Not installed | Not installed | ready | 203 |
| release-notes | Not installed | Not installed | Not installed | Installed | Not installed | idle | 12 |
| qa-triage | Installed | Not installed | Installed | Not installed | Not installed | ready | 86 |
Filled = installed · Ring = not installed
A production agent, a maintained fork, evidence upstream.
- 01
First production agent
A customer-facing WhatsApp sales agent (Boondi) on Gantry's API mode: persona variants per channel, MCP tool sources with signed identity, memory digests, message cap, handoff controller, settings contract for Docker and ECS.
- 02
Fork and artifact pipeline
The WhatsApp agent's fork of Gantry packed as a vendored tarball, so client builds never depend on a sibling checkout; a repack script and a shared observability package.
- 03
Capacity evidence
The staircase load test against real ECS and RDS that exposed the global advisory lock and pool ceiling, with dashboards and runbooks the rest of the core team could act on.
- 04
Runtime contracts
Settings, credential and MCP caller-identity contracts as consumed by a real client: what the parser accepts, what Docker derives, what the deploy pipeline enforces.
- 05
Operational surface
Control API token management, role permissions and per-turn trace payloads exposed through an admin console for non-engineers.
- 06
Upstream feedback
Bugs, limits and design notes from running a stranger-facing agent on a runtime designed for teammates.

knacklabs/gantry on GitHub · MIT · 2,000+ commits KNACKLABS/GANTRY ON GITHUB · MIT · 2,000+ COMMITS
A seat for the agent. Control for the team.
Gantry turned 'we have a bot in Slack' into 'we onboarded an AI employee with a badge'. For me it is the runtime that let one engineer ship a customer-facing agent in twelve weeks without building identity, memory, jobs or audit from scratch.
- One permission model across Slack, Teams, Telegram, Discord, SDK and WhatsApp through API mode
- Provider swaps are a settings change; agent processes never see a raw key
- 285 concurrent turns on one task after the fixes the WhatsApp agent's load tests motivated
- 137 decision records and 775 test files: the harness documents itself for the next agent, human or model
- MIT-licensed and self-hosted, so the audit trail stays in your Postgres
“Onboard AI employees like real ones. Give them a seat, only the access they need, a full audit trail, and offboarding in one command.”GANTRY README
NOTE · GANTRY IS A RUNTIME AND CLI; THE VISUALS ON THIS PAGE ARE THE PUBLIC REPOSITORY, ITS README ILLUSTRATION, AND RECONSTRUCTIONS OF THE CLI AND PERMISSION FLOW.