# MCPify Slack (`inovaflow/mcpify-slack`) Actor

Turn your Slack into an MCP client for your Apify tools and any MCP server. DM or @mention the bot — it runs your own tools and replies in-thread.

- **URL**: https://apify.com/inovaflow/mcpify-slack.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Agents, MCP servers, AI
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / actor start

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## MCPify Slack

**Talk to your own Apify tools — and any MCP server — right inside Slack. DM the bot or @mention it in plain English, and it runs *your* tools and answers in the thread.**

If your team already lives in Slack, you've probably wished you could just *ask* for things — "pull the latest leads," "scrape this page," "check that listing" — without leaving the chat to go run a tool somewhere else. MCPify does exactly that. It connects your MCP connectors (the Apify MCP server and any others you've saved) to Slack, so the bot can use your real tools to answer.

Here's the part that's usually painful: to do this yourself, every team would have to **build and maintain its own Slack app** and wire up the gateway and backend that sit between Slack and your tools. We did that once. **MCPify is one shared Slack app** — the gateway and backend are already built and hosted by us — so your workspace just installs it in a single click, and the rest is handled. You don't touch Slack app config, OAuth, or event plumbing at all.

### Who it's for

- **Teams on Apify** who want to trigger their Actors and MCP tools by chatting, not clicking.
- **Anyone who lives in Slack** and would rather DM a bot than open another tab.
- **Privacy-minded teams** who want the AI to run on *their* account with *their* keys — never a shared, multi-tenant toolbox.

### How it works

There are three pieces, and only the middle one is shared:

1. **The MCPify Slack app** — one app you add to your workspace. It receives your Slack messages and posts the replies.
2. **Our control plane** (hosted by us at `mcpify.inovaflow.app`) — the small service in the middle. It handles the one-click install, remembers which workspace is paired to which Actor, and routes messages.
3. **This Actor** — your own copy, running on *your* Apify account. It does the real work: it connects your MCP tools and runs the Claude tool-use loop to produce the reply.

What actually flows between them: when you **@mention the bot in a channel or DM it**, that Slack message goes to the MCPify app → to our control plane → forwarded to **your** Actor. Your Actor runs your tools, produces the reply text, and sends it back the same way; we post it into Slack. That's the whole loop.

#### Security & privacy

- **We don't store your messages.** Your Slack messages, the surrounding thread, and the bot's replies are never written to our database or disk. For each message we read the thread live from Slack, pass it through in memory to your Actor, post the reply, and discard it.
- **Your tools and AI key never leave your account.** Your MCP connectors and your Anthropic key live only in this Actor, on your Apify account — they're never shared with us or anyone else.
- **What we keep is the minimum to run the app, encrypted.** Just two records on our control plane: your install (team ID/name + Slack bot token) and your pairing (your Actor's address + a scoped Apify token to wake it). Both are encrypted at rest (AES-256-GCM); the Slack token is used only to read those messages and post replies.

### How to set up

📹 **Prefer to watch?** [Step-by-step setup video](https://www.veed.io/view/855d9879-f76d-4f7f-bfb4-0a8d39d8000d?source=editor&panel=share)

You'll need a free Apify account and the MCPify app in your Slack. Four steps.

1. **Add the MCPify app to your Slack workspace.** Click **Add to Slack** at **https://mcpify.inovaflow.app/slack/install** — that works for any workspace, with no Slack Marketplace listing needed. It runs the standard Slack OAuth flow and adds the bot to your workspace.
   - Once you authorize, your **setup code** (looks like `MCP-XXXX-XXXX-XXXX`) is shown right there — keep it private, since anyone who has it before your instance registers could pair their own. If you missed it, run `/mcpify pair` in Slack to see the same code again.
2. **Open this Actor on Apify and create a *Task*.** (Create a Task — don't just hit "Start" on the bare Actor; only a Task's saved input reaches the Standby run.) In the Task input: paste the **setup code**, add an **Apify API token**, and pick your **MCP connector(s)** (and a model; optionally your own Anthropic key).
3. **Turn on *Standby* for the Task and Start it — once.** That one Start **registers** the Task with MCPify. After that you don't keep a run alive: even if the run stops, **Standby keeps serving as long as the Task stays saved** — the platform wakes it on demand when a message arrives.
4. **@mention the bot in a channel, or DM it.** It uses your tools and replies in the thread.

### Input

| Field | What it is |
| --- | --- |
| **Slack setup code** | The `MCP-XXXX-XXXX-XXXX` code from `/mcpify pair`. Links this Actor to your workspace — first run only. Keep it private. |
| **Apify token** | Lets MCPify **wake this Actor** when you message the bot (see the FAQ — this is *not* your connectors' token). A standard Apify API token works; if you scope it down, make sure it can still start this Actor. Stored encrypted. |
| **MCP connectors** | Your saved MCP connectors (**Console → Settings → API & Integrations → MCP Connectors**), e.g. the Apify one at `https://mcp.apify.com`. Pick several and MCPify merges their tools. At least one required. |
| **Model** | Haiku (fast & cheap, default) or Sonnet (smartest for complex, multi-step tasks). |
| **Anthropic API key (BYOK)** *(optional)* | Leave blank to use MCPify's shared key (metered by token — see **Costs**; paid Apify plans only). Or bring your own key, and the AI is free. |

### Conversation memory

The bot remembers the conversation. On each message, MCPify reads the surrounding Slack thread (or recent DM history) and gives it to this Actor as context, so you can say "now book the second one" or "do that again for next week" and it knows what you mean.

- **Nothing is stored.** That thread is read live from Slack each time and passed through in memory — MCPify keeps no copy of your messages or the replies (see **Security & privacy** above).
- **Security:** only **your own messages** and **the bot's own replies** are used as memory. Other people's messages — and anything posted by other apps in the same thread — are dropped, so nobody can slip instructions into a bot that's holding your connectors.
- DMs work out of the box; for channel memory the bot just needs to be in the channel (it is — that's how you @mention it).

### Slack commands

- `/mcpify pair` — get your private setup code + the activation steps.
- `/mcpify status` — check whether your instance is connected.
- `/mcpify unpair` — disconnect this workspace (installer only; also rotates the setup code, then points you back to `/mcpify pair` to reconnect).
- `/mcpify help` — list the commands.

### Costs

MCPify runs entirely on YOUR Apify account, so the bill is yours and fully transparent. You pay only for what you use:

| Charge | When | Price |
| --- | --- | --- |
| **Standby compute** | Keeps the bot reachable; scales to zero when idle | Apify's usual compute rate |
| **Tool runs** | Any Apify Actor your tools trigger | bills to your account as usual |
| **Actor start** | Each time the bot wakes from idle — about once per run, *not* per message | **$0.05** |
| **AI tokens** (shared key) | Per reply, by model — Haiku **$1 / $5** per 1M tokens (in / out), Sonnet **$3 / $15** | metered per use |

The token charges are Anthropic's standard per-million-token rates, passed through at essentially zero margin — Haiku is cheap (a typical question is a cent or two; Sonnet costs more). **Bring your own Anthropic key (BYOK)** and the AI tokens drop to **zero** — you pay Anthropic directly; only the start fee and compute/tool runs remain.

> **Tip:** set a **Maximum charge per run** to cap spend — when it's hit, the bot asks you to raise it or switch to your own key.

### FAQ

**Why does it need an Apify token?** Only so MCPify can **wake and reach this Actor** when you message the bot (Apify's Standby gate needs an authorized caller). It is **not** used for your MCP connectors — those run on the token Apify injects into every run for free. Think of the pasted token as the "wake my Actor" key. It's stored encrypted.

**Why create a Task instead of just running the Actor?** A bare Actor's Standby runs receive no input, so it couldn't know your setup code or connectors. A **Task** saves your input and hands it to the Standby run — that's the supported way to run a configured Standby Actor.

**Do I have to keep a run going?** No. You Start the Task once to register it; after that, Standby serves on demand as long as the Task stays saved. The platform wakes it when a message arrives and lets it sleep when idle.

**Is the first reply slow?** If the Actor has scaled to zero, the first message wakes it and takes a few seconds (~6s) while it boots; after that, replies are instant. MCPify waits for the boot to finish rather than failing the first ping.

### Notes

- This Actor runs in **Standby mode** (default). It exposes no public API of its own — it only accepts events signed by the MCPify app.
- It never sees your Slack token. It returns reply text; the MCPify app posts to Slack.
- It runs on **your** Apify account with **your** credentials — your data stays yours.

# Actor input Schema

## `setupCode` (type: `string`):

Required. The code from `/mcpify pair` in Slack (looks like MCP-XXXX-XXXX-XXXX). It links this Actor to your workspace. Keep it private.
## `scopedApifyToken` (type: `string`):

Required. Lets MCPify wake this Standby Actor on your account when you message the bot. It must be allowed to START this Actor.
## `mcpConnectors` (type: `array`):

The MCP connector(s) whose tools the bot can use. With none connected, the bot just chats with the AI. Authorize them first in Console → Settings → MCP Connectors.
## `model` (type: `string`):

Which Claude model replies. Haiku is fast and cheap (default); Sonnet is smarter but pricier.
## `anthropicApiKey` (type: `string`):

Optional. Your own Anthropic key runs the AI on your account with no per-message charge. Leave blank to use MCPify's shared key (paid Apify plans only).
## `maxToolIterations` (type: `integer`):

How many tool rounds the bot may take per message. Default 12; raise it if multi-step tasks get cut off.
## `maxOutputTokens` (type: `integer`):

Longest a single reply can be, in tokens. Default 2048.
## `historyWindow` (type: `integer`):

How many recent thread messages the bot keeps as context. Default 24.

## Actor input object example

```json
{
  "model": "claude-haiku-4-5-20251001",
  "maxToolIterations": 12,
  "maxOutputTokens": 2048,
  "historyWindow": 24
}
````

# Actor output Schema

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "model": "claude-haiku-4-5-20251001"
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/mcpify-slack").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "model": "claude-haiku-4-5-20251001" }

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/mcpify-slack").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "model": "claude-haiku-4-5-20251001"
}' |
apify call inovaflow/mcpify-slack --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=inovaflow/mcpify-slack",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "MCPify Slack",
        "description": "Turn your Slack into an MCP client for your Apify tools and any MCP server. DM or @mention the bot — it runs your own tools and replies in-thread.",
        "version": "0.1",
        "x-build-id": "kgm76gBFVAaYrz6h1"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/inovaflow~mcpify-slack/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-inovaflow-mcpify-slack",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/inovaflow~mcpify-slack/runs": {
            "post": {
                "operationId": "runs-sync-inovaflow-mcpify-slack",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/inovaflow~mcpify-slack/run-sync": {
            "post": {
                "operationId": "run-sync-inovaflow-mcpify-slack",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "setupCode",
                    "scopedApifyToken"
                ],
                "properties": {
                    "setupCode": {
                        "title": "Slack setup code",
                        "type": "string",
                        "description": "Required. The code from `/mcpify pair` in Slack (looks like MCP-XXXX-XXXX-XXXX). It links this Actor to your workspace. Keep it private."
                    },
                    "scopedApifyToken": {
                        "title": "Apify token",
                        "type": "string",
                        "description": "Required. Lets MCPify wake this Standby Actor on your account when you message the bot. It must be allowed to START this Actor."
                    },
                    "mcpConnectors": {
                        "title": "MCP connectors",
                        "type": "array",
                        "description": "The MCP connector(s) whose tools the bot can use. With none connected, the bot just chats with the AI. Authorize them first in Console → Settings → MCP Connectors."
                    },
                    "model": {
                        "title": "Model",
                        "enum": [
                            "claude-haiku-4-5-20251001",
                            "claude-sonnet-4-6"
                        ],
                        "type": "string",
                        "description": "Which Claude model replies. Haiku is fast and cheap (default); Sonnet is smarter but pricier.",
                        "default": "claude-haiku-4-5-20251001"
                    },
                    "anthropicApiKey": {
                        "title": "Anthropic API key (BYOK)",
                        "type": "string",
                        "description": "Optional. Your own Anthropic key runs the AI on your account with no per-message charge. Leave blank to use MCPify's shared key (paid Apify plans only)."
                    },
                    "maxToolIterations": {
                        "title": "Max tool rounds per reply",
                        "minimum": 1,
                        "maximum": 25,
                        "type": "integer",
                        "description": "How many tool rounds the bot may take per message. Default 12; raise it if multi-step tasks get cut off.",
                        "default": 12
                    },
                    "maxOutputTokens": {
                        "title": "Max reply length (tokens)",
                        "minimum": 256,
                        "maximum": 8192,
                        "type": "integer",
                        "description": "Longest a single reply can be, in tokens. Default 2048.",
                        "default": 2048
                    },
                    "historyWindow": {
                        "title": "Conversation memory (messages)",
                        "minimum": 4,
                        "maximum": 60,
                        "type": "integer",
                        "description": "How many recent thread messages the bot keeps as context. Default 24.",
                        "default": 24
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
