Building a Slack Integration MCP Tool
Let AI agents interact with Slack — send messages, create channels, search conversations. Full walkthrough.
What You'll Build
send_message — send a message to a channel or user
list_channels — list all channels the bot can see
search_messages — search conversation history
create_channel — create a new channel
Step 1: Setup Slack App
- Go to https://api.slack.com/apps
- Create a new app → "From scratch"
- Name it (e.g., "MCP Slack Bot")
- Under OAuth & Permissions, add scopes:
chat:write — send messages
channels:read — list channels
channels:history — search messages
channels:manage — create channels
search:read — search messages
- Install to workspace → copy the Bot User OAuth Token (starts with
xoxb-)
Step 2: Initialize
<span class="hljs-built_in">mkdir</span> slack-mcp && <span class="hljs-built_in">cd</span> slack-mcp
npm init -y
npm install @modelcontextprotocol/sdk @slack/web-api
Step 3: Build the Server
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Server</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/index.js"</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">StdioServerTransport</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/stdio.js"</span>;
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">WebClient</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@slack/web-api"</span>;
<span class="hljs-keyword">const</span> <span class="hljs-variable constant_">TOKEN</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">SLACK_BOT_TOKEN</span>;
<span class="hljs-keyword">if</span> (!<span class="hljs-variable constant_">TOKEN</span>) {
<span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">"SLACK_BOT_TOKEN is required"</span>);
process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>);
}
<span class="hljs-keyword">const</span> slack = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebClient</span>(<span class="hljs-variable constant_">TOKEN</span>);
<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Server</span>({
<span class="hljs-attr">name</span>: <span class="hljs-string">"slack-mcp"</span>,
<span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span>,
}, { <span class="hljs-attr">capabilities</span>: { <span class="hljs-attr">tools</span>: {} } });
server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/list"</span>, <span class="hljs-title function_">async</span> () => ({
<span class="hljs-attr">tools</span>: [
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"send_message"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Send a message to a Slack channel or user"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">channel</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Channel name (e.g., '#general') or channel ID"</span>
},
<span class="hljs-attr">text</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Message text (supports Slack mrkdwn)"</span>
}
},
<span class="hljs-attr">required</span>: [<span class="hljs-string">"channel"</span>, <span class="hljs-string">"text"</span>]
}
},
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"list_channels"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"List all public channels in the workspace"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">include_archived</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"boolean"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Include archived channels (default: false)"</span>
}
}
}
},
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"search_messages"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Search for messages matching a query"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">query</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Search query"</span>
},
<span class="hljs-attr">channel</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Limit search to a specific channel"</span>
},
<span class="hljs-attr">count</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"number"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Number of results (default: 10, max: 50)"</span>
}
},
<span class="hljs-attr">required</span>: [<span class="hljs-string">"query"</span>]
}
},
{
<span class="hljs-attr">name</span>: <span class="hljs-string">"create_channel"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Create a new public channel"</span>,
<span class="hljs-attr">inputSchema</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>,
<span class="hljs-attr">properties</span>: {
<span class="hljs-attr">name</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Channel name (lowercase, no spaces, max 80 chars)"</span>
},
<span class="hljs-attr">is_private</span>: {
<span class="hljs-attr">type</span>: <span class="hljs-string">"boolean"</span>,
<span class="hljs-attr">description</span>: <span class="hljs-string">"Create a private channel (default: false)"</span>
}
},
<span class="hljs-attr">required</span>: [<span class="hljs-string">"name"</span>]
}
}
]
}));
server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/call"</span>, <span class="hljs-title function_">async</span> (request) => {
<span class="hljs-keyword">const</span> { name, <span class="hljs-attr">arguments</span>: args } = request.<span class="hljs-property">params</span>;
<span class="hljs-keyword">try</span> {
<span class="hljs-keyword">switch</span> (name) {
<span class="hljs-keyword">case</span> <span class="hljs-string">"send_message"</span>: {
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">chat</span>.<span class="hljs-title function_">postMessage</span>({
<span class="hljs-attr">channel</span>: args.<span class="hljs-property">channel</span>,
<span class="hljs-attr">text</span>: args.<span class="hljs-property">text</span>
});
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`✅ Message sent to <span class="hljs-subst">${args.channel}</span> (<span class="hljs-subst">${result.ts}</span>)`</span>
}]
};
}
<span class="hljs-keyword">case</span> <span class="hljs-string">"list_channels"</span>: {
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">conversations</span>.<span class="hljs-title function_">list</span>({
<span class="hljs-attr">exclude_archived</span>: !args.<span class="hljs-property">include_archived</span>,
<span class="hljs-attr">types</span>: <span class="hljs-string">"public_channel"</span>
});
<span class="hljs-keyword">const</span> channels = result.<span class="hljs-property">channels</span>
.<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">c</span> =></span> <span class="hljs-string">` #<span class="hljs-subst">${c.name}</span> <span class="hljs-subst">${c.is_archived ? <span class="hljs-string">"(archived)"</span> : <span class="hljs-string">""</span>}</span>`</span>)
.<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>);
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`📋 Channels (<span class="hljs-subst">${result.channels.length}</span>):
<span class="hljs-subst">${channels}</span>`</span>
}]
};
}
<span class="hljs-keyword">case</span> <span class="hljs-string">"search_messages"</span>: {
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">search</span>.<span class="hljs-title function_">messages</span>({
<span class="hljs-attr">query</span>: args.<span class="hljs-property">query</span>,
<span class="hljs-attr">count</span>: <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">min</span>(args.<span class="hljs-property">count</span> || <span class="hljs-number">10</span>, <span class="hljs-number">50</span>)
});
<span class="hljs-keyword">const</span> messages = result.<span class="hljs-property">messages</span>.<span class="hljs-property">matches</span>
.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, args.<span class="hljs-property">count</span> || <span class="hljs-number">10</span>)
.<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">m, i</span>) =></span>
<span class="hljs-string">`<span class="hljs-subst">${i + <span class="hljs-number">1</span>}</span>. [<span class="hljs-subst">${m.channel.name}</span>] <span class="hljs-subst">${m.username}</span>: <span class="hljs-subst">${m.text.slice(<span class="hljs-number">0</span>, <span class="hljs-number">100</span>)}</span>`</span>
).<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>);
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`🔍 Results for "<span class="hljs-subst">${args.query}</span>":
<span class="hljs-subst">${messages || <span class="hljs-string">"No messages found."</span>}</span>`</span>
}]
};
}
<span class="hljs-keyword">case</span> <span class="hljs-string">"create_channel"</span>: {
<span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">conversations</span>.<span class="hljs-title function_">create</span>({
<span class="hljs-attr">name</span>: args.<span class="hljs-property">name</span>.<span class="hljs-title function_">toLowerCase</span>().<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[^a-z0-9-_]/g</span>, <span class="hljs-string">""</span>).<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, <span class="hljs-number">80</span>),
<span class="hljs-attr">is_private</span>: args.<span class="hljs-property">is_private</span> || <span class="hljs-literal">false</span>
});
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`✅ Channel #<span class="hljs-subst">${result.channel.name}</span> created!`</span>
}]
};
}
<span class="hljs-attr">default</span>:
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Unknown tool: <span class="hljs-subst">${name}</span>`</span> }],
<span class="hljs-attr">isError</span>: <span class="hljs-literal">true</span>
};
}
} <span class="hljs-keyword">catch</span> (err) {
<span class="hljs-keyword">return</span> {
<span class="hljs-attr">content</span>: [{
<span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>,
<span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Slack error: <span class="hljs-subst">${err.message}</span>`</span>
}],
<span class="hljs-attr">isError</span>: <span class="hljs-literal">true</span>
};
}
});
<span class="hljs-keyword">const</span> transport = <span class="hljs-keyword">new</span> <span class="hljs-title class_">StdioServerTransport</span>();
<span class="hljs-keyword">await</span> server.<span class="hljs-title function_">connect</span>(transport);
Step 4: Test and Publish
SLACK_BOT_TOKEN=xoxb-your-token node index.js
mcpm-dev publish
Security Notes
- Bot tokens have limited scope — configure only what you need
- Never expose tokens — use environment variables
- Be careful with
create_channel — can create channel spam
- Add approval for sensitive actions if needed
Your AI agent now has full Slack superpowers. 🎉
#MCP #Tutorial #Slack #Integration #mcpm
Building a Slack Integration MCP Tool
Let AI agents interact with Slack — send messages, create channels, search conversations. Full walkthrough.
What You'll Build
send_message— send a message to a channel or userlist_channels— list all channels the bot can seesearch_messages— search conversation historycreate_channel— create a new channelStep 1: Setup Slack App
chat:write— send messageschannels:read— list channelschannels:history— search messageschannels:manage— create channelssearch:read— search messagesxoxb-)Step 2: Initialize
<span class="hljs-built_in">mkdir</span> slack-mcp && <span class="hljs-built_in">cd</span> slack-mcp npm init -y npm install @modelcontextprotocol/sdk @slack/web-apiStep 3: Build the Server
<span class="hljs-keyword">import</span> { <span class="hljs-title class_">Server</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/index.js"</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">StdioServerTransport</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@modelcontextprotocol/sdk/server/stdio.js"</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">WebClient</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">"@slack/web-api"</span>; <span class="hljs-keyword">const</span> <span class="hljs-variable constant_">TOKEN</span> = process.<span class="hljs-property">env</span>.<span class="hljs-property">SLACK_BOT_TOKEN</span>; <span class="hljs-keyword">if</span> (!<span class="hljs-variable constant_">TOKEN</span>) { <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">"SLACK_BOT_TOKEN is required"</span>); process.<span class="hljs-title function_">exit</span>(<span class="hljs-number">1</span>); } <span class="hljs-keyword">const</span> slack = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebClient</span>(<span class="hljs-variable constant_">TOKEN</span>); <span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Server</span>({ <span class="hljs-attr">name</span>: <span class="hljs-string">"slack-mcp"</span>, <span class="hljs-attr">version</span>: <span class="hljs-string">"1.0.0"</span>, }, { <span class="hljs-attr">capabilities</span>: { <span class="hljs-attr">tools</span>: {} } }); server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/list"</span>, <span class="hljs-title function_">async</span> () => ({ <span class="hljs-attr">tools</span>: [ { <span class="hljs-attr">name</span>: <span class="hljs-string">"send_message"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Send a message to a Slack channel or user"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">channel</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Channel name (e.g., '#general') or channel ID"</span> }, <span class="hljs-attr">text</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Message text (supports Slack mrkdwn)"</span> } }, <span class="hljs-attr">required</span>: [<span class="hljs-string">"channel"</span>, <span class="hljs-string">"text"</span>] } }, { <span class="hljs-attr">name</span>: <span class="hljs-string">"list_channels"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"List all public channels in the workspace"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">include_archived</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"boolean"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Include archived channels (default: false)"</span> } } } }, { <span class="hljs-attr">name</span>: <span class="hljs-string">"search_messages"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Search for messages matching a query"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">query</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Search query"</span> }, <span class="hljs-attr">channel</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Limit search to a specific channel"</span> }, <span class="hljs-attr">count</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"number"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Number of results (default: 10, max: 50)"</span> } }, <span class="hljs-attr">required</span>: [<span class="hljs-string">"query"</span>] } }, { <span class="hljs-attr">name</span>: <span class="hljs-string">"create_channel"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Create a new public channel"</span>, <span class="hljs-attr">inputSchema</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"object"</span>, <span class="hljs-attr">properties</span>: { <span class="hljs-attr">name</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"string"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Channel name (lowercase, no spaces, max 80 chars)"</span> }, <span class="hljs-attr">is_private</span>: { <span class="hljs-attr">type</span>: <span class="hljs-string">"boolean"</span>, <span class="hljs-attr">description</span>: <span class="hljs-string">"Create a private channel (default: false)"</span> } }, <span class="hljs-attr">required</span>: [<span class="hljs-string">"name"</span>] } } ] })); server.<span class="hljs-title function_">setRequestHandler</span>(<span class="hljs-string">"tools/call"</span>, <span class="hljs-title function_">async</span> (request) => { <span class="hljs-keyword">const</span> { name, <span class="hljs-attr">arguments</span>: args } = request.<span class="hljs-property">params</span>; <span class="hljs-keyword">try</span> { <span class="hljs-keyword">switch</span> (name) { <span class="hljs-keyword">case</span> <span class="hljs-string">"send_message"</span>: { <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">chat</span>.<span class="hljs-title function_">postMessage</span>({ <span class="hljs-attr">channel</span>: args.<span class="hljs-property">channel</span>, <span class="hljs-attr">text</span>: args.<span class="hljs-property">text</span> }); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`✅ Message sent to <span class="hljs-subst">${args.channel}</span> (<span class="hljs-subst">${result.ts}</span>)`</span> }] }; } <span class="hljs-keyword">case</span> <span class="hljs-string">"list_channels"</span>: { <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">conversations</span>.<span class="hljs-title function_">list</span>({ <span class="hljs-attr">exclude_archived</span>: !args.<span class="hljs-property">include_archived</span>, <span class="hljs-attr">types</span>: <span class="hljs-string">"public_channel"</span> }); <span class="hljs-keyword">const</span> channels = result.<span class="hljs-property">channels</span> .<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">c</span> =></span> <span class="hljs-string">` #<span class="hljs-subst">${c.name}</span> <span class="hljs-subst">${c.is_archived ? <span class="hljs-string">"(archived)"</span> : <span class="hljs-string">""</span>}</span>`</span>) .<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`📋 Channels (<span class="hljs-subst">${result.channels.length}</span>): <span class="hljs-subst">${channels}</span>`</span> }] }; } <span class="hljs-keyword">case</span> <span class="hljs-string">"search_messages"</span>: { <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">search</span>.<span class="hljs-title function_">messages</span>({ <span class="hljs-attr">query</span>: args.<span class="hljs-property">query</span>, <span class="hljs-attr">count</span>: <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">min</span>(args.<span class="hljs-property">count</span> || <span class="hljs-number">10</span>, <span class="hljs-number">50</span>) }); <span class="hljs-keyword">const</span> messages = result.<span class="hljs-property">messages</span>.<span class="hljs-property">matches</span> .<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, args.<span class="hljs-property">count</span> || <span class="hljs-number">10</span>) .<span class="hljs-title function_">map</span>(<span class="hljs-function">(<span class="hljs-params">m, i</span>) =></span> <span class="hljs-string">`<span class="hljs-subst">${i + <span class="hljs-number">1</span>}</span>. [<span class="hljs-subst">${m.channel.name}</span>] <span class="hljs-subst">${m.username}</span>: <span class="hljs-subst">${m.text.slice(<span class="hljs-number">0</span>, <span class="hljs-number">100</span>)}</span>`</span> ).<span class="hljs-title function_">join</span>(<span class="hljs-string">"\n"</span>); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`🔍 Results for "<span class="hljs-subst">${args.query}</span>": <span class="hljs-subst">${messages || <span class="hljs-string">"No messages found."</span>}</span>`</span> }] }; } <span class="hljs-keyword">case</span> <span class="hljs-string">"create_channel"</span>: { <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> slack.<span class="hljs-property">conversations</span>.<span class="hljs-title function_">create</span>({ <span class="hljs-attr">name</span>: args.<span class="hljs-property">name</span>.<span class="hljs-title function_">toLowerCase</span>().<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[^a-z0-9-_]/g</span>, <span class="hljs-string">""</span>).<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, <span class="hljs-number">80</span>), <span class="hljs-attr">is_private</span>: args.<span class="hljs-property">is_private</span> || <span class="hljs-literal">false</span> }); <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`✅ Channel #<span class="hljs-subst">${result.channel.name}</span> created!`</span> }] }; } <span class="hljs-attr">default</span>: <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Unknown tool: <span class="hljs-subst">${name}</span>`</span> }], <span class="hljs-attr">isError</span>: <span class="hljs-literal">true</span> }; } } <span class="hljs-keyword">catch</span> (err) { <span class="hljs-keyword">return</span> { <span class="hljs-attr">content</span>: [{ <span class="hljs-attr">type</span>: <span class="hljs-string">"text"</span>, <span class="hljs-attr">text</span>: <span class="hljs-string">`❌ Slack error: <span class="hljs-subst">${err.message}</span>`</span> }], <span class="hljs-attr">isError</span>: <span class="hljs-literal">true</span> }; } }); <span class="hljs-keyword">const</span> transport = <span class="hljs-keyword">new</span> <span class="hljs-title class_">StdioServerTransport</span>(); <span class="hljs-keyword">await</span> server.<span class="hljs-title function_">connect</span>(transport);Step 4: Test and Publish
Security Notes
create_channel— can create channel spamYour AI agent now has full Slack superpowers. 🎉
#MCP #Tutorial #Slack #Integration #mcpm