Slack
Run agents, teams, and workflows in Slack with session routing, streaming, file handling, and human-in-the-loop approvals.
The Slack interface routes messages from Slack users and threads to agents, teams, or workflows in AgentOS.
The Slack interface provides:
- Session routing: Slack users and threads map to AgentOS user and session IDs
- File handling: Uploads and downloads work out of the box
- Human in the loop: Pause for approvals before sensitive actions
- Streaming: Responses stream live with task cards showing progress
Add a database and enable history or memory on the agent or team when replies need context from earlier runs.
Quick start
from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.os.app import AgentOS
from agno.os.interfaces.slack import Slack
agent = Agent(name="Support Bot", model=OpenAIResponses(id="gpt-5.4"))
agent_os = AgentOS(
agents=[agent],
interfaces=[Slack(agent=agent)],
)
app = agent_os.get_app()
if __name__ == "__main__":
agent_os.serve(app="agent:app", reload=True)from agno.agent import Agent
from agno.team import Team
from agno.models.openai import OpenAIResponses
from agno.os.app import AgentOS
from agno.os.interfaces.slack import Slack
researcher = Agent(name="Researcher", role="Find information", model=OpenAIResponses(id="gpt-5.4"))
writer = Agent(name="Writer", role="Draft responses", model=OpenAIResponses(id="gpt-5.4"))
support_team = Team(
name="Support Team",
mode="coordinate",
members=[researcher, writer],
model=OpenAIResponses(id="gpt-5.4"),
)
agent_os = AgentOS(
teams=[support_team],
interfaces=[Slack(team=support_team)],
)
app = agent_os.get_app()
if __name__ == "__main__":
agent_os.serve(app="team:app", reload=True)The team coordinator routes messages to the right specialist. Each thread is one session belonging to the team.
from agno.agent import Agent
from agno.workflow import Step, Workflow
from agno.models.openai import OpenAIResponses
from agno.os.app import AgentOS
from agno.os.interfaces.slack import Slack
researcher = Agent(name="Researcher", model=OpenAIResponses(id="gpt-5.4"))
writer = Agent(name="Writer", model=OpenAIResponses(id="gpt-5.4"))
research_flow = Workflow(
name="Research",
steps=[
Step(name="Research", agent=researcher),
Step(name="Write", agent=writer),
],
)
agent_os = AgentOS(
workflows=[research_flow],
interfaces=[Slack(workflow=research_flow)],
)
app = agent_os.get_app()
if __name__ == "__main__":
agent_os.serve(app="workflow:app", reload=True)Each message triggers the workflow. Task cards show step progress as the workflow moves through stages.
Install dependencies
uv pip install 'agno[os,slack]' openaiCreate Slack App
Follow the setup guide to create your app and get credentials.
Set credentials
export OPENAI_API_KEY="..."
export SLACK_TOKEN="xoxb-..."
export SLACK_SIGNING_SECRET="..."Run
Run the file from the tab you used:
python agent.pypython team.pypython workflow.pySee more examples including streaming, teams, workflows, and multiple bots.
Multiple bots
Run multiple agents on the same server, each with its own Slack App. Useful when you need separate bots for different functions (support vs. sales) or different workspaces.
agent_os = AgentOS(
agents=[ace_agent, dash_agent],
interfaces=[
Slack(
agent=ace_agent,
prefix="/ace",
token=getenv("ACE_SLACK_TOKEN"),
signing_secret=getenv("ACE_SLACK_SIGNING_SECRET"),
),
Slack(
agent=dash_agent,
prefix="/dash",
token=getenv("DASH_SLACK_TOKEN"),
signing_secret=getenv("DASH_SLACK_SIGNING_SECRET"),
),
],
)agent_os = AgentOS(
teams=[support_team, research_team],
interfaces=[
Slack(
team=support_team,
prefix="/support",
token=getenv("SUPPORT_SLACK_TOKEN"),
signing_secret=getenv("SUPPORT_SLACK_SIGNING_SECRET"),
),
Slack(
team=research_team,
prefix="/research",
token=getenv("RESEARCH_SLACK_TOKEN"),
signing_secret=getenv("RESEARCH_SLACK_SIGNING_SECRET"),
),
],
)agent_os = AgentOS(
workflows=[review_flow, publish_flow],
interfaces=[
Slack(
workflow=review_flow,
prefix="/review",
token=getenv("REVIEW_SLACK_TOKEN"),
signing_secret=getenv("REVIEW_SLACK_SIGNING_SECRET"),
),
Slack(
workflow=publish_flow,
prefix="/publish",
token=getenv("PUBLISH_SLACK_TOKEN"),
signing_secret=getenv("PUBLISH_SLACK_SIGNING_SECRET"),
),
],
)Each interface mounts on its own prefix. Set each Slack App's Request URL accordingly (/ace/events, /dash/events, etc.).