universal-mcp-applications 0.1.32__py3-none-any.whl → 0.1.36rc2__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.
Files changed (105) hide show
  1. universal_mcp/applications/ahrefs/app.py +52 -198
  2. universal_mcp/applications/airtable/app.py +23 -122
  3. universal_mcp/applications/apollo/app.py +111 -464
  4. universal_mcp/applications/asana/app.py +417 -1567
  5. universal_mcp/applications/aws_s3/app.py +36 -103
  6. universal_mcp/applications/bill/app.py +546 -1957
  7. universal_mcp/applications/box/app.py +1068 -3981
  8. universal_mcp/applications/braze/app.py +364 -1430
  9. universal_mcp/applications/browser_use/app.py +2 -8
  10. universal_mcp/applications/cal_com_v2/app.py +207 -625
  11. universal_mcp/applications/calendly/app.py +61 -200
  12. universal_mcp/applications/canva/app.py +45 -110
  13. universal_mcp/applications/clickup/app.py +207 -674
  14. universal_mcp/applications/coda/app.py +146 -426
  15. universal_mcp/applications/confluence/app.py +310 -1098
  16. universal_mcp/applications/contentful/app.py +36 -151
  17. universal_mcp/applications/crustdata/app.py +28 -107
  18. universal_mcp/applications/dialpad/app.py +283 -756
  19. universal_mcp/applications/digitalocean/app.py +1766 -5777
  20. universal_mcp/applications/domain_checker/app.py +3 -54
  21. universal_mcp/applications/e2b/app.py +14 -64
  22. universal_mcp/applications/elevenlabs/app.py +9 -47
  23. universal_mcp/applications/exa/app.py +6 -17
  24. universal_mcp/applications/falai/app.py +24 -101
  25. universal_mcp/applications/figma/app.py +53 -137
  26. universal_mcp/applications/file_system/app.py +2 -13
  27. universal_mcp/applications/firecrawl/app.py +51 -152
  28. universal_mcp/applications/fireflies/app.py +59 -281
  29. universal_mcp/applications/fpl/app.py +91 -528
  30. universal_mcp/applications/fpl/utils/fixtures.py +15 -49
  31. universal_mcp/applications/fpl/utils/helper.py +25 -89
  32. universal_mcp/applications/fpl/utils/league_utils.py +20 -64
  33. universal_mcp/applications/ghost_content/app.py +52 -161
  34. universal_mcp/applications/github/app.py +19 -56
  35. universal_mcp/applications/gong/app.py +88 -248
  36. universal_mcp/applications/google_calendar/app.py +16 -68
  37. universal_mcp/applications/google_docs/app.py +85 -189
  38. universal_mcp/applications/google_drive/app.py +141 -463
  39. universal_mcp/applications/google_gemini/app.py +12 -64
  40. universal_mcp/applications/google_mail/app.py +28 -157
  41. universal_mcp/applications/google_searchconsole/app.py +15 -48
  42. universal_mcp/applications/google_sheet/app.py +100 -581
  43. universal_mcp/applications/google_sheet/helper.py +10 -37
  44. universal_mcp/applications/hashnode/app.py +57 -269
  45. universal_mcp/applications/heygen/app.py +44 -122
  46. universal_mcp/applications/http_tools/app.py +10 -32
  47. universal_mcp/applications/hubspot/api_segments/crm_api.py +460 -1573
  48. universal_mcp/applications/hubspot/api_segments/marketing_api.py +74 -262
  49. universal_mcp/applications/hubspot/app.py +23 -87
  50. universal_mcp/applications/jira/app.py +2071 -7986
  51. universal_mcp/applications/klaviyo/app.py +494 -1376
  52. universal_mcp/applications/linkedin/README.md +9 -2
  53. universal_mcp/applications/linkedin/app.py +240 -181
  54. universal_mcp/applications/mailchimp/app.py +450 -1605
  55. universal_mcp/applications/markitdown/app.py +8 -20
  56. universal_mcp/applications/miro/app.py +217 -699
  57. universal_mcp/applications/ms_teams/app.py +64 -186
  58. universal_mcp/applications/neon/app.py +86 -192
  59. universal_mcp/applications/notion/app.py +21 -36
  60. universal_mcp/applications/onedrive/app.py +16 -38
  61. universal_mcp/applications/openai/app.py +42 -165
  62. universal_mcp/applications/outlook/app.py +24 -84
  63. universal_mcp/applications/perplexity/app.py +4 -19
  64. universal_mcp/applications/pipedrive/app.py +832 -3142
  65. universal_mcp/applications/posthog/app.py +163 -432
  66. universal_mcp/applications/reddit/app.py +40 -139
  67. universal_mcp/applications/resend/app.py +41 -107
  68. universal_mcp/applications/retell/app.py +14 -41
  69. universal_mcp/applications/rocketlane/app.py +221 -934
  70. universal_mcp/applications/scraper/README.md +7 -4
  71. universal_mcp/applications/scraper/app.py +50 -109
  72. universal_mcp/applications/semanticscholar/app.py +22 -64
  73. universal_mcp/applications/semrush/app.py +43 -77
  74. universal_mcp/applications/sendgrid/app.py +512 -1262
  75. universal_mcp/applications/sentry/app.py +271 -906
  76. universal_mcp/applications/serpapi/app.py +40 -143
  77. universal_mcp/applications/sharepoint/app.py +17 -39
  78. universal_mcp/applications/shopify/app.py +1551 -4287
  79. universal_mcp/applications/shortcut/app.py +155 -417
  80. universal_mcp/applications/slack/app.py +33 -115
  81. universal_mcp/applications/spotify/app.py +126 -325
  82. universal_mcp/applications/supabase/app.py +104 -213
  83. universal_mcp/applications/tavily/app.py +1 -1
  84. universal_mcp/applications/trello/app.py +693 -2656
  85. universal_mcp/applications/twilio/app.py +14 -50
  86. universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
  87. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
  88. universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
  89. universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
  90. universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
  91. universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
  92. universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
  93. universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
  94. universal_mcp/applications/whatsapp/app.py +35 -186
  95. universal_mcp/applications/whatsapp/audio.py +2 -6
  96. universal_mcp/applications/whatsapp/whatsapp.py +17 -51
  97. universal_mcp/applications/whatsapp_business/app.py +70 -283
  98. universal_mcp/applications/wrike/app.py +45 -118
  99. universal_mcp/applications/yahoo_finance/app.py +19 -65
  100. universal_mcp/applications/youtube/app.py +75 -261
  101. universal_mcp/applications/zenquotes/app.py +2 -2
  102. {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/METADATA +2 -2
  103. {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/RECORD +105 -105
  104. {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.dist-info}/WHEEL +0 -0
  105. {universal_mcp_applications-0.1.32.dist-info → universal_mcp_applications-0.1.36rc2.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
 
@@ -17,35 +16,22 @@ class SlackApp(APIApplication):
17
16
  """
18
17
  if not self.integration:
19
18
  raise ValueError("Integration not configured for SlackApp")
20
-
21
19
  credentials = self.integration.get_credentials()
22
20
  if not credentials:
23
21
  raise ValueError("No credentials found for Slack integration")
24
-
25
22
  access_token = None
26
- raw = credentials.get('raw', {})
27
- if isinstance(raw, dict) and 'authed_user' in raw:
28
- authed_user = raw.get('authed_user', {})
23
+ raw = credentials.get("raw", {})
24
+ if isinstance(raw, dict) and "authed_user" in raw:
25
+ authed_user = raw.get("authed_user", {})
29
26
  if isinstance(authed_user, dict):
30
- access_token = authed_user.get('access_token')
31
-
27
+ access_token = authed_user.get("access_token")
32
28
  if not access_token:
33
- access_token = credentials.get('access_token')
34
-
29
+ access_token = credentials.get("access_token")
35
30
  if not access_token:
36
31
  raise ValueError("Access token not found in Slack credentials")
37
-
38
- return {
39
- "Authorization": f"Bearer {access_token}",
40
- "Content-Type": "application/json",
41
- }
32
+ return {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
42
33
 
43
- def chat_delete(
44
- self,
45
- as_user: bool | None = None,
46
- channel: str | None = None,
47
- ts: float | None = None,
48
- ) -> dict[str, Any]:
34
+ async def chat_delete(self, as_user: bool | None = None, channel: str | None = None, ts: float | None = None) -> dict[str, Any]:
49
35
  """
50
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.
51
37
 
@@ -64,25 +50,14 @@ class SlackApp(APIApplication):
64
50
  chat
65
51
  """
66
52
  request_body_data = None
67
- request_body_data = {
68
- "as_user": as_user,
69
- "channel": channel,
70
- "ts": ts,
71
- }
72
- request_body_data = {
73
- k: v for k, v in request_body_data.items() if v is not None
74
- }
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}
75
55
  url = f"{self.base_url}/chat.delete"
76
56
  query_params = {}
77
- response = self._post(
78
- url,
79
- data=request_body_data,
80
- params=query_params,
81
- content_type="application/x-www-form-urlencoded",
82
- )
57
+ response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
83
58
  return self._handle_response(response)
84
59
 
85
- def chat_post_message(
60
+ async def chat_post_message(
86
61
  self,
87
62
  as_user: bool | None = None,
88
63
  attachments: str | None = None,
@@ -147,20 +122,13 @@ class SlackApp(APIApplication):
147
122
  "unfurl_media": unfurl_media,
148
123
  "username": username,
149
124
  }
150
- request_body_data = {
151
- k: v for k, v in request_body_data.items() if v is not None
152
- }
125
+ request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
153
126
  url = f"{self.base_url}/chat.postMessage"
154
127
  query_params = {}
155
- response = self._post(
156
- url,
157
- data=request_body_data,
158
- params=query_params,
159
- content_type="application/x-www-form-urlencoded",
160
- )
128
+ response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
161
129
  return self._handle_response(response)
162
130
 
163
- def chat_update(
131
+ async def chat_update(
164
132
  self,
165
133
  as_user: str | None = None,
166
134
  attachments: str | None = None,
@@ -204,20 +172,13 @@ class SlackApp(APIApplication):
204
172
  "text": text,
205
173
  "ts": ts,
206
174
  }
207
- request_body_data = {
208
- k: v for k, v in request_body_data.items() if v is not None
209
- }
175
+ request_body_data = {k: v for k, v in request_body_data.items() if v is not None}
210
176
  url = f"{self.base_url}/chat.update"
211
177
  query_params = {}
212
- response = self._post(
213
- url,
214
- data=request_body_data,
215
- params=query_params,
216
- content_type="application/x-www-form-urlencoded",
217
- )
178
+ response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
218
179
  return self._handle_response(response)
219
180
 
220
- def conversations_history(
181
+ async def conversations_history(
221
182
  self,
222
183
  token: str | None = None,
223
184
  channel: str | None = None,
@@ -265,7 +226,7 @@ class SlackApp(APIApplication):
265
226
  response = self._get(url, params=query_params)
266
227
  return self._handle_response(response)
267
228
 
268
- def conversations_list(
229
+ async def conversations_list(
269
230
  self,
270
231
  token: str | None = None,
271
232
  exclude_archived: bool | None = None,
@@ -295,19 +256,13 @@ class SlackApp(APIApplication):
295
256
  url = f"{self.base_url}/conversations.list"
296
257
  query_params = {
297
258
  k: v
298
- for k, v in [
299
- ("token", token),
300
- ("exclude_archived", exclude_archived),
301
- ("types", types),
302
- ("limit", limit),
303
- ("cursor", cursor),
304
- ]
259
+ for k, v in [("token", token), ("exclude_archived", exclude_archived), ("types", types), ("limit", limit), ("cursor", cursor)]
305
260
  if v is not None
306
261
  }
307
262
  response = self._get(url, params=query_params)
308
263
  return self._handle_response(response)
309
264
 
310
- 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]:
311
266
  """
312
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.
313
268
 
@@ -326,25 +281,14 @@ class SlackApp(APIApplication):
326
281
  reactions
327
282
  """
328
283
  request_body_data = None
329
- request_body_data = {
330
- "channel": channel,
331
- "name": name,
332
- "timestamp": timestamp,
333
- }
334
- request_body_data = {
335
- k: v for k, v in request_body_data.items() if v is not None
336
- }
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}
337
286
  url = f"{self.base_url}/reactions.add"
338
287
  query_params = {}
339
- response = self._post(
340
- url,
341
- data=request_body_data,
342
- params=query_params,
343
- content_type="application/x-www-form-urlencoded",
344
- )
288
+ response = self._post(url, data=request_body_data, params=query_params, content_type="application/x-www-form-urlencoded")
345
289
  return self._handle_response(response)
346
290
 
347
- def get_reactions_for_item(
291
+ async def get_reactions_for_item(
348
292
  self,
349
293
  token: str,
350
294
  channel: str | None = None,
@@ -389,7 +333,7 @@ class SlackApp(APIApplication):
389
333
  response = self._get(url, params=query_params)
390
334
  return self._handle_response(response)
391
335
 
392
- def get_user_reactions(
336
+ async def get_user_reactions(
393
337
  self,
394
338
  token: str,
395
339
  user: str | None = None,
@@ -437,7 +381,7 @@ class SlackApp(APIApplication):
437
381
  response = self._get(url, params=query_params)
438
382
  return self._handle_response(response)
439
383
 
440
- def search_messages(
384
+ async def search_messages(
441
385
  self,
442
386
  token: str,
443
387
  query: str,
@@ -485,7 +429,7 @@ class SlackApp(APIApplication):
485
429
  response = self._get(url, params=query_params)
486
430
  return self._handle_response(response)
487
431
 
488
- 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]:
489
433
  """
490
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.
491
435
 
@@ -503,18 +447,11 @@ class SlackApp(APIApplication):
503
447
  team
504
448
  """
505
449
  url = f"{self.base_url}/team.info"
506
- query_params = {
507
- k: v for k, v in [("token", token), ("team", team)] if v is not None
508
- }
450
+ query_params = {k: v for k, v in [("token", token), ("team", team)] if v is not None}
509
451
  response = self._get(url, params=query_params)
510
452
  return self._handle_response(response)
511
453
 
512
- def get_user_info(
513
- self,
514
- token: str,
515
- include_locale: bool | None = None,
516
- user: str | None = None,
517
- ) -> dict[str, Any]:
454
+ async def get_user_info(self, token: str, include_locale: bool | None = None, user: str | None = None) -> dict[str, Any]:
518
455
  """
519
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.
520
457
 
@@ -533,24 +470,12 @@ class SlackApp(APIApplication):
533
470
  users, important
534
471
  """
535
472
  url = f"{self.base_url}/users.info"
536
- query_params = {
537
- k: v
538
- for k, v in [
539
- ("token", token),
540
- ("include_locale", include_locale),
541
- ("user", user),
542
- ]
543
- if v is not None
544
- }
473
+ query_params = {k: v for k, v in [("token", token), ("include_locale", include_locale), ("user", user)] if v is not None}
545
474
  response = self._get(url, params=query_params)
546
475
  return self._handle_response(response)
547
476
 
548
- def users_list(
549
- self,
550
- token: str | None = None,
551
- limit: int | None = None,
552
- cursor: str | None = None,
553
- 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
554
479
  ) -> dict[str, Any]:
555
480
  """
556
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.
@@ -572,14 +497,7 @@ class SlackApp(APIApplication):
572
497
  """
573
498
  url = f"{self.base_url}/users.list"
574
499
  query_params = {
575
- k: v
576
- for k, v in [
577
- ("token", token),
578
- ("limit", limit),
579
- ("cursor", cursor),
580
- ("include_locale", include_locale),
581
- ]
582
- 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
583
501
  }
584
502
  response = self._get(url, params=query_params)
585
503
  return self._handle_response(response)