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
@@ -12,11 +12,11 @@ class GoogleSheetApp(APIApplication):
12
12
  Application for interacting with Google Sheets API.
13
13
  Provides tools to create and manage Google Spreadsheets.
14
14
  """
15
-
15
+
16
16
  def __init__(self, integration: Integration | None = None) -> None:
17
17
  super().__init__(name="google-sheet", integration=integration)
18
18
  self.base_api_url = "https://sheets.googleapis.com/v4/spreadsheets"
19
-
19
+
20
20
  def _get_headers(self):
21
21
  if not self.integration:
22
22
  raise ValueError("Integration not configured for GoogleSheetsApp")
@@ -31,122 +31,138 @@ class GoogleSheetApp(APIApplication):
31
31
  "Authorization": f"Bearer {credentials['access_token']}",
32
32
  "Content-Type": "application/json",
33
33
  }
34
-
34
+
35
35
  def create_spreadsheet(self, title: str) -> dict[str, Any]:
36
36
  """
37
- Creates a new blank Google Spreadsheet with the specified title.
38
-
37
+ Creates a new blank Google Spreadsheet with the specified title and returns the API response.
38
+
39
39
  Args:
40
- title: The title of the spreadsheet to create required , which is provided by the user
41
-
40
+ title: String representing the desired title for the new spreadsheet
41
+
42
42
  Returns:
43
- The response from the Google Sheets API
43
+ Dictionary containing the full response from the Google Sheets API, including the spreadsheet's metadata and properties
44
+
45
+ Raises:
46
+ HTTPError: When the API request fails due to invalid authentication, network issues, or API limitations
47
+ ValueError: When the title parameter is empty or contains invalid characters
48
+
49
+ Tags:
50
+ create, spreadsheet, google-sheets, api, important
44
51
  """
45
52
  url = self.base_api_url
46
- spreadsheet_data = {
47
- "properties": {
48
- "title": title
49
- }
50
- }
51
-
53
+ spreadsheet_data = {"properties": {"title": title}}
52
54
  response = self._post(url, data=spreadsheet_data)
53
55
  return response.json()
54
-
56
+
55
57
  def get_spreadsheet(self, spreadsheet_id: str) -> dict[str, Any]:
56
58
  """
57
- Returns the spreadsheet details.
58
-
59
+ Retrieves detailed information about a specific Google Spreadsheet using its ID.
60
+
59
61
  Args:
60
- spreadsheet_id: The ID of the spreadsheet to retrieve
61
-
62
+ spreadsheet_id: The unique identifier of the Google Spreadsheet to retrieve (found in the spreadsheet's URL)
63
+
62
64
  Returns:
63
- The response from the Google Sheets API containing the spreadsheet data and details
65
+ A dictionary containing the full spreadsheet metadata and contents, including properties, sheets, named ranges, and other spreadsheet-specific information from the Google Sheets API
66
+
67
+ Raises:
68
+ HTTPError: When the API request fails due to invalid spreadsheet_id or insufficient permissions
69
+ ConnectionError: When there's a network connectivity issue
70
+ ValueError: When the response cannot be parsed as JSON
71
+
72
+ Tags:
73
+ get, retrieve, spreadsheet, api, metadata, read, important
64
74
  """
65
75
  url = f"{self.base_api_url}/{spreadsheet_id}"
66
76
  response = self._get(url)
67
77
  return response.json()
68
-
69
- def batch_get_values(self, spreadsheet_id: str, ranges: list[str] = None) -> dict[str, Any]:
78
+
79
+ def batch_get_values(
80
+ self, spreadsheet_id: str, ranges: list[str] = None
81
+ ) -> dict[str, Any]:
70
82
  """
71
- Returns one or more ranges of values from a spreadsheet.
72
-
83
+ Retrieves multiple ranges of values from a Google Spreadsheet in a single batch request.
84
+
73
85
  Args:
74
- spreadsheet_id: The ID of the spreadsheet to retrieve values from
75
- ranges: Optional list of A1 notation or R1C1 notation ranges to retrieve values from
76
- (e.g. ['Sheet1!A1:B2', 'Sheet2!C3:D4'])
77
-
86
+ spreadsheet_id: The unique identifier of the Google Spreadsheet to retrieve values from
87
+ ranges: Optional list of A1 notation or R1C1 notation range strings (e.g., ['Sheet1!A1:B2', 'Sheet2!C3:D4']). If None, returns values from the entire spreadsheet
88
+
78
89
  Returns:
79
- The response from the Google Sheets API containing the requested values
90
+ A dictionary containing the API response with the requested spreadsheet values and metadata
91
+
92
+ Raises:
93
+ HTTPError: If the API request fails due to invalid spreadsheet_id, insufficient permissions, or invalid range format
94
+ ValueError: If the spreadsheet_id is empty or invalid
95
+
96
+ Tags:
97
+ get, batch, read, spreadsheet, values, important
80
98
  """
81
99
  url = f"{self.base_api_url}/{spreadsheet_id}/values:batchGet"
82
-
83
100
  params = {}
84
101
  if ranges:
85
102
  params["ranges"] = ranges
86
-
87
103
  response = self._get(url, params=params)
88
104
  return response.json()
89
-
105
+
90
106
  def clear_values(self, spreadsheet_id: str, range: str) -> dict[str, Any]:
91
107
  """
92
- Clears values from a spreadsheet. Only values are cleared -- all other properties
93
- of the cell (such as formatting, data validation, etc.) are kept.
94
-
108
+ Clears all values from a specified range in a Google Spreadsheet while preserving cell formatting and other properties
109
+
95
110
  Args:
96
- spreadsheet_id: The ID of the spreadsheet to update
97
- range: The A1 notation or R1C1 notation of the values to clear
98
- (e.g. 'Sheet1!A1:B2')
99
-
111
+ spreadsheet_id: The unique identifier of the Google Spreadsheet to modify
112
+ range: The A1 or R1C1 notation range of cells to clear (e.g., 'Sheet1!A1:B2')
113
+
100
114
  Returns:
101
- The response from the Google Sheets API
115
+ A dictionary containing the Google Sheets API response
116
+
117
+ Raises:
118
+ HttpError: When the API request fails due to invalid spreadsheet_id, invalid range format, or insufficient permissions
119
+ ValueError: When spreadsheet_id is empty or range is in invalid format
120
+
121
+ Tags:
122
+ clear, modify, spreadsheet, api, sheets, data-management, important
102
123
  """
103
124
  url = f"{self.base_api_url}/{spreadsheet_id}/values/{range}:clear"
104
-
105
125
  response = self._post(url, data={})
106
126
  return response.json()
107
-
127
+
108
128
  def update_values(
109
- self,
110
- spreadsheet_id: str,
111
- range: str,
112
- values: list[list[Any]],
113
- value_input_option: str = "RAW"
129
+ self,
130
+ spreadsheet_id: str,
131
+ range: str,
132
+ values: list[list[Any]],
133
+ value_input_option: str = "RAW",
114
134
  ) -> dict[str, Any]:
115
135
  """
116
- Sets values in a range of a spreadsheet.
117
-
136
+ Updates cell values in a specified range of a Google Spreadsheet using the Sheets API
137
+
118
138
  Args:
119
- spreadsheet_id: The ID of the spreadsheet to update
120
- range: The A1 notation of the values to update (e.g. 'Sheet1!A1:B2')
121
- values: The data to write, as a list of lists (rows of values)
122
- value_input_option: How the input data should be interpreted.
123
- Accepted values are:
124
- - "RAW": The values will be stored as-is
125
- - "USER_ENTERED": The values will be parsed as if the user typed them into the UI
126
-
139
+ spreadsheet_id: The unique identifier of the target Google Spreadsheet
140
+ range: The A1 notation range where values will be updated (e.g., 'Sheet1!A1:B2')
141
+ values: A list of lists containing the data to write, where each inner list represents a row of values
142
+ value_input_option: Determines how input data should be interpreted: 'RAW' (as-is) or 'USER_ENTERED' (parsed as UI input). Defaults to 'RAW'
143
+
127
144
  Returns:
128
- The response from the Google Sheets API
145
+ A dictionary containing the Google Sheets API response with update details
146
+
147
+ Raises:
148
+ RequestError: When the API request fails due to invalid parameters or network issues
149
+ AuthenticationError: When authentication with the Google Sheets API fails
150
+
151
+ Tags:
152
+ update, write, sheets, api, important, data-modification, google-sheets
129
153
  """
130
154
  url = f"{self.base_api_url}/{spreadsheet_id}/values/{range}"
131
-
132
- params = {
133
- "valueInputOption": value_input_option
134
- }
135
-
136
- data = {
137
- "range": range,
138
- "values": values
139
- }
140
-
155
+ params = {"valueInputOption": value_input_option}
156
+ data = {"range": range, "values": values}
141
157
  response = self._put(url, data=data, params=params)
142
158
  return response.json()
143
-
159
+
144
160
  def list_tools(self):
145
161
  """Returns a list of methods exposed as tools."""
146
162
  return [
147
- self.create_spreadsheet,
148
- self.get_spreadsheet,
149
- self.batch_get_values,
150
- self.clear_values,
151
- self.update_values
163
+ self.create_spreadsheet,
164
+ self.get_spreadsheet,
165
+ self.batch_get_values,
166
+ self.clear_values,
167
+ self.update_values,
152
168
  ]
@@ -9,7 +9,8 @@ class MarkitdownApp(Application):
9
9
  self.markitdown = MarkItDown()
10
10
 
11
11
  async def convert_to_markdown(self, uri: str) -> str:
12
- """Fetches content from a URI and converts its primary textual representation into Markdown.
12
+ """
13
+ Asynchronously converts a URI to markdown format using the markitdown converter.
13
14
 
14
15
  This tool aims to extract the main text content from various sources. It supports:
15
16
  - Web Pages: General HTML, specific handlers for RSS/Atom feeds, Wikipedia articles (main content), YouTube (transcripts if available), Bing SERPs.
@@ -19,9 +20,6 @@ class MarkitdownApp(Application):
19
20
  - Audio: Extracts metadata and attempts transcription to get text.
20
21
  - Archives: ZIP (extracts and attempts to convert supported files within, concatenating results).
21
22
 
22
- Note: Conversion quality depends on the source format. Complex layouts, encrypted files, or missing transcripts/OCR data may limit output.
23
- Enhanced PDF/Image processing via Azure Document Intelligence may be active if configured server-side.
24
-
25
23
  Args:
26
24
  uri (str): The URI pointing to the resource. Supported schemes:
27
25
  - http:// or https:// (Web pages, feeds, APIs)
@@ -29,11 +27,14 @@ class MarkitdownApp(Application):
29
27
  - data: (Embedded data)
30
28
 
31
29
  Returns:
32
- str: The extracted content converted to Markdown format.
30
+ A string containing the markdown representation of the content at the specified URI
31
+
32
+ Raises:
33
+ ValueError: If the URI is invalid or empty
34
+ ConnectionError: If the URI cannot be accessed or content cannot be retrieved
33
35
 
34
- Example:
35
- >>> await convert_to_markdown("https://example.com")
36
- "# Example Domain\n\nThis domain is for use in illustrative examples..."
36
+ Tags:
37
+ convert, markdown, async, uri, transform, document
37
38
  """
38
39
  return self.markitdown.convert_uri(uri).markdown
39
40