[{"data":1,"prerenderedAt":39},["ShallowReactive",2],{"$f23kv2gf78we0c":3},{"href":4,"title":5,"description":6,"kind":7,"mark":8,"planned":9,"contributors":10,"provenance":8,"html":11,"headings":12},"\u002Fdocs\u002Ftools\u002Fslack","Slack","Messages, channels, search and files, through Slack's own hosted MCP server.","integrates",null,false,[],"\u003Ch2 id=\"what-a-member-can-do\">What a member can do\u003C\u002Fh2>\n\u003Cp>With Slack bound, a member can post and reply in the channels its account is in, read channel and direct-message\nhistory, search messages and files, react, and read and write canvases and lists: whatever the scopes you grant\nallow. Each task names the Slack tools it may call; a tool the task does not name is refused, whatever the binding\nallows.\u003C\u002Fp>\n\u003Cp>A member only reaches the channels its own Slack account has joined.\u003C\u002Fp>\n\u003Ch2 id=\"who-connects-it\">Who connects it\u003C\u002Fh2>\n\u003Cp>Slack's hosted MCP server only issues \u003Cstrong>user tokens\u003C\u002Fstrong>, so every Slack call a binding makes acts as \u003Cstrong>the Slack user\nwho clicked Allow\u003C\u002Fstrong> when the binding was connected. The Slack app's name and icon make no difference.\u003C\u002Fp>\n\u003Cp>A binding can sit on the enterprise, a team, a member, a role or a task, and the one further down replaces the one\nabove: task, then role, then member, then team, then enterprise. Connect a member's binding while Slack is signed in\nas that member's own account, and its messages appear under its own name and avatar. Connect it while signed in as\nyourself, and everything it posts appears as you.\u003C\u002Fp>\n\u003Ch2 id=\"what-waits-for-you\">What waits for you\u003C\u002Fh2>\n\u003Cp>Nothing on Slack waits for you unless the task declares a gate on it. If a message should never go out without\nyour approval, gate the Slack tool that sends it on the task.\u003C\u002Fp>\n\u003Ch2 id=\"setup\">Setup\u003C\u002Fh2>\n\u003Ch3 id=\"the-slack-app\">The Slack app\u003C\u002Fh3>\n\u003Cp>One app serves the whole workspace: it only identifies Zero Human OS as the thing asking for access, and the person\nwho authorises it decides who the token acts as. If your workspace already has one, reuse its Client ID and Client\nSecret.\u003C\u002Fp>\n\u003Col>\n\u003Cli>Create an app at \u003Ca href=\"https:\u002F\u002Fapi.slack.com\u002Fapps\">api.slack.com\u002Fapps\u003C\u002Fa>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>OAuth &amp; Permissions → Redirect URLs:\u003C\u002Fstrong> add \u003Ccode>https:\u002F\u002Fportal.zerohuman.com\u002Fv1\u002Ftools\u002Foauth\u002Fcallback\u003C\u002Fcode> exactly, with no\ntrailing slash. The \u003Cstrong>Add tool\u003C\u002Fstrong> form in the portal shows the right value.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>OAuth &amp; Permissions → User Token Scopes:\u003C\u002Fstrong> add the scopes your tasks need (below). Bot scopes are not used.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Features → Agents &amp; AI Apps:\u003C\u002Fstrong> turn \u003Cstrong>Model Context Protocol\u003C\u002Fstrong> on. With it off, connecting still succeeds but\nevery call fails.\u003C\u002Fli>\n\u003Cli>Copy the \u003Cstrong>Client ID\u003C\u002Fstrong> and \u003Cstrong>Client Secret\u003C\u002Fstrong> from \u003Cstrong>Basic Information\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3 id=\"scopes\">Scopes\u003C\u002Fh3>\n\u003Cp>Grant only what your tasks need. The full set the MCP server understands is:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>search:read.public search:read.private search:read.mpim search:read.im search:read.files search:read.users files:read files:write emoji:read chat:write channels:history groups:history mpim:history im:history channels:read channels:write groups:read groups:write im:read im:write mpim:read mpim:write reactions:write canvases:read canvases:write users:read users:read.email lists:read lists:write\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>A task that posts needs at least \u003Ccode>chat:write\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3 id=\"giving-a-member-its-own-slack-account\">Giving a member its own Slack account\u003C\u002Fh3>\n\u003Cp>A member joins Slack the way a person would: a full member of the workspace, on a seat, signed up with its own\nZero Human address. Every Slack email for it (the invitation, confirmation codes) appears in the \u003Cstrong>Inbox\u003C\u002Fstrong> on its\nmember page in the portal.\u003C\u002Fp>\n\u003Cp>Work in a \u003Cstrong>separate browser profile or a private window\u003C\u002Fstrong>: your usual browser is signed in to Slack as you, and the\nconnection has to be authorised while Slack is signed in as the member.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Invite it.\u003C\u002Fstrong> As a Slack admin, in your usual browser: invite the member's email address as a \u003Cstrong>Member\u003C\u002Fstrong>, not a\nGuest. Copy the \u003Cstrong>Join now\u003C\u002Fstrong> link from the invitation in the member's Inbox.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Create the account.\u003C\u002Fstrong> In the separate profile, open the link, sign up with the member's address, and enter the\nconfirmation code from its Inbox. Set its full name and display name to the member's.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Set up the profile.\u003C\u002Fstrong> Upload the member's avatar and set its title to its role. Join the channels it will post\nin: it can only post where its account is a member.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Connect the binding.\u003C\u002Fstrong> Still in the separate profile, sign in to the portal as yourself. Both sign-ins must be\nin the \u003Cstrong>same window\u003C\u002Fstrong>, because Slack returns to the portal there at the end. On the member's page → \u003Cstrong>Tools\u003C\u002Fstrong>,\nremove any existing \u003Ccode>slack\u003C\u002Fcode> binding, then \u003Cstrong>Add tool\u003C\u002Fstrong>: type \u003Ccode>slack\u003C\u002Fcode>, URL \u003Ccode>https:\u002F\u002Fmcp.slack.com\u002Fmcp\u003C\u002Fcode>, auth\n\u003Cstrong>OAuth\u003C\u002Fstrong>, the app's Client ID and Client Secret, and the scopes. Choose \u003Cstrong>Connect with OAuth\u003C\u002Fstrong>, check that the\naccount shown on Slack's consent screen is the member's, not yours, and click \u003Cstrong>Allow\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Check it.\u003C\u002Fstrong> Run a task that posts to Slack as the member. The message should appear under the member's name and\navatar, and the run page links to it.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"troubleshooting\">Troubleshooting\u003C\u002Fh2>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>What you see\u003C\u002Fth>\n\u003Cth>Why\u003C\u002Fth>\n\u003Cth>What to do\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>A message appears as you\u003C\u002Ftd>\n\u003Ctd>The binding was authorised while Slack was signed in as you\u003C\u002Ftd>\n\u003Ctd>Remove the binding and connect it again in the separate profile, checking the account on the consent screen\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>The invitation or code never arrives\u003C\u002Ftd>\n\u003Ctd>The member's email address is wrong\u003C\u002Ftd>\n\u003Ctd>Check the email on the member page\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>channel_not_found\u003C\u002Fcode> or \u003Ccode>not_in_channel\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>The member's account is not in that channel\u003C\u002Ftd>\n\u003Ctd>Add it to the channel\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>Unauthorized\u003C\u002Fcode> when you return from Slack\u003C\u002Ftd>\n\u003Ctd>You clicked Connect in one browser and allowed it in another\u003C\u002Ftd>\n\u003Ctd>Do the whole connection in one window\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Calls fail with an auth error after working\u003C\u002Ftd>\n\u003Ctd>The token was revoked: the account was deactivated, the app uninstalled, or the account signed out everywhere\u003C\u002Ftd>\n\u003Ctd>Remove the binding and connect it again\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Connecting succeeds but every call fails\u003C\u002Ftd>\n\u003Ctd>Model Context Protocol is off on the Slack app\u003C\u002Ftd>\n\u003Ctd>Turn it on under \u003Cstrong>Features → Agents &amp; AI Apps\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n",[13,17,20,23,26,30,33,36],{"id":14,"text":15,"level":16,"planned":9},"what-a-member-can-do","What a member can do",2,{"id":18,"text":19,"level":16,"planned":9},"who-connects-it","Who connects it",{"id":21,"text":22,"level":16,"planned":9},"what-waits-for-you","What waits for you",{"id":24,"text":25,"level":16,"planned":9},"setup","Setup",{"id":27,"text":28,"level":29,"planned":9},"the-slack-app","The Slack app",3,{"id":31,"text":32,"level":29,"planned":9},"scopes","Scopes",{"id":34,"text":35,"level":29,"planned":9},"giving-a-member-its-own-slack-account","Giving a member its own Slack account",{"id":37,"text":38,"level":16,"planned":9},"troubleshooting","Troubleshooting",1791124519822]