universal-mcp-applications 0.1.30rc1__py3-none-any.whl → 0.1.36rc1__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.
Potentially problematic release.
This version of universal-mcp-applications might be problematic. Click here for more details.
- universal_mcp/applications/ahrefs/app.py +52 -198
- universal_mcp/applications/airtable/app.py +23 -122
- universal_mcp/applications/apollo/app.py +111 -464
- universal_mcp/applications/asana/app.py +417 -1567
- universal_mcp/applications/aws_s3/app.py +33 -100
- universal_mcp/applications/bill/app.py +546 -1957
- universal_mcp/applications/box/app.py +1068 -3981
- universal_mcp/applications/braze/app.py +364 -1430
- universal_mcp/applications/browser_use/app.py +2 -8
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +61 -200
- universal_mcp/applications/canva/app.py +45 -110
- universal_mcp/applications/clickup/app.py +207 -674
- universal_mcp/applications/coda/app.py +146 -426
- universal_mcp/applications/confluence/app.py +310 -1098
- universal_mcp/applications/contentful/app.py +36 -151
- universal_mcp/applications/crustdata/app.py +28 -107
- universal_mcp/applications/dialpad/app.py +283 -756
- universal_mcp/applications/digitalocean/app.py +1766 -5777
- universal_mcp/applications/domain_checker/app.py +3 -54
- universal_mcp/applications/e2b/app.py +14 -64
- universal_mcp/applications/elevenlabs/app.py +9 -47
- universal_mcp/applications/exa/app.py +6 -17
- universal_mcp/applications/falai/app.py +23 -100
- universal_mcp/applications/figma/app.py +53 -137
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +51 -152
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +91 -528
- universal_mcp/applications/fpl/utils/fixtures.py +15 -49
- universal_mcp/applications/fpl/utils/helper.py +25 -89
- universal_mcp/applications/fpl/utils/league_utils.py +20 -64
- universal_mcp/applications/ghost_content/app.py +52 -161
- universal_mcp/applications/github/app.py +19 -56
- universal_mcp/applications/gong/app.py +88 -248
- universal_mcp/applications/google_calendar/app.py +16 -68
- universal_mcp/applications/google_docs/app.py +88 -188
- universal_mcp/applications/google_drive/app.py +140 -462
- universal_mcp/applications/google_gemini/app.py +12 -64
- universal_mcp/applications/google_mail/app.py +28 -157
- universal_mcp/applications/google_searchconsole/app.py +15 -48
- universal_mcp/applications/google_sheet/app.py +101 -578
- universal_mcp/applications/google_sheet/helper.py +10 -37
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/app.py +44 -122
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/api_segments/crm_api.py +460 -1573
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +74 -262
- universal_mcp/applications/hubspot/app.py +23 -87
- universal_mcp/applications/jira/app.py +2071 -7986
- universal_mcp/applications/klaviyo/app.py +494 -1376
- universal_mcp/applications/linkedin/README.md +23 -4
- universal_mcp/applications/linkedin/app.py +392 -212
- universal_mcp/applications/mailchimp/app.py +450 -1605
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +217 -699
- universal_mcp/applications/ms_teams/app.py +64 -186
- universal_mcp/applications/neon/app.py +86 -192
- universal_mcp/applications/notion/app.py +21 -36
- universal_mcp/applications/onedrive/app.py +14 -36
- universal_mcp/applications/openai/app.py +42 -165
- universal_mcp/applications/outlook/app.py +16 -76
- universal_mcp/applications/perplexity/app.py +4 -19
- universal_mcp/applications/pipedrive/app.py +832 -3142
- universal_mcp/applications/posthog/app.py +163 -432
- universal_mcp/applications/reddit/app.py +40 -139
- universal_mcp/applications/resend/app.py +41 -107
- universal_mcp/applications/retell/app.py +14 -41
- universal_mcp/applications/rocketlane/app.py +221 -934
- universal_mcp/applications/scraper/README.md +7 -4
- universal_mcp/applications/scraper/app.py +280 -93
- universal_mcp/applications/semanticscholar/app.py +22 -64
- universal_mcp/applications/semrush/app.py +43 -77
- universal_mcp/applications/sendgrid/app.py +512 -1262
- universal_mcp/applications/sentry/app.py +271 -906
- universal_mcp/applications/serpapi/app.py +40 -143
- universal_mcp/applications/sharepoint/app.py +15 -37
- universal_mcp/applications/shopify/app.py +1551 -4287
- universal_mcp/applications/shortcut/app.py +155 -417
- universal_mcp/applications/slack/app.py +50 -101
- universal_mcp/applications/spotify/app.py +126 -325
- universal_mcp/applications/supabase/app.py +104 -213
- universal_mcp/applications/tavily/app.py +1 -1
- universal_mcp/applications/trello/app.py +693 -2656
- universal_mcp/applications/twilio/app.py +14 -50
- universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
- universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
- universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
- universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
- universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
- universal_mcp/applications/whatsapp/app.py +35 -186
- universal_mcp/applications/whatsapp/audio.py +2 -6
- universal_mcp/applications/whatsapp/whatsapp.py +17 -51
- universal_mcp/applications/whatsapp_business/app.py +70 -283
- universal_mcp/applications/wrike/app.py +45 -118
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +75 -261
- universal_mcp/applications/zenquotes/app.py +2 -2
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/METADATA +2 -2
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/RECORD +105 -106
- universal_mcp/applications/scraper/scraper_testers.py +0 -17
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.30rc1.dist-info → universal_mcp_applications-0.1.36rc1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from typing import Any
|
|
2
|
-
|
|
3
2
|
from universal_mcp.applications.application import APIApplication
|
|
4
3
|
from universal_mcp.integrations import Integration
|
|
5
4
|
|
|
@@ -9,12 +8,30 @@ class SlackApp(APIApplication):
|
|
|
9
8
|
super().__init__(name="slack", integration=integration, **kwargs)
|
|
10
9
|
self.base_url = "https://slack.com/api"
|
|
11
10
|
|
|
12
|
-
def
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
def _get_headers(self) -> dict[str, str]:
|
|
12
|
+
"""
|
|
13
|
+
Get headers for Slack API requests.
|
|
14
|
+
Prioritizes user-scoped access token from raw.authed_user.access_token
|
|
15
|
+
over the bot token at the root level.
|
|
16
|
+
"""
|
|
17
|
+
if not self.integration:
|
|
18
|
+
raise ValueError("Integration not configured for SlackApp")
|
|
19
|
+
credentials = self.integration.get_credentials()
|
|
20
|
+
if not credentials:
|
|
21
|
+
raise ValueError("No credentials found for Slack integration")
|
|
22
|
+
access_token = None
|
|
23
|
+
raw = credentials.get("raw", {})
|
|
24
|
+
if isinstance(raw, dict) and "authed_user" in raw:
|
|
25
|
+
authed_user = raw.get("authed_user", {})
|
|
26
|
+
if isinstance(authed_user, dict):
|
|
27
|
+
access_token = authed_user.get("access_token")
|
|
28
|
+
if not access_token:
|
|
29
|
+
access_token = credentials.get("access_token")
|
|
30
|
+
if not access_token:
|
|
31
|
+
raise ValueError("Access token not found in Slack credentials")
|
|
32
|
+
return {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
|
|
33
|
+
|
|
34
|
+
async def chat_delete(self, as_user: bool | None = None, channel: str | None = None, ts: float | None = None) -> dict[str, Any]:
|
|
18
35
|
"""
|
|
19
36
|
Deletes a specific message from a Slack channel. It identifies the message using its channel ID and timestamp (`ts`). This function is distinct from `chat_update` which modifies a message, and `chat_post_message` which sends a new one.
|
|
20
37
|
|
|
@@ -33,25 +50,14 @@ class SlackApp(APIApplication):
|
|
|
33
50
|
chat
|
|
34
51
|
"""
|
|
35
52
|
request_body_data = None
|
|
36
|
-
request_body_data = {
|
|
37
|
-
|
|
38
|
-
"channel": channel,
|
|
39
|
-
"ts": ts,
|
|
40
|
-
}
|
|
41
|
-
request_body_data = {
|
|
42
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
43
|
-
}
|
|
53
|
+
request_body_data = {"as_user": as_user, "channel": channel, "ts": ts}
|
|
54
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
44
55
|
url = f"{self.base_url}/chat.delete"
|
|
45
56
|
query_params = {}
|
|
46
|
-
response = self._post(
|
|
47
|
-
url,
|
|
48
|
-
data=request_body_data,
|
|
49
|
-
params=query_params,
|
|
50
|
-
content_type="application/x-www-form-urlencoded",
|
|
51
|
-
)
|
|
57
|
+
response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
|
|
52
58
|
return self._handle_response(response)
|
|
53
59
|
|
|
54
|
-
def chat_post_message(
|
|
60
|
+
async def chat_post_message(
|
|
55
61
|
self,
|
|
56
62
|
as_user: bool | None = None,
|
|
57
63
|
attachments: str | None = None,
|
|
@@ -116,20 +122,13 @@ class SlackApp(APIApplication):
|
|
|
116
122
|
"unfurl_media": unfurl_media,
|
|
117
123
|
"username": username,
|
|
118
124
|
}
|
|
119
|
-
request_body_data = {
|
|
120
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
121
|
-
}
|
|
125
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
122
126
|
url = f"{self.base_url}/chat.postMessage"
|
|
123
127
|
query_params = {}
|
|
124
|
-
response = self._post(
|
|
125
|
-
url,
|
|
126
|
-
data=request_body_data,
|
|
127
|
-
params=query_params,
|
|
128
|
-
content_type="application/x-www-form-urlencoded",
|
|
129
|
-
)
|
|
128
|
+
response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
|
|
130
129
|
return self._handle_response(response)
|
|
131
130
|
|
|
132
|
-
def chat_update(
|
|
131
|
+
async def chat_update(
|
|
133
132
|
self,
|
|
134
133
|
as_user: str | None = None,
|
|
135
134
|
attachments: str | None = None,
|
|
@@ -173,20 +172,13 @@ class SlackApp(APIApplication):
|
|
|
173
172
|
"text": text,
|
|
174
173
|
"ts": ts,
|
|
175
174
|
}
|
|
176
|
-
request_body_data = {
|
|
177
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
178
|
-
}
|
|
175
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
179
176
|
url = f"{self.base_url}/chat.update"
|
|
180
177
|
query_params = {}
|
|
181
|
-
response = self._post(
|
|
182
|
-
url,
|
|
183
|
-
data=request_body_data,
|
|
184
|
-
params=query_params,
|
|
185
|
-
content_type="application/x-www-form-urlencoded",
|
|
186
|
-
)
|
|
178
|
+
response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
|
|
187
179
|
return self._handle_response(response)
|
|
188
180
|
|
|
189
|
-
def conversations_history(
|
|
181
|
+
async def conversations_history(
|
|
190
182
|
self,
|
|
191
183
|
token: str | None = None,
|
|
192
184
|
channel: str | None = None,
|
|
@@ -234,7 +226,7 @@ class SlackApp(APIApplication):
|
|
|
234
226
|
response = self._get(url, params=query_params)
|
|
235
227
|
return self._handle_response(response)
|
|
236
228
|
|
|
237
|
-
def conversations_list(
|
|
229
|
+
async def conversations_list(
|
|
238
230
|
self,
|
|
239
231
|
token: str | None = None,
|
|
240
232
|
exclude_archived: bool | None = None,
|
|
@@ -264,19 +256,13 @@ class SlackApp(APIApplication):
|
|
|
264
256
|
url = f"{self.base_url}/conversations.list"
|
|
265
257
|
query_params = {
|
|
266
258
|
k: v
|
|
267
|
-
for k, v in [
|
|
268
|
-
("token", token),
|
|
269
|
-
("exclude_archived", exclude_archived),
|
|
270
|
-
("types", types),
|
|
271
|
-
("limit", limit),
|
|
272
|
-
("cursor", cursor),
|
|
273
|
-
]
|
|
259
|
+
for k, v in [("token", token), ("exclude_archived", exclude_archived), ("types", types), ("limit", limit), ("cursor", cursor)]
|
|
274
260
|
if v is not None
|
|
275
261
|
}
|
|
276
262
|
response = self._get(url, params=query_params)
|
|
277
263
|
return self._handle_response(response)
|
|
278
264
|
|
|
279
|
-
def reactions_add(self, channel: str, name: str, timestamp: str) -> dict[str, Any]:
|
|
265
|
+
async def reactions_add(self, channel: str, name: str, timestamp: str) -> dict[str, Any]:
|
|
280
266
|
"""
|
|
281
267
|
Adds a specific emoji reaction to a message in a Slack channel, identifying the message by its channel ID and timestamp. This method creates a new reaction, unlike `reactions_get` or `reactions_list` which retrieve existing reaction data for items or users.
|
|
282
268
|
|
|
@@ -295,25 +281,14 @@ class SlackApp(APIApplication):
|
|
|
295
281
|
reactions
|
|
296
282
|
"""
|
|
297
283
|
request_body_data = None
|
|
298
|
-
request_body_data = {
|
|
299
|
-
|
|
300
|
-
"name": name,
|
|
301
|
-
"timestamp": timestamp,
|
|
302
|
-
}
|
|
303
|
-
request_body_data = {
|
|
304
|
-
k: v for k, v in request_body_data.items() if v is not None
|
|
305
|
-
}
|
|
284
|
+
request_body_data = {"channel": channel, "name": name, "timestamp": timestamp}
|
|
285
|
+
request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
|
|
306
286
|
url = f"{self.base_url}/reactions.add"
|
|
307
287
|
query_params = {}
|
|
308
|
-
response = self._post(
|
|
309
|
-
url,
|
|
310
|
-
data=request_body_data,
|
|
311
|
-
params=query_params,
|
|
312
|
-
content_type="application/x-www-form-urlencoded",
|
|
313
|
-
)
|
|
288
|
+
response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
|
|
314
289
|
return self._handle_response(response)
|
|
315
290
|
|
|
316
|
-
def get_reactions_for_item(
|
|
291
|
+
async def get_reactions_for_item(
|
|
317
292
|
self,
|
|
318
293
|
token: str,
|
|
319
294
|
channel: str | None = None,
|
|
@@ -358,7 +333,7 @@ class SlackApp(APIApplication):
|
|
|
358
333
|
response = self._get(url, params=query_params)
|
|
359
334
|
return self._handle_response(response)
|
|
360
335
|
|
|
361
|
-
def get_user_reactions(
|
|
336
|
+
async def get_user_reactions(
|
|
362
337
|
self,
|
|
363
338
|
token: str,
|
|
364
339
|
user: str | None = None,
|
|
@@ -406,7 +381,7 @@ class SlackApp(APIApplication):
|
|
|
406
381
|
response = self._get(url, params=query_params)
|
|
407
382
|
return self._handle_response(response)
|
|
408
383
|
|
|
409
|
-
def search_messages(
|
|
384
|
+
async def search_messages(
|
|
410
385
|
self,
|
|
411
386
|
token: str,
|
|
412
387
|
query: str,
|
|
@@ -454,7 +429,7 @@ class SlackApp(APIApplication):
|
|
|
454
429
|
response = self._get(url, params=query_params)
|
|
455
430
|
return self._handle_response(response)
|
|
456
431
|
|
|
457
|
-
def team_info(self, token: str, team: str | None = None) -> dict[str, Any]:
|
|
432
|
+
async def team_info(self, token: str, team: str | None = None) -> dict[str, Any]:
|
|
458
433
|
"""
|
|
459
434
|
Fetches details for a Slack team, such as name and domain, by calling the `team.info` API endpoint. This function requires an authentication token and can optionally target a specific team by its ID, distinguishing it from user or channel-specific functions.
|
|
460
435
|
|
|
@@ -472,18 +447,11 @@ class SlackApp(APIApplication):
|
|
|
472
447
|
team
|
|
473
448
|
"""
|
|
474
449
|
url = f"{self.base_url}/team.info"
|
|
475
|
-
query_params = {
|
|
476
|
-
k: v for k, v in [("token", token), ("team", team)] if v is not None
|
|
477
|
-
}
|
|
450
|
+
query_params = {k: v for k, v in [("token", token), ("team", team)] if v is not None}
|
|
478
451
|
response = self._get(url, params=query_params)
|
|
479
452
|
return self._handle_response(response)
|
|
480
453
|
|
|
481
|
-
def get_user_info(
|
|
482
|
-
self,
|
|
483
|
-
token: str,
|
|
484
|
-
include_locale: bool | None = None,
|
|
485
|
-
user: str | None = None,
|
|
486
|
-
) -> dict[str, Any]:
|
|
454
|
+
async def get_user_info(self, token: str, include_locale: bool | None = None, user: str | None = None) -> dict[str, Any]:
|
|
487
455
|
"""
|
|
488
456
|
Fetches detailed profile information for a single Slack user, identified by their user ID. Unlike `users_list`, which retrieves all workspace members, this function targets an individual and can optionally include their locale information. It directly calls the `users.info` Slack API endpoint.
|
|
489
457
|
|
|
@@ -502,24 +470,12 @@ class SlackApp(APIApplication):
|
|
|
502
470
|
users, important
|
|
503
471
|
"""
|
|
504
472
|
url = f"{self.base_url}/users.info"
|
|
505
|
-
query_params = {
|
|
506
|
-
k: v
|
|
507
|
-
for k, v in [
|
|
508
|
-
("token", token),
|
|
509
|
-
("include_locale", include_locale),
|
|
510
|
-
("user", user),
|
|
511
|
-
]
|
|
512
|
-
if v is not None
|
|
513
|
-
}
|
|
473
|
+
query_params = {k: v for k, v in [("token", token), ("include_locale", include_locale), ("user", user)] if v is not None}
|
|
514
474
|
response = self._get(url, params=query_params)
|
|
515
475
|
return self._handle_response(response)
|
|
516
476
|
|
|
517
|
-
def users_list(
|
|
518
|
-
self,
|
|
519
|
-
token: str | None = None,
|
|
520
|
-
limit: int | None = None,
|
|
521
|
-
cursor: str | None = None,
|
|
522
|
-
include_locale: bool | None = None,
|
|
477
|
+
async def users_list(
|
|
478
|
+
self, token: str | None = None, limit: int | None = None, cursor: str | None = None, include_locale: bool | None = None
|
|
523
479
|
) -> dict[str, Any]:
|
|
524
480
|
"""
|
|
525
481
|
Fetches a paginated list of all users in a Slack workspace, including deactivated members. Unlike `users_info` which retrieves a single user's details, this function returns a collection and supports limiting results or including locale data through optional parameters.
|
|
@@ -541,14 +497,7 @@ class SlackApp(APIApplication):
|
|
|
541
497
|
"""
|
|
542
498
|
url = f"{self.base_url}/users.list"
|
|
543
499
|
query_params = {
|
|
544
|
-
k: v
|
|
545
|
-
for k, v in [
|
|
546
|
-
("token", token),
|
|
547
|
-
("limit", limit),
|
|
548
|
-
("cursor", cursor),
|
|
549
|
-
("include_locale", include_locale),
|
|
550
|
-
]
|
|
551
|
-
if v is not None
|
|
500
|
+
k: v for k, v in [("token", token), ("limit", limit), ("cursor", cursor), ("include_locale", include_locale)] if v is not None
|
|
552
501
|
}
|
|
553
502
|
response = self._get(url, params=query_params)
|
|
554
503
|
return self._handle_response(response)
|