A simple Slack bot that uses the OpenAI Agents SDK to interact with Model Context Protocol (MCP) servers.
See also: agentic-telegram-bot — a similar demo bot for Telegram.
- Channel @mention and DM support
- Thread-aware conversations (follow-ups stay in the same thread)
- Connects to any MCP server via
servers_config.json - Optional local shell via
ShellTool, controlled bySHELL_ENABLEDandSHELL_SKILLS_DIR - Supports OpenAI and OpenAI-compatible endpoints (including Azure OpenAI v1 API)
- Per-conversation history with automatic truncation (last 10 turns)
uv sync- Create a new Slack app at api.slack.com/apps.
- Enable Socket Mode and generate an app-level token (
xapp-...). - Under OAuth & Permissions, add the following bot token scopes:
app_mentions:readchat:writeim:historyusers:read
- Under Event Subscriptions, subscribe to:
app_mentionmessage.im
- Install the app to your workspace and copy the bot token (
xoxb-...).
Create a .envrc or .env file in the root directory:
export SLACK_BOT_TOKEN=""
export SLACK_APP_TOKEN=""
export OPENAI_API_KEY=""
# Local shell (disabled by default)
# export SHELL_ENABLED=1
# export SHELL_SKILLS_DIR="./skills" # optional; mount skills alongside the shell
If you are using Azure OpenAI (v1 API) or another OpenAI-compatible endpoint:
export OPENAI_API_KEY=""
export OPENAI_BASE_URL="https://<resource-name>.openai.azure.com/openai/v1/"
Optional HTTP proxy for outbound requests:
export HTTP_PROXY=""
Optional verbose OpenAI Agents SDK logging:
export AGENT_VERBOSE_LOG=1
AGENT_VERBOSE_LOG is defined by this project: when set to a truthy value, the app
calls the SDK's enable_verbose_stdout_logging() helper during startup. Values like
0, false, no, off (case-insensitive) are treated as disabled.
The following are environment variables read directly by the OpenAI Agents SDK (not this project). By default, the SDK does not log model or tool payloads. To include them temporarily for debugging:
export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=0
export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=0
These payload logs may contain sensitive data. Re-enable the defaults after debugging:
export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1
export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1
Create an instructions.md file in the project root with the agent system prompt:
You are a helpful assistant in a Slack workspace.
When responding, you must strictly use Slack's `mrkdwn` formatting syntax only.
Keep responses concise and well-structured.An example is provided in instructions.md.example. The bot will fail to start if this file is missing.
Create a servers_config.json file to add your MCP servers. If this file is not provided, the bot starts with no MCP servers configured.
{
"model": "gpt-5.4",
"mcpServers": {
"my-server": {
"command": "uvx",
"args": ["my-mcp-server"]
}
}
}model is optional and defaults to gpt-5.4. Each MCP server also accepts timeout (seconds, default 30.0) and enabled (default true).
For HTTP-based MCP servers (Streamable HTTP), use url:
{
"mcpServers": {
"my-server": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Accept": "application/json, text/event-stream"
}
}
}
}For local MCP servers, use uv --directory:
{
"mcpServers": {
"my-server": {
"command": "uv",
"args": ["--directory", "/path/to/my-server", "run", "my-entrypoint"]
}
}
}uv run botThe bot can expose a local ShellTool. This is disabled by default. Enable it with:
export SHELL_ENABLED=1
With just SHELL_ENABLED=1, the agent gets bare local shell access with no pre-defined skills.
You can optionally mount a skills directory alongside the shell. Each immediate subdirectory containing a SKILL.md file is registered as a skill and exposed to the agent as a hint (skills are advisory metadata — they do not sandbox command execution).
export SHELL_ENABLED=1
export SHELL_SKILLS_DIR="./skills"
SHELL_SKILLS_DIR is ignored unless SHELL_ENABLED is set. If the directory is missing or contains no valid skills, the bot falls back to a bare shell and logs a warning.
When using the Docker image, mount your skills directory at runtime (the image build excludes it by default):
-v /path/to/skills:/app/skills:roThe SKILL.md file should have YAML frontmatter with name and description fields:
---
name: my-skill
description: A brief description of what this skill does
---
Detailed instructions for the agent...docker build -t agentic-slackbot .
docker run -d \
--name slackbot \
-e SLACK_BOT_TOKEN="" \
-e SLACK_APP_TOKEN="" \
-e OPENAI_API_KEY="" \
-e SHELL_ENABLED=1 \
-e SHELL_SKILLS_DIR=/app/skills \
-v /path/to/instructions.md:/app/instructions.md \
-v /path/to/skills:/app/skills:ro \
agentic-slackbotTo use MCP servers, also mount your config:
docker run -d \
--name slackbot \
-e SLACK_BOT_TOKEN="" \
-e SLACK_APP_TOKEN="" \
-e OPENAI_API_KEY="" \
-e SHELL_ENABLED=1 \
-e SHELL_SKILLS_DIR=/app/skills \
-v /path/to/instructions.md:/app/instructions.md \
-v /path/to/skills:/app/skills:ro \
-v /path/to/servers_config.json:/app/servers_config.json \
agentic-slackbotThis project is based on the sooperset/mcp-client-slackbot example.