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