Create a Slack app
Go to api.slack.com/apps, click "Create New App", choose "From scratch", name it anything you like, and pick your workspace.
Install on macOS or Linux, connect your Slack workspace, configure Claude Code, and deploy your first agent - all in one afternoon.
Jump to any section or read top to bottom for a full setup walkthrough.
01 - Installation
EffectiveBots runs on macOS (12+) and any modern Linux distribution. You need Node 20+, Git, and access to Claude Code. Nothing is sent to external servers except model inference calls.
macOS
Homebrew or direct Node install both work. Apple Silicon and Intel supported.
Linux
Ubuntu 22.04, Debian 12, Fedora 38 and later tested. Docker image available.
Clone and install dependencies
git clone https://github.com/effectivebots/effectivebots cd effectivebots npm install
Copy the example config
cp config.example.yml config.yml
Start the service
$ effectivebots up [ok] config loaded from ./config.yml [ok] Slack Socket Mode connected [ok] 2 agents initialized [ok] dashboard at http://localhost:4321
Docker alternative
docker run -v $(pwd)/config.yml:/app/config.yml \ effectivebots/effectivebots:latest
02 - Slack Configuration
Socket Mode keeps all traffic inside your network. You create a Slack app in your workspace, enable Socket Mode, and paste two tokens into your config file. No public URLs or webhooks needed.
Go to api.slack.com/apps, click "Create New App", choose "From scratch", name it anything you like, and pick your workspace.
Under "Socket Mode", flip the toggle on. Under "OAuth and Permissions", add these bot token scopes:
app_mentions:read channels:history channels:read chat:write files:write im:history users:read
Install the app to your workspace, then add the two tokens to config.yml:
slack: bot_token: xoxb-... app_token: xapp-...
Enable event subscriptions
Under "Event Subscriptions", subscribe to these bot events: app_mention, message.channels, message.im. Save and reinstall the app if prompted.
03 - Claude Code Setup
Each bot runs its own persistent Claude Code session. You need the Claude Code CLI installed on the same host and an active Claude subscription or API key. EffectiveBots is not affiliated with Anthropic.
Install Claude Code CLI
npm install -g @anthropic-ai/claude-code
Authenticate once
claude auth login
Follow the browser prompt. The credential is stored in ~/.claude and picked up automatically by all agents.
Point the config at the binary
claude_code: binary: claude # or /usr/local/bin/claude timeout_seconds: 300
Session isolation
Each bot gets its own Claude Code process and working directory. Sessions do not share context across agents unless you explicitly configure a shared memory file.
Timeouts and retries
Set timeout_seconds per agent to cap long-running tasks. If Claude Code exits unexpectedly, EffectiveBots restarts the session and notifies the channel.
API key mode
If you prefer key-based auth over browser login, set ANTHROPIC_API_KEY in your environment before starting the service.
04 - Creating Agents
Agent definitions live in plain YAML. Version them alongside your code. Each agent gets its own Slack identity (a separate Slack app or a named persona), a workspace directory, and an optional memory file.
Full agent definition example
agents:
- name: triage-bot
slack_display_name: "Triage Bot"
slack_emoji: ":robot_face:"
workspace: /repos/my-app
role: |
You triage incoming GitHub issues.
When assigned a task, reproduce the
bug locally, label it, and post a
short summary with the likely cause.
memory_file: .bots/triage-memory.md
allowed_branches:
- "triage/*"
max_parallel_tasks: 2
name
Used in @mentions and in log output. Lowercase, hyphens allowed.
role
A plain text brief. The bot receives this as its system prompt. Keep it specific - "triage bugs" outperforms "help the team".
memory_file
A Markdown file the bot reads and writes between sessions. It records decisions, learned conventions, and recurring facts.
allowed_branches
Glob patterns for branches the bot may push to. Omit to restrict to reads only. Merge to main still requires a human.
Assigning a task from Slack
Mention the bot in any channel it has been invited to. It will reply in the same thread.
you: @triage-bot take a look at issue #412, the login timeout one
triage-bot: On it. I'll reproduce locally and post findings here.
triage-bot: Root cause: session token not refreshed on tab refocus.
Branch triage/412-session-refresh is ready for review.
05 - MCP Integration
MCP lets you hand agents access to external tools - a database read-only query endpoint, a REST API, a file vault - without giving them shell-level credentials. Each MCP server you define becomes a callable tool inside Claude Code sessions.
Adding an MCP server to an agent
agents:
- name: data-bot
workspace: /repos/analytics
mcp_servers:
- name: readonly-db
command: node
args: [./mcp/db-server.js]
env:
DB_URL: postgres://localhost/app_db
- name: github-api
command: npx
args: [-y, @modelcontextprotocol/server-github]
env:
GITHUB_TOKEN: ghp_...
Per-agent tool scope
MCP servers are defined per agent, so a triage bot can query the issue tracker while a docs bot only sees the content repo.
Process isolation
Each MCP server runs as a child process of its agent session. It exits when the agent is paused or stopped.
Compatible servers
Any MCP-compliant server works - the official Anthropic servers, community packages, or ones you write yourself using the MCP SDK.
06 - Scheduled Tasks
Use schedule blocks inside any agent definition to trigger tasks at set times. Results are posted to a channel of your choice.
Cron syntax
Standard five-field cron expressions. Timezone can be set per schedule block.
Report channel
Results post to any channel the bot is invited to. Use a dedicated channel to keep scheduled output separate from conversations.
Skip if busy
If an agent is already running a task when a schedule fires, the trigger is skipped and a note is posted. No queuing, no overlap.
Schedule definition
agents:
- name: deps-bot
workspace: /repos/my-app
schedule:
- cron: "0 9 * * 1" # Mondays 9am
timezone: "America/New_York"
prompt: |
Check for outdated npm dependencies.
Upgrade patch and minor versions on a
new branch. Run tests. Post a summary
with anything that needed a code fix.
report_channel: "#bot-reports"
- cron: "0 8 * * *" # Every day 8am
prompt: |
Scan open issues labelled 'stale'.
Post a list of any older than 30 days
with a suggested next action for each.
report_channel: "#triage"
Example scheduled output in Slack
deps-bot Mon 9:04am
Checked 214 deps. 3 minor upgrades applied.
lodash 4.17.20 -> 4.17.21 (no code change)
axios 1.4.0 -> 1.6.8 (no code change)
vite 4.5.0 -> 5.2.10 (vite.config.js updated)
Branch: deps/2024-04-08 - ready to review.
07 - Admin Dashboard
The dashboard runs locally at localhost:4321 when the service is up. No account needed. It shows live session state, task history, and memory contents for every agent.
Session status
Each agent card shows current state (idle, working, paused), the last task it completed, and when it last posted to Slack.
Task log
Every task is logged with the original prompt, the Claude Code output, the files touched, and whether it succeeded or was cancelled.
Memory inspector
View the Markdown memory file for any agent, edit it directly in the browser, or reset it to an empty state without restarting the service.
Controls
Pause an agent so it stops accepting new Slack tasks (it finishes the current one). Restart its Claude Code session without restarting the whole service.
Schedule tracker
A timeline showing when each scheduled task fires next, with the option to trigger it early or skip the next occurrence.
Access
The dashboard binds to 127.0.0.1. To expose it on a private network, set dashboard.host in config and add your own auth layer.
Dashboard config options
dashboard: enabled: true host: 127.0.0.1 # change to 0.0.0.0 for LAN port: 4321 log_retention_days: 30 show_memory_editor: true
08 - Config Reference
All keys go in config.yml unless noted otherwise. YAML anchors are supported for sharing values across agents.
slack.bot_token
required
Bot OAuth token starting with xoxb-. Comes from your Slack app's OAuth page.
slack.app_token
required
App-level token starting with xapp-. Needed for Socket Mode.
claude_code.binary
optional
Path to the claude binary. Defaults to claude (assumes it is on PATH).
claude_code.timeout_seconds
optional
Global task timeout in seconds. Default: 300. Can be overridden per agent.
agents[].name
required
Unique identifier for the agent. Used in logs and as the Slack mention handle.
agents[].workspace
required
Absolute path to the directory Claude Code runs in. Usually a cloned repo.
agents[].role
required
Plain text system prompt for this agent. Multiline YAML block scalars work well here.
agents[].memory_file
optional
Relative (to workspace) or absolute path to a Markdown file used as persistent memory.
agents[].allowed_branches
optional
List of glob patterns for branches the agent may push. Omit to set read-only mode.
agents[].mcp_servers
optional
List of MCP server definitions (name, command, args, env). Each starts as a child process.
agents[].schedule
optional
List of schedule blocks with cron, prompt, and report_channel.
dashboard.port
optional
Port the local dashboard listens on. Default: 4321.
Clone the repo, follow the steps above, and have an agent working in your Slack workspace within the hour. Free for up to 10 bots.