Slack Integration: Build a Team Notification Skill
Build Claude Code skills that integrate with Slack. Send notifications, post updates, and keep your team informed automatically.
Build Claude Code skills that integrate with Slack. Send notifications, post updates, and keep your team informed automatically.
Development doesn't happen in isolation. Teams need to know when deployments finish, when builds break, when PRs need review. But constant context switching between code and Slack destroys productivity.
What if Claude Code could handle team communication for you? Post deployment notifications, request reviews, share updates—all without leaving your terminal.
This tutorial shows you how to build a Slack integration skill that keeps your team informed without interrupting your flow.
You'll need:
Webhooks (Simpler):
Slack App (Full Featured):
We'll cover both, starting with webhooks.
Store the webhook URL securely:
# Add to .env (don't commit this!)
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
.claude/commands/notify.md:
---
description: Send a notification to Slack
arguments:
- name: message
description: Message to send
required: true
- name: channel
description: Channel override (if multiple webhooks configured)
required: false
---
# Slack Notification
Send a message to the team Slack channel.
## Send Message
Use curl to post to the webhook:
```bash
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"MESSAGE_HERE"}' \
$SLACK_WEBHOOK_URL
Slack supports mrkdwn format:
code → codecode block → code blockConfirm message was sent or report error.
### Rich Notification Skill
**.claude/commands/slack-notify.md:**
```markdown
---
description: Send rich Slack notifications
arguments:
- name: type
description: Notification type (deploy, build, pr, custom)
required: true
- name: status
description: Status (success, failure, warning, info)
required: false
default: info
- name: message
description: Custom message
required: false
---
# Rich Slack Notifications
Send formatted notifications with context.
## Message Templates
### Deploy Notification
```json
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "🚀 Deployment Complete",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Environment:*\nProduction"
},
{
"type": "mrkdwn",
"text": "*Version:*\nv1.2.3"
},
{
"type": "mrkdwn",
"text": "*Deployed by:*\n@username"
},
{
"type": "mrkdwn",
"text": "*Time:*\n2 minutes"
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Changes:*\n• Feature A\n• Bug fix B\n• Update C"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Deployment"
},
"url": "https://app.example.com"
}
]
}
]
}
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "✅ Build Passed",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Branch:*\nmain"
},
{
"type": "mrkdwn",
"text": "*Commit:*\n<commit_url|abc1234>"
},
{
"type": "mrkdwn",
"text": "*Duration:*\n4m 23s"
},
{
"type": "mrkdwn",
"text": "*Tests:*\n142 passed"
}
]
}
]
}
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "📝 PR Ready for Review",
"emoji": true
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<pr_url|#42 Add user authentication>*\nby @author"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "This PR adds complete authentication with login, logout, and session management."
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Files:*\n12 changed"
},
{
"type": "mrkdwn",
"text": "*Lines:*\n+450 / -23"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Review PR"
},
"url": "pr_url",
"style": "primary"
}
]
}
]
}
Add color to indicate status:
{
"attachments": [
{
"color": "#36a64f", // green for success
"blocks": [...]
}
]
}
Colors:
curl -X POST -H 'Content-type: application/json' \
--data '[JSON_PAYLOAD]' \
$SLACK_WEBHOOK_URL
## Full Slack App Integration
For two-way communication and advanced features, create a full Slack App.
### Setting Up the Slack App
1. Go to [api.slack.com/apps](https://api.slack.com/apps)
2. Create New App > From scratch
3. Add OAuth scopes:
- `chat:write` - Send messages
- `chat:write.public` - Post to any public channel
- `channels:read` - List channels
- `users:read` - Get user info
4. Install to workspace
5. Copy the Bot User OAuth Token
Store securely:
```bash
SLACK_BOT_TOKEN=xoxb-your-bot-token
Create an MCP server for Slack integration:
slack-mcp/src/index.ts:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN;
async function slackAPI(endpoint: string, body: any) {
const response = await fetch(`https://slack.com/api/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${SLACK_BOT_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
return response.json();
}
const server = new Server(
{ name: "slack-server", version: "1.0.0" },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: "send_message",
description: "Send a message to a Slack channel",
inputSchema: {
type: "object",
properties: {
channel: { type: "string", description: "Channel ID or name" },
text: { type: "string", description: "Message text" },
thread_ts: { type: "string", description: "Thread timestamp for replies" },
},
required: ["channel", "text"],
},
},
{
name: "list_channels",
description: "List available Slack channels",
inputSchema: { type: "object", properties: {} },
},
{
name: "get_channel_history",
description: "Get recent messages from a channel",
inputSchema: {
type: "object",
properties: {
channel: { type: "string" },
limit: { type: "number", default: 10 },
},
required: ["channel"],
},
},
],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case "send_message": {
const result = await slackAPI("chat.postMessage", {
channel: args.channel,
text: args.text,
thread_ts: args.thread_ts,
});
return {
content: [{
type: "text",
text: result.ok
? `Message sent to ${args.channel}`
: `Error: ${result.error}`,
}],
};
}
case "list_channels": {
const result = await slackAPI("conversations.list", {
types: "public_channel,private_channel",
});
const channels = result.channels?.map((c: any) =>
`#${c.name} (${c.id})`
).join("\n");
return {
content: [{ type: "text", text: channels || "No channels found" }],
};
}
case "get_channel_history": {
const result = await slackAPI("conversations.history", {
channel: args.channel,
limit: args.limit || 10,
});
const messages = result.messages?.map((m: any) =>
`${m.user}: ${m.text}`
).join("\n\n");
return {
content: [{ type: "text", text: messages || "No messages" }],
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
.claude/mcp.json:
{
"mcpServers": {
"slack": {
"command": "npx",
"args": ["ts-node", "/path/to/slack-mcp/src/index.ts"],
"env": {
"SLACK_BOT_TOKEN": "${SLACK_BOT_TOKEN}"
}
}
}
}
.claude/agents/deploy-notify.md:
---
description: Send deployment notifications to Slack
trigger:
event: post-deploy
---
# Deployment Notification Agent
After deployments, notify the team on Slack.
## Gather Information
1. Get deployment details:
- Version deployed
- Environment
- Who deployed
- Duration
2. Get changes included:
- Commits since last deploy
- PRs merged
- Issues resolved
## Compose Message
🚀 Deployment Complete
Environment: [env] Version: [version] Deployed by: @[user] Duration: [time]
Changes: • [Change 1] • [Change 2] • [Change 3]
Resolved Issues: • #42 - Login bug • #38 - Performance issue
<url|View Deployment>
## Send Notification
Use Slack MCP or webhook to post to #deployments channel.
## Handle Failures
If deployment failed:
- Use red color
- Include error summary
- Tag on-call person
- Include rollback instructions
.claude/agents/review-request.md:
---
description: Request PR reviews via Slack
trigger:
event: pr-created
condition: "not draft"
---
# PR Review Request Agent
When a PR is ready for review, notify potential reviewers.
## Determine Reviewers
Based on:
1. Code owners for changed files
2. Recent contributors to affected areas
3. Team rotation schedule (if configured)
## Check Availability
If integrated with calendar:
- Skip people in meetings
- Skip people on PTO
- Prefer people in similar timezone
## Send Request
📝 Review Requested
<pr_url|#42 Add user authentication> by @author
[Brief description of changes]
Files Changed:
@reviewer1 @reviewer2 - Please review when available
<pr_url|View PR>
## Follow Up
If no review after 24 hours:
- Send reminder
- Expand reviewer pool
- Escalate if critical
.claude/agents/build-alert.md:
---
description: Alert on build failures
trigger:
event: ci-failure
---
# Build Failure Alert Agent
When CI fails, notify the team and the commit author.
## Analyze Failure
1. Get failure details
2. Identify failing step
3. Extract error message
4. Find recent changes
## Notify
### To #builds channel:
❌ Build Failed
Branch: [branch] Commit: <commit_url|abc1234> by @author
Failed Step: [step name] Error:
[error message]
@author - Please check and fix
<run_url|View Build>
### DM to author (if enabled):
Hey! Your recent commit broke the build.
Error: [summary]
<run_url|View Details>
Need help? Ask in #dev-help
## Track
Log failure for metrics:
- Time to fix
- Failure frequency
- Common failure types
.claude/commands/standup.md:
---
description: Post standup reminder with context
---
# Standup Reminder
Post a standup reminder with relevant context for the team.
## Gather Context
1. Yesterday's activity:
- PRs merged
- Issues closed
- Deployments
2. Today's priorities:
- Open PRs needing review
- Issues in progress
- Upcoming deadlines
## Post Reminder
🌅 Good morning team!
Yesterday: • Merged 3 PRs • Closed 5 issues • Deployed v1.2.3 to production
Today's Focus: • 2 PRs awaiting review • Sprint ends Friday
Blockers? React with 🚧
Time for standup! Share your updates: • What did you do yesterday? • What are you doing today? • Any blockers?
.claude/commands/weekly-summary.md:
---
description: Post weekly development summary
---
# Weekly Summary
Generate and post a summary of the week's development activity.
## Gather Data
From GitHub:
- PRs merged
- Issues closed
- New issues created
- Releases published
From CI:
- Build success rate
- Deploy count
- Test coverage changes
## Generate Summary
📊 Weekly Development Summary Week of [date]
Highlights: • Released v1.3.0 with new dashboard • Reduced load time by 40% • Onboarded 2 new team members
Stats:
| Metric | This Week | Last Week | Trend |
|---|---|---|---|
| PRs Merged | 15 | 12 | ↑ |
| Issues Closed | 23 | 18 | ↑ |
| Build Success | 94% | 89% | ↑ |
| Test Coverage | 82% | 80% | ↑ |
Contributors: 🏆 @developer1 - 5 PRs merged 🥈 @developer2 - 4 PRs merged 🥉 @developer3 - 3 PRs merged
Next Week: • Feature freeze for v1.4 • Security audit • Performance testing
Great work everyone! 🎉
## Post
Send to #engineering and #general
Choose what to notify:
Let users configure their preferences.
Keep channels clean by using threads:
Every notification should have:
Don't notify people outside work hours:
Monitor if notifications are useful:
Slack integration keeps your team informed without constant context switching. Send updates, request reviews, and coordinate work—all from Claude Code.
| Skill | Purpose |
|---|---|
/notify | Basic Slack notification |
/slack-notify | Rich formatted notifications |
/standup | Standup reminders with context |
/weekly-summary | Weekly development report |
| Agent | Trigger | Purpose |
|---|---|---|
| deploy-notify | Post-deploy | Deployment announcements |
| review-request | PR created | Review requests |
| build-alert | CI failure | Build failure alerts |
You've now completed the tutorials section! Ready to apply these skills to your own projects? Start with Installing Your First Skill and build from there.
skill from anthropics/skills
This skill provides a structured workflow for guiding users through collaborative document creation. Act as an active guide, walking users through three stages: Context Gathering, Refinement & Structu
This skill provides guidance for creating effective skills.
skill from anthropics/skills