kite-agent 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kite/__init__.py +46 -0
- kite/ab_testing.py +384 -0
- kite/agent.py +556 -0
- kite/agents/__init__.py +3 -0
- kite/agents/plan_execute.py +191 -0
- kite/agents/react_agent.py +509 -0
- kite/agents/reflective_agent.py +90 -0
- kite/agents/rewoo.py +119 -0
- kite/agents/tot.py +151 -0
- kite/conversation.py +125 -0
- kite/core.py +974 -0
- kite/data_loaders.py +111 -0
- kite/embedding_providers.py +372 -0
- kite/llm_providers.py +1278 -0
- kite/memory/__init__.py +6 -0
- kite/memory/advanced_rag.py +333 -0
- kite/memory/graph_rag.py +719 -0
- kite/memory/session_memory.py +423 -0
- kite/memory/vector_memory.py +579 -0
- kite/monitoring.py +611 -0
- kite/observers.py +107 -0
- kite/optimization/__init__.py +9 -0
- kite/optimization/resource_router.py +80 -0
- kite/persistence.py +42 -0
- kite/pipeline/__init__.py +5 -0
- kite/pipeline/deterministic_pipeline.py +323 -0
- kite/pipeline/reactive_pipeline.py +171 -0
- kite/pipeline_manager.py +15 -0
- kite/routing/__init__.py +6 -0
- kite/routing/aggregator_router.py +325 -0
- kite/routing/llm_router.py +149 -0
- kite/routing/semantic_router.py +228 -0
- kite/safety/__init__.py +6 -0
- kite/safety/circuit_breaker.py +360 -0
- kite/safety/guardrails.py +82 -0
- kite/safety/idempotency_manager.py +304 -0
- kite/safety/kill_switch.py +75 -0
- kite/tool.py +183 -0
- kite/tool_registry.py +87 -0
- kite/tools/__init__.py +21 -0
- kite/tools/code_execution.py +53 -0
- kite/tools/contrib/__init__.py +19 -0
- kite/tools/contrib/calculator.py +26 -0
- kite/tools/contrib/datetime_utils.py +20 -0
- kite/tools/contrib/linkedin.py +428 -0
- kite/tools/contrib/web_search.py +30 -0
- kite/tools/mcp/__init__.py +31 -0
- kite/tools/mcp/database_mcp.py +267 -0
- kite/tools/mcp/gdrive_mcp_server.py +503 -0
- kite/tools/mcp/gmail_mcp_server.py +601 -0
- kite/tools/mcp/postgres_mcp_server.py +490 -0
- kite/tools/mcp/slack_mcp_server.py +538 -0
- kite/tools/mcp/stripe_mcp_server.py +219 -0
- kite/tools/search.py +90 -0
- kite/tools/system_tools.py +54 -0
- kite/tools_manager.py +27 -0
- kite_agent-0.1.0.dist-info/METADATA +621 -0
- kite_agent-0.1.0.dist-info/RECORD +61 -0
- kite_agent-0.1.0.dist-info/WHEEL +5 -0
- kite_agent-0.1.0.dist-info/licenses/LICENSE +21 -0
- kite_agent-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Slack MCP Server Implementation
|
|
3
|
+
Based on Chapter 4: MCP (Model Context Protocol)
|
|
4
|
+
|
|
5
|
+
Allows AI agents to interact with Slack workspaces.
|
|
6
|
+
|
|
7
|
+
Tools provided:
|
|
8
|
+
- send_message: Send messages to channels
|
|
9
|
+
- read_channel: Read recent messages
|
|
10
|
+
- search_messages: Search message history
|
|
11
|
+
- get_user_info: Get user details
|
|
12
|
+
|
|
13
|
+
Run: python slack_mcp_server.py
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import json
|
|
18
|
+
from typing import Dict, List, Optional, Any
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from datetime import datetime, timedelta
|
|
21
|
+
from dotenv import load_dotenv
|
|
22
|
+
|
|
23
|
+
load_dotenv()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# ============================================================================
|
|
27
|
+
# CONFIGURATION
|
|
28
|
+
# ============================================================================
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class SlackConfig:
|
|
34
|
+
"""Configuration for Slack MCP server."""
|
|
35
|
+
bot_token: str = ""
|
|
36
|
+
workspace_id: str = ""
|
|
37
|
+
|
|
38
|
+
# Safety limits
|
|
39
|
+
max_message_length: int = 4000
|
|
40
|
+
rate_limit_per_minute: int = 60
|
|
41
|
+
allowed_channels: Optional[List[str]] = None # None = all channels
|
|
42
|
+
|
|
43
|
+
# Features
|
|
44
|
+
enable_send: bool = True
|
|
45
|
+
enable_search: bool = True
|
|
46
|
+
enable_user_lookup: bool = True
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ============================================================================
|
|
50
|
+
# SLACK MCP SERVER
|
|
51
|
+
# ============================================================================
|
|
52
|
+
|
|
53
|
+
class SlackMCPServer:
|
|
54
|
+
"""
|
|
55
|
+
MCP Server for Slack integration.
|
|
56
|
+
|
|
57
|
+
Provides tools for AI agents to interact with Slack:
|
|
58
|
+
- Send messages to channels
|
|
59
|
+
- Read channel history
|
|
60
|
+
- Search messages
|
|
61
|
+
- Get user information
|
|
62
|
+
|
|
63
|
+
Requires: slack_sdk
|
|
64
|
+
Install: pip install slack-sdk
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
from slack_sdk import WebClient
|
|
68
|
+
|
|
69
|
+
config = SlackConfig(bot_token=os.getenv("SLACK_BOT_TOKEN"))
|
|
70
|
+
server = SlackMCPServer(config)
|
|
71
|
+
|
|
72
|
+
# Send message
|
|
73
|
+
result = server.send_message("C001", "Hello team!")
|
|
74
|
+
|
|
75
|
+
# Read channel
|
|
76
|
+
messages = server.read_channel("C001", limit=5)
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def __init__(self, config: SlackConfig = None, bot_token: str = None, **kwargs):
|
|
80
|
+
self.config = config or SlackConfig()
|
|
81
|
+
if bot_token:
|
|
82
|
+
self.config.bot_token = bot_token
|
|
83
|
+
|
|
84
|
+
# Initialize Slack client (requires slack_sdk)
|
|
85
|
+
try:
|
|
86
|
+
from slack_sdk import WebClient
|
|
87
|
+
self.client = WebClient(token=self.config.bot_token)
|
|
88
|
+
# Test connection
|
|
89
|
+
auth_test = self.client.auth_test()
|
|
90
|
+
if not auth_test.get("ok"):
|
|
91
|
+
raise Exception("Slack authentication failed")
|
|
92
|
+
except ImportError:
|
|
93
|
+
raise ImportError(
|
|
94
|
+
"slack_sdk is required for SlackMCPServer. "
|
|
95
|
+
"Install it with: pip install slack-sdk"
|
|
96
|
+
)
|
|
97
|
+
except Exception as e:
|
|
98
|
+
raise Exception(f"Failed to initialize Slack client: {e}")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Rate limiting
|
|
102
|
+
self.request_count = 0
|
|
103
|
+
self.window_start = datetime.now()
|
|
104
|
+
|
|
105
|
+
print(f"[OK] Slack MCP Server initialized")
|
|
106
|
+
print(f" Workspace: {self.config.workspace_id or 'demo'}")
|
|
107
|
+
print(f" Rate limit: {self.config.rate_limit_per_minute}/min")
|
|
108
|
+
|
|
109
|
+
def _check_rate_limit(self) -> bool:
|
|
110
|
+
"""Check if rate limit allows request."""
|
|
111
|
+
now = datetime.now()
|
|
112
|
+
|
|
113
|
+
# Reset counter if window expired
|
|
114
|
+
if (now - self.window_start).seconds >= 60:
|
|
115
|
+
self.request_count = 0
|
|
116
|
+
self.window_start = now
|
|
117
|
+
|
|
118
|
+
# Check limit
|
|
119
|
+
if self.request_count >= self.config.rate_limit_per_minute:
|
|
120
|
+
return False
|
|
121
|
+
|
|
122
|
+
self.request_count += 1
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
def _is_channel_allowed(self, channel: str) -> bool:
|
|
126
|
+
"""Check if channel is in allowed list."""
|
|
127
|
+
if self.config.allowed_channels is None:
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
return channel in self.config.allowed_channels
|
|
131
|
+
|
|
132
|
+
def send_message(self, channel: str, text: str) -> Dict[str, Any]:
|
|
133
|
+
"""
|
|
134
|
+
Send message to Slack channel.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
channel: Channel ID (e.g., "C001") or name
|
|
138
|
+
text: Message text
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Result dictionary
|
|
142
|
+
"""
|
|
143
|
+
print(f"\n Sending message to {channel}")
|
|
144
|
+
|
|
145
|
+
# Safety checks
|
|
146
|
+
if not self.config.enable_send:
|
|
147
|
+
return {
|
|
148
|
+
"success": False,
|
|
149
|
+
"error": "Send messages is disabled"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if not self._check_rate_limit():
|
|
153
|
+
return {
|
|
154
|
+
"success": False,
|
|
155
|
+
"error": "Rate limit exceeded"
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if not self._is_channel_allowed(channel):
|
|
159
|
+
return {
|
|
160
|
+
"success": False,
|
|
161
|
+
"error": f"Channel {channel} not in allowed list"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if len(text) > self.config.max_message_length:
|
|
165
|
+
return {
|
|
166
|
+
"success": False,
|
|
167
|
+
"error": f"Message too long ({len(text)} > {self.config.max_message_length})"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Send message
|
|
171
|
+
try:
|
|
172
|
+
response = self.client.chat_postMessage(
|
|
173
|
+
channel=channel,
|
|
174
|
+
text=text
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if response.get("ok"):
|
|
178
|
+
print(f" [OK] Message sent successfully")
|
|
179
|
+
return {
|
|
180
|
+
"success": True,
|
|
181
|
+
"channel": channel,
|
|
182
|
+
"timestamp": response["ts"]
|
|
183
|
+
}
|
|
184
|
+
else:
|
|
185
|
+
print(f" Failed: {response.get('error')}")
|
|
186
|
+
return {
|
|
187
|
+
"success": False,
|
|
188
|
+
"error": response.get("error", "Unknown error")
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
except Exception as e:
|
|
192
|
+
print(f" Exception: {e}")
|
|
193
|
+
return {
|
|
194
|
+
"success": False,
|
|
195
|
+
"error": str(e)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
def read_channel(self, channel: str, limit: int = 10) -> Dict[str, Any]:
|
|
199
|
+
"""
|
|
200
|
+
Read recent messages from channel.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
channel: Channel ID
|
|
204
|
+
limit: Number of messages to retrieve
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Messages list
|
|
208
|
+
"""
|
|
209
|
+
print(f"\n Reading {limit} messages from {channel}")
|
|
210
|
+
|
|
211
|
+
if not self._check_rate_limit():
|
|
212
|
+
return {
|
|
213
|
+
"success": False,
|
|
214
|
+
"error": "Rate limit exceeded"
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if not self._is_channel_allowed(channel):
|
|
218
|
+
return {
|
|
219
|
+
"success": False,
|
|
220
|
+
"error": f"Channel {channel} not in allowed list"
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
try:
|
|
224
|
+
response = self.client.conversations_history(
|
|
225
|
+
channel=channel,
|
|
226
|
+
limit=min(limit, 100) # Cap at 100
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if response.get("ok"):
|
|
230
|
+
messages = response["messages"]
|
|
231
|
+
print(f" [OK] Retrieved {len(messages)} messages")
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
"success": True,
|
|
235
|
+
"channel": channel,
|
|
236
|
+
"messages": messages,
|
|
237
|
+
"count": len(messages)
|
|
238
|
+
}
|
|
239
|
+
else:
|
|
240
|
+
return {
|
|
241
|
+
"success": False,
|
|
242
|
+
"error": response.get("error", "Unknown error")
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
except Exception as e:
|
|
246
|
+
return {
|
|
247
|
+
"success": False,
|
|
248
|
+
"error": str(e)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
def search_messages(self, query: str) -> Dict[str, Any]:
|
|
252
|
+
"""
|
|
253
|
+
Search messages across workspace.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
query: Search query
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Search results
|
|
260
|
+
"""
|
|
261
|
+
print(f"\n Searching for: {query}")
|
|
262
|
+
|
|
263
|
+
if not self.config.enable_search:
|
|
264
|
+
return {
|
|
265
|
+
"success": False,
|
|
266
|
+
"error": "Search is disabled"
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if not self._check_rate_limit():
|
|
270
|
+
return {
|
|
271
|
+
"success": False,
|
|
272
|
+
"error": "Rate limit exceeded"
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
try:
|
|
276
|
+
response = self.client.search_messages(query=query)
|
|
277
|
+
|
|
278
|
+
if response.get("ok"):
|
|
279
|
+
matches = response["messages"]["matches"]
|
|
280
|
+
print(f" [OK] Found {len(matches)} matches")
|
|
281
|
+
|
|
282
|
+
return {
|
|
283
|
+
"success": True,
|
|
284
|
+
"query": query,
|
|
285
|
+
"results": matches,
|
|
286
|
+
"count": len(matches)
|
|
287
|
+
}
|
|
288
|
+
else:
|
|
289
|
+
return {
|
|
290
|
+
"success": False,
|
|
291
|
+
"error": response.get("error", "Unknown error")
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
except Exception as e:
|
|
295
|
+
return {
|
|
296
|
+
"success": False,
|
|
297
|
+
"error": str(e)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
def get_user_info(self, user_id: str) -> Dict[str, Any]:
|
|
301
|
+
"""
|
|
302
|
+
Get user information.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
user_id: User ID
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
User info
|
|
309
|
+
"""
|
|
310
|
+
print(f"\n Getting info for user {user_id}")
|
|
311
|
+
|
|
312
|
+
if not self.config.enable_user_lookup:
|
|
313
|
+
return {
|
|
314
|
+
"success": False,
|
|
315
|
+
"error": "User lookup is disabled"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if not self._check_rate_limit():
|
|
319
|
+
return {
|
|
320
|
+
"success": False,
|
|
321
|
+
"error": "Rate limit exceeded"
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
try:
|
|
325
|
+
response = self.client.users_info(user=user_id)
|
|
326
|
+
|
|
327
|
+
if response.get("ok"):
|
|
328
|
+
user = response["user"]
|
|
329
|
+
print(f" [OK] Found user: {user.get('name')}")
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
"success": True,
|
|
333
|
+
"user": user
|
|
334
|
+
}
|
|
335
|
+
else:
|
|
336
|
+
return {
|
|
337
|
+
"success": False,
|
|
338
|
+
"error": response.get("error", "Unknown error")
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
except Exception as e:
|
|
342
|
+
return {
|
|
343
|
+
"success": False,
|
|
344
|
+
"error": str(e)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
def get_tool_definitions(self) -> List[Dict]:
|
|
348
|
+
"""
|
|
349
|
+
Get MCP tool definitions for AI agents.
|
|
350
|
+
|
|
351
|
+
These follow the MCP standard format.
|
|
352
|
+
"""
|
|
353
|
+
tools = []
|
|
354
|
+
|
|
355
|
+
if self.config.enable_send:
|
|
356
|
+
tools.append({
|
|
357
|
+
"name": "slack_send_message",
|
|
358
|
+
"description": "Send a message to a Slack channel",
|
|
359
|
+
"input_schema": {
|
|
360
|
+
"type": "object",
|
|
361
|
+
"properties": {
|
|
362
|
+
"channel": {
|
|
363
|
+
"type": "string",
|
|
364
|
+
"description": "Channel ID or name (e.g., 'C001' or 'general')"
|
|
365
|
+
},
|
|
366
|
+
"text": {
|
|
367
|
+
"type": "string",
|
|
368
|
+
"description": "Message text to send"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
"required": ["channel", "text"]
|
|
372
|
+
}
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
tools.append({
|
|
376
|
+
"name": "slack_read_channel",
|
|
377
|
+
"description": "Read recent messages from a Slack channel",
|
|
378
|
+
"input_schema": {
|
|
379
|
+
"type": "object",
|
|
380
|
+
"properties": {
|
|
381
|
+
"channel": {
|
|
382
|
+
"type": "string",
|
|
383
|
+
"description": "Channel ID or name"
|
|
384
|
+
},
|
|
385
|
+
"limit": {
|
|
386
|
+
"type": "integer",
|
|
387
|
+
"description": "Number of messages to retrieve (max 100)",
|
|
388
|
+
"default": 10
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
"required": ["channel"]
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
if self.config.enable_search:
|
|
396
|
+
tools.append({
|
|
397
|
+
"name": "slack_search_messages",
|
|
398
|
+
"description": "Search messages across Slack workspace",
|
|
399
|
+
"input_schema": {
|
|
400
|
+
"type": "object",
|
|
401
|
+
"properties": {
|
|
402
|
+
"query": {
|
|
403
|
+
"type": "string",
|
|
404
|
+
"description": "Search query"
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
"required": ["query"]
|
|
408
|
+
}
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
if self.config.enable_user_lookup:
|
|
412
|
+
tools.append({
|
|
413
|
+
"name": "slack_get_user_info",
|
|
414
|
+
"description": "Get information about a Slack user",
|
|
415
|
+
"input_schema": {
|
|
416
|
+
"type": "object",
|
|
417
|
+
"properties": {
|
|
418
|
+
"user_id": {
|
|
419
|
+
"type": "string",
|
|
420
|
+
"description": "Slack user ID"
|
|
421
|
+
}
|
|
422
|
+
},
|
|
423
|
+
"required": ["user_id"]
|
|
424
|
+
}
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
return tools
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
# ============================================================================
|
|
431
|
+
# DEMO
|
|
432
|
+
# ============================================================================
|
|
433
|
+
|
|
434
|
+
def demo():
|
|
435
|
+
print("=" * 70)
|
|
436
|
+
print("SLACK MCP SERVER DEMO")
|
|
437
|
+
print("=" * 70)
|
|
438
|
+
print("\nBased on Chapter 4: Model Context Protocol")
|
|
439
|
+
print("Allows AI agents to interact with Slack workspaces\n")
|
|
440
|
+
print("=" * 70)
|
|
441
|
+
|
|
442
|
+
# Initialize server
|
|
443
|
+
config = SlackConfig(
|
|
444
|
+
bot_token="xoxb-demo-token",
|
|
445
|
+
workspace_id="demo-workspace",
|
|
446
|
+
allowed_channels=["C001", "C002", "C003"]
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
server = SlackMCPServer(config)
|
|
450
|
+
|
|
451
|
+
# Demo 1: Read channel
|
|
452
|
+
print(f"\n{'='*70}")
|
|
453
|
+
print("DEMO 1: Read channel messages")
|
|
454
|
+
print('='*70)
|
|
455
|
+
|
|
456
|
+
result = server.read_channel("C002", limit=5)
|
|
457
|
+
if result["success"]:
|
|
458
|
+
print(f"\nMessages in {result['channel']}:")
|
|
459
|
+
for msg in result["messages"]:
|
|
460
|
+
user = msg.get("user", "Unknown")
|
|
461
|
+
text = msg.get("text", "")
|
|
462
|
+
print(f" [{user}] {text}")
|
|
463
|
+
|
|
464
|
+
# Demo 2: Search messages
|
|
465
|
+
print(f"\n{'='*70}")
|
|
466
|
+
print("DEMO 2: Search messages")
|
|
467
|
+
print('='*70)
|
|
468
|
+
|
|
469
|
+
result = server.search_messages("deployment")
|
|
470
|
+
if result["success"]:
|
|
471
|
+
print(f"\nFound {result['count']} messages matching '{result['query']}':")
|
|
472
|
+
for msg in result["results"]:
|
|
473
|
+
channel = msg.get("channel", "Unknown")
|
|
474
|
+
user = msg.get("user", "Unknown")
|
|
475
|
+
text = msg.get("text", "")
|
|
476
|
+
print(f" [#{channel}] [{user}] {text}")
|
|
477
|
+
|
|
478
|
+
# Demo 3: Send message
|
|
479
|
+
print(f"\n{'='*70}")
|
|
480
|
+
print("DEMO 3: Send message")
|
|
481
|
+
print('='*70)
|
|
482
|
+
|
|
483
|
+
result = server.send_message(
|
|
484
|
+
"C001",
|
|
485
|
+
"Hello team! This is a message from the AI agent."
|
|
486
|
+
)
|
|
487
|
+
print(f"\nSend result: {result}")
|
|
488
|
+
|
|
489
|
+
# Demo 4: Get user info
|
|
490
|
+
print(f"\n{'='*70}")
|
|
491
|
+
print("DEMO 4: Get user info")
|
|
492
|
+
print('='*70)
|
|
493
|
+
|
|
494
|
+
result = server.get_user_info("U123")
|
|
495
|
+
if result["success"]:
|
|
496
|
+
user = result["user"]
|
|
497
|
+
print(f"\nUser information:")
|
|
498
|
+
print(f" ID: {user['id']}")
|
|
499
|
+
print(f" Name: {user['name']}")
|
|
500
|
+
print(f" Email: {user.get('email', 'N/A')}")
|
|
501
|
+
|
|
502
|
+
# Show tool definitions
|
|
503
|
+
print(f"\n{'='*70}")
|
|
504
|
+
print("MCP TOOL DEFINITIONS")
|
|
505
|
+
print('='*70)
|
|
506
|
+
|
|
507
|
+
tools = server.get_tool_definitions()
|
|
508
|
+
print(f"\nAvailable tools: {len(tools)}")
|
|
509
|
+
for tool in tools:
|
|
510
|
+
print(f"\n {tool['name']}")
|
|
511
|
+
print(f" {tool['description']}")
|
|
512
|
+
|
|
513
|
+
print("\n" + "="*70)
|
|
514
|
+
print("USAGE WITH AI AGENT")
|
|
515
|
+
print("="*70)
|
|
516
|
+
print("""
|
|
517
|
+
# In your agent code:
|
|
518
|
+
from slack_mcp_server import SlackMCPServer, SlackConfig
|
|
519
|
+
|
|
520
|
+
# Initialize
|
|
521
|
+
config = SlackConfig(bot_token=os.getenv("SLACK_BOT_TOKEN"))
|
|
522
|
+
slack = SlackMCPServer(config)
|
|
523
|
+
|
|
524
|
+
# Get tools for agent
|
|
525
|
+
tools = slack.get_tool_definitions()
|
|
526
|
+
|
|
527
|
+
# When agent calls tool:
|
|
528
|
+
if tool_name == "slack_send_message":
|
|
529
|
+
result = slack.send_message(args["channel"], args["text"])
|
|
530
|
+
elif tool_name == "slack_read_channel":
|
|
531
|
+
result = slack.read_channel(args["channel"], args.get("limit", 10))
|
|
532
|
+
elif tool_name == "slack_search_messages":
|
|
533
|
+
result = slack.search_messages(args["query"])
|
|
534
|
+
""")
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
if __name__ == "__main__":
|
|
538
|
+
demo()
|