Preventing Your AI Agent From Messaging #general
It starts innocently. You give your agent access to Slack so it can post a daily standup summary. Twenty minutes later, it has sent 83 messages to #general, replied to the CEO’s thread about Q2 planning with a hallucinated revenue forecast, and added the :clown_face: reaction to every message in #engineering. Your phone is vibrating non-stop and three people have already DM’d you asking if you’ve been hacked.
The Slack MCP server is powerful. That is precisely the problem.
What the Slack MCP server exposes
The official Slack MCP server gives agents access to 8 tools. Five are read-only and relatively harmless:
slack_list_channels— list public channelsslack_get_channel_history— read recent messages from a channelslack_get_thread_replies— read replies in a threadslack_get_users— list workspace membersslack_get_user_profile— get a user’s profile
The other three are where things get interesting:
slack_post_message— post a new message to any channel the bot is inslack_reply_to_thread— reply to a specific threadslack_add_reaction— add an emoji reaction to a message
An agent stuck in a reasoning loop can burn through all three at extraordinary speed. Slack’s own API rate limits are generous enough that dozens of messages can land before anything throttles. By then, the damage — and the embarrassment — is done.
Rate limiting messages
Intercept sits between your agent and the Slack MCP server, evaluating every tools/call against a YAML policy. Here is the full Slack policy:
version: "1"
description: "Policy for modelcontextprotocol/server-slack"
default: "allow"
tools:
slack_get_channel_history:
rules: []
slack_get_thread_replies:
rules: []
slack_get_user_profile:
rules: []
slack_get_users:
rules: []
slack_list_channels:
rules: []
slack_add_reaction:
rules:
- name: "reaction-rate-limit"
rate_limit: "20/hour"
on_deny: "Rate limit: max 20 reactions per hour"
slack_post_message:
rules:
- name: "message-send-rate-limit"
rate_limit: "10/hour"
on_deny: "Rate limit: max 10 messages per hour — review message activity before retrying"
slack_reply_to_thread:
rules:
- name: "reply-send-rate-limit"
rate_limit: "10/hour"
on_deny: "Rate limit: max 10 thread replies per hour — review message activity before retrying"
"*":
rules:
- name: "global-rate-limit"
rate_limit: "60/minute"
on_deny: "Global rate limit: max 60 tool calls per minute across all Slack tools"
The read tools have empty rulesets — no restrictions. The three write tools each carry hourly rate limits: 10 messages, 10 thread replies, 20 reactions. The wildcard rule at the bottom adds a global cap of 60 calls per minute across everything, including reads.
When an agent hits a limit, Intercept blocks the call at the transport layer and returns the on_deny message. The request never reaches Slack. The agent gets a clear signal to stop, and your workspace stays intact.
The rate_limit shorthand expands internally into a stateful counter with calendar-aligned windows — top of each hour, midnight UTC for daily limits. Counters persist across agent restarts, so an agent cannot dodge limits by reconnecting. For more on how this works under the hood, see Rate Limiting MCP Tool Calls.
Getting started
Install Intercept and point it at your Slack MCP server:
# Install
npm install -g @policylayer/intercept
# Run with the Slack policy
intercept -c slack.yaml -- npx -y @modelcontextprotocol/server-slack
Save the YAML above as slack.yaml, or generate a starter policy with intercept scan. Intercept proxies all traffic through the policy engine — no code changes to your agent or the MCP server.
Adjust the limits to match your use case. A customer support agent might need 50 messages per hour. An internal reporting bot might need 5. The point is that the ceiling exists, and it is enforced deterministically regardless of what the LLM decides to do.
Protect your agent in 30 seconds
Scans your MCP config and generates enforcement policies for every server.
npx -y @policylayer/intercept init