universal-mcp-applications 0.1.33__py3-none-any.whl → 0.1.39rc8__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.

Files changed (113) hide show
  1. universal_mcp/applications/ahrefs/app.py +92 -238
  2. universal_mcp/applications/airtable/app.py +23 -122
  3. universal_mcp/applications/apollo/app.py +122 -475
  4. universal_mcp/applications/asana/app.py +605 -1755
  5. universal_mcp/applications/aws_s3/app.py +36 -103
  6. universal_mcp/applications/bill/app.py +644 -2055
  7. universal_mcp/applications/box/app.py +1246 -4159
  8. universal_mcp/applications/braze/app.py +410 -1476
  9. universal_mcp/applications/browser_use/README.md +15 -1
  10. universal_mcp/applications/browser_use/__init__.py +1 -0
  11. universal_mcp/applications/browser_use/app.py +86 -24
  12. universal_mcp/applications/cal_com_v2/app.py +207 -625
  13. universal_mcp/applications/calendly/app.py +103 -242
  14. universal_mcp/applications/canva/app.py +75 -140
  15. universal_mcp/applications/clickup/app.py +331 -798
  16. universal_mcp/applications/coda/app.py +240 -520
  17. universal_mcp/applications/confluence/app.py +497 -1285
  18. universal_mcp/applications/contentful/app.py +36 -151
  19. universal_mcp/applications/crustdata/app.py +42 -121
  20. universal_mcp/applications/dialpad/app.py +451 -924
  21. universal_mcp/applications/digitalocean/app.py +2071 -6082
  22. universal_mcp/applications/domain_checker/app.py +3 -54
  23. universal_mcp/applications/e2b/app.py +14 -64
  24. universal_mcp/applications/elevenlabs/app.py +9 -47
  25. universal_mcp/applications/exa/README.md +8 -4
  26. universal_mcp/applications/exa/app.py +408 -186
  27. universal_mcp/applications/falai/app.py +24 -101
  28. universal_mcp/applications/figma/app.py +91 -175
  29. universal_mcp/applications/file_system/app.py +2 -13
  30. universal_mcp/applications/firecrawl/app.py +186 -163
  31. universal_mcp/applications/fireflies/app.py +59 -281
  32. universal_mcp/applications/fpl/app.py +92 -529
  33. universal_mcp/applications/fpl/utils/fixtures.py +15 -49
  34. universal_mcp/applications/fpl/utils/helper.py +25 -89
  35. universal_mcp/applications/fpl/utils/league_utils.py +20 -64
  36. universal_mcp/applications/ghost_content/app.py +66 -175
  37. universal_mcp/applications/github/app.py +28 -65
  38. universal_mcp/applications/gong/app.py +140 -300
  39. universal_mcp/applications/google_calendar/app.py +26 -78
  40. universal_mcp/applications/google_docs/app.py +98 -202
  41. universal_mcp/applications/google_drive/app.py +194 -793
  42. universal_mcp/applications/google_gemini/app.py +27 -62
  43. universal_mcp/applications/google_mail/README.md +1 -0
  44. universal_mcp/applications/google_mail/app.py +93 -214
  45. universal_mcp/applications/google_searchconsole/app.py +25 -58
  46. universal_mcp/applications/google_sheet/app.py +171 -624
  47. universal_mcp/applications/google_sheet/helper.py +26 -53
  48. universal_mcp/applications/hashnode/app.py +57 -269
  49. universal_mcp/applications/heygen/app.py +77 -155
  50. universal_mcp/applications/http_tools/app.py +10 -32
  51. universal_mcp/applications/hubspot/README.md +1 -1
  52. universal_mcp/applications/hubspot/app.py +7508 -99
  53. universal_mcp/applications/jira/app.py +2419 -8334
  54. universal_mcp/applications/klaviyo/app.py +737 -1619
  55. universal_mcp/applications/linkedin/README.md +5 -0
  56. universal_mcp/applications/linkedin/app.py +332 -227
  57. universal_mcp/applications/mailchimp/app.py +696 -1851
  58. universal_mcp/applications/markitdown/app.py +8 -20
  59. universal_mcp/applications/miro/app.py +333 -815
  60. universal_mcp/applications/ms_teams/app.py +85 -207
  61. universal_mcp/applications/neon/app.py +144 -250
  62. universal_mcp/applications/notion/app.py +36 -51
  63. universal_mcp/applications/onedrive/app.py +26 -48
  64. universal_mcp/applications/openai/app.py +42 -165
  65. universal_mcp/applications/outlook/README.md +22 -9
  66. universal_mcp/applications/outlook/app.py +403 -141
  67. universal_mcp/applications/perplexity/README.md +2 -1
  68. universal_mcp/applications/perplexity/app.py +162 -20
  69. universal_mcp/applications/pipedrive/app.py +1021 -3331
  70. universal_mcp/applications/posthog/app.py +272 -541
  71. universal_mcp/applications/reddit/app.py +61 -160
  72. universal_mcp/applications/resend/app.py +41 -107
  73. universal_mcp/applications/retell/app.py +23 -50
  74. universal_mcp/applications/rocketlane/app.py +250 -963
  75. universal_mcp/applications/scraper/app.py +67 -125
  76. universal_mcp/applications/semanticscholar/app.py +36 -78
  77. universal_mcp/applications/semrush/app.py +43 -77
  78. universal_mcp/applications/sendgrid/app.py +826 -1576
  79. universal_mcp/applications/sentry/app.py +444 -1079
  80. universal_mcp/applications/serpapi/app.py +40 -143
  81. universal_mcp/applications/sharepoint/app.py +27 -49
  82. universal_mcp/applications/shopify/app.py +1743 -4479
  83. universal_mcp/applications/shortcut/app.py +272 -534
  84. universal_mcp/applications/slack/app.py +41 -123
  85. universal_mcp/applications/spotify/app.py +206 -405
  86. universal_mcp/applications/supabase/app.py +174 -283
  87. universal_mcp/applications/tavily/app.py +2 -2
  88. universal_mcp/applications/trello/app.py +853 -2816
  89. universal_mcp/applications/twilio/app.py +14 -50
  90. universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
  91. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
  92. universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
  93. universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
  94. universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
  95. universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
  96. universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
  97. universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
  98. universal_mcp/applications/whatsapp/app.py +35 -186
  99. universal_mcp/applications/whatsapp/audio.py +2 -6
  100. universal_mcp/applications/whatsapp/whatsapp.py +17 -51
  101. universal_mcp/applications/whatsapp_business/app.py +86 -299
  102. universal_mcp/applications/wrike/app.py +80 -153
  103. universal_mcp/applications/yahoo_finance/app.py +19 -65
  104. universal_mcp/applications/youtube/app.py +120 -306
  105. universal_mcp/applications/zenquotes/app.py +3 -3
  106. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/METADATA +4 -2
  107. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/RECORD +109 -113
  108. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/WHEEL +1 -1
  109. universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
  110. universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
  111. universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
  112. universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
  113. {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc8.dist-info}/licenses/LICENSE +0 -0
@@ -3,8 +3,7 @@ import io
3
3
  import os
4
4
  import uuid
5
5
  import wave
6
- from typing import Annotated
7
-
6
+ from typing import Annotated, Literal
8
7
  from google import genai
9
8
  from google.genai import types
10
9
  from PIL import Image
@@ -22,11 +21,7 @@ class GoogleGeminiApp(APIApplication):
22
21
  if self._genai_client is not None:
23
22
  return self._genai_client
24
23
  credentials = self.integration.get_credentials()
25
- api_key = (
26
- credentials.get("api_key")
27
- or credentials.get("API_KEY")
28
- or credentials.get("apiKey")
29
- )
24
+ api_key = credentials.get("api_key") or credentials.get("API_KEY") or credentials.get("apiKey")
30
25
  if not api_key:
31
26
  raise ValueError("API key not found in integration credentials")
32
27
  self._genai_client = genai.Client(api_key=api_key)
@@ -35,7 +30,12 @@ class GoogleGeminiApp(APIApplication):
35
30
  async def generate_text(
36
31
  self,
37
32
  prompt: Annotated[str, "The prompt to generate text from"],
38
- model: str = "gemini-2.5-flash",
33
+ model: Literal[
34
+ "gemini-2.5-flash",
35
+ "gemini-2.5-pro",
36
+ "gemini-3-flash-preview",
37
+ "gemini-3-pro-preview",
38
+ ] = "gemini-2.5-flash",
39
39
  ) -> str:
40
40
  """Generates text using the Google Gemini model based on a given prompt.
41
41
  This tool is suitable for various natural language processing tasks such as content generation, summarization, translation, and question answering.
@@ -54,16 +54,17 @@ class GoogleGeminiApp(APIApplication):
54
54
  Tags:
55
55
  text, generate, llm, important
56
56
  """
57
- response = self.genai_client.models.generate_content(
58
- contents=prompt, model=model
59
- )
57
+ response = self.genai_client.models.generate_content(contents=prompt, model=model)
60
58
  return response.text
61
59
 
62
60
  async def generate_image(
63
61
  self,
64
62
  prompt: Annotated[str, "The prompt to generate image from"],
65
- images: Annotated[list[str], "The reference image URLs"] | None = None,
66
- model: str = "gemini-2.5-flash-image-preview",
63
+ images: Annotated[list[str], "The reference image URLs"] | None = None,
64
+ model: Literal[
65
+ "gemini-3-pro-image-preview",
66
+ "gemini-2.5-flash-image"
67
+ ] = "gemini-2.5-flash-image",
67
68
  ) -> dict:
68
69
  """
69
70
  Generates an image based on a text prompt and an optional reference image using the Google Gemini model.
@@ -73,12 +74,12 @@ class GoogleGeminiApp(APIApplication):
73
74
  Args:
74
75
  prompt (str): The descriptive text prompt to guide the image generation. For example: "A futuristic city at sunset with flying cars."
75
76
  images (list[str], optional): An optional list of URLs to reference images. These images will be used as a basis for the generation.
76
- model (str, optional): The Gemini model to use for image generation. Defaults to "gemini-2.5-flash-image-preview".
77
+ model (str, optional): The Gemini model to use for image generation. Defaults to "gemini-2.5-flash-image".
77
78
 
78
79
  Returns:
79
80
  dict: A dictionary containing:
80
81
  - 'type' (str): Always "image".
81
- - 'data' (str): The base64 encoded image data.
82
+ - 'data' (str): The base64 encoded image data. Either upload or save this and then render the file path/link in markdown to the user. DO NOT use a data url.
82
83
  - 'mime_type' (str): The MIME type of the image (e.g., "image/png").
83
84
  - 'file_name' (str): A suggested file name for the generated image.
84
85
  - 'text' (str): Any accompanying text generated by the model.
@@ -91,7 +92,6 @@ class GoogleGeminiApp(APIApplication):
91
92
  Tags:
92
93
  image, generate, vision, important
93
94
  """
94
- # The Gemini API is synchronous, so run in a thread
95
95
  contents = [prompt]
96
96
  if images:
97
97
  for image in images:
@@ -104,36 +104,26 @@ class GoogleGeminiApp(APIApplication):
104
104
  else:
105
105
  image = Image.open(image)
106
106
  contents.append(image)
107
- response = self.genai_client.models.generate_content(
108
- model=model,
109
- contents=contents,
110
- )
107
+ response = self.genai_client.models.generate_content(model=model, contents=contents)
111
108
  candidate = response.candidates[0]
112
109
  text = ""
113
110
  for part in candidate.content.parts:
114
111
  if part.text is not None:
115
112
  text += part.text
116
113
  elif part.inline_data is not None:
117
- # Return the raw image bytes
118
114
  image_bytes = part.inline_data.data
119
-
120
115
  img_base64 = base64.b64encode(image_bytes).decode("utf-8")
121
-
122
116
  file_name = f"{uuid.uuid4()}.png"
123
-
124
- return {
125
- "type": "image",
126
- "data": img_base64,
127
- "mime_type": "image/png",
128
- "file_name": file_name,
129
- "text": text,
130
- }
117
+ return {"type": "image", "data": img_base64, "mime_type": "image/png", "file_name": file_name, "text": text}
131
118
 
132
119
  async def generate_audio(
133
120
  self,
134
121
  prompt: Annotated[str, "The prompt to generate audio from"],
135
- model: str = "gemini-2.5-flash-preview-tts",
136
- ) -> str:
122
+ model: Literal[
123
+ "gemini-2.5-flash-preview-tts",
124
+ "gemini-2.5-pro-preview-tts"
125
+ ] = "gemini-2.5-flash-preview-tts",
126
+ ) -> str:
137
127
  """Generates audio from a given text prompt using the Google Gemini model's Text-to-Speech (TTS) capabilities.
138
128
  This tool is useful for converting text into spoken audio, which can be used for voiceovers, accessibility features, or interactive applications.
139
129
  It returns a dictionary containing the generated audio data (base64 encoded), its MIME type, and a suggested file name.
@@ -156,7 +146,6 @@ class GoogleGeminiApp(APIApplication):
156
146
  audio, generate, tts, speech, important
157
147
  """
158
148
 
159
- # Set up the wave file to save the output:
160
149
  def wave_file(filename, pcm, channels=1, rate=24000, sample_width=2):
161
150
  with wave.open(filename, "wb") as wf:
162
151
  wf.setnchannels(channels)
@@ -170,52 +159,28 @@ class GoogleGeminiApp(APIApplication):
170
159
  config=types.GenerateContentConfig(
171
160
  response_modalities=["AUDIO"],
172
161
  speech_config=types.SpeechConfig(
173
- voice_config=types.VoiceConfig(
174
- prebuilt_voice_config=types.PrebuiltVoiceConfig(
175
- voice_name="Kore",
176
- )
177
- )
162
+ voice_config=types.VoiceConfig(prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore"))
178
163
  ),
179
164
  ),
180
165
  )
181
-
182
166
  data = response.candidates[0].content.parts[0].inline_data.data
183
-
184
167
  file_name = f"{uuid.uuid4()}.wav"
185
168
  wave_file(file_name, data)
186
-
187
- # read the file
188
169
  with open(file_name, "rb") as f:
189
170
  data = f.read()
190
-
191
- # delete the file
192
171
  os.remove(file_name)
193
-
194
- # Convert to base64
195
172
  import base64
196
173
 
197
174
  audio_base64 = base64.b64encode(data).decode("utf-8")
198
-
199
- return {
200
- "type": "audio",
201
- "data": audio_base64,
202
- "mime_type": "audio/wav",
203
- "file_name": file_name,
204
- }
175
+ return {"type": "audio", "data": audio_base64, "mime_type": "audio/wav", "file_name": file_name}
205
176
 
206
177
  def list_tools(self):
207
- return [
208
- self.generate_text,
209
- self.generate_image,
210
- self.generate_audio,
211
- ]
178
+ return [self.generate_text, self.generate_image, self.generate_audio]
212
179
 
213
180
 
214
181
  async def test_google_gemini():
215
182
  app = GoogleGeminiApp()
216
- await app.generate_image(
217
- "A beautiful women potrait with red green hair color"
218
- )
183
+ await app.generate_image("A beautiful women potrait with red green hair color")
219
184
 
220
185
 
221
186
  if __name__ == "__main__":
@@ -16,6 +16,7 @@ This is automatically generated from OpenAPI schema for the GoogleMailApp API.
16
16
  | `list_drafts` | Fetches a list of email drafts, allowing filtering by a search query and limiting results. It can optionally include drafts from spam and trash, returning a collection of draft objects. This is distinct from `get_draft`, which retrieves only a single, specific draft by its ID. |
17
17
  | `get_message_details` | Retrieves a specific email from Gmail by its ID. It parses the API response to extract and format key details—including sender, subject, body, and attachments—into a structured dictionary. This function provides detailed data for a single message, distinguishing it from `list_messages` which fetches multiple messages. |
18
18
  | `list_messages` | Fetches a paginated list of detailed email messages using optional search queries. It concurrently retrieves full content (sender, subject, body) for each message, returning the results and a pagination token. This differs from `get_message_details`, which fetches only a single message. |
19
+ | `get_email_thread` | Fetches a complete email conversation by its unique thread ID. Unlike `get_message_details`, which retrieves a single message, this returns all messages and metadata for the entire thread, providing the full context of the conversation. |
19
20
  | `list_labels` | Fetches a complete list of all available labels from the user's Gmail account via the API. It retrieves both system-defined (e.g., INBOX) and user-created labels, returning their names and IDs, complementing management functions like `create_label` and `update_label`. |
20
21
  | `create_label` | Creates a new Gmail label with a specified name, hardcoding its visibility to ensure it appears in both label and message lists. This function complements `update_label` and `delete_label` by adding new organizational tags to the user's account via the API. |
21
22
  | `get_profile` | Retrieves the authenticated user's Gmail profile from the API. The profile includes the user's email address, total message and thread counts, and the mailbox's history ID, offering a high-level summary of the account's state. |