Skip to main content
Agno and AgentOS make it easy to deploy your agents on Discord with just 2 extra lines of code. This example creates a simple agent for answering questions:
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.os import AgentOS
from agno.os.interfaces.discord import Discord

discord_agent = Agent(
    name="Discord Bot",
    model=OpenAIChat(id="gpt-4o-mini"),
    add_history_to_context=True,
    num_history_runs=3,
    add_datetime_to_context=True,
    markdown=True,
)

agent_os = AgentOS(
    agents=[discord_agent],
    interfaces=[Discord(agent=discord_agent, stream=True)],
)
app = agent_os.get_app()

if __name__ == "__main__":
    agent_os.serve(app="discord_bot:app", port=7777, reload=True)
Install Discord dependencies: pip install 'agno[discord]'
The bot automatically creates threads for each @mention conversation and uses per-thread session tracking to maintain context. In DMs, each channel gets its own session.

Setup and Configuration

1

Prerequisites

Ensure you have the following:
  • A Discord account
  • ngrok (for development)
  • Python 3.7+
2

Create a Discord Application

  1. Go to the Discord Developer Portal
  2. Click “New Application”
  3. Provide an application name (e.g., “My Agno Bot”)
  4. Accept the Developer Terms of Service and click “Create”
  5. Note the Application ID and Public Key from the “General Information” page
3

Create a Bot User

  1. In your application settings, navigate to the “Bot” section
  2. Click “Reset Token” to generate a new bot token
  3. Copy and save this token securely — you won’t be able to see it again
4

Configure Bot Permissions

In the Bot settings, ensure your bot has these permissions:
  • Send Messages
  • Read Message History
  • Create Public Threads
  • Send Messages in Threads
  • Manage Threads
  • Attach Files
  • Embed Links
5

Invite Bot to Your Server

  1. In your application settings, go to “OAuth2” > “URL Generator”
  2. Under “Scopes”, select bot and applications.commands
  3. Under “Bot Permissions”, select the permissions listed above
  4. Copy the generated URL, open it in your browser, and select your server
6

Setup Environment Variables

Create a .env file in your project root:
DISCORD_BOT_TOKEN="your-bot-token"
DISCORD_PUBLIC_KEY="your-public-key"
DISCORD_APPLICATION_ID="your-application-id"
7

Register Slash Commands

Register the /ask slash command with Discord:
curl -X PUT \
  -H "Authorization: Bot $DISCORD_BOT_TOKEN" \
  -H "Content-Type: application/json" \
  "https://discord.com/api/v10/applications/$DISCORD_APPLICATION_ID/commands" \
  -d '[{
    "name": "ask",
    "description": "Send a message to the bot",
    "type": 1,
    "options": [
      {"name": "message", "description": "Your message", "type": 3, "required": true},
      {"name": "file", "description": "Optional file attachment", "type": 11, "required": false}
    ]
  }]'
8

Setup Webhook with ngrok (Development)

  1. Run ngrok to expose your local server:
    ngrok http 7777
    
  2. Copy the https:// URL provided by ngrok
  3. Set the interactions endpoint in the Discord Developer Portal:
    • Go to “General Information”
    • Set “Interactions Endpoint URL” to https://<your-ngrok-url>/discord/interactions
    • Discord will send a verification PING — your server must be running
9

Configure for Production

For production deployments:
  1. Replace the ngrok URL with your production domain
  2. Update the Interactions Endpoint URL in the Developer Portal to https://<your-domain>/discord/interactions
ngrok is used only for local development and testing. For production deployments, see the deployment tutorials.

How It Works

The Discord interface uses two concurrent transports:
  1. HTTP Webhook - Handles /ask slash commands via Discord’s Interactions API. The bot responds with a deferred message, processes the request in the background, and edits the response.
  2. Gateway WebSocket - Listens for @mentions and DMs via a persistent WebSocket connection. Auto-activates when discord.py is installed and DISCORD_BOT_TOKEN is set.
Both transports share the same processing core, so your agent logic is written once.

Developer Resources