Common issues and their solutions.
If first-run setup is failing, validate command resolution in a clean directory:
tmpdir="$(mktemp -d)"
cd "$tmpdir"
npx -y @jtalk22/slack-mcp --version
npx -y @jtalk22/slack-mcp --help
npx -y @jtalk22/slack-mcp --doctor
Expected:
--version and --help exit 0--doctor exits with one of:
0 ready1 missing credentials2 invalid/expired credentials3 connectivity/runtime issue--status is read-only and never attempts Chrome extraction.If --version fails here, the issue is install/runtime path, not Slack credentials.
Symptom: slack_list_conversations returns channels but no DMs.
Cause: Slack’s conversations.list API doesn’t return IMs when using xoxc browser tokens.
Solution: This is handled automatically. The server discovers DMs by calling conversations.open for each user in your workspace. This happens in lib/handlers.js.
If DMs still don’t appear:
slack_list_conversations types=im,mpimslack_list_usersSymptom: {"error":"ratelimited"} in API responses.
Cause: Slack limits API calls, especially when listing many users/DMs.
Solution: The client (lib/slack-client.js) implements automatic retry with exponential backoff:
If you still hit limits, reduce batch sizes:
slack_list_conversations limit=50
Symptom: invalid_auth or token_expired errors.
Cause: Browser tokens (xoxc/xoxd) expire after 1-2 weeks.
Solution: The server has 4 layers of token recovery:
~/.slack-mcp-tokens.jsonTo refresh tokens:
# Option 1: In Claude Code/Desktop
slack_refresh_tokens
# Option 2: Package setup wizard
npx -y @jtalk22/slack-mcp --setup
# Option 3: Diagnostics check
npx -y @jtalk22/slack-mcp --doctor
# Option 4: Repo CLI
npm run tokens:auto
# Option 5: Manual
npm run tokens:refresh
Solution: Use LaunchAgent for persistence:
# Create LaunchAgent
cat > ~/Library/LaunchAgents/com.slack-web-api.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.slack-web-api</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/node</string>
<string>/Users/YOUR_USERNAME/slack-mcp-server/src/web-server.js</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/YOUR_USERNAME/slack-mcp-server</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.slack-web-api.plist
The web server generates a unique API key on first run, stored in ~/.slack-mcp-api-key.
The key is printed to the console when you start the server:
Dashboard: http://localhost:3000/?key=smcp_xxxxxxxxxxxx
API Key: smcp_xxxxxxxxxxxx
You can also set a custom key:
SLACK_API_KEY=your-custom-key npm run web
Check if the server is running:
# Get your API key from ~/.slack-mcp-api-key
curl http://localhost:3000/health -H "Authorization: Bearer $(cat ~/.slack-mcp-api-key)"
Check LaunchAgent status:
launchctl list | grep slack-web-api
Check logs:
cat /tmp/slack-web-api.log
cat /tmp/slack-web-api.error.log
Symptom: Claude Desktop doesn’t show Slack tools after adding config.
Solutions:
cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | python -m json.tool
cat ~/Library/Logs/Claude/mcp-server-slack.log
which node
# Use this full path in config
Check the log:
tail -50 ~/Library/Logs/Claude/mcp-server-slack.log
Common causes:
/opt/homebrew/bin/node)Symptom: slack_refresh_tokens returns “Could not extract from Chrome”
Requirements:
app.slack.com (not desktop app)View > Developer > Allow JavaScript from Apple EventsCheck permissions: System Preferences → Privacy & Security → Accessibility → Ensure Terminal is enabled
Question: Why not just create a Slack app with proper OAuth?
Answer: Slack apps cannot access DMs without explicit OAuth authorization for each conversation. This is by design for privacy.
Browser tokens (xoxc/xoxd) provide the same access you have in Slack’s web interface - everything you can see, Claude can see.
Trade-offs:
~/Library/Logs/Claude/mcp-server-slack.log/tmp/slack-web-api.logcd ~/slack-mcp-server
node src/server.js # Should say "running"
npm run tokens:status