Quick start
For AI Agents: the Markdown version of this page is at https://ankole.agentbull.com/en-US/docs/quickstart/index.md. The documentation index is at https://ankole.agentbull.com/en-US/llms.txt.
How Ankole is deployed
A private Ankole deployment instance has one control plane and one or more Agent Computer Workers. The control plane owns durable domain state and supervision as the management platform; a Worker provides the execution environment and acts as the Agent’s work computer.
One Worker can serve several Agents. In finance or another environment that needs strict isolation, give each Agent a dedicated Worker, just as a work computer can be shared by several interns or assigned to one colleague.
Each instance also needs PostgreSQL and persistent disk storage. A single-host deployment can use a local or virtual disk. A Kubernetes deployment needs NFS or another shared volume that supports ReadWriteMany.
Terms used in this guide
This page defines the terms used in Ankole user documentation and interfaces. The names in parentheses match third-party platforms, configuration fields, and APIs. Later sections use the short form.
| Canonical term | Meaning | Short form |
|---|---|---|
| Private deployment instance | One complete Ankole system that an enterprise deploys and manages | Instance |
| Principal | A person, Agent, or system service that can have an identity and permissions in Ankole | Principal |
| Identity Provider (IdP) | An external identity source that provides Console SSO and synchronizes employees, contacts, and organization structure | IdP |
| Chat platform | An external conversation platform such as Slack, Teams, Lark/Feishu, DingTalk, WeCom, Telegram, Discord, LINE, WhatsApp, or a mailbox | Platform |
| Channel Provider | One chat application or bot configuration that receives messages and sends Agent replies | Channel Provider |
| Signal Routing Rule (Signal Binding) | The rule that sends messages or events from a signal source to an Agent | Routing rule |
| LLM Provider | A configuration that stores a model service endpoint, credentials, and available models | LLM Provider |
Background Agent Jobs profile (internal key: coding) |
Selects the AIGateway provider and model for Background Agent Jobs; normal conversations do not select it by code volume | Background Agent Jobs |
Let an Agent complete the setup
You can send this prompt to Codex, Claude Code, or another Agent that can operate a terminal:
Use https://ankole.agentbull.com/en-US/docs/quickstart/index.md to help me deploy and configure a private Ankole deployment instance. First, inspect my environment and recommend Docker Compose, Kubernetes, or installing from source. Then help me set up the Identity Provider (IdP), LLM Provider, Agent, Channel Provider, and Signal Routing Rule (Signal Binding). If I did not specify an IdP and IM platform, ask which identity source and chat platform I want to use. Do not choose them for me. Do not expose secrets in chat or command output. You are finished only when I receive a real Agent reply in my selected IM.
1. Deploy Ankole
Use Docker Compose for one host or Kubernetes for an enterprise deployment. Install from source for development and debugging.
The best starting point for most teams. One Linux, macOS, or Windows host with Docker runs PostgreSQL, the control plane, one Agent Computer Worker, and Caddy HTTPS.
Before you start
- A Linux, macOS, or Windows host that can run Linux amd64 or arm64 containers
- Docker Engine with the Compose plugin, or Docker Desktop
- Persistent disk, a DNS name, and ports 80 and 443
Basic setup
Install with Docker Compose
Keep provider API keys out of this deployment file. You will add them in the Console after sign-in.
- 01
Get the deployment package
bashgit clone https://github.com/AgentBull/ankole.git cd ankole/tools/deploy/docker-compose cp .env.example .env chmod 600 .env - 02
Generate three independent secrets
Copy and run this command. Then paste its complete output into .env.
bashprintf '%s\n' \ '# PostgreSQL database password' \ "POSTGRES_PASSWORD=$(openssl rand -hex 32)" \ '' \ '# ANKOLE master encryption key' \ "ANKOLE_SECRET_BASE=$(openssl rand -hex 32)" \ '' \ '# Authentication key shared by the ANKOLE control plane and Agent Workers' \ "ANKOLE_RUNTIME_FABRIC_WORKER_AUTH_KEY=$(openssl rand -hex 32)" - 03
Set the public host
Set ANKOLE_HOST to the DNS name that points to this host. Set ACME_EMAIL to an address that can receive certificate notices.
- ANKOLE_HOST
- ankole.example.com
- The HTTPS host that people and provider callbacks will use.
- ACME_EMAIL
- ops@example.com
- Contact address for Caddy certificate management.
- 04
Start and verify the stack
Compose waits for PostgreSQL, runs migrations, stores the Worker key, and then starts the control plane, Worker, and Caddy.
bashdocker compose pull docker compose up -d docker compose ps - 05
Open the first setup
Open https://<ANKOLE_HOST>/setup and enter the activation code.
bashdocker compose logs control-plane | grep "SETUP ACTIVATION CODE"
2. Set up the identity provider first
Ankole is designed for private deployment inside an enterprise. Each enterprise operates one instance. Inside that instance, Agents, employees, and system services are represented as Principals, and the authorization module manages their permissions.
Like Hermes Agent and OpenClaw, Ankole connects to chat channels. It also connects to the enterprise identity source so it can synchronize employees, directory contacts, and the organization structure. Configure an Identity Provider (IdP) before you configure the chat channel.
| Setting | What it controls | Configure it where |
|---|---|---|
| Identity Provider (IdP) | Console SSO and the employees, contacts, organization structure, and permission groups synchronized from the enterprise directory | /setup first, then Console → Identity Providers |
| Channel Provider | The IM app or bot that receives messages and sends Agent replies | Console → Signal Routing |
The identity source and chat channel can use different platforms. Employees can sign in through Google Workspace and talk to the Agent in Slack. Entra ID can supply identity while Lark, Slack, DingTalk, Teams, or WeCom carries the conversation.
Complete the setup for your IdP
Select the identity source that your enterprise uses. Each tab starts in the provider console and ends with the first sign-in and directory sync.
If you enable the adapter for the first time, restart the control plane after the first sign-in. This restart starts the plugin background work, such as directory connections and Graph subscriptions.
Use one Slack app for Console sign-in and for workspace member and user-group sync. The default setup needs an OAuth client, a Bot Token, and an App Token.
Before you start
- A workspace administrator who can create and install a Slack app
- A public HTTPS address for Ankole
- A workspace member account for the first sign-in
Basic setup
Set up the Slack IdP
- 01
Copy the callback URL from Ankole
Open https://<ANKOLE_HOST>/setup and enter the activation code. Select Slack Adapter on the plugin page, save the selection, and then select Slack.
Keep Configuration ID (Provider ID) as slack-main. Use Copy to copy the login callback URL. Do not type or change this URL by hand.
- 02
Create the Slack app
Open Slack API Your Apps and select Create New App → From scratch. Enter an app name and select the workspace that holds your employees.
Open Basic Information → App Credentials. Copy the Client ID and Client Secret.
- 03
Register the login callback
Open OAuth & Permissions → Redirect URLs. Select Add New Redirect URL, paste the complete URL from Ankole, and save it.
Ankole requests the openid, profile, and email sign-in scopes by default. Do not replace them with chat bot scopes.
- 04
Grant directory access and get the Bot Token
On OAuth & Permissions, add the three scopes below under Bot Token Scopes. Then select Install to Workspace and approve the installation.
users:readRead member profiles
users:read.emailRead member email addresses
usergroups:readRead user groups and their members
Copy the Bot User OAuth Token after installation. It must start with xoxb-. Reinstall the app after each scope change.
- 05
Get the App Token and enable Socket Mode
Open Basic Information → App-Level Tokens. Select Generate Token and Scopes, add the scope below, and copy the generated xapp- token. Then open Socket Mode and turn on Enable Socket Mode.
connections:writeLet the App Token open a Socket Mode connection
- 06
Subscribe to directory events
Open Event Subscriptions and enable events. Under Subscribe to bot events, add each of the five events below.
team_joinA member joins the workspace
user_changeA member profile changes
subteam_createdA user group is created
subteam_updatedA user group changes
subteam_members_changedA user-group membership changes
- 07
Enter the Slack values in Ankole
Keep Sync directory and Sync directory changes on. Select Validate configuration and sign in. Then complete the Slack authorization.
- Client ID: the Client ID from Basic Information
- Client Secret: the Client Secret on the same page
- Workspace ID: optional. Enter the T… value after /client/ in the Slack web URL to preselect a sign-in workspace; it does not limit directory sync
- Bot User OAuth Token: the xoxb- token
- App-Level Token: the xapp- token
- 08
Verify sign-in and the first sync
After Slack returns to Ankole, this user becomes the first root administrator. Open Console → Identity Providers, select slack-main, and select Run full sync.
When the sync finishes, check Console → Principals and Principal groups for the workspace members and Slack user groups.
3. Add an LLM Provider and create an Agent
An Agent model profile stores a model reference, so add the LLM Provider first. Sign in to the Console. Open Providers → New provider, choose the provider kind, give it a stable Provider ID, enter the endpoint and credential fields, and save.
Provider credentials stay encrypted in the control plane. Do not put them in deployment environment files or Agent files.
Open Agents → New Agent. Give the Agent a stable UID, a clear display name, and a mission that says what it owns and what counts as an acceptable result.
Then configure its model profiles:
| Profile | First-run use |
|---|---|
primary |
Main reasoning model |
light |
Short and frequent work |
heavy |
Hard synthesis |
All three are required before the Agent can run. For the first conversation, you can bind the same known-good provider and model to all three. Split them only after the end-to-end path works.
4. Connect a chat channel and create its signal routing rule
Enable the chat platform’s Control Plane Plugin in the Console, and then create the bot or application on that platform. Use separate apps for the IdP and chat roles, even when both use the same platform. This separation keeps sign-in and directory permissions away from bot permissions. It also separates credential rotation and app releases.
One chat app usually represents one bot identity. If several Agents need different bot names, avatars, or permissions, create several apps on that platform. After you prepare an app, create its routing rule in the Console and connect it to the intended Agent.
Slack, Teams, Lark/Feishu, DingTalk, and WeCom are enterprise platforms: their users come from the directory that the IdP synchronized. Telegram, Discord, LINE, and WhatsApp are consumer IMs: their users have no employee record, so an administrator maps each new sender to an account under Identity → Pending mappings before the Agent serves them; WhatsApp maps a sender by itself when a known account already owns the phone number. Email connects a dedicated mailbox, and a sender is known only through an explicit email identity binding.
Slack uses Socket Mode. Ankole opens an outbound WebSocket, so the chat path does not need a public Slack webhook.
Before you start
- Permission to create and install a Slack app
- A test channel or direct message
Basic setup
Prepare a Slack app
- 01
Create the app and enable Socket Mode
Create a Slack app from scratch. Under Basic Information, create an App-Level Token, add the scope below, and then enable Socket Mode.
connections:writeLet the App Token open a Socket Mode connection
- 02
Subscribe to chat and channel-state events
Open Event Subscriptions → Subscribe to bot events. Add each event below. This set matches the message, reaction, and channel-state capabilities implemented by the Slack adapter.
app_mentionReceive channel @-mentions
message.channelsReceive public-channel messages
message.groupsReceive private-channel messages
message.imReceive direct messages
message.mpimReceive multi-person direct messages
reaction_addedReceive added reactions
reaction_removedReceive removed reactions
member_joined_channelSync members who join a channel
member_left_channelSync members who leave a channel
channel_renameSync channel renames
group_renameSync private-channel renames
channel_deletedSync channel deletion
channel_archiveSync channel archival
- 03
Enable direct messages
Open App Home → Show Tabs. Turn on Display Messages tab and select Allow users to send Slash commands and messages from the messages tab. The Messages tab alone shows the surface but does not let users send direct messages to the Agent.
- 04
Enable Slack-native interactivity
Open Interactivity & Shortcuts and enable Interactivity. Socket Mode delivers Block Kit button actions over the existing WebSocket, so a public Request URL is not required.
- 05
Grant the complete chat scopes and install the app
Under OAuth & Permissions → Bot Token Scopes, add each scope below. This set covers only Slack APIs that Ankole calls. Do not grant unused assistant, workflow, document, or meeting scopes.
app_mentions:readRead messages that mention the bot
channels:readSync public channels and their members
channels:historyRead public-channel messages and reconcile replies
groups:readSync private channels and their members
groups:historyRead private-channel messages and reconcile replies
im:readSync direct-message conversations
im:historyRead direct messages and reconcile replies
mpim:readSync multi-person direct messages and their members
mpim:historyRead multi-person direct messages and reconcile replies
chat:writeSend, update, and delete bot messages
reactions:readReceive reaction changes
reactions:writeAdd and remove reactions
files:readRead files attached to messages
files:writeUpload files sent by the Agent
users:readIdentify channel members and exclude bot accounts
After a scope change, reinstall the app to the workspace and write the new Bot Token to Ankole.
- 06
Collect the Console fields
- botToken
- xoxb-…
- Bot User OAuth Token. The xoxb- prefix is required.
- appToken
- xapp-…
- App-Level Token for Socket Mode. The xapp- prefix is required.
Complete the connection in the Console
The current release uses a direct connection. One routing rule connects one Channel Provider to one Agent. It records the adapter, app credentials, target Agent, and group-message behavior. Create a separate rule for each bot.
In the Console, open Signal Routing → New routing rule and set:
| Field | What to choose |
|---|---|
| Target Agent | The Agent you created in step 3 |
| Adapter | Slack, Teams, Lark/Feishu, DingTalk, WeCom, Telegram, Discord, LINE, WhatsApp, or Email |
| Rule name | A stable name such as slack-main or lark-main |
| Group message mode | Start with addressed_only |
| Channel settings | Paste the credentials and values from the channel tab |
Save the rule. The list must show it as enabled. If the form rejects a credential, fix that error before testing the IM; the adapter has not opened its connection yet.
5. Talk to the Agent in the IM
Add the bot to a test conversation. In a group chat, start with an explicit @-mention:
@Ankole What can you do, and which team are you serving?
After the first real model reply, tune the Agent mission, models, and group-chat policy for the team.
If the Agent does not reply
Check one boundary at a time, in this order:
- The latest provider app version is published and available to the test user.
- The bot is installed in the channel, team, or conversation.
- The required message event and scopes are active.
- The routing rule is enabled and points to the intended Agent.
- The Agent has
primary,light, andheavymodel profiles. - The LLM Provider credential and model selector are valid.
- At least one Worker is ready.
For Compose, inspect docker compose logs -f control-plane worker. For Kubernetes, inspect the control-plane and Worker pod logs. Read only the relevant error; do not print environment variables or secrets.
Once the reply arrives, continue with Agents, Signal routing rules, or Background Agent Jobs.