universal-mcp 0.1.8rc2__py3-none-any.whl → 0.1.8rc3__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 (45) hide show
  1. universal_mcp/__init__.py +0 -2
  2. universal_mcp/analytics.py +75 -0
  3. universal_mcp/applications/application.py +27 -5
  4. universal_mcp/applications/calendly/app.py +413 -160
  5. universal_mcp/applications/coda/README.md +133 -0
  6. universal_mcp/applications/coda/__init__.py +0 -0
  7. universal_mcp/applications/coda/app.py +3704 -0
  8. universal_mcp/applications/e2b/app.py +6 -7
  9. universal_mcp/applications/firecrawl/app.py +1 -1
  10. universal_mcp/applications/github/app.py +41 -42
  11. universal_mcp/applications/google_calendar/app.py +20 -20
  12. universal_mcp/applications/google_docs/app.py +22 -29
  13. universal_mcp/applications/google_drive/app.py +53 -59
  14. universal_mcp/applications/google_mail/app.py +40 -40
  15. universal_mcp/applications/google_sheet/app.py +44 -51
  16. universal_mcp/applications/markitdown/app.py +4 -4
  17. universal_mcp/applications/notion/app.py +93 -83
  18. universal_mcp/applications/perplexity/app.py +5 -5
  19. universal_mcp/applications/reddit/app.py +32 -32
  20. universal_mcp/applications/resend/app.py +4 -4
  21. universal_mcp/applications/serpapi/app.py +4 -4
  22. universal_mcp/applications/tavily/app.py +4 -4
  23. universal_mcp/applications/wrike/app.py +566 -226
  24. universal_mcp/applications/youtube/app.py +626 -166
  25. universal_mcp/applications/zenquotes/app.py +3 -3
  26. universal_mcp/exceptions.py +1 -0
  27. universal_mcp/integrations/__init__.py +11 -2
  28. universal_mcp/integrations/integration.py +2 -2
  29. universal_mcp/logger.py +3 -56
  30. universal_mcp/servers/__init__.py +2 -1
  31. universal_mcp/servers/server.py +76 -77
  32. universal_mcp/stores/store.py +5 -3
  33. universal_mcp/tools/__init__.py +1 -1
  34. universal_mcp/tools/adapters.py +4 -1
  35. universal_mcp/tools/func_metadata.py +5 -6
  36. universal_mcp/tools/tools.py +108 -51
  37. universal_mcp/utils/docgen.py +121 -69
  38. universal_mcp/utils/docstring_parser.py +44 -21
  39. universal_mcp/utils/dump_app_tools.py +33 -23
  40. universal_mcp/utils/openapi.py +121 -47
  41. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc3.dist-info}/METADATA +2 -2
  42. universal_mcp-0.1.8rc3.dist-info/RECORD +75 -0
  43. universal_mcp-0.1.8rc2.dist-info/RECORD +0 -71
  44. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc3.dist-info}/WHEEL +0 -0
  45. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc3.dist-info}/entry_points.txt +0 -0
@@ -37,15 +37,15 @@ class GoogleDriveApp(APIApplication):
37
37
  def get_drive_info(self) -> dict[str, Any]:
38
38
  """
39
39
  Retrieves detailed information about the user's Google Drive storage and account.
40
-
40
+
41
41
  Returns:
42
42
  A dictionary containing Drive information including storage quota (usage, limit) and user details (name, email, etc.).
43
-
43
+
44
44
  Raises:
45
45
  HTTPError: If the API request fails or returns an error status code
46
46
  ConnectionError: If there are network connectivity issues
47
47
  AuthenticationError: If the authentication credentials are invalid or expired
48
-
48
+
49
49
  Tags:
50
50
  get, info, storage, drive, quota, user, api, important
51
51
  """
@@ -54,22 +54,24 @@ class GoogleDriveApp(APIApplication):
54
54
  response = self._get(url, params=params)
55
55
  return response.json()
56
56
 
57
- def list_files(self, page_size: int = 10, query: str = None, order_by: str = None) -> dict[str, Any]:
57
+ def list_files(
58
+ self, page_size: int = 10, query: str = None, order_by: str = None
59
+ ) -> dict[str, Any]:
58
60
  """
59
61
  Lists and retrieves files from Google Drive with optional filtering, pagination, and sorting.
60
-
62
+
61
63
  Args:
62
64
  page_size: Maximum number of files to return per page (default: 10)
63
65
  query: Optional search query string using Google Drive query syntax (e.g., "mimeType='image/jpeg'")
64
66
  order_by: Optional field name to sort results by, with optional direction (e.g., "modifiedTime desc")
65
-
67
+
66
68
  Returns:
67
69
  Dictionary containing a list of files and metadata, including 'files' array and optional 'nextPageToken' for pagination
68
-
70
+
69
71
  Raises:
70
72
  HTTPError: Raised when the API request fails or returns an error status code
71
73
  RequestException: Raised when network connectivity issues occur during the API request
72
-
74
+
73
75
  Tags:
74
76
  list, files, search, google-drive, pagination, important
75
77
  """
@@ -84,22 +86,21 @@ class GoogleDriveApp(APIApplication):
84
86
  response = self._get(url, params=params)
85
87
  response.raise_for_status()
86
88
  return response.json()
87
-
88
89
 
89
90
  def get_file(self, file_id: str) -> dict[str, Any]:
90
91
  """
91
92
  Retrieves detailed metadata for a specific file using its ID.
92
-
93
+
93
94
  Args:
94
95
  file_id: String identifier of the file whose metadata should be retrieved
95
-
96
+
96
97
  Returns:
97
98
  Dictionary containing the file's metadata including properties such as name, size, type, and other attributes
98
-
99
+
99
100
  Raises:
100
101
  HTTPError: When the API request fails due to invalid file_id or network issues
101
102
  JSONDecodeError: When the API response cannot be parsed as JSON
102
-
103
+
103
104
  Tags:
104
105
  retrieve, file, metadata, get, api, important
105
106
  """
@@ -110,16 +111,16 @@ class GoogleDriveApp(APIApplication):
110
111
  def delete_file(self, file_id: str) -> dict[str, Any]:
111
112
  """
112
113
  Deletes a specified file from Google Drive and returns a status message.
113
-
114
+
114
115
  Args:
115
116
  file_id: The unique identifier string of the file to be deleted from Google Drive
116
-
117
+
117
118
  Returns:
118
119
  A dictionary containing either a success message {'message': 'File deleted successfully'} or an error message {'error': 'error description'}
119
-
120
+
120
121
  Raises:
121
122
  Exception: When the DELETE request fails due to network issues, invalid file_id, insufficient permissions, or other API errors
122
-
123
+
123
124
  Tags:
124
125
  delete, file-management, google-drive, api, important
125
126
  """
@@ -129,37 +130,34 @@ class GoogleDriveApp(APIApplication):
129
130
  return {"message": "File deleted successfully"}
130
131
  except Exception as e:
131
132
  return {"error": str(e)}
132
-
133
+
133
134
  def create_file_from_text(
134
135
  self,
135
136
  file_name: str,
136
137
  text_content: str,
137
138
  parent_id: str = None,
138
- mime_type: str = "text/plain"
139
+ mime_type: str = "text/plain",
139
140
  ) -> dict[str, Any]:
140
141
  """
141
142
  Creates a new file in Google Drive with specified text content and returns the file's metadata.
142
-
143
+
143
144
  Args:
144
145
  file_name: Name of the file to create on Google Drive
145
146
  text_content: Plain text content to be written to the file
146
147
  parent_id: Optional ID of the parent folder where the file will be created
147
148
  mime_type: MIME type of the file (defaults to 'text/plain')
148
-
149
+
149
150
  Returns:
150
151
  Dictionary containing metadata of the created file including ID, name, and other Google Drive file properties
151
-
152
+
152
153
  Raises:
153
154
  HTTPStatusError: Raised when the API request fails during file creation or content upload
154
155
  UnicodeEncodeError: Raised when the text_content cannot be encoded in UTF-8
155
-
156
+
156
157
  Tags:
157
158
  create, file, upload, drive, text, important, storage, document
158
159
  """
159
- metadata = {
160
- "name": file_name,
161
- "mimeType": mime_type
162
- }
160
+ metadata = {"name": file_name, "mimeType": mime_type}
163
161
  if parent_id:
164
162
  metadata["parents"] = [parent_id]
165
163
  create_url = f"{self.base_url}/files"
@@ -170,27 +168,25 @@ class GoogleDriveApp(APIApplication):
170
168
  upload_headers = self._get_headers()
171
169
  upload_headers["Content-Type"] = f"{mime_type}; charset=utf-8"
172
170
  upload_response = httpx.patch(
173
- upload_url,
174
- headers=upload_headers,
175
- content=text_content.encode("utf-8")
171
+ upload_url, headers=upload_headers, content=text_content.encode("utf-8")
176
172
  )
177
173
  upload_response.raise_for_status()
178
174
  response_data = upload_response.json()
179
175
  return response_data
180
-
176
+
181
177
  def find_folder_id_by_name(self, folder_name: str) -> str | None:
182
178
  """
183
179
  Searches for and retrieves a Google Drive folder's ID using its name.
184
-
180
+
185
181
  Args:
186
182
  folder_name: The name of the folder to search for in Google Drive
187
-
183
+
188
184
  Returns:
189
185
  str | None: The folder's ID if a matching folder is found, None if no folder is found or if an error occurs
190
-
186
+
191
187
  Raises:
192
188
  Exception: Caught internally and logged when API requests fail or response parsing errors occur
193
-
189
+
194
190
  Tags:
195
191
  search, find, google-drive, folder, query, api, utility
196
192
  """
@@ -198,35 +194,36 @@ class GoogleDriveApp(APIApplication):
198
194
  try:
199
195
  response = self._get(
200
196
  f"{self.base_url}/files",
201
- params={"q": query, "fields": "files(id,name)"}
197
+ params={"q": query, "fields": "files(id,name)"},
202
198
  )
203
199
  files = response.json().get("files", [])
204
200
  return files[0]["id"] if files else None
205
201
  except Exception as e:
206
202
  logger.error(f"Error finding folder ID by name: {e}")
207
203
  return None
208
-
204
+
209
205
  def create_folder(self, folder_name: str, parent_id: str = None) -> dict[str, Any]:
210
206
  """
211
207
  Creates a new folder in Google Drive with optional parent folder specification
212
-
208
+
213
209
  Args:
214
210
  folder_name: Name of the folder to create
215
211
  parent_id: ID or name of the parent folder. Can be either a folder ID string or a folder name that will be automatically looked up
216
-
212
+
217
213
  Returns:
218
214
  Dictionary containing the created folder's metadata including its ID, name, and other Drive-specific information
219
-
215
+
220
216
  Raises:
221
217
  ValueError: Raised when a parent folder name is provided but cannot be found in Google Drive
222
-
218
+
223
219
  Tags:
224
220
  create, folder, drive, storage, important, management
225
221
  """
226
222
  import re
223
+
227
224
  metadata = {
228
225
  "name": folder_name,
229
- "mimeType": "application/vnd.google-apps.folder"
226
+ "mimeType": "application/vnd.google-apps.folder",
230
227
  }
231
228
  if parent_id:
232
229
  if not re.match(r"^[a-zA-Z0-9_-]{28,33}$", parent_id):
@@ -234,7 +231,9 @@ class GoogleDriveApp(APIApplication):
234
231
  if found_id:
235
232
  metadata["parents"] = [found_id]
236
233
  else:
237
- raise ValueError(f"Could not find parent folder with name: {parent_id}")
234
+ raise ValueError(
235
+ f"Could not find parent folder with name: {parent_id}"
236
+ )
238
237
  else:
239
238
  metadata["parents"] = [parent_id]
240
239
  url = f"{self.base_url}/files"
@@ -247,49 +246,44 @@ class GoogleDriveApp(APIApplication):
247
246
  file_name: str,
248
247
  file_path: str,
249
248
  parent_id: str = None,
250
- mime_type: str = None
249
+ mime_type: str = None,
251
250
  ) -> dict[str, Any]:
252
251
  """
253
252
  Uploads a file to Google Drive by creating a file metadata entry and uploading the binary content.
254
-
253
+
255
254
  Args:
256
255
  file_name: Name to give the file on Google Drive
257
256
  file_path: Path to the local file to upload
258
257
  parent_id: Optional ID of the parent folder to create the file in
259
258
  mime_type: MIME type of the file (e.g., 'image/jpeg', 'image/png', 'application/pdf')
260
-
259
+
261
260
  Returns:
262
261
  Dictionary containing the uploaded file's metadata from Google Drive
263
-
262
+
264
263
  Raises:
265
264
  FileNotFoundError: When the specified file_path does not exist or is not accessible
266
265
  HTTPError: When the API request fails or returns an error status code
267
266
  IOError: When there are issues reading the file content
268
-
267
+
269
268
  Tags:
270
269
  upload, file-handling, google-drive, api, important, binary, storage
271
270
  """
272
- metadata = {
273
- "name": file_name,
274
- "mimeType": mime_type
275
- }
271
+ metadata = {"name": file_name, "mimeType": mime_type}
276
272
  if parent_id:
277
273
  metadata["parents"] = [parent_id]
278
274
  create_url = f"{self.base_url}/files"
279
275
  create_response = self._post(create_url, data=metadata)
280
276
  file_data = create_response.json()
281
277
  file_id = file_data.get("id")
282
- with open(file_path, 'rb') as file_content:
278
+ with open(file_path, "rb") as file_content:
283
279
  binary_content = file_content.read()
284
-
280
+
285
281
  upload_url = f"https://www.googleapis.com/upload/drive/v3/files/{file_id}?uploadType=media"
286
282
  upload_headers = self._get_headers()
287
283
  upload_headers["Content-Type"] = mime_type
288
-
284
+
289
285
  upload_response = httpx.patch(
290
- upload_url,
291
- headers=upload_headers,
292
- content=binary_content
286
+ upload_url, headers=upload_headers, content=binary_content
293
287
  )
294
288
  upload_response.raise_for_status()
295
289
  response_data = upload_response.json()
@@ -306,4 +300,4 @@ class GoogleDriveApp(APIApplication):
306
300
  self.create_folder,
307
301
  self.get_file,
308
302
  self.delete_file,
309
- ]
303
+ ]
@@ -32,20 +32,20 @@ class GoogleMailApp(APIApplication):
32
32
  def send_email(self, to: str, subject: str, body: str) -> str:
33
33
  """
34
34
  Sends an email using the Gmail API and returns a confirmation or error message.
35
-
35
+
36
36
  Args:
37
37
  to: The email address of the recipient
38
38
  subject: The subject line of the email
39
39
  body: The main content of the email message
40
-
40
+
41
41
  Returns:
42
42
  A string containing either a success confirmation message or an error description
43
-
43
+
44
44
  Raises:
45
45
  NotAuthorizedError: When Gmail API authentication is not valid or has expired
46
46
  KeyError: When required configuration keys are missing
47
47
  Exception: For any other unexpected errors during the email sending process
48
-
48
+
49
49
  Tags:
50
50
  send, email, api, communication, important
51
51
  """
@@ -100,20 +100,20 @@ class GoogleMailApp(APIApplication):
100
100
  def create_draft(self, to: str, subject: str, body: str) -> str:
101
101
  """
102
102
  Creates a draft email message in Gmail using the Gmail API and returns a confirmation status.
103
-
103
+
104
104
  Args:
105
105
  to: The email address of the recipient
106
106
  subject: The subject line of the draft email
107
107
  body: The main content/message of the draft email
108
-
108
+
109
109
  Returns:
110
110
  A string containing either a success message with the draft ID or an error message describing the failure
111
-
111
+
112
112
  Raises:
113
113
  NotAuthorizedError: When the user's Gmail API authorization is invalid or expired
114
114
  KeyError: When required configuration keys are missing
115
115
  Exception: For general API errors, network issues, or other unexpected problems
116
-
116
+
117
117
  Tags:
118
118
  create, email, draft, gmail, api, important
119
119
  """
@@ -149,18 +149,18 @@ class GoogleMailApp(APIApplication):
149
149
  def send_draft(self, draft_id: str) -> str:
150
150
  """
151
151
  Sends an existing draft email using the Gmail API and returns a confirmation message.
152
-
152
+
153
153
  Args:
154
154
  draft_id: The unique identifier of the Gmail draft to be sent
155
-
155
+
156
156
  Returns:
157
157
  A string containing either a success message with the sent message ID or an error message detailing the failure reason
158
-
158
+
159
159
  Raises:
160
160
  NotAuthorizedError: When the user's Gmail API authorization is invalid or expired
161
161
  KeyError: When required configuration keys are missing from the API response
162
162
  Exception: For other unexpected errors during the API request or response handling
163
-
163
+
164
164
  Tags:
165
165
  send, email, api, communication, important, draft
166
166
  """
@@ -194,19 +194,19 @@ class GoogleMailApp(APIApplication):
194
194
  def get_draft(self, draft_id: str, format: str = "full") -> str:
195
195
  """
196
196
  Retrieves and formats a specific draft email from Gmail by its ID
197
-
197
+
198
198
  Args:
199
199
  draft_id: String identifier of the draft email to retrieve
200
200
  format: Output format of the draft (options: minimal, full, raw, metadata). Defaults to 'full'
201
-
201
+
202
202
  Returns:
203
203
  A formatted string containing the draft email details (ID, recipient, subject) or an error message if retrieval fails
204
-
204
+
205
205
  Raises:
206
206
  NotAuthorizedError: When the user's Gmail authorization is invalid or expired
207
207
  KeyError: When required configuration keys or response data fields are missing
208
208
  Exception: For any other unexpected errors during draft retrieval
209
-
209
+
210
210
  Tags:
211
211
  retrieve, email, gmail, draft, api, format, important
212
212
  """
@@ -261,20 +261,20 @@ class GoogleMailApp(APIApplication):
261
261
  ) -> str:
262
262
  """
263
263
  Retrieves and formats a list of email drafts from the user's Gmail mailbox with optional filtering and pagination.
264
-
264
+
265
265
  Args:
266
266
  max_results: Maximum number of drafts to return (max 500, default 20)
267
267
  q: Search query string to filter drafts using Gmail search syntax (default None)
268
268
  include_spam_trash: Boolean flag to include drafts from spam and trash folders (default False)
269
-
269
+
270
270
  Returns:
271
271
  A formatted string containing the list of draft IDs and count information, or an error message if the request fails
272
-
272
+
273
273
  Raises:
274
274
  NotAuthorizedError: When the Gmail API authentication is missing or invalid
275
275
  KeyError: When required configuration keys are missing
276
276
  Exception: For general errors during API communication or data processing
277
-
277
+
278
278
  Tags:
279
279
  list, email, drafts, gmail, api, search, query, pagination, important
280
280
  """
@@ -333,18 +333,18 @@ class GoogleMailApp(APIApplication):
333
333
  def get_message(self, message_id: str) -> str:
334
334
  """
335
335
  Retrieves and formats a specific email message from Gmail API by its ID, including sender, recipient, date, subject, and message preview.
336
-
336
+
337
337
  Args:
338
338
  message_id: The unique identifier of the Gmail message to retrieve
339
-
339
+
340
340
  Returns:
341
341
  A formatted string containing the message details (ID, From, To, Date, Subject, Preview) or an error message if the retrieval fails
342
-
342
+
343
343
  Raises:
344
344
  NotAuthorizedError: When the request lacks proper Gmail API authorization
345
345
  KeyError: When required configuration keys or message fields are missing
346
346
  Exception: For general API communication errors or unexpected issues
347
-
347
+
348
348
  Tags:
349
349
  retrieve, email, format, api, gmail, message, important
350
350
  """
@@ -406,20 +406,20 @@ class GoogleMailApp(APIApplication):
406
406
  ) -> str:
407
407
  """
408
408
  Retrieves and formats a list of messages from the user's Gmail mailbox with optional filtering and pagination support.
409
-
409
+
410
410
  Args:
411
411
  max_results: Maximum number of messages to return (max 500, default 20)
412
412
  q: Search query string to filter messages using Gmail search syntax
413
413
  include_spam_trash: Boolean flag to include messages from spam and trash folders (default False)
414
-
414
+
415
415
  Returns:
416
416
  A formatted string containing the list of message IDs and thread IDs, or an error message if the operation fails
417
-
417
+
418
418
  Raises:
419
419
  NotAuthorizedError: When the Gmail API authentication is invalid or missing
420
420
  KeyError: When required configuration keys are missing
421
421
  Exception: For general API errors, network issues, or other unexpected problems
422
-
422
+
423
423
  Tags:
424
424
  list, messages, gmail, search, query, pagination, important
425
425
  """
@@ -482,17 +482,17 @@ class GoogleMailApp(APIApplication):
482
482
  def list_labels(self) -> str:
483
483
  """
484
484
  Retrieves and formats a list of all labels (both system and user-created) from the user's Gmail account, organizing them by type and sorting them alphabetically.
485
-
485
+
486
486
  Args:
487
487
  None: This method takes no arguments
488
-
488
+
489
489
  Returns:
490
490
  A formatted string containing a list of Gmail labels categorized by type (system and user), with their IDs, or an error message if the operation fails.
491
-
491
+
492
492
  Raises:
493
493
  NotAuthorizedError: Raised when the user's Gmail authorization is invalid or missing
494
494
  Exception: Raised when any other unexpected error occurs during the API request or data processing
495
-
495
+
496
496
  Tags:
497
497
  list, gmail, labels, fetch, organize, important, management
498
498
  """
@@ -562,17 +562,17 @@ class GoogleMailApp(APIApplication):
562
562
  def create_label(self, name: str) -> str:
563
563
  """
564
564
  Creates a new Gmail label with specified visibility settings and returns creation status details.
565
-
565
+
566
566
  Args:
567
567
  name: The display name of the label to create
568
-
568
+
569
569
  Returns:
570
570
  A formatted string containing the creation status, including the new label's name and ID if successful, or an error message if the creation fails
571
-
571
+
572
572
  Raises:
573
573
  NotAuthorizedError: Raised when the request lacks proper Gmail API authorization
574
574
  Exception: Raised for any other unexpected errors during label creation
575
-
575
+
576
576
  Tags:
577
577
  create, label, gmail, management, important
578
578
  """
@@ -615,17 +615,17 @@ class GoogleMailApp(APIApplication):
615
615
  def get_profile(self) -> str:
616
616
  """
617
617
  Retrieves and formats the user's Gmail profile information including email address, message count, thread count, and history ID.
618
-
618
+
619
619
  Args:
620
620
  None: This method takes no arguments besides self
621
-
621
+
622
622
  Returns:
623
623
  A formatted string containing the user's Gmail profile information or an error message if the request fails
624
-
624
+
625
625
  Raises:
626
626
  NotAuthorizedError: Raised when the user's credentials are invalid or authorization is required
627
627
  Exception: Raised for any other unexpected errors during the API request or data processing
628
-
628
+
629
629
  Tags:
630
630
  fetch, profile, gmail, user-info, api-request, important
631
631
  """