# Slack MCP access for IT team, configured safely

> Slack MCP access for IT team work in Claude: allow channel reads, pin the posting channel, block DM-everyone and user deactivation, then read the audit trail.

**TL;DR** Elaichi serves Slack tools through one organization-wide MCP endpoint, so an IT team can read channels in Claude and post to a single pinned channel. Allow rules name the read operations plus the one write, frozen parameters pin the destination channel, and block rules keep DM-everyone and user deactivation out of reach. A restriction change takes about two minutes to take effect, and every tool-call attempt lands in the audit trail naming the Slack account actually reached.

## IT lives in Slack, and now the agent does too

Your IT team answers most of its tickets in Slack threads. Someone reports a laptop that will not enroll, a screenshot follows, and the thread becomes the record. Point Claude at Slack and the same team gets an agent that reads the thread and posts a summary back. The question is what else that agent reaches on the way. Setting up Slack MCP access for IT team work means deciding three things before anyone connects an account. The three are: which reads are allowed, where the agent may post, and which Slack operations nobody's agent should call at all.

MCP is the protocol an AI client uses to call tools in other systems. Elaichi serves it from one organization-wide endpoint, `POST /mcp`, standard MCP over Streamable HTTP, behind OAuth (the authorization framework the client signs in through). Claude, ChatGPT and Cursor are pointed at that single address through their own admin consoles. There are no per-user server URLs and no tokens pasted into a client config file. The address is the same for everyone. The grant, the role and the restrictions are what vary.

## What does Slack MCP access for IT team work need to allow first?

Start with an allow rule that names the Slack read operations the team needs, plus the single write it needs. Nothing else.

A restriction in Elaichi is a rule about which connectors and which individual tools a target may reach. Restrictions have one property that catches people out: the allowlist stage engages on the presence of an allow rule, not its contents, so an allow rule that names nothing denies everything. An allow rule that names nothing therefore denies everything. It is the strictest rule you can express, and it is easy to create by accident while drafting one.

Allow rules match on the pinned operation only. When you write a rule against a connector and tool, Elaichi pins the canonical resource and method against the catalog at write time. The advertised tool name is a label that whoever edits the connector documentation controls. The operation is not. Governance binds the operation, never the label.

One more detail shapes what the IT team sees in Claude. Reads carry MCP's read-only hint, deletes carry the destructive hint, and a plain write carries no annotation at all. The protocol has no hint for "changes something without destroying it", so Elaichi does not invent one.

## Pinning the channel an agent may post to

Use frozen parameters. A frozen parameter is a fixed argument value attached to a toolbox entry, where a toolbox entry is one tool pinned to one connected account. Freeze the channel argument on the Slack post operation and the agent can post to that channel and no other.

Freezing has two effects, and both matter here. The frozen key is stripped from the advertised schema, so the model never sees a channel argument to fill in. The frozen value is then merged over caller arguments at execution, so passing the key anyway cannot un-freeze it. Full precedence runs entry defaults, then caller and model arguments, then frozen parameters.

That combination is what makes a pinned channel hold up against an instruction pasted into a ticket. The model is not being asked to respect a channel policy. It has no argument to change.

## Blocking DM-everyone and user deactivation

Write both as block rules. Within the winning layer, allow rules union, block rules union, and blocks always beat allows. A block rule matches on the tool name or on the pinned operation, which is the asymmetry worth knowing: the block survives a rename, and the allow does not widen on one. The reasoning behind that split is worked through in [why a block matches the name and an allow matches the operation](/blog/block-matches-name-allow-matches-operation/).

User deactivation is the operation to be most deliberate about. A deactivation reached over MCP needs the `mcp:destructive` OAuth scope, since scopes ladder from `mcp:read` through `mcp:write` to `mcp:destructive`. A tool classified `forbidden` is reachable under no scope at all. Scopes limit the blast radius. The block rule is what keeps a specific operation out of a specific team's hands.

Bulk direct messaging is a different risk and gets the same treatment. Nothing about it is destructive, so the scope ladder will not stop it. A block rule will.

One honest limitation belongs here. The prompt-injection write gate in the Elaichi agent window does not apply to `POST /mcp`, and cannot, because an MCP server never sees a user prompt. What does hold on the endpoint is RBAC per operation, the `forbidden` classification, output redaction, OAuth scope limits and full audit logging. Do not plan a Slack rollout on the assumption that the endpoint reasons about intent. Plan it on the assumption that the rules are the control.

## Role or user: which target carries the rule

Restriction targets are role or user. There is no organization target. The organization default is the absence of any rule, which means allow-all, so an unrestricted connector is fully reachable by anyone who can execute tools.

For an IT team, put the rule on the role. That keeps the policy attached to the persona rather than to a list of names, and every member carries exactly one role, enforced by a unique index. Use a user-targeted rule only for a genuine exception, and know what it does: a user rule replaces the role's rules entirely rather than layering on top of them. If a senior engineer needs one extra operation, their user rule has to restate everything the role allowed, or they lose it.

Timing matters when you are mid-rollout. A role change or a restriction change takes effect within about two minutes, because both resolve through a short cache plus edge propagation. Only grant revocation, member removal and suspension are effective on the next call. If somebody has to lose Slack access right now, revoke the grant or suspend the member rather than editing a rule and watching.

Enforcement runs at four points against the same resolver: browse, connect, advertise and execute, plus a final check on the fully substituted outbound URL. A blocked Slack tool is not advertised to Claude in the first place. Tools withheld by a restriction do not count toward the 30-tool threshold at which connected tools collapse behind `search_tools` and `execute_tool`.

## Multi-step incident work runs through the same gates

An incident summary is rarely one call. Read the channel, pull the ticket, post the write-up. A synthetic tool packages that as a directed acyclic graph of steps, each calling a connected account's tool with templated arguments over inputs and prior outputs. Cycles are rejected at save, and independent steps run in parallel.

The governance point is that nothing is skipped. Every step goes through the same restriction and audit pipeline as any other call. A synthetic tool that reaches for user deactivation meets the block rule at the same resolver, and each step lands in the audit trail naming the Slack account it actually reached.

## What the audit trail shows after a post

The audit trail is the organization-visible, append-only record of what was attempted. Every tool-call attempt produces one entry, succeeded or failed, and every entry names the connection actually reached rather than the one the caller intended. If the IT team has two Slack workspaces connected, the log says which one received the message.

Each record carries the operation and tool, the connection, the classification, whether the call was approved, the outcome, and an error code. Here `actor_kind` is a recorded field, not something inferred later from a user agent, and `ai_assistant` is one of its values. So "did a person post that or did Claude" is answered by the record itself.

Here is the trade-off to plan around. Argument names and counts are logged; argument values never are. The audit trail will not show you the text of the message or the channel ID passed in. That is why the pinned channel belongs in a frozen parameter rather than in a convention the team agrees to follow. The configuration proves the destination, and the log proves the operation ran against a named Slack account.

The trail is newest-first, cursor-paginated, and filterable by free text, category, actor, action kind and time. It is eventually consistent, so a row may take a moment to appear. A departed member renders as "Former member" rather than vanishing from history. Audit events and application logs share one record shape, which is what lets a single query answer "what happened" instead of correlating two systems by eye. Error text returned to the caller is never written to the trail, so a Slack response body cannot travel out through the log pipe. If you forward logs onward, Datadog export is implemented; Splunk HEC and Microsoft Sentinel are accepted but not yet delivering.

Give the person who reviews all of this an Auditor seat. Auditor is read-only, sits off the role chain, and is free, so a compliance reviewer does not consume a license. Auditor also lacks `tool:execute`, and that permission gates the whole endpoint ahead of every scope, so an Auditor cannot call a Slack tool while reading about one.

## What happens when the engineer who connected Slack leaves

Removal is effective on the next call, and the connection gets resolved before the removal completes. The OAuth grant's revoked timestamp is re-read from the organization store on every single call, with no cache. removing or suspending a member revokes every live grant in the same transaction as the membership change.

Offboarding then runs a preflight. A personal Slack connection referenced by a toolbox entry must be transferred to the organization, a team or another member, or deleted, or the removal is refused. Unreferenced personal connections are cleaned up. A private connection is not transferable at all, because a credential only its owner could ever use does not become somebody else's when its owner leaves. Contractors make this routine, and the short version for that case is in [what to do about contractor AI access today](/blog/shadow-ai-contractor-offboarding/).

## When this is more setup than the IT team needs

If three people use Claude, all three are admins, and the only Slack account connected is a bot with read scopes, restrictions are overhead. The honest version of that argument, including the signals that mean you have crossed over, is in [when you don't need an MCP gateway yet](/blog/when-you-dont-need-an-mcp-gateway/).

The crossover usually arrives with the first non-admin. The moment a contractor or a junior analyst holds a grant, allow-all stops being a decision and becomes a default nobody made.

## The order to do it in

Connect the Slack account first, write the allow rule second, freeze the channel third, add the blocks fourth, and check the audit trail fifth with a deliberate test post. Reversing the first two leaves a window where allow-all applies to a live account.

A sales team version of the same sequence, run against Salesforce in ChatGPT, is written up in [the Salesforce rollout playbook](/blog/sales-team-chatgpt-salesforce-accounts/). For what else the IT team can reach from the same endpoint, browse the [connector catalog](/connectors/), and for how other functions set this up, see [the use-cases directory](/use-cases/). More posts in this series sit under [team playbooks](/blog/category/team-playbooks/).

## FAQ

### Can Elaichi restrict a Slack agent to posting in one channel?

Yes, using frozen parameters. A frozen parameter is a fixed argument value attached to a toolbox entry, which is one tool pinned to one connected account. Freezing the channel argument strips that key from the schema the AI client sees, so the model is never offered a channel to choose. At execution the frozen value is merged over any caller arguments, so passing the key anyway cannot override it. The precedence is entry defaults, then caller and model arguments, then frozen parameters.

### How long does a Slack restriction change take to take effect in Elaichi?

about two minutes. Role membership and restriction changes resolve through a short cache plus edge propagation on every surface, including MCP, the console and the REST API. Only grant revocation, member removal and member suspension are effective on the next call. If somebody must lose access right now, revoke the grant or suspend the member rather than editing a restriction rule.

### Does the Elaichi audit log show which Slack channel a message went to?

No. Argument names and counts are logged; argument values never are, so the channel ID and the message text do not appear in the record. Each entry does name the operation, the connection actually reached, the classification, whether the call was approved and the outcome. To prove a destination, pin the channel with a frozen parameter so the configuration, not the log, is the evidence.

### Can an allow rule accidentally block everything?

Yes. In Elaichi the allowlist stage engages on the presence of an allow rule, not its contents, so an allow rule that names nothing denies everything, so an allow rule that names no tools denies everything. It is the strictest rule you can express. Check that a newly saved allow rule names the operations the team needs before you rely on it.

### What happens to a Slack connection when the IT member who set it up leaves?

Removing the member revokes every live grant in the same transaction, so access stops on the next call. Offboarding also runs a preflight: a personal connection referenced by a toolbox entry must be transferred to the organization, a team or another member, or deleted, or the removal is refused. Unreferenced personal connections are cleaned up, and a private connection is not transferable at all.

## Read next

- [NetSuite MCP access for finance team in Claude](/blog/finance-team-claude-netsuite-ledger/) — NetSuite MCP access for finance team work: read-only analysts, journal posting behind a user override, and an audit entry naming the subsidiary account reached.
- [HubSpot MCP access for marketing team, safely](/blog/marketing-team-chatgpt-hubspot-campaigns/) — How to set up HubSpot MCP access for marketing team use in ChatGPT: reads allowed, list deletion and bulk email send blocked, the portal frozen, every attempt logged.
- [Salesforce MCP access for sales team, done right](/blog/sales-team-chatgpt-salesforce-accounts/) — Salesforce MCP access for sales team, set up so reps see only their own accounts. Bulk update and mass delete are restricted at the operation, the owner field is frozen, and an audit query proves it.
