universal-mcp 0.1.8rc2__py3-none-any.whl → 0.1.8rc4__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 (53) hide show
  1. universal_mcp/__init__.py +0 -2
  2. universal_mcp/analytics.py +75 -0
  3. universal_mcp/applications/ahrefs/README.md +76 -0
  4. universal_mcp/applications/ahrefs/__init__.py +0 -0
  5. universal_mcp/applications/ahrefs/app.py +2291 -0
  6. universal_mcp/applications/application.py +94 -5
  7. universal_mcp/applications/calendly/app.py +412 -171
  8. universal_mcp/applications/coda/README.md +133 -0
  9. universal_mcp/applications/coda/__init__.py +0 -0
  10. universal_mcp/applications/coda/app.py +3671 -0
  11. universal_mcp/applications/e2b/app.py +8 -35
  12. universal_mcp/applications/figma/README.md +74 -0
  13. universal_mcp/applications/figma/__init__.py +0 -0
  14. universal_mcp/applications/figma/app.py +1261 -0
  15. universal_mcp/applications/firecrawl/app.py +3 -33
  16. universal_mcp/applications/github/app.py +41 -42
  17. universal_mcp/applications/google_calendar/app.py +20 -31
  18. universal_mcp/applications/google_docs/app.py +21 -46
  19. universal_mcp/applications/google_drive/app.py +53 -76
  20. universal_mcp/applications/google_mail/app.py +40 -56
  21. universal_mcp/applications/google_sheet/app.py +43 -68
  22. universal_mcp/applications/markitdown/app.py +4 -4
  23. universal_mcp/applications/notion/app.py +93 -83
  24. universal_mcp/applications/perplexity/app.py +4 -38
  25. universal_mcp/applications/reddit/app.py +32 -32
  26. universal_mcp/applications/resend/app.py +4 -22
  27. universal_mcp/applications/serpapi/app.py +6 -32
  28. universal_mcp/applications/tavily/app.py +4 -24
  29. universal_mcp/applications/wrike/app.py +565 -237
  30. universal_mcp/applications/youtube/app.py +625 -183
  31. universal_mcp/applications/zenquotes/app.py +3 -3
  32. universal_mcp/exceptions.py +1 -0
  33. universal_mcp/integrations/__init__.py +11 -2
  34. universal_mcp/integrations/agentr.py +27 -4
  35. universal_mcp/integrations/integration.py +14 -6
  36. universal_mcp/logger.py +3 -56
  37. universal_mcp/servers/__init__.py +2 -1
  38. universal_mcp/servers/server.py +73 -77
  39. universal_mcp/stores/store.py +5 -3
  40. universal_mcp/tools/__init__.py +1 -1
  41. universal_mcp/tools/adapters.py +4 -1
  42. universal_mcp/tools/func_metadata.py +5 -6
  43. universal_mcp/tools/tools.py +108 -51
  44. universal_mcp/utils/docgen.py +121 -69
  45. universal_mcp/utils/docstring_parser.py +44 -21
  46. universal_mcp/utils/dump_app_tools.py +33 -23
  47. universal_mcp/utils/installation.py +199 -8
  48. universal_mcp/utils/openapi.py +121 -47
  49. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/METADATA +2 -2
  50. universal_mcp-0.1.8rc4.dist-info/RECORD +81 -0
  51. universal_mcp-0.1.8rc2.dist-info/RECORD +0 -71
  52. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/WHEEL +0 -0
  53. {universal_mcp-0.1.8rc2.dist-info → universal_mcp-0.1.8rc4.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@ from universal_mcp.integrations import Integration
6
6
 
7
7
  class NotionApp(APIApplication):
8
8
  def __init__(self, integration: Integration = None, **kwargs) -> None:
9
- super().__init__(name='notion', integration=integration, **kwargs)
9
+ super().__init__(name="notion", integration=integration, **kwargs)
10
10
  self.base_url = "https://api.notion.com"
11
11
 
12
12
  def _get_headers(self):
@@ -19,23 +19,23 @@ class NotionApp(APIApplication):
19
19
  "Authorization": f"Bearer {credentials['access_token']}",
20
20
  "Accept": "application/json",
21
21
  "Notion-Version": "2022-06-28",
22
- }
22
+ }
23
23
 
24
24
  def retrieve_a_user(self, id, request_body=None) -> dict[str, Any]:
25
25
  """
26
26
  Retrieves a user's details from the server using their unique identifier.
27
-
27
+
28
28
  Args:
29
29
  id: The unique identifier of the user to retrieve
30
30
  request_body: Optional request body data for the request. Defaults to None
31
-
31
+
32
32
  Returns:
33
33
  A dictionary containing user details retrieved from the server response
34
-
34
+
35
35
  Raises:
36
36
  ValueError: Raised when the 'id' parameter is None
37
37
  requests.exceptions.HTTPError: Raised when the server returns an unsuccessful status code
38
-
38
+
39
39
  Tags:
40
40
  retrieve, get, user, api, single-record, important
41
41
  """
@@ -47,20 +47,22 @@ class NotionApp(APIApplication):
47
47
  response.raise_for_status()
48
48
  return response.json()
49
49
 
50
- def list_all_users(self, ) -> dict[str, Any]:
50
+ def list_all_users(
51
+ self,
52
+ ) -> dict[str, Any]:
51
53
  """
52
54
  Retrieves a complete list of users from the API endpoint.
53
-
55
+
54
56
  Args:
55
57
  None: This method does not take any parameters.
56
-
58
+
57
59
  Returns:
58
60
  dict[str, Any]: A dictionary containing user data where keys are strings and values can be of any type, representing user information retrieved from the API.
59
-
61
+
60
62
  Raises:
61
63
  HTTPError: Raised when the API request fails or returns a non-200 status code
62
64
  RequestException: Raised when there are network connectivity issues or other request-related problems
63
-
65
+
64
66
  Tags:
65
67
  list, users, api, fetch, management, important
66
68
  """
@@ -70,17 +72,19 @@ class NotionApp(APIApplication):
70
72
  response.raise_for_status()
71
73
  return response.json()
72
74
 
73
- def retrieve_your_token_sbot_user(self, ) -> dict[str, Any]:
75
+ def retrieve_your_token_sbot_user(
76
+ self,
77
+ ) -> dict[str, Any]:
74
78
  """
75
79
  Retrieves the current user's authentication token information from the SBOT service.
76
-
80
+
77
81
  Returns:
78
82
  A dictionary containing the authentication token and related user information from the JSON response.
79
-
83
+
80
84
  Raises:
81
85
  requests.exceptions.HTTPError: When the API request fails or returns a non-200 status code
82
86
  requests.exceptions.RequestException: When there are network connectivity issues or other request-related problems
83
-
87
+
84
88
  Tags:
85
89
  retrieve, authentication, token, user, api, important
86
90
  """
@@ -93,17 +97,17 @@ class NotionApp(APIApplication):
93
97
  def retrieve_a_database(self, id) -> dict[str, Any]:
94
98
  """
95
99
  Retrieves detailed information about a specific database using its unique identifier.
96
-
100
+
97
101
  Args:
98
102
  id: Unique identifier for the database to retrieve. Must be a non-null value.
99
-
103
+
100
104
  Returns:
101
105
  A dictionary containing detailed information about the requested database.
102
-
106
+
103
107
  Raises:
104
108
  ValueError: Raised when the 'id' parameter is None
105
109
  HTTPError: Raised when the API request fails or returns an error status code
106
-
110
+
107
111
  Tags:
108
112
  retrieve, get, database, api, data-access, important
109
113
  """
@@ -118,18 +122,18 @@ class NotionApp(APIApplication):
118
122
  def update_a_database(self, id, request_body=None) -> dict[str, Any]:
119
123
  """
120
124
  Updates a database entry with the specified ID using a PATCH request.
121
-
125
+
122
126
  Args:
123
127
  id: The unique identifier of the database entry to update.
124
128
  request_body: Optional dictionary containing the fields and values to update. Defaults to None.
125
-
129
+
126
130
  Returns:
127
131
  dict[str, Any]: A dictionary containing the server's JSON response after the update operation.
128
-
132
+
129
133
  Raises:
130
134
  ValueError: When the 'id' parameter is None.
131
135
  requests.exceptions.HTTPError: When the server returns an unsuccessful status code.
132
-
136
+
133
137
  Tags:
134
138
  update, database, patch, important, api, management
135
139
  """
@@ -144,18 +148,18 @@ class NotionApp(APIApplication):
144
148
  def query_a_database(self, id, request_body=None) -> dict[str, Any]:
145
149
  """
146
150
  Executes a database query operation using a specified database ID and optional request parameters
147
-
151
+
148
152
  Args:
149
153
  id: The unique identifier of the database to query
150
154
  request_body: Optional JSON-compatible dictionary representing the body of the query request; if None, no additional query data is sent
151
-
155
+
152
156
  Returns:
153
157
  A dictionary containing the response data from the database query as parsed from JSON
154
-
158
+
155
159
  Raises:
156
160
  ValueError: Raised when the required 'id' parameter is None
157
161
  HTTPError: Raised when the HTTP request fails or returns an error status code
158
-
162
+
159
163
  Tags:
160
164
  query, database, api, data-retrieval, http, important
161
165
  """
@@ -170,18 +174,18 @@ class NotionApp(APIApplication):
170
174
  def create_a_database(self, request_body=None) -> dict[str, Any]:
171
175
  """
172
176
  Creates a new database on the server by sending a POST request to the database endpoint.
173
-
177
+
174
178
  Args:
175
179
  request_body: Optional dictionary containing configuration parameters for the new database. Defaults to None.
176
-
180
+
177
181
  Returns:
178
182
  A dictionary containing the server's JSON response with details of the created database.
179
-
183
+
180
184
  Raises:
181
185
  HTTPError: Raised when the server returns a non-200 status code indicating database creation failure
182
186
  RequestException: Raised when network connectivity issues occur during the API request
183
187
  JSONDecodeError: Raised when the server response cannot be parsed as valid JSON
184
-
188
+
185
189
  Tags:
186
190
  create, database, api, management, important
187
191
  """
@@ -194,17 +198,17 @@ class NotionApp(APIApplication):
194
198
  def create_a_page(self, request_body=None) -> dict[str, Any]:
195
199
  """
196
200
  Creates a new page by sending a POST request to the API endpoint.
197
-
201
+
198
202
  Args:
199
203
  request_body: Optional dictionary containing the page data to be sent in the POST request body. Defaults to None.
200
-
204
+
201
205
  Returns:
202
206
  Dictionary containing the JSON response from the server with details of the newly created page.
203
-
207
+
204
208
  Raises:
205
209
  HTTPError: When the server returns a non-200 status code, indicating a failed request
206
210
  RequestException: When network-related issues occur during the API request
207
-
211
+
208
212
  Tags:
209
213
  create, page, api, http, post, important
210
214
  """
@@ -217,17 +221,17 @@ class NotionApp(APIApplication):
217
221
  def retrieve_a_page(self, id) -> dict[str, Any]:
218
222
  """
219
223
  Retrieves a specific page's data from a remote server using its unique identifier.
220
-
224
+
221
225
  Args:
222
226
  id: The unique identifier of the page to retrieve
223
-
227
+
224
228
  Returns:
225
229
  A dictionary containing the page data returned from the server's JSON response
226
-
230
+
227
231
  Raises:
228
232
  ValueError: When the 'id' parameter is None
229
233
  HTTPError: When the server returns an unsuccessful status code
230
-
234
+
231
235
  Tags:
232
236
  retrieve, fetch, api, http, get, page, important
233
237
  """
@@ -242,19 +246,19 @@ class NotionApp(APIApplication):
242
246
  def update_page_properties(self, id, request_body=None) -> dict[str, Any]:
243
247
  """
244
248
  Updates the properties of a page with the specified ID using the provided request body.
245
-
249
+
246
250
  Args:
247
251
  id: The unique identifier of the page to update. Must not be None.
248
252
  request_body: Optional dictionary containing the properties to be updated. Defaults to None.
249
-
253
+
250
254
  Returns:
251
255
  Dictionary containing the updated page properties as returned by the server.
252
-
256
+
253
257
  Raises:
254
258
  ValueError: When the required 'id' parameter is None
255
259
  HTTPError: When the server returns an unsuccessful status code
256
260
  RequestException: When there is an error making the HTTP request
257
-
261
+
258
262
  Tags:
259
263
  update, api, page-management, http, important
260
264
  """
@@ -269,18 +273,18 @@ class NotionApp(APIApplication):
269
273
  def retrieve_a_page_property_item(self, page_id, property_id) -> dict[str, Any]:
270
274
  """
271
275
  Retrieves a specific property item from a Notion page using the page ID and property ID.
272
-
276
+
273
277
  Args:
274
278
  page_id: The unique identifier of the Notion page from which to retrieve the property
275
279
  property_id: The unique identifier of the specific property to retrieve
276
-
280
+
277
281
  Returns:
278
282
  A dictionary containing the property item's details from the API response
279
-
283
+
280
284
  Raises:
281
285
  ValueError: When either page_id or property_id is None
282
286
  HTTPError: When the API request fails or returns an error status code
283
-
287
+
284
288
  Tags:
285
289
  retrieve, get, property, page, api, notion, important
286
290
  """
@@ -297,25 +301,25 @@ class NotionApp(APIApplication):
297
301
  def retrieve_block_children(self, id, page_size=None) -> dict[str, Any]:
298
302
  """
299
303
  Retrieves all child blocks for a specified parent block using its ID via the API.
300
-
304
+
301
305
  Args:
302
306
  id: The unique identifier of the parent block whose children are to be retrieved
303
307
  page_size: Optional integer specifying the maximum number of children to return per page in the response
304
-
308
+
305
309
  Returns:
306
310
  A dictionary containing the API response data with the children blocks information
307
-
311
+
308
312
  Raises:
309
313
  ValueError: When the required 'id' parameter is None
310
314
  HTTPError: When the API request fails or returns an error status code
311
-
315
+
312
316
  Tags:
313
317
  retrieve, list, blocks, children, pagination, api-call, important
314
318
  """
315
319
  if id is None:
316
320
  raise ValueError("Missing required parameter 'id'")
317
321
  url = f"{self.base_url}/v1/blocks/{id}/children"
318
- query_params = {k: v for k, v in [('page_size', page_size)] if v is not None}
322
+ query_params = {k: v for k, v in [("page_size", page_size)] if v is not None}
319
323
  response = self._get(url, params=query_params)
320
324
  response.raise_for_status()
321
325
  return response.json()
@@ -323,18 +327,18 @@ class NotionApp(APIApplication):
323
327
  def append_block_children(self, id, request_body=None) -> dict[str, Any]:
324
328
  """
325
329
  Appends child elements to a specified block and returns the updated block data.
326
-
330
+
327
331
  Args:
328
332
  id: String identifier of the block to which children will be appended
329
333
  request_body: Optional dictionary containing the child elements to be appended (default: None)
330
-
334
+
331
335
  Returns:
332
336
  dict[str, Any]: A dictionary containing the updated block data after appending the children
333
-
337
+
334
338
  Raises:
335
339
  ValueError: When the required 'id' parameter is None
336
340
  HTTPError: When the API request fails or returns an error status code
337
-
341
+
338
342
  Tags:
339
343
  append, update, blocks, children, api, important
340
344
  """
@@ -349,17 +353,17 @@ class NotionApp(APIApplication):
349
353
  def retrieve_a_block(self, id) -> dict[str, Any]:
350
354
  """
351
355
  Retrieves a specific block of data from the API using its unique identifier.
352
-
356
+
353
357
  Args:
354
358
  id: The unique identifier for the block to be retrieved. Must be a non-None value.
355
-
359
+
356
360
  Returns:
357
361
  A dictionary containing the block data retrieved from the API, parsed from the JSON response.
358
-
362
+
359
363
  Raises:
360
364
  ValueError: When the 'id' parameter is None
361
365
  HTTPError: When the API request fails or returns an error status code
362
-
366
+
363
367
  Tags:
364
368
  retrieve, fetch, api, data, block, single, important
365
369
  """
@@ -374,17 +378,17 @@ class NotionApp(APIApplication):
374
378
  def delete_a_block(self, id) -> dict[str, Any]:
375
379
  """
376
380
  Deletes a specified block by its ID and returns the server response.
377
-
381
+
378
382
  Args:
379
383
  id: The unique identifier of the block to be deleted. Must not be None.
380
-
384
+
381
385
  Returns:
382
386
  A dictionary containing the server's response data after the deletion operation.
383
-
387
+
384
388
  Raises:
385
389
  ValueError: When the 'id' parameter is None
386
390
  HTTPError: When the server returns an unsuccessful status code
387
-
391
+
388
392
  Tags:
389
393
  delete, important, management, api, http, block-management
390
394
  """
@@ -399,18 +403,18 @@ class NotionApp(APIApplication):
399
403
  def update_a_block(self, id, request_body=None) -> dict[str, Any]:
400
404
  """
401
405
  Updates a specific block resource via a PATCH request to the API endpoint
402
-
406
+
403
407
  Args:
404
408
  id: The unique identifier of the block to update
405
409
  request_body: Optional dictionary containing the update data for the block. Defaults to None
406
-
410
+
407
411
  Returns:
408
412
  Dictionary containing the server's JSON response with the updated block information
409
-
413
+
410
414
  Raises:
411
415
  ValueError: When the required 'id' parameter is None
412
416
  HTTPError: When the server responds with an error status code
413
-
417
+
414
418
  Tags:
415
419
  update, patch, api, block-management, important
416
420
  """
@@ -425,17 +429,17 @@ class NotionApp(APIApplication):
425
429
  def search(self, request_body=None) -> dict[str, Any]:
426
430
  """
427
431
  Executes a search operation by sending a POST request to the search endpoint and returns the results
428
-
432
+
429
433
  Args:
430
434
  request_body: Optional dictionary containing the search parameters and filters to be sent in the request. Defaults to None.
431
-
435
+
432
436
  Returns:
433
437
  A dictionary containing the parsed JSON response from the search operation with search results and metadata
434
-
438
+
435
439
  Raises:
436
440
  HTTPError: Raised when the search request fails or returns a non-200 status code
437
441
  JSONDecodeError: Raised when the response cannot be parsed as valid JSON
438
-
442
+
439
443
  Tags:
440
444
  search, important, http, query, api-request, json
441
445
  """
@@ -445,27 +449,33 @@ class NotionApp(APIApplication):
445
449
  response.raise_for_status()
446
450
  return response.json()
447
451
 
448
- def retrieve_comments(self, block_id=None, page_size=None, request_body=None) -> dict[str, Any]:
452
+ def retrieve_comments(
453
+ self, block_id=None, page_size=None, request_body=None
454
+ ) -> dict[str, Any]:
449
455
  """
450
456
  Retrieves comments from a remote server with optional block filtering and pagination support.
451
-
457
+
452
458
  Args:
453
459
  block_id: Optional string or ID that specifies which block's comments to retrieve. If None, retrieves all comments.
454
460
  page_size: Optional integer specifying the number of comments to return per page. If None, uses server's default pagination.
455
461
  request_body: Optional dictionary for future extensibility. Currently unused.
456
-
462
+
457
463
  Returns:
458
464
  Dictionary containing comment data parsed from the server's JSON response.
459
-
465
+
460
466
  Raises:
461
467
  HTTPError: Raised when the server returns a non-200 status code
462
468
  RequestException: Raised for network-related errors during the HTTP request
463
-
469
+
464
470
  Tags:
465
471
  retrieve, fetch, comments, api, pagination, http, important
466
472
  """
467
473
  url = f"{self.base_url}/v1/comments"
468
- query_params = {k: v for k, v in [('block_id', block_id), ('page_size', page_size)] if v is not None}
474
+ query_params = {
475
+ k: v
476
+ for k, v in [("block_id", block_id), ("page_size", page_size)]
477
+ if v is not None
478
+ }
469
479
  response = self._get(url, params=query_params)
470
480
  response.raise_for_status()
471
481
  return response.json()
@@ -473,17 +483,17 @@ class NotionApp(APIApplication):
473
483
  def add_comment_to_page(self, request_body=None) -> dict[str, Any]:
474
484
  """
475
485
  Adds a comment to a page by making an HTTP POST request to the comments endpoint.
476
-
486
+
477
487
  Args:
478
488
  request_body: Optional dictionary containing the comment data to be posted. If None, an empty comment will be created. Defaults to None.
479
-
489
+
480
490
  Returns:
481
491
  Dictionary containing the server's JSON response with details of the created comment.
482
-
492
+
483
493
  Raises:
484
494
  HTTPError: Raised when the server returns a non-200 status code, indicating the comment creation failed.
485
495
  RequestException: Raised when there are network connectivity issues or other request-related problems.
486
-
496
+
487
497
  Tags:
488
498
  add, create, comment, post, api, content-management, important
489
499
  """
@@ -513,5 +523,5 @@ class NotionApp(APIApplication):
513
523
  self.update_a_block,
514
524
  self.search,
515
525
  self.retrieve_comments,
516
- self.add_comment_to_page
526
+ self.add_comment_to_page,
517
527
  ]
@@ -1,7 +1,5 @@
1
1
  from typing import Any, Literal
2
2
 
3
- from loguru import logger
4
-
5
3
  from universal_mcp.applications.application import APIApplication
6
4
  from universal_mcp.integrations import Integration
7
5
 
@@ -12,38 +10,6 @@ class PerplexityApp(APIApplication):
12
10
  self.api_key: str | None = None
13
11
  self.base_url = "https://api.perplexity.ai"
14
12
 
15
- def _set_api_key(self):
16
- if self.api_key:
17
- return
18
-
19
- if not self.integration:
20
- raise ValueError("Integration is None. Cannot retrieve Perplexity API Key.")
21
-
22
- credentials = self.integration.get_credentials()
23
- if not credentials:
24
- raise ValueError(
25
- f"Failed to retrieve Perplexity API Key using integration '{self.integration.name}'. "
26
- )
27
- api_key = (
28
- credentials.get("api_key")
29
- or credentials.get("API_KEY")
30
- or credentials.get("apiKey")
31
- )
32
- if not api_key:
33
- raise ValueError(
34
- f"Invalid credential format received for Perplexity API Key via integration '{self.integration.name}'. "
35
- )
36
- self.api_key = api_key
37
-
38
- def _get_headers(self) -> dict[str, str]:
39
- self._set_api_key()
40
- logger.info(f"Perplexity API Key: {self.api_key}")
41
- return {
42
- "Authorization": f"Bearer {self.api_key}",
43
- "Content-Type": "application/json",
44
- "Accept": "application/json",
45
- }
46
-
47
13
  def chat(
48
14
  self,
49
15
  query: str,
@@ -60,20 +26,20 @@ class PerplexityApp(APIApplication):
60
26
  ) -> dict[str, Any] | str:
61
27
  """
62
28
  Initiates a chat completion request to generate AI responses using various models with customizable parameters.
63
-
29
+
64
30
  Args:
65
31
  query: The input text/prompt to send to the chat model
66
32
  model: The model to use for chat completion. Options include 'r1-1776', 'sonar', 'sonar-pro', 'sonar-reasoning', 'sonar-reasoning-pro', 'sonar-deep-research'. Defaults to 'sonar'
67
33
  temperature: Controls randomness in the model's output. Higher values make output more random, lower values more deterministic. Defaults to 1
68
34
  system_prompt: Initial system message to guide the model's behavior. Defaults to 'Be precise and concise.'
69
-
35
+
70
36
  Returns:
71
37
  A dictionary containing the generated content and citations, with keys 'content' (str) and 'citations' (list), or a string in some cases
72
-
38
+
73
39
  Raises:
74
40
  AuthenticationError: Raised when API authentication fails due to missing or invalid credentials
75
41
  HTTPError: Raised when the API request fails or returns an error status
76
-
42
+
77
43
  Tags:
78
44
  chat, generate, ai, completion, important
79
45
  """