Merge pull request #3240 from levxn/main
Integration: Advanced Slack MCP tools Integration (~45+ tools), compatibility and working checked with all other existing tools
This commit is contained in:
@@ -231,6 +231,64 @@ class GoogleSearchHealthChecker:
|
||||
)
|
||||
|
||||
|
||||
class SlackHealthChecker:
|
||||
"""Health checker for Slack bot tokens."""
|
||||
|
||||
ENDPOINT = "https://slack.com/api/auth.test"
|
||||
TIMEOUT = 10.0
|
||||
|
||||
def check(self, bot_token: str) -> HealthCheckResult:
|
||||
"""
|
||||
Validate Slack bot token by calling auth.test.
|
||||
|
||||
Makes a POST request to auth.test to verify the token works.
|
||||
"""
|
||||
try:
|
||||
with httpx.Client(timeout=self.TIMEOUT) as client:
|
||||
response = client.post(
|
||||
self.ENDPOINT,
|
||||
headers={"Authorization": f"Bearer {bot_token}"},
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return HealthCheckResult(
|
||||
valid=False,
|
||||
message=f"Slack API returned HTTP {response.status_code}",
|
||||
details={"status_code": response.status_code},
|
||||
)
|
||||
|
||||
data = response.json()
|
||||
if data.get("ok"):
|
||||
return HealthCheckResult(
|
||||
valid=True,
|
||||
message="Slack bot token valid",
|
||||
details={
|
||||
"team": data.get("team"),
|
||||
"user": data.get("user"),
|
||||
"bot_id": data.get("bot_id"),
|
||||
},
|
||||
)
|
||||
else:
|
||||
error = data.get("error", "unknown_error")
|
||||
return HealthCheckResult(
|
||||
valid=False,
|
||||
message=f"Slack token invalid: {error}",
|
||||
details={"error": error},
|
||||
)
|
||||
except httpx.TimeoutException:
|
||||
return HealthCheckResult(
|
||||
valid=False,
|
||||
message="Slack API request timed out",
|
||||
details={"error": "timeout"},
|
||||
)
|
||||
except httpx.RequestError as e:
|
||||
return HealthCheckResult(
|
||||
valid=False,
|
||||
message=f"Failed to connect to Slack: {e}",
|
||||
details={"error": str(e)},
|
||||
)
|
||||
|
||||
|
||||
class AnthropicHealthChecker:
|
||||
"""Health checker for Anthropic API credentials."""
|
||||
|
||||
@@ -434,6 +492,7 @@ class ResendHealthChecker:
|
||||
HEALTH_CHECKERS: dict[str, CredentialHealthChecker] = {
|
||||
"hubspot": HubSpotHealthChecker(),
|
||||
"brave_search": BraveSearchHealthChecker(),
|
||||
"slack": SlackHealthChecker(),
|
||||
"google_search": GoogleSearchHealthChecker(),
|
||||
"anthropic": AnthropicHealthChecker(),
|
||||
"github": GitHubHealthChecker(),
|
||||
|
||||
@@ -42,6 +42,7 @@ from .file_system_toolkits.write_to_file import register_tools as register_write
|
||||
from .github_tool import register_tools as register_github
|
||||
from .hubspot_tool import register_tools as register_hubspot
|
||||
from .pdf_read_tool import register_tools as register_pdf_read
|
||||
from .slack_tool import register_tools as register_slack
|
||||
from .web_scrape_tool import register_tools as register_web_scrape
|
||||
from .web_search_tool import register_tools as register_web_search
|
||||
|
||||
@@ -73,6 +74,7 @@ def register_all_tools(
|
||||
# email supports multiple providers (Resend) with auto-detection
|
||||
register_email(mcp, credentials=credentials)
|
||||
register_hubspot(mcp, credentials=credentials)
|
||||
register_slack(mcp, credentials=credentials)
|
||||
|
||||
# Register file system toolkits
|
||||
register_view_file(mcp)
|
||||
@@ -137,7 +139,65 @@ def register_all_tools(
|
||||
"hubspot_get_deal",
|
||||
"hubspot_create_deal",
|
||||
"hubspot_update_deal",
|
||||
"slack_send_message",
|
||||
"slack_list_channels",
|
||||
"slack_get_channel_history",
|
||||
"slack_add_reaction",
|
||||
"slack_get_user_info",
|
||||
"slack_update_message",
|
||||
"slack_delete_message",
|
||||
"slack_schedule_message",
|
||||
"slack_create_channel",
|
||||
"slack_archive_channel",
|
||||
"slack_invite_to_channel",
|
||||
"slack_set_channel_topic",
|
||||
"slack_remove_reaction",
|
||||
"slack_list_users",
|
||||
"slack_upload_file",
|
||||
# Advanced Slack tools
|
||||
"slack_search_messages",
|
||||
"slack_get_thread_replies",
|
||||
"slack_pin_message",
|
||||
"slack_unpin_message",
|
||||
"slack_list_pins",
|
||||
"slack_add_bookmark",
|
||||
"slack_list_scheduled_messages",
|
||||
"slack_delete_scheduled_message",
|
||||
"slack_send_dm",
|
||||
"slack_get_permalink",
|
||||
"slack_send_ephemeral",
|
||||
# Block Kit & Views
|
||||
"slack_post_blocks",
|
||||
"slack_open_modal",
|
||||
"slack_update_home_tab",
|
||||
# Phase 2: User Status & Presence
|
||||
"slack_set_status",
|
||||
"slack_set_presence",
|
||||
"slack_get_presence",
|
||||
# Phase 2: Reminders
|
||||
"slack_create_reminder",
|
||||
"slack_list_reminders",
|
||||
"slack_delete_reminder",
|
||||
# Phase 2: User Groups
|
||||
"slack_create_usergroup",
|
||||
"slack_list_usergroups",
|
||||
# Phase 2: Emoji
|
||||
"slack_list_emoji",
|
||||
# Phase 2: Canvas
|
||||
"slack_create_canvas",
|
||||
"slack_edit_canvas",
|
||||
# Phase 2: Analytics (AI-Driven)
|
||||
"slack_get_messages_for_analysis",
|
||||
# Phase 2: Workflow
|
||||
"slack_trigger_workflow",
|
||||
# Phase 3: Critical Power Tools
|
||||
"slack_get_conversation_context",
|
||||
"slack_find_user_by_email",
|
||||
"slack_kick_user_from_channel",
|
||||
"slack_delete_file",
|
||||
"slack_get_team_stats",
|
||||
]
|
||||
|
||||
|
||||
|
||||
__all__ = ["register_all_tools"]
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# Slack Tool
|
||||
|
||||
Send messages and interact with Slack workspaces via the Slack Web API.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
# Required - Bot token for most operations
|
||||
export SLACK_BOT_TOKEN=xoxb-your-bot-token-here
|
||||
|
||||
# Optional - User token for search.messages API (requires user token)
|
||||
export SLACK_USER_TOKEN=xoxp-your-user-token-here
|
||||
```
|
||||
|
||||
## All Tools (26 Total)
|
||||
|
||||
### Messages (4)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_send_message` | Send message to channel | `chat:write` |
|
||||
| `slack_update_message` | Edit existing message | `chat:write` |
|
||||
| `slack_delete_message` | Delete a message | `chat:write` |
|
||||
| `slack_schedule_message` | Schedule future message | `chat:write` |
|
||||
|
||||
### Channels (6)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_list_channels` | List workspace channels | `channels:read`, `groups:read` |
|
||||
| `slack_get_channel_history` | Read channel messages | `channels:history` |
|
||||
| `slack_create_channel` | Create new channel | `channels:manage` |
|
||||
| `slack_archive_channel` | Archive a channel | `channels:manage` |
|
||||
| `slack_invite_to_channel` | Invite users to channel | `channels:manage` |
|
||||
| `slack_set_channel_topic` | Set channel topic | `channels:manage` |
|
||||
|
||||
### Reactions (2)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_add_reaction` | Add emoji reaction | `reactions:write` |
|
||||
| `slack_remove_reaction` | Remove emoji reaction | `reactions:write` |
|
||||
|
||||
### Users (2)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_get_user_info` | Get user profile | `users:read` |
|
||||
| `slack_list_users` | List workspace users | `users:read` |
|
||||
|
||||
### Files (1)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_upload_file` | Upload text file | `files:write` |
|
||||
|
||||
### Search (1)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_search_messages` | Search messages across workspace | `search:read` |
|
||||
|
||||
### Threads (1)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_get_thread_replies` | Get all replies in a thread | `channels:history` |
|
||||
|
||||
### Pins (3)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_pin_message` | Pin message to channel | `pins:write` |
|
||||
| `slack_unpin_message` | Unpin message from channel | `pins:write` |
|
||||
| `slack_list_pins` | List pinned items | `pins:read` |
|
||||
|
||||
### Bookmarks (1)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_add_bookmark` | Add bookmark/link to channel | `bookmarks:write` |
|
||||
|
||||
### Scheduled Messages (2)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_list_scheduled_messages` | List pending scheduled msgs | `chat:write` |
|
||||
| `slack_delete_scheduled_message` | Cancel scheduled message | `chat:write` |
|
||||
|
||||
### Direct Messages (1)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_send_dm` | Send DM to user | `im:write` |
|
||||
|
||||
### Utilities (2)
|
||||
| Tool | Description | Scope |
|
||||
|------|-------------|-------|
|
||||
| `slack_get_permalink` | Get permanent link to message | `chat:write` |
|
||||
| `slack_send_ephemeral` | Send message visible to one user | `chat:write` |
|
||||
|
||||
## Required Scopes
|
||||
|
||||
Add these to your Slack app under **OAuth & Permissions**:
|
||||
- `chat:write`, `channels:read`, `channels:history`, `channels:manage`
|
||||
- `groups:read`, `reactions:write`, `users:read`, `files:write`
|
||||
- `search:read`, `pins:read`, `pins:write`, `bookmarks:write`, `im:write`
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Send message
|
||||
slack_send_message(channel="C0123456789", text="Hello!")
|
||||
|
||||
# Search workspace
|
||||
slack_search_messages(query="from:@john urgent", count=10)
|
||||
|
||||
# Read thread
|
||||
slack_get_thread_replies(channel="C0123456789", thread_ts="1234567890.123456")
|
||||
|
||||
# Send DM
|
||||
slack_send_dm(user_id="U0123456789", text="Hello privately!")
|
||||
|
||||
# Pin a message
|
||||
slack_pin_message(channel="C0123456789", timestamp="1234567890.123456")
|
||||
|
||||
# Add bookmark
|
||||
slack_add_bookmark(channel="C0123456789", title="Docs", link="https://docs.example.com")
|
||||
```
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Error | Meaning |
|
||||
|-------|---------|
|
||||
| `invalid_auth` | Token invalid or expired |
|
||||
| `channel_not_found` | Channel doesn't exist or bot not a member |
|
||||
| `missing_scope` | Token lacks required scope |
|
||||
| `ratelimited` | Rate limit hit, retry later |
|
||||
@@ -0,0 +1,5 @@
|
||||
"""Slack tool package for Aden Tools."""
|
||||
|
||||
from .slack_tool import register_tools
|
||||
|
||||
__all__ = ["register_tools"]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,15 @@ class TestHealthCheckerRegistry:
|
||||
|
||||
def test_all_expected_checkers_registered(self):
|
||||
"""All expected health checkers are in the registry."""
|
||||
expected = {"hubspot", "brave_search", "google_search", "anthropic", "github", "resend"}
|
||||
expected = {
|
||||
"hubspot",
|
||||
"brave_search",
|
||||
"google_search",
|
||||
"anthropic",
|
||||
"github",
|
||||
"resend",
|
||||
"slack",
|
||||
}
|
||||
assert set(HEALTH_CHECKERS.keys()) == expected
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user