> ## Documentation Index
> Fetch the complete documentation index at: https://learn.actionist.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Slack

> Connect your AI agents to Slack as a live bot, approve actions with one tap, and read or write Slack data from any workflow.

<div className="mxp-hero xc-border">
  <div className="exp-eyebrow mxp-rise">SLACK INTEGRATION</div>

  <h2 className="mxp-hero-title mxp-rise" style={{animationDelay:'0.06s'}}>
    Put your agents where your <span style={{background:'linear-gradient(90deg,#24A4FF,#9000FF,#E3008E)',WebkitBackgroundClip:'text',backgroundClip:'text',color:'transparent'}}>team already works.</span>
  </h2>

  <p className="mxp-hero-dek mxp-rise" style={{animationDelay:'0.13s'}}>
    Give an agent its own Slack bot and your team can send tasks, get answers, and tap Approve — without opening the desktop app. Or wire Slack as a live data source so agents read channels and post structured results into workflows.
  </p>
</div>

<div className="w-full py-10">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">See it in action</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">A Slack message, round-trip.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      From channel mention to agent processing to threaded reply — three stops, one seamless loop. Pick a stage:
    </p>
  </div>

  <div className="xasl-rt exp-tool-shell xc-try">
    <div className="mxp-srch-chips">
      <label htmlFor="xasl-ra"><input className="mxp-r" type="radio" name="xasl-r" id="xasl-ra" defaultChecked />1. Channel mention</label>
      <label htmlFor="xasl-rb"><input className="mxp-r" type="radio" name="xasl-r" id="xasl-rb" />2. Agent processes</label>
      <label htmlFor="xasl-rc"><input className="mxp-r" type="radio" name="xasl-r" id="xasl-rc" />3. Threaded reply</label>
    </div>

    {/* Panel A — the incoming mention */}

    <div className="xasl-rtp xasl-rtp-a">
      <div className="mxp-window">
        <div className="mxp-window-bar">
          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-title">#sales-ops</span>
        </div>

        <div className="mxp-window-body" style={{minHeight:'auto',padding:'16px 20px'}}>
          <div className="xasl-msg mxp-s1">
            <span className="xasl-msg-who">dana</span>
            <span className="xasl-msg-body">@sales can you pull the Q3 pipeline summary for Northwind?</span>
          </div>

          <div className="mxp-stream-event mxp-s2">message received · bot mention · routed to sales agent</div>
        </div>
      </div>

      <div className="mxs-match">The bot receives the message via <em>Socket Mode</em> — an outbound WebSocket from Actionist to Slack. No inbound port, no firewall rule, no public URL needed.</div>
    </div>

    {/* Panel B — agent processes */}

    <div className="xasl-rtp xasl-rtp-b">
      <div className="mxp-window">
        <div className="mxp-window-bar">
          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-title">agent · sales · processing</span>
        </div>

        <div className="mxp-window-body" style={{minHeight:'auto',padding:'16px 20px'}}>
          <div className="mxp-stream-event mxp-s1">tool · Search Memory · "northwind pipeline q3"</div>

          <div className="xasl-msg mxp-s2">
            <span className="xasl-msg-who">memory</span>
            <span className="xasl-msg-body">Northwind — enterprise tier, <em>renewal October</em>, champion Dana Voss. Last pipeline entry: <em>\$48k open</em>.</span>
          </div>

          <div className="mxp-stream-event mxp-s3">tool · slack\_post\_message · composing reply</div>
        </div>
      </div>

      <div className="mxs-match">The agent runs inside Actionist — it can call any tool it has access to: Memory search, CRM lookup, web browsing, or another MCP. The Slack message is just the trigger.</div>
    </div>

    {/* Panel C — threaded reply */}

    <div className="xasl-rtp xasl-rtp-c">
      <div className="mxp-window">
        <div className="mxp-window-bar">
          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-dot" />

          <span className="mxp-window-title">#sales-ops · thread</span>
        </div>

        <div className="mxp-window-body" style={{minHeight:'auto',padding:'16px 20px'}}>
          <div className="xasl-msg" style={{opacity:0.55}}>
            <span className="xasl-msg-who">dana</span>
            <span className="xasl-msg-body">@sales can you pull the Q3 pipeline summary for Northwind?</span>
          </div>

          <div className="xasl-thread">
            <div className="xasl-msg mxp-s1">
              <span className="xasl-msg-who">sales bot</span>
              <span className="xasl-msg-body"><em>Northwind Q3:</em> \$48k open, renewal in October. Champion Dana Voss. Last touch: demo follow-up sent June 4.</span>
            </div>

            <div className="xasl-msg mxp-s2" style={{marginTop:'6px'}}>
              <span className="xasl-msg-who">sales bot</span>
              <span className="xasl-msg-body">Want me to draft a check-in email to Dana? <span className="mxp-caret" /></span>
            </div>
          </div>
        </div>
      </div>

      <div className="mxs-match">The reply lands in the <em>thread</em> — keeping channels clean. If the agent needs sign-off on an action, it posts <em>Approve</em> and <em>Deny</em> buttons into the same thread.</div>
    </div>
  </div>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Two modes</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Know which one you need.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      Slack works with Actionist in two completely separate ways. Understand the difference before you set anything up.
    </p>
  </div>

  <div className="mxs-tiers" style={{gridTemplateColumns:'repeat(auto-fit,minmax(240px,1fr))'}}>
    <div className="mxs-tier" style={{borderTopColor:'#9000FF'}}>
      <strong>Channel (bot) mode</strong>
      <span className="tag">Agents → Channels tab</span>
      <p>The agent lives as a Slack bot. Your team sends it tasks, asks questions, and taps Approve/Deny buttons inline — all from Slack. Set up via <strong>Agents → select an agent → Channels tab</strong>.</p>
    </div>

    <div className="mxs-tier" style={{borderTopColor:'#24A4FF'}}>
      <strong>MCP tool mode</strong>
      <span className="tag">Apps → MCPs tab</span>
      <p>The agent reads and writes Slack as a data source. Send structured messages to channels, read thread history, search for users. Set up via <strong>Apps → MCPs tab</strong>, then install <code>slack-oauth</code>.</p>
    </div>
  </div>

  <Note>
    Most teams will want both. Channel mode handles conversation and approvals; MCP mode handles data actions inside workflows.
  </Note>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Channel (bot) mode</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Connect a Slack bot to an agent.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      Each agent can have its own dedicated bot, or multiple agents can share one Slack app and be routed by @mention. The wizard walks you through three steps.
    </p>
  </div>

  <Steps>
    <Step title="Create a Slack app">
      Go to `api.slack.com/apps`, create a new app, enable <strong>Socket Mode</strong>, and grant the bot these scopes: `chat:write`, `im:history`, `channels:history`, `groups:history`.

      Copy both tokens from the app settings — you will need them in the next step:

      * <strong>Bot token</strong> — starts with `xoxb-`
      * <strong>App-level token</strong> — starts with `xapp-`

      Then open <strong>Agents</strong> in the Actionist sidebar, select the agent you want on Slack, and click the <strong>Channels</strong> tab. Find the Slack card and click <strong>Configure</strong>.
    </Step>

    <Step title="Enter your tokens and set a mention name">
      Paste both tokens into the <strong>Bot token (xoxb-…)</strong> and <strong>App-level token (xapp-…)</strong> fields, or pick saved credentials from your vault — both must come from the same source (both pasted or both vault-picked; mixing the two is not allowed).

      In the <strong>Set a mention name (for shared channels)</strong> step, type a short identifier like `support` or `finance`. When multiple agents share one Slack app, users type `@support do something` to route to this agent. Leave blank if this agent has its own dedicated Slack app.

      Mention names are auto-lowercased and restricted to `[a-z0-9_-]`.
    </Step>

    <Step title="Validate the tokens">
      Click <strong>Connect</strong>. Actionist calls `auth.test` to verify the bot is reachable. On success the card shows <span className="xasl-connected-badge">Connected · token saved</span> and displays the workspace name. The bot auto-connects on every app launch, with up to 8 retry attempts.
    </Step>
  </Steps>

  {/* TODO(image): slack-channels-tab — IMAGE SPEC: Channels tab inside an agent detail view (Agents → select agent → Channels). Show the Slack card expanded with the 3-step wizard: Step 1 displays Bot token (xoxb-…) and App-level token (xapp-…) fields with values filled in; Step 2 shows the mention-name input with a short value such as 'support'. Dark background, vault-hint badge visible below the token fields. — replace this CSS mock with the real screenshot */}

  <div className="mxp-window" style={{fontSize:'13px',marginBottom:'16px'}}>
    <div className="mxp-window-bar">
      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="xasl-mock-tabrow">
        <span className="xasl-mock-tab">Overview</span>
        <span className="xasl-mock-tab xasl-mock-tab-active">Channels</span>
        <span className="xasl-mock-tab">Tools</span>
        <span className="xasl-mock-tab">Memory</span>
      </span>
    </div>

    <div className="mxp-window-body" style={{padding:'18px'}}>
      <div className="xasl-mock-card">
        <div className="xasl-mock-card-header">
          <div className="xasl-mock-slack-logo" aria-hidden="true" />

          <div>
            <div className="xasl-mock-card-title">Slack</div>
            <div className="xasl-mock-card-sub">Socket Mode bot</div>
          </div>
        </div>

        <div className="xasl-mock-step-row">
          <span className="xasl-mock-step-num xasl-mock-step-done">1</span>

          <div className="xasl-mock-step-body">
            <div className="xasl-mock-label">Bot token (xoxb-…)</div>
            <div className="xasl-mock-field"><span className="xasl-mock-field-val">xoxb-4812093847-8201938740-2f9c…</span></div>
            <div className="xasl-mock-label" style={{marginTop:'8px'}}>App-level token (xapp-…)</div>
            <div className="xasl-mock-field"><span className="xasl-mock-field-val">xapp-1-A082R…-12345…</span></div>
            <div className="xasl-mock-vault-hint">Vault-bound tokens resolve at gateway connect. Never stored locally.</div>
          </div>
        </div>

        <div className="xasl-mock-step-row">
          <span className="xasl-mock-step-num xasl-mock-step-active">2</span>

          <div className="xasl-mock-step-body">
            <div className="xasl-mock-label">Set a mention name (for shared channels)</div>
            <div className="xasl-mock-field xasl-mock-field-active"><span className="xasl-mock-field-val">support</span><span className="xasl-mock-cursor" /></div>
          </div>
        </div>

        <div className="xasl-mock-step-row" style={{opacity:0.4}}>
          <span className="xasl-mock-step-num">3</span>

          <div className="xasl-mock-step-body">
            <div className="xasl-mock-label">Validate tokens</div>
          </div>
        </div>

        <div style={{marginTop:'12px',display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:'12.5px',fontWeight:650,padding:'7px 20px',borderRadius:'8px',background:'linear-gradient(90deg,#9000FF,#C800B3)',color:'#fff',cursor:'default',letterSpacing:'0.02em',boxShadow:'0 4px 14px rgb(144 0 255 / 0.28)'}}>Connect</div>
      </div>
    </div>
  </div>

  {/* TODO(image): slack-bot-connected — IMAGE SPEC: The Slack card in its connected state. Shows the green 'Connected · token saved' label, the 'Connected to [workspace name]' banner beneath it, and the vault-hint chip reading 'Vault-bound tokens resolve at gateway connect. Never stored locally.' — replace this CSS mock with the real screenshot */}

  <div className="mxp-window" style={{fontSize:'13px',marginTop:'16px'}}>
    <div className="mxp-window-bar">
      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="xasl-mock-tabrow">
        <span className="xasl-mock-tab">Overview</span>
        <span className="xasl-mock-tab xasl-mock-tab-active">Channels</span>
        <span className="xasl-mock-tab">Tools</span>
        <span className="xasl-mock-tab">Memory</span>
      </span>
    </div>

    <div className="mxp-window-body" style={{padding:'18px'}}>
      <div className="xasl-mock-card">
        <div className="xasl-mock-card-header">
          <div className="xasl-mock-slack-logo" aria-hidden="true" />

          <div>
            <div className="xasl-mock-card-title">Slack</div>
            <div className="xasl-mock-card-sub">Socket Mode bot</div>
          </div>

          <span className="xasl-connected-badge" style={{marginLeft:'auto'}}>Connected · token saved</span>
        </div>

        <div style={{fontSize:'12px',padding:'9px 12px',borderRadius:'8px',background:'rgb(72 198 90 / 0.07)',border:'1px solid rgb(72 198 90 / 0.22)',color:'#2a9b40',marginTop:'4px'}}>
          Connected to <strong>Acme Corp</strong> · acme.slack.com
        </div>

        <div className="xasl-mock-vault-hint" style={{marginTop:'10px'}}>Vault-bound tokens resolve at gateway connect. Never stored locally.</div>
      </div>
    </div>
  </div>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Multi-agent pattern</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">One Slack workspace, multiple agents.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      Create a single Slack app and share its tokens across all your agents. Give each agent a unique mention name. Your team routes to the right specialist with a single @mention.
    </p>
  </div>

  <div className="xasl-routing-diagram">
    <div className="xasl-rd-source">
      <div className="xasl-rd-icon xasl-rd-icon-slack" aria-hidden="true" />

      <div className="xasl-rd-label">Slack workspace</div>
      <div className="xasl-rd-sub">one shared app</div>
    </div>

    <div className="xasl-rd-arrows">
      <div className="xasl-rd-arrow">
        <span className="xasl-rd-arrow-line" />

        <span className="xasl-rd-arrow-chip">@sales do X</span>
      </div>

      <div className="xasl-rd-arrow">
        <span className="xasl-rd-arrow-line" />

        <span className="xasl-rd-arrow-chip">@finance do Y</span>
      </div>

      <div className="xasl-rd-arrow xasl-rd-arrow-dm">
        <span className="xasl-rd-arrow-line xasl-rd-arrow-line-dm" />

        <span className="xasl-rd-arrow-chip xasl-rd-arrow-chip-dm">DM (no mention needed)</span>
      </div>
    </div>

    <div className="xasl-rd-targets">
      <div className="xasl-rd-target">
        <div className="xasl-rd-target-dot" style={{background:'#9000FF'}} />

        <span>Sales agent</span>
      </div>

      <div className="xasl-rd-target">
        <div className="xasl-rd-target-dot" style={{background:'#24A4FF'}} />

        <span>Finance agent</span>
      </div>

      <div className="xasl-rd-target xasl-rd-target-dm">
        <div className="xasl-rd-target-dot" style={{background:'#00DBFF'}} />

        <span>Any agent (DM routing)</span>
      </div>
    </div>
  </div>

  <Info>
    DMs always route to the agent without requiring a mention name. In shared channels, the user must type `@mention-name do something`. Messages in a channel that don't include an @mention are silently dropped — the bot does not reply.
  </Info>

  <Warning>
    Each agent's mention name must be unique across agents sharing the same Slack app. Duplicate mention names will fail validation at save.
  </Warning>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Approvals</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Approve or deny without leaving Slack.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      When an agent hits a step that needs your sign-off, it posts Approve and Deny buttons directly into the Slack thread using Slack Block Kit. One tap resolves the approval — no need to open the Actionist desktop app.
    </p>
  </div>

  <div className="mxp-window" style={{marginBottom:'20px'}}>
    <div className="mxp-window-bar">
      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="mxp-window-title">#finance · thread</span>
    </div>

    <div className="mxp-window-body" style={{minHeight:'auto',padding:'16px 20px'}}>
      <div className="xasl-msg">
        <span className="xasl-msg-who">jordan</span>
        <span className="xasl-msg-body">@finance send the Q3 invoice to [acme@example.com](mailto:acme@example.com)</span>
      </div>

      <div className="xasl-thread">
        <div className="xasl-msg mxp-s1">
          <span className="xasl-msg-who">finance bot</span>
          <span className="xasl-msg-body">Ready to send invoice <em>#INV-2041</em> (\$12,400) to <em>[acme@example.com](mailto:acme@example.com)</em>. Confirm?</span>
        </div>

        <div className="xasl-btns mxp-s2">
          <span className="xasl-btn-approve">Approve</span>
          <span className="xasl-btn-deny">Deny</span>
        </div>
      </div>
    </div>
  </div>

  <Check>
    Inline approval buttons work from any device where you have Slack — including mobile.
  </Check>

  {/* TODO(image): slack-approval-buttons — IMAGE SPEC: A Slack message thread showing the Actionist bot posting an approval request. The message contains a short description of the action requiring approval (for example 'Send this email to alex@example.com?') followed by two Slack Block Kit buttons: 'Approve' (green) and 'Deny' (red). Show the thread context with one or two prior messages from the agent above. — replace this CSS mock with the real screenshot */}

  <div className="mxp-window" style={{fontSize:'13px',marginTop:'4px'}}>
    <div className="mxp-window-bar">
      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span className="mxp-window-dot" />

      <span style={{fontSize:'11.5px',fontWeight:600,opacity:0.5,marginLeft:'8px'}}>#finance · thread</span>
    </div>

    <div className="mxp-window-body" style={{padding:'14px 18px'}}>
      <div className="xasl-msg" style={{opacity:0.5}}>
        <span className="xasl-msg-who">jordan</span>
        <span className="xasl-msg-body">@finance draft a payment confirmation for [acme@example.com](mailto:acme@example.com)</span>
      </div>

      <div className="xasl-thread">
        <div className="xasl-msg mxp-s1">
          <span className="xasl-msg-who">finance bot</span>
          <span className="xasl-msg-body">Drafted confirmation email for <em>[acme@example.com](mailto:acme@example.com)</em>. Subject: Payment received — Invoice #INV-2041.</span>
        </div>

        <div className="xasl-msg mxp-s2" style={{marginTop:'4px'}}>
          <span className="xasl-msg-who">finance bot</span>
          <span className="xasl-msg-body">Send this email to <em>[acme@example.com](mailto:acme@example.com)</em>?</span>
        </div>

        <div className="mxp-s3" style={{display:'flex',gap:'8px',marginTop:'10px'}}>
          <span style={{padding:'6px 20px',borderRadius:'4px',fontSize:'13px',fontWeight:600,cursor:'default',background:'#007a5a',color:'#fff'}}>Approve</span>
          <span style={{padding:'6px 20px',borderRadius:'4px',fontSize:'13px',fontWeight:600,cursor:'default',background:'rgb(239 68 68 / 0.12)',color:'#EF4444',border:'1px solid rgb(239 68 68 / 0.35)'}}>Deny</span>
        </div>
      </div>
    </div>
  </div>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">MCP tool mode</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Use Slack as a data source in workflows.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      Install the bundled <code>slack-oauth</code> MCP server and any agent can send messages to channels, read thread history, and search for users — making Slack a live input and output for scheduled workflows.
    </p>
  </div>

  <Steps>
    <Step title="Open the MCP catalog">
      In the Actionist sidebar, click <strong>Apps</strong>, then select the <strong>MCPs</strong> tab. Search for "Slack" and find the <code>slack-oauth</code> entry.
    </Step>

    <Step title="Authenticate via OAuth">
      Click <strong>Install</strong>. Actionist opens a browser OAuth window to Slack. Authorize the requested scopes: `channels:read`, `channels:history`, `chat:write`, `users:read`, `files:read`, `groups:read`, `im:read`, `mpim:read`.
    </Step>

    <Step title="Use Slack tools in your agents">
      Once connected, agents can call Slack actions such as sending messages, reading channel history, and looking up users — as steps in any workflow.
    </Step>
  </Steps>

  <Info>
    The Slack MCP server connects over HTTP/SSE to `https://mcp.slack.com/mcp`. No additional local server setup is required.
  </Info>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Best practices</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Tips before you go live.</h2>
  </div>

  <AccordionGroup>
    <Accordion title="Use vault credentials, not pasted tokens" icon="lock" defaultOpen={true}>
      Select tokens from the credential picker rather than pasting them directly. Vault-bound tokens are resolved server-side at connect time and never written to local storage. If a token is ever compromised, you can rotate it from the Credentials Vault without re-editing every agent that uses it.
    </Accordion>

    <Accordion title="Both tokens must come from the same source" icon="link">
      You cannot paste the bot token and vault-pick the app-level token — both must be pasted together or both vault-picked. Mixed mode is rejected with an error: "Both the bot token and the app-level token are required — paste both, or pick saved credentials for both."
    </Accordion>

    <Accordion title="Socket Mode means no firewall rules needed" icon="shield-check">
      Slack's Socket Mode uses an outbound WebSocket, not an inbound HTTPS endpoint. No port forwarding, no public URL, and no firewall rule changes are required. It works behind corporate firewalls.
    </Accordion>

    <Accordion title="Keep mention names short and unique" icon="at-sign">
      Mention names are auto-lowercased to `[a-z0-9_-]` characters. Two agents sharing the same Slack app cannot have the same mention name — saving will fail with a validation error. Use short, role-specific names (`sales`, `finance`, `support`).
    </Accordion>

    <Accordion title="Marketplace publishing strips Slack tokens" icon="package">
      When you publish an agent to the Actionist marketplace, both Slack tokens are automatically stripped. Subscribers who install the agent must add their own Slack app credentials. This applies to both the bot token and the app-level token.
    </Accordion>

    <Accordion title="VPS agents: check runtime status first" icon="server">
      For agents running on a Paired VPS, the Connect button is disabled until the VPS is online. If you see "Saved — connecting on your VPS…", the connection is queued and will complete once the runtime heartbeat is detected. Check the Cloud tab if the VPS appears offline.
    </Accordion>
  </AccordionGroup>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Limits</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Limits and gotchas.</h2>
  </div>

  <div className="mxs-limits" style={{gridTemplateColumns:'repeat(auto-fit,minmax(175px,1fr))'}}>
    <div className="mxs-limit"><b>10,000</b><span>character cap on text file attachments (.txt, .md, .csv, .json, etc.)</span></div>
    <div className="mxs-limit"><b>5 MB</b><span>max image attachment size; first photo only, passed as base64</span></div>
    <div className="mxs-limit"><b>5 min</b><span>message deduplication window; map capped at 1,000 entries</span></div>
    <div className="mxs-limit"><b>24 chars</b><span>max suggestion pill text; tokens expire after 1 hour</span></div>
    <div className="mxs-limit"><b>8</b><span>bot startup retry attempts with a 1.5-second delay between each</span></div>
    <div className="mxs-limit"><b>\[a-z0-9\_-]</b><span>mention name charset, auto-lowercased</span></div>
  </div>

  <Warning>
    Slack reaction emoji calls from the agent are currently no-ops. The agent cannot add or remove reactions on Slack messages.
  </Warning>

  <Warning>
    Bare channel messages (no @mention) are silently dropped — the bot does not reply. Channel management in the web app returns "Unavailable" for locally-hosted agents; manage from the desktop app.
  </Warning>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Recipes</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Three automations worth stealing.</h2>

    <p className="text-base text-gray-600 dark:text-gray-400 max-w-3xl">
      Copy any of these into your own agent. Each one runs entirely through the Slack bot — no desktop app open required.
    </p>
  </div>

  <div className="xc-recipes">
    <div className="xc-recipe">
      <div className="xc-recipe-who">
        <i style={{background:'linear-gradient(135deg,#7C5BFF,#E3008E)'}} />

        Maya · Marketing Manager
      </div>

      <p className="xc-recipe-flow">
        Every weekday at <em>08:30</em>, the agent reads the last 24 hours of <em>#marketing</em> and <em>#launches</em>, surfaces the top 3 threads that need a reply, and posts a tidy digest into <em>#team-digest</em> — tagged by urgency. The whole channel sees it before standup; Maya skips 20 minutes of scroll.
      </p>

      <span className="xc-recipe-save">saves \~20 min/day</span>
    </div>

    <div className="xc-recipe">
      <div className="xc-recipe-who">
        <i style={{background:'linear-gradient(135deg,#486EFF,#9000FF)'}} />

        Sam · Solo founder
      </div>

      <p className="xc-recipe-flow">
        When a pull-request sits in <em>#eng-prs</em> for more than <em>4 hours</em> with no reviewer reaction, the agent DMs the on-call reviewer with a direct link and a one-line summary of the diff. If it hits <em>8 hours</em>, it nudges a second reviewer. Typical PRs go from open to reviewed same day — no nag messages written by hand.
      </p>

      <span className="xc-recipe-save">saves \~3 hrs/wk</span>
    </div>

    <div className="xc-recipe">
      <div className="xc-recipe-who">
        <i style={{background:'linear-gradient(135deg,#4ED8A7,#24A4FF)'}} />

        Priya · Support lead
      </div>

      <p className="xc-recipe-flow">
        Customers post in <em>#support</em>. The agent reads each new thread, checks the knowledge base for a matching answer, and either replies directly with a resolution or labels the thread <em>NEEDS-HUMAN</em> and pings the on-call rep. Roughly <em>6 in 10</em> threads resolve without a human reply. Priya reviews the queue in one pass instead of monitoring the channel all day.
      </p>

      <span className="xc-recipe-save">saves \~1.5 hrs/day</span>
    </div>
  </div>
</div>

<div className="w-full py-10 xc-rise">
  <div className="actionist-cta-panel xc-border">
    <div className="relative z-10 flex flex-col items-center gap-5 max-w-2xl mx-auto">
      <span className="actionist-eyebrow">One bot, every team member</span>

      <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-white leading-tight">
        Your agents, where your team lives.
      </h2>

      <p className="text-base md:text-lg text-white/85">
        Connect once. Your whole team can message, task, and approve — without leaving Slack, without opening the desktop app.
      </p>

      <div className="flex flex-wrap items-center justify-center gap-3 pt-2">
        <a className="actionist-cta-btn-primary" href="https://app.actionist.ai" target="_blank" rel="noreferrer">
          Open the Dashboard

          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M5 12h14" />

            <path d="m12 5 7 7-7 7" />
          </svg>
        </a>

        <a className="actionist-cta-btn-secondary" href="mailto:support@actionist.ai">
          Email the team
        </a>
      </div>
    </div>
  </div>
</div>

<div className="w-full pt-2 pb-6">
  <p className="actionist-trust-line">
    Tokens stored in the encrypted Credentials Vault — never in local storage.<br />
    Socket Mode · Block Kit approvals · MCP data actions.
  </p>
</div>

<div className="w-full pb-16">
  <div className="actionist-tight flex flex-col gap-2 mb-6">
    <span className="actionist-section-eyebrow">Keep going</span>
    <h2 className="text-2xl md:text-3xl font-semibold tracking-tight text-gray-900 dark:text-gray-50">Related topics.</h2>
  </div>

  <Columns cols={4}>
    <Card title="Channels" icon="messages-square" href="/Folders/channels">
      The full Channels surface — Telegram, Slack, and how both fit into the agent model.
    </Card>

    <Card title="MCP" icon="plug" href="/Folders/mcp">
      How to install and configure MCP servers, including the Slack MCP OAuth flow.
    </Card>

    <Card title="Credentials" icon="key" href="/Folders/credentials">
      The encrypted Credentials Vault — store and rotate Slack tokens without touching agent config.
    </Card>

    <Card title="Cloud" icon="cloud" href="/Folders/cloud">
      Run Slack bots 24/7 on a Paired VPS so they stay online when your laptop is closed.
    </Card>
  </Columns>
</div>
