universal-mcp-applications 0.1.22__py3-none-any.whl → 0.1.24__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.
@@ -3,18 +3,20 @@ from typing import Annotated
3
3
  from universal_mcp.applications.application import APIApplication
4
4
  from universal_mcp.integrations import Integration
5
5
 
6
- from browser_use import BrowserUseClient
6
+ from browser_use_sdk import BrowserUse
7
7
 
8
8
 
9
9
  class BrowserUseApp(APIApplication):
10
- def __init__(self, integration: Integration = None, **kwargs) -> None:
10
+ def __init__(self, integration: Integration | None = None, **kwargs) -> None:
11
11
  super().__init__(name="browser_use", integration=integration, **kwargs)
12
- self._client = None
12
+ self._browser_client = None
13
13
 
14
14
  @property
15
- def client(self) -> BrowserUseClient:
16
- if self._client is not None:
17
- return self._client
15
+ def browser_client(self) -> BrowserUse:
16
+ if self._browser_client is not None:
17
+ return self._browser_client
18
+ if not self.integration:
19
+ raise ValueError("Integration is required but not provided")
18
20
  credentials = self.integration.get_credentials()
19
21
  api_key = (
20
22
  credentials.get("api_key")
@@ -23,8 +25,8 @@ class BrowserUseApp(APIApplication):
23
25
  )
24
26
  if not api_key:
25
27
  raise ValueError("API key not found in integration credentials")
26
- self._client = BrowserUseClient(api_key=api_key)
27
- return self._client
28
+ self._browser_client = BrowserUse(api_key=api_key)
29
+ return self._browser_client
28
30
 
29
31
  async def browser_task(
30
32
  self,
@@ -43,34 +45,27 @@ class BrowserUseApp(APIApplication):
43
45
  Returns:
44
46
  dict: The result of the completed task, including output and other metadata.
45
47
  """
46
- created_task = self.client.tasks.create_task(
48
+ created_task = self.browser_client.tasks.create_task(
47
49
  llm=llm, task=task, max_steps=max_steps
48
50
  )
49
51
  result = created_task.complete()
50
- return result.to_dict()
52
+ return result.model_dump()
51
53
 
52
54
  async def get_browser_task_status(
53
55
  self,
54
56
  task_id: Annotated[str, "Task ID to check"],
55
- enable_polling: Annotated[bool, "Auto-poll for 28s (default: true)"] = True,
56
57
  ) -> dict:
57
58
  """
58
59
  Checks task progress with smart polling.
59
60
 
60
61
  Args:
61
62
  task_id (str): The ID of the task to check.
62
- enable_polling (bool, optional): If true, polls for the task status for up to 28 seconds. Defaults to True.
63
63
 
64
64
  Returns:
65
65
  dict: The current status and details of the task.
66
66
  """
67
- if enable_polling:
68
- task = self.client.tasks.get(task_id)
69
- result = task.poll()
70
- return result.to_dict()
71
- else:
72
- task = self.client.tasks.get(task_id)
73
- return task.to_dict()
67
+ task = self.browser_client.tasks.get_task(task_id)
68
+ return task.model_dump()
74
69
 
75
70
  def list_tools(self):
76
71
  return [self.browser_task, self.get_browser_task_status]
@@ -11,18 +11,18 @@ class GoogleDocsApp(APIApplication):
11
11
 
12
12
  def create_document(self, title: str) -> dict[str, Any]:
13
13
  """
14
- Creates a blank Google Document with a specified title using a POST request to the Google Docs API. This is the primary creation method, returning the document's metadata, including the ID required by functions like `get_document` or `insert_text` to perform subsequent operations on the new file.
15
-
14
+ Creates a blank Google Document with a specified title by sending a POST request to the Google Docs API. The function returns a dictionary containing the new document's metadata, including the unique document ID required by other functions for subsequent modifications or retrieval.
15
+
16
16
  Args:
17
- title: The title for the new Google Document to be created
18
-
17
+ title: The title for the new Google Document to be created.
18
+
19
19
  Returns:
20
- A dictionary containing the Google Docs API response with document details and metadata
21
-
20
+ A dictionary containing the response from the Google Docs API with document details and metadata.
21
+
22
22
  Raises:
23
- HTTPError: If the API request fails due to network issues, authentication errors, or invalid parameters
24
- RequestException: If there are connection errors or timeout issues during the API request
25
-
23
+ HTTPError: If the API request fails due to network issues, authentication errors, or invalid parameters.
24
+ RequestException: If there are connection errors or timeout issues during the API request.
25
+
26
26
  Tags:
27
27
  create, document, api, important, google-docs, http
28
28
  """
@@ -34,18 +34,18 @@ class GoogleDocsApp(APIApplication):
34
34
 
35
35
  def get_document(self, document_id: str) -> dict[str, Any]:
36
36
  """
37
- Retrieves the complete content and metadata for a specific Google Document using its unique ID. This function performs a GET request to the API, returning the full JSON response. It's the primary read operation, contrasting with `create_document` which creates new documents.
38
-
37
+ Retrieves the complete, raw JSON object for a Google Document by its ID. This function returns the full, unprocessed API response with all metadata and structural elements, distinguishing it from `get_document_content`, which parses this data to extract only the title and plain text.
38
+
39
39
  Args:
40
- document_id: The unique identifier of the document to retrieve
41
-
40
+ document_id: The unique identifier of the Google Document to retrieve.
41
+
42
42
  Returns:
43
- A dictionary containing the document data from the Google Docs API response
44
-
43
+ A dictionary containing the complete document data as returned by the Google Docs API.
44
+
45
45
  Raises:
46
- HTTPError: If the API request fails or the document is not found
47
- JSONDecodeError: If the API response cannot be parsed as JSON
48
-
46
+ HTTPError: If the API request fails or the specified document cannot be found.
47
+ JSONDecodeError: If the API response is not valid JSON and cannot be parsed.
48
+
49
49
  Tags:
50
50
  retrieve, read, api, document, google-docs, important
51
51
  """
@@ -53,24 +53,57 @@ class GoogleDocsApp(APIApplication):
53
53
  response = self._get(url)
54
54
  return response.json()
55
55
 
56
+ def get_document_content(self, document_id: str) -> dict[str, Any]:
57
+ """
58
+ Retrieves a document's raw data via `get_document`, then parses the complex JSON to extract and concatenate all plain text from its body. This function returns a simplified dictionary containing only the title and the clean, concatenated text content, distinct from `get_document`'s full metadata response.
59
+
60
+ Args:
61
+ document_id: The unique identifier of the Google Document to retrieve.
62
+
63
+ Returns:
64
+ A dictionary containing the document's title under the key 'title' and the concatenated plain text content under the key 'content'.
65
+
66
+ Raises:
67
+ KeyError: If the response structure from get_document is missing expected keys such as 'body' or 'content', a KeyError may be raised during extraction.
68
+ Exception: Any exception raised by the underlying get_document call, such as network errors or API issues, will propagate.
69
+
70
+ Tags:
71
+ retrieve, document, text-processing, parsing, important
72
+ """
73
+ response = self.get_document(document_id)
74
+ title = response.get("title", "")
75
+ text_chunks: list[str] = []
76
+ body_content = response.get("body", {}).get("content", [])
77
+ for element in body_content:
78
+ if "paragraph" in element:
79
+ for para_elem in element["paragraph"].get("elements", []):
80
+ text_run = para_elem.get("textRun")
81
+ if text_run and "content" in text_run:
82
+ text_chunks.append(text_run["content"])
83
+ content = "".join(text_chunks).strip()
84
+ return {
85
+ "title": title,
86
+ "content": content,
87
+ }
88
+
56
89
  def insert_text(
57
90
  self, document_id: str, content: str, index: int = 1
58
91
  ) -> dict[str, Any]:
59
92
  """
60
- Inserts a text string at a specified index within an existing Google Document using the `batchUpdate` API. This function adds new textual content, distinguishing it from functions that insert non-text elements like tables or apply formatting (`apply_text_style`) to existing content.
61
-
93
+ Inserts a text string at a specified index within a Google Document using the batchUpdate API. Unlike functions that format existing text or delete content ranges, this method specifically adds new textual content to the document body.
94
+
62
95
  Args:
63
- document_id: The unique identifier of the Google Document to be updated
64
- content: The text content to be inserted into the document
65
- index: The zero-based position in the document where the text should be inserted (default: 1)
66
-
96
+ document_id: The unique identifier of the Google Document to be updated.
97
+ content: The text content to be inserted into the document.
98
+ index: The zero-based position in the document where the text should be inserted (default is 1).
99
+
67
100
  Returns:
68
- A dictionary containing the Google Docs API response after performing the batch update operation
69
-
101
+ A dictionary containing the Google Docs API response after performing the batch update operation.
102
+
70
103
  Raises:
71
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
72
- RequestException: When there are network connectivity issues or API endpoint problems
73
-
104
+ HTTPError: If the API request fails, for example due to invalid document_id or insufficient permissions.
105
+ RequestException: If there are network connectivity issues or problems contacting the API endpoint.
106
+
74
107
  Tags:
75
108
  update, insert, document, api, google-docs, batch, content-management, important
76
109
  """
@@ -98,56 +131,48 @@ class GoogleDocsApp(APIApplication):
98
131
  background_color: dict[str, float] | None = None,
99
132
  ) -> dict[str, Any]:
100
133
  """
101
- Applies character-level formatting such as bold, italic, font size, color, and hyperlinks to a specified text range in a document. This function modifies text appearance, distinguishing it from `update_paragraph_style`, which handles block-level formatting like alignment and headings.
102
-
134
+ Applies character-level formatting (e.g., bold, italic, color, links) to a specified text range. This function modifies text attributes directly, distinguishing it from `update_paragraph_style` which handles block-level properties like alignment.
135
+
103
136
  Args:
104
- document_id: The unique identifier of the Google Document to be updated
105
- start_index: The zero-based start index of the text range to style
106
- end_index: The zero-based end index of the text range to style (exclusive)
107
- bold: Whether the text should be bold
108
- italic: Whether the text should be italicized
109
- underline: Whether the text should be underlined
110
- font_size: The font size in points (e.g., 12.0 for 12pt)
111
- link_url: URL to make the text a hyperlink
112
- foreground_color: RGB color dict with 'red', 'green', 'blue' values (0.0 to 1.0)
113
- background_color: RGB color dict with 'red', 'green', 'blue' values (0.0 to 1.0)
114
-
137
+ document_id: The unique identifier of the Google Document to update.
138
+ start_index: The zero-based start index of the text range to apply the style.
139
+ end_index: The zero-based end index (exclusive) of the text range to apply the style.
140
+ bold: Whether to apply bold formatting to the text.
141
+ italic: Whether to apply italic formatting to the text.
142
+ underline: Whether to apply underline formatting to the text.
143
+ font_size: Font size in points (e.g., 12.0 for 12pt) to apply to the text.
144
+ link_url: URL to apply as a hyperlink to the text.
145
+ foreground_color: RGB color dictionary with 'red', 'green', and 'blue' floats (0.0 to 1.0) for the text color.
146
+ background_color: RGB color dictionary with 'red', 'green', and 'blue' floats (0.0 to 1.0) for the text background color.
147
+
115
148
  Returns:
116
- A dictionary containing the Google Docs API response
117
-
149
+ A dictionary containing the Google Docs API response, or a message if no styling was applied.
150
+
118
151
  Raises:
119
- HTTPError: When the API request fails
120
- RequestException: When there are network connectivity issues
121
-
152
+ HTTPError: If the Google Docs API request fails.
153
+ RequestException: If there are network connectivity issues during the API request.
154
+
122
155
  Tags:
123
- style, format, text, document, api, google-docs, simple
156
+ style, format, text, document, api, google-docs, important
124
157
  """
125
158
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
126
-
127
- # Build the text style object with only common properties
128
159
  text_style = {}
129
160
  fields_to_update = []
130
-
131
161
  if bold:
132
162
  text_style["bold"] = True
133
163
  fields_to_update.append("bold")
134
-
135
164
  if italic:
136
165
  text_style["italic"] = True
137
166
  fields_to_update.append("italic")
138
-
139
167
  if underline:
140
168
  text_style["underline"] = True
141
169
  fields_to_update.append("underline")
142
-
143
170
  if font_size is not None:
144
171
  text_style["fontSize"] = {"magnitude": font_size, "unit": "PT"}
145
172
  fields_to_update.append("fontSize")
146
-
147
173
  if link_url is not None:
148
174
  text_style["link"] = {"url": link_url}
149
175
  fields_to_update.append("link")
150
-
151
176
  if foreground_color is not None:
152
177
  text_style["foregroundColor"] = {
153
178
  "color": {
@@ -159,7 +184,6 @@ class GoogleDocsApp(APIApplication):
159
184
  }
160
185
  }
161
186
  fields_to_update.append("foregroundColor")
162
-
163
187
  if background_color is not None:
164
188
  text_style["backgroundColor"] = {
165
189
  "color": {
@@ -171,11 +195,8 @@ class GoogleDocsApp(APIApplication):
171
195
  }
172
196
  }
173
197
  fields_to_update.append("backgroundColor")
174
-
175
- # If no styling requested, return early
176
198
  if not text_style:
177
199
  return {"message": "No styling applied"}
178
-
179
200
  batch_update_data = {
180
201
  "requests": [
181
202
  {
@@ -187,7 +208,6 @@ class GoogleDocsApp(APIApplication):
187
208
  }
188
209
  ]
189
210
  }
190
-
191
211
  response = self._post(url, data=batch_update_data)
192
212
  return self._handle_response(response)
193
213
 
@@ -204,64 +224,51 @@ class GoogleDocsApp(APIApplication):
204
224
  tab_id: str | None = None,
205
225
  ) -> dict[str, Any]:
206
226
  """
207
- Applies paragraph-level formatting, such as named styles (e.g., 'HEADING_1'), alignment, or text direction, to a specified text range. This function handles block-level styles, distinguishing it from `apply_text_style`, which formats individual characters with attributes like bold or italic.
208
-
227
+ Applies paragraph-level formatting like alignment, named styles (e.g., 'HEADING_1'), and text direction to a text range in a Google Doc. Distinct from `apply_text_style`, which handles character formatting, this method modifies properties for entire paragraphs using the batchUpdate API.
228
+
209
229
  Args:
210
- document_id: The unique identifier of the Google Document to be updated
211
- start_index: The zero-based start index of the paragraph range to style
212
- end_index: The zero-based end index of the paragraph range to style (exclusive)
213
- named_style_type: The named style type (e.g., 'NORMAL_TEXT', 'TITLE', 'HEADING_1', etc.)
214
- alignment: The paragraph alignment ('START', 'CENTER', 'END', 'JUSTIFIED')
215
- direction: The content direction ('LEFT_TO_RIGHT', 'RIGHT_TO_LEFT')
216
- spacing_mode: The spacing mode ('NEVER_COLLAPSE', 'COLLAPSE_LISTS')
217
- segment_id: The segment ID for the range (optional)
218
- tab_id: The tab ID for the range (optional)
219
-
230
+ document_id: The unique identifier of the Google Document to update.
231
+ start_index: The zero-based start index of the paragraph range to style.
232
+ end_index: The zero-based end index of the paragraph range to style (exclusive).
233
+ named_style_type: The named style type to apply (e.g., 'NORMAL_TEXT', 'TITLE', 'HEADING_1').
234
+ alignment: Paragraph alignment option ('START', 'CENTER', 'END', 'JUSTIFIED').
235
+ direction: Content direction of the paragraph ('LEFT_TO_RIGHT', 'RIGHT_TO_LEFT').
236
+ spacing_mode: Spacing mode for the paragraph ('NEVER_COLLAPSE', 'COLLAPSE_LISTS').
237
+ segment_id: Optional segment ID for the text range.
238
+ tab_id: Optional tab ID for the text range.
239
+
220
240
  Returns:
221
- A dictionary containing the Google Docs API response
222
-
241
+ A dictionary containing the API response from the Google Docs batchUpdate request.
242
+
223
243
  Raises:
224
- HTTPError: When the API request fails
225
- RequestException: When there are network connectivity issues
226
-
244
+ HTTPError: If the API request to update the document fails due to an HTTP error.
245
+ RequestException: If there are network connectivity issues during the API request.
246
+
227
247
  Tags:
228
- style, format, paragraph, document, api, google-docs, batch, content-management
248
+ style, format, paragraph, document, api, google-docs, batch, content-management, important
229
249
  """
230
250
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
231
-
232
- # Build the paragraph style object with only specified properties
233
251
  paragraph_style = {}
234
252
  fields_to_update = []
235
-
236
253
  if named_style_type is not None:
237
254
  paragraph_style["namedStyleType"] = named_style_type
238
255
  fields_to_update.append("namedStyleType")
239
-
240
256
  if alignment is not None:
241
257
  paragraph_style["alignment"] = alignment
242
258
  fields_to_update.append("alignment")
243
-
244
259
  if direction is not None:
245
260
  paragraph_style["direction"] = direction
246
261
  fields_to_update.append("direction")
247
-
248
262
  if spacing_mode is not None:
249
263
  paragraph_style["spacingMode"] = spacing_mode
250
264
  fields_to_update.append("spacingMode")
251
-
252
- # If no styling requested, return early
253
265
  if not paragraph_style:
254
266
  return {"message": "No paragraph styling applied"}
255
-
256
- # Build the range object
257
267
  range_obj: dict[str, Any] = {"startIndex": start_index, "endIndex": end_index}
258
-
259
- # Add optional parameters if provided
260
268
  if segment_id is not None:
261
269
  range_obj["segmentId"] = segment_id
262
270
  if tab_id is not None:
263
271
  range_obj["tabId"] = tab_id
264
-
265
272
  batch_update_data = {
266
273
  "requests": [
267
274
  {
@@ -273,7 +280,6 @@ class GoogleDocsApp(APIApplication):
273
280
  }
274
281
  ]
275
282
  }
276
-
277
283
  response = self._post(url, data=batch_update_data)
278
284
  return self._handle_response(response)
279
285
 
@@ -286,40 +292,34 @@ class GoogleDocsApp(APIApplication):
286
292
  tab_id: str | None = None,
287
293
  ) -> dict[str, Any]:
288
294
  """
289
- Deletes content within a specified index range in a Google Document via the batchUpdate API. It removes any content based on location, distinguishing it from functions like `delete_header` or `delete_paragraph_bullets`, which remove specific structures or styles instead.
290
-
295
+ Removes content from a specified index range in a Google Document via the batchUpdate API. Unlike functions that delete entire elements (e.g., `delete_header`), this provides granular control by targeting content based on its precise start and end location, optionally within a specific segment or tab.
296
+
291
297
  Args:
292
- document_id: The unique identifier of the Google Document to be updated
293
- start_index: The zero-based start index of the content range to delete
294
- end_index: The zero-based end index of the content range to delete (exclusive)
295
- segment_id: The ID of the header, footer, or footnote segment (optional)
296
- tab_id: The ID of the tab containing the content to delete (optional)
297
-
298
+ document_id: The unique identifier of the Google Document to be updated.
299
+ start_index: The zero-based start index of the content range to delete.
300
+ end_index: The zero-based end index of the content range to delete (exclusive).
301
+ segment_id: Optional; the ID of the header, footer, or footnote segment containing the content.
302
+ tab_id: Optional; the ID of the tab containing the content to delete.
303
+
298
304
  Returns:
299
- A dictionary containing the Google Docs API response after performing the delete operation
300
-
305
+ A dictionary representing the Google Docs API response after performing the delete operation.
306
+
301
307
  Raises:
302
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
303
- RequestException: When there are network connectivity issues or API endpoint problems
304
-
308
+ HTTPError: Raised when the API request fails due to issues such as invalid document ID or insufficient permissions.
309
+ RequestException: Raised when there are network connectivity issues or problems with the API endpoint.
310
+
305
311
  Tags:
306
312
  delete, remove, content, document, api, google-docs, batch, content-management, important
307
313
  """
308
314
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
309
-
310
- # Build the delete content range request
311
315
  delete_request: dict[str, Any] = {
312
316
  "range": {"startIndex": start_index, "endIndex": end_index}
313
317
  }
314
-
315
- # Add optional parameters if provided
316
318
  if segment_id is not None:
317
319
  delete_request["range"]["segmentId"] = segment_id
318
320
  if tab_id is not None:
319
321
  delete_request["tabId"] = tab_id
320
-
321
322
  batch_update_data = {"requests": [{"deleteContentRange": delete_request}]}
322
-
323
323
  response = self._post(url, data=batch_update_data)
324
324
  return self._handle_response(response)
325
325
 
@@ -333,39 +333,32 @@ class GoogleDocsApp(APIApplication):
333
333
  tab_id: str = None,
334
334
  ) -> dict[str, Any]:
335
335
  """
336
- Inserts a table with specified row and column dimensions at a given index in a Google Document. This function uses the `batchUpdate` API for precise placement, allowing the table to be added to the document's body, a header, or a footer, returning the API's response.
337
-
336
+ Inserts a table with specified rows and columns at a given index in a Google Document using the batchUpdate API. It can optionally place the table within specific document segments, such as headers or footers, handling structural additions rather than text or style modifications.
337
+
338
338
  Args:
339
- document_id: The unique identifier of the Google Document to be updated
340
- location_index: The zero-based index where the table should be inserted
341
- rows: The number of rows in the table
342
- columns: The number of columns in the table
343
- segment_id: The ID of the header, footer or footnote segment (optional)
344
- tab_id: The ID of the tab containing the location (optional)
345
-
339
+ document_id: The unique identifier of the Google Document to be updated.
340
+ location_index: The zero-based index within the document body or segment where the table should be inserted.
341
+ rows: The number of rows the inserted table should have.
342
+ columns: The number of columns the inserted table should have.
343
+ segment_id: Optional ID of the header, footer, or footnote segment where the table will be inserted (if applicable).
344
+ tab_id: Optional ID of the tab containing the insertion location.
345
+
346
346
  Returns:
347
- A dictionary containing the Google Docs API response after performing the insert table operation
348
-
347
+ A dictionary containing the response from the Google Docs API after performing the table insertion.
348
+
349
349
  Raises:
350
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
351
- RequestException: When there are network connectivity issues or API endpoint problems
352
-
350
+ HTTPError: Raised when the API request fails due to reasons such as invalid document ID or insufficient permissions.
351
+ RequestException: Raised when there are network connectivity issues or problems reaching the API endpoint.
352
+
353
353
  Tags:
354
- table, insert, document, api, google-docs, batch, content-management
354
+ table, insert, document, api, google-docs, batch, content-management, important
355
355
  """
356
356
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
357
-
358
- # Build the location object according to Google Docs API specification
359
357
  location = {"index": location_index}
360
-
361
- # Add segment_id if provided (empty string for document body, specific ID for header/footer/footnote)
362
358
  if segment_id is not None:
363
359
  location["segmentId"] = segment_id
364
-
365
- # Add tab_id if provided
366
360
  if tab_id is not None:
367
361
  location["tabId"] = tab_id
368
-
369
362
  batch_update_data = {
370
363
  "requests": [
371
364
  {
@@ -377,7 +370,6 @@ class GoogleDocsApp(APIApplication):
377
370
  }
378
371
  ]
379
372
  }
380
-
381
373
  response = self._post(url, data=batch_update_data)
382
374
  return self._handle_response(response)
383
375
 
@@ -390,31 +382,27 @@ class GoogleDocsApp(APIApplication):
390
382
  section_break_tab_id: str = None,
391
383
  ) -> dict[str, Any]:
392
384
  """
393
- Creates a footer of a specified type in a Google Document via the batch update API. The footer can optionally be associated with a specific section break, enabling distinct footers for different document sections, distinguishing it from the `create_header` and `create_footnote` functions.
394
-
385
+ Creates a footer of a specified type in a Google Document using the batch update API. This function, distinct from `create_header`, can optionally associate the new footer with a specific section break, enabling section-specific footers within the document.
386
+
395
387
  Args:
396
- document_id: The unique identifier of the Google Document to be updated
397
- footer_type: The type of footer to create (DEFAULT, HEADER_FOOTER_TYPE_UNSPECIFIED)
398
- section_break_location_index: The index of the SectionBreak location (optional)
399
- section_break_segment_id: The segment ID of the SectionBreak location (optional)
400
- section_break_tab_id: The tab ID of the SectionBreak location (optional)
401
-
388
+ document_id: The unique identifier of the Google Document to update.
389
+ footer_type: The type of footer to create, such as 'DEFAULT' or 'HEADER_FOOTER_TYPE_UNSPECIFIED'.
390
+ section_break_location_index: Optional index of the SectionBreak location to associate with the footer.
391
+ section_break_segment_id: Optional segment ID of the SectionBreak location.
392
+ section_break_tab_id: Optional tab ID of the SectionBreak location.
393
+
402
394
  Returns:
403
- A dictionary containing the Google Docs API response after performing the create footer operation
404
-
395
+ A dictionary containing the Google Docs API response from the create footer operation.
396
+
405
397
  Raises:
406
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
407
- RequestException: When there are network connectivity issues or API endpoint problems
408
-
398
+ HTTPError: Raised when the API request fails due to reasons like invalid document_id or insufficient permissions.
399
+ RequestException: Raised when there are network connectivity issues or problems with the API endpoint.
400
+
409
401
  Tags:
410
- footer, create, document, api, google-docs, batch, content-management
402
+ footer, create, document, api, google-docs, batch, content-management, important
411
403
  """
412
404
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
413
-
414
- # Build the create footer request
415
405
  create_footer_request = {"type": footer_type}
416
-
417
- # Add section break location if provided
418
406
  if section_break_location_index is not None:
419
407
  section_break_location = {"index": section_break_location_index}
420
408
 
@@ -425,9 +413,7 @@ class GoogleDocsApp(APIApplication):
425
413
  section_break_location["tabId"] = section_break_tab_id
426
414
 
427
415
  create_footer_request["sectionBreakLocation"] = section_break_location
428
-
429
416
  batch_update_data = {"requests": [{"createFooter": create_footer_request}]}
430
-
431
417
  response = self._post(url, data=batch_update_data)
432
418
  return self._handle_response(response)
433
419
 
@@ -442,32 +428,29 @@ class GoogleDocsApp(APIApplication):
442
428
  end_of_segment_tab_id: str = None,
443
429
  ) -> dict[str, Any]:
444
430
  """
445
- Creates a footnote via the batch update API, inserting a numbered reference at a specified index or a segment's end. This function adds an in-body citation, distinguishing it from `create_footer` which creates a content block at the bottom of the page.
446
-
431
+ Inserts a numbered footnote reference into a Google Document using the batchUpdate API. The footnote can be placed at a precise index or at the end of a document segment, distinct from the `create_footer` function which adds standard page footers.
432
+
447
433
  Args:
448
- document_id: The unique identifier of the Google Document to be updated
449
- location_index: The index where to insert the footnote reference (optional)
450
- location_segment_id: The segment ID for the location (optional, must be empty for body)
451
- location_tab_id: The tab ID for the location (optional)
452
- end_of_segment_location: Whether to insert at end of segment (optional)
453
- end_of_segment_segment_id: The segment ID for end of segment location (optional)
454
- end_of_segment_tab_id: The tab ID for end of segment location (optional)
455
-
434
+ document_id: The unique identifier of the Google Document to be updated.
435
+ location_index: The zero-based index within the document where the footnote reference will be inserted (optional if inserting at end of segment).
436
+ location_segment_id: The segment ID where the footnote reference should be inserted (optional, usually empty for the document body).
437
+ location_tab_id: The tab ID for the location within the segment (optional).
438
+ end_of_segment_location: If True, inserts the footnote reference at the end of a segment instead of a specific index (default is False).
439
+ end_of_segment_segment_id: The segment ID indicating where to insert the footnote at the end of a segment (optional).
440
+ end_of_segment_tab_id: The tab ID for the end-of-segment location (optional).
441
+
456
442
  Returns:
457
- A dictionary containing the Google Docs API response after performing the create footnote operation
458
-
443
+ A dictionary containing the response from the Google Docs API after performing the footnote creation operation.
444
+
459
445
  Raises:
460
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
461
- RequestException: When there are network connectivity issues or API endpoint problems
462
-
446
+ HTTPError: Raised when the API request fails, such as due to an invalid document ID or insufficient permissions.
447
+ RequestException: Raised when there are network connectivity issues or problems reaching the API endpoint.
448
+
463
449
  Tags:
464
- footnote, create, document, api, google-docs, batch, content-management
450
+ footnote, create, document, api, google-docs, batch, content-management, important
465
451
  """
466
452
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
467
-
468
- # Build the create footnote request
469
453
  create_footnote_request = {}
470
-
471
454
  if end_of_segment_location:
472
455
  # Use endOfSegmentLocation
473
456
  end_of_segment_location_obj = {}
@@ -492,9 +475,7 @@ class GoogleDocsApp(APIApplication):
492
475
  location["tabId"] = location_tab_id
493
476
 
494
477
  create_footnote_request["location"] = location
495
-
496
478
  batch_update_data = {"requests": [{"createFootnote": create_footnote_request}]}
497
-
498
479
  response = self._post(url, data=batch_update_data)
499
480
  return self._handle_response(response)
500
481
 
@@ -505,34 +486,28 @@ class GoogleDocsApp(APIApplication):
505
486
  tab_id: str = None,
506
487
  ) -> dict[str, Any]:
507
488
  """
508
- Deletes a specific footer from a Google Document using its unique ID via a `batchUpdate` request. This operation, the counterpart to `create_footer`, removes an entire footer section, unlike `delete_content_range` which targets text within a specified index range.
509
-
489
+ Deletes a specific footer from a Google Document using its unique ID via a batchUpdate API request. This operation removes the entire footer object, optionally within a specific tab, distinguishing it from functions that delete headers (`delete_header`) or general content (`delete_content_range`).
490
+
510
491
  Args:
511
- document_id: The unique identifier of the Google Document to be updated
512
- footer_id: The ID of the footer to delete
513
- tab_id: The tab that contains the footer to delete (optional)
514
-
492
+ document_id: The unique identifier of the Google Document to be updated.
493
+ footer_id: The identifier of the footer to delete.
494
+ tab_id: Optional identifier of the tab containing the footer to delete.
495
+
515
496
  Returns:
516
- A dictionary containing the Google Docs API response after performing the delete footer operation
517
-
497
+ A dictionary containing the response from the Google Docs API after performing the delete footer operation.
498
+
518
499
  Raises:
519
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
520
- RequestException: When there are network connectivity issues or API endpoint problems
521
-
500
+ HTTPError: Raised when the API request fails due to reasons such as an invalid document ID or insufficient permissions.
501
+ RequestException: Raised for network-related issues or problems reaching the API endpoint.
502
+
522
503
  Tags:
523
- footer, delete, remove, document, api, google-docs, batch, content-management
504
+ footer, delete, remove, document, api, google-docs, batch, content-management, important
524
505
  """
525
506
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
526
-
527
- # Build the delete footer request
528
507
  delete_footer_request = {"footerId": footer_id}
529
-
530
- # Add tab_id if provided
531
508
  if tab_id is not None:
532
509
  delete_footer_request["tabId"] = tab_id
533
-
534
510
  batch_update_data = {"requests": [{"deleteFooter": delete_footer_request}]}
535
-
536
511
  response = self._post(url, data=batch_update_data)
537
512
  return self._handle_response(response)
538
513
 
@@ -545,31 +520,27 @@ class GoogleDocsApp(APIApplication):
545
520
  section_break_tab_id: str = None,
546
521
  ) -> dict[str, Any]:
547
522
  """
548
- Creates a header in a specified Google Document via the batchUpdate API endpoint. This function allows defining the header type and can optionally associate it with a specific section break location. It complements the `delete_header` and `create_footer` functions for managing document structure.
549
-
523
+ Creates a header of a specified type in a Google Document using the batchUpdate API. This function can optionally associate the new header with a specific section break, distinguishing it from the `create_footer` method, which performs the equivalent action for footers.
524
+
550
525
  Args:
551
- document_id: The unique identifier of the Google Document to be updated
552
- header_type: The type of header to create (DEFAULT, HEADER_FOOTER_TYPE_UNSPECIFIED)
553
- section_break_location_index: The index of the SectionBreak location (optional)
554
- section_break_segment_id: The segment ID of the SectionBreak location (optional)
555
- section_break_tab_id: The tab ID of the SectionBreak location (optional)
556
-
526
+ document_id: The unique identifier of the Google Document to be updated.
527
+ header_type: The type of header to create, e.g., 'DEFAULT' or 'HEADER_FOOTER_TYPE_UNSPECIFIED'.
528
+ section_break_location_index: The index position of the section break location within the document, if applicable.
529
+ section_break_segment_id: The segment ID associated with the section break location, if applicable.
530
+ section_break_tab_id: The tab ID associated with the section break location, if applicable.
531
+
557
532
  Returns:
558
- A dictionary containing the Google Docs API response after performing the create header operation
559
-
533
+ A dictionary containing the response from the Google Docs API after the header creation request.
534
+
560
535
  Raises:
561
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
562
- RequestException: When there are network connectivity issues or API endpoint problems
563
-
536
+ HTTPError: If the API request fails due to issues such as an invalid document ID or insufficient permissions.
537
+ RequestException: If there are network problems or issues reaching the API endpoint.
538
+
564
539
  Tags:
565
540
  header, create, document, api, google-docs, batch, content-management, important
566
541
  """
567
542
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
568
-
569
- # Build the create header request
570
543
  create_header_request = {"type": header_type}
571
-
572
- # Add section break location if provided
573
544
  if section_break_location_index is not None:
574
545
  section_break_location = {"index": section_break_location_index}
575
546
 
@@ -580,9 +551,7 @@ class GoogleDocsApp(APIApplication):
580
551
  section_break_location["tabId"] = section_break_tab_id
581
552
 
582
553
  create_header_request["sectionBreakLocation"] = section_break_location
583
-
584
554
  batch_update_data = {"requests": [{"createHeader": create_header_request}]}
585
-
586
555
  response = self._post(url, data=batch_update_data)
587
556
  return self._handle_response(response)
588
557
 
@@ -593,34 +562,28 @@ class GoogleDocsApp(APIApplication):
593
562
  tab_id: str = None,
594
563
  ) -> dict[str, Any]:
595
564
  """
596
- Removes a specific header from a Google Document using its unique ID. This function sends a `deleteHeader` request to the batch update API, acting as the direct counterpart to `create_header` and distinguishing it from `delete_footer` which removes footers.
597
-
565
+ Deletes a specific header from a Google Document using its unique ID via a batchUpdate API request. This function, the counterpart to `create_header`, removes headers and can optionally target a header within a specific tab. It requires both the document and header IDs for the operation.
566
+
598
567
  Args:
599
- document_id: The unique identifier of the Google Document to be updated
600
- header_id: The ID of the header to delete
601
- tab_id: The tab containing the header to delete (optional)
602
-
568
+ document_id: The unique identifier of the Google Document to be updated.
569
+ header_id: The ID of the header to delete.
570
+ tab_id: Optional ID of the tab containing the header to delete.
571
+
603
572
  Returns:
604
- A dictionary containing the Google Docs API response after performing the delete header operation
605
-
573
+ A dictionary containing the response from the Google Docs API after performing the delete header operation.
574
+
606
575
  Raises:
607
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
608
- RequestException: When there are network connectivity issues or API endpoint problems
609
-
576
+ HTTPError: Raised when the API request fails due to invalid document_id, insufficient permissions, or other HTTP errors.
577
+ RequestException: Raised when network connectivity issues or API endpoint problems occur during the request.
578
+
610
579
  Tags:
611
- header, delete, remove, document, api, google-docs, batch, content-management
580
+ header, delete, remove, document, api, google-docs, batch, content-management, important
612
581
  """
613
582
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
614
-
615
- # Build the delete header request
616
583
  delete_header_request = {"headerId": header_id}
617
-
618
- # Add tab_id if provided
619
584
  if tab_id is not None:
620
585
  delete_header_request["tabId"] = tab_id
621
-
622
586
  batch_update_data = {"requests": [{"deleteHeader": delete_header_request}]}
623
-
624
587
  response = self._post(url, data=batch_update_data)
625
588
  return self._handle_response(response)
626
589
 
@@ -634,53 +597,32 @@ class GoogleDocsApp(APIApplication):
634
597
  tab_id: str = None,
635
598
  ) -> dict[str, Any]:
636
599
  """
637
- Applies a predefined bulleted or numbered list format to paragraphs within a specified range using a `bullet_preset`. This function adds list formatting, distinguishing it from its counterpart, `delete_paragraph_bullets`, and other styling functions like `update_paragraph_style`, which handles alignment and headings.
638
-
600
+ Applies a predefined list style (bulleted or numbered) to paragraphs within a specified range using a chosen preset. Unlike `delete_paragraph_bullets`, which removes list formatting, this function creates it, distinguishing it from other text and paragraph styling methods in the class.
601
+
639
602
  Args:
640
- document_id: The unique identifier of the Google Document to be updated
641
- start_index: The zero-based start index of the range to apply bullets to
642
- end_index: The zero-based end index of the range to apply bullets to (exclusive)
643
- bullet_preset: The kind of bullet glyphs to use. Available options:
644
- - BULLET_GLYPH_PRESET_UNSPECIFIED: The bullet glyph preset is unspecified
645
- - BULLET_DISC_CIRCLE_SQUARE: DISC, CIRCLE and SQUARE for first 3 nesting levels
646
- - BULLET_DIAMONDX_ARROW3D_SQUARE: DIAMONDX, ARROW3D and SQUARE for first 3 nesting levels
647
- - BULLET_CHECKBOX: CHECKBOX bullet glyphs for all nesting levels
648
- - BULLET_ARROW_DIAMOND_DISC: ARROW, DIAMOND and DISC for first 3 nesting levels
649
- - BULLET_STAR_CIRCLE_SQUARE: STAR, CIRCLE and SQUARE for first 3 nesting levels
650
- - BULLET_ARROW3D_CIRCLE_SQUARE: ARROW3D, CIRCLE and SQUARE for first 3 nesting levels
651
- - BULLET_LEFTTRIANGLE_DIAMOND_DISC: LEFTTRIANGLE, DIAMOND and DISC for first 3 nesting levels
652
- - BULLET_DIAMONDX_HOLLOWDIAMOND_SQUARE: DIAMONDX, HOLLOWDIAMOND and SQUARE for first 3 nesting levels
653
- - BULLET_DIAMOND_CIRCLE_SQUARE: DIAMOND, CIRCLE and SQUARE for first 3 nesting levels
654
- - NUMBERED_DECIMAL_ALPHA_ROMAN: DECIMAL, ALPHA and ROMAN with periods
655
- - NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS: DECIMAL, ALPHA and ROMAN with parenthesis
656
- - NUMBERED_DECIMAL_NESTED: DECIMAL with nested numbering (1., 1.1., 2., 2.2.)
657
- - NUMBERED_UPPERALPHA_ALPHA_ROMAN: UPPERALPHA, ALPHA and ROMAN with periods
658
- - NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL: UPPERROMAN, UPPERALPHA and DECIMAL with periods
659
- - NUMBERED_ZERODECIMAL_ALPHA_ROMAN: ZERODECIMAL, ALPHA and ROMAN with periods
660
- segment_id: The segment ID for the range (optional)
661
- tab_id: The tab ID for the range (optional)
662
-
603
+ document_id: The unique identifier of the Google Document to be updated.
604
+ start_index: The zero-based start index of the text range to which the list style should be applied.
605
+ end_index: The zero-based end index (exclusive) of the text range to apply the list style.
606
+ bullet_preset: Specifies the bullet or numbering style preset to use (e.g., bulleted or numbered formats with specific glyphs).
607
+ segment_id: Optional segment ID within the document where the updates apply.
608
+ tab_id: Optional tab ID within the segment to narrow the update scope.
609
+
663
610
  Returns:
664
- A dictionary containing the Google Docs API response after performing the create bullets operation
665
-
611
+ A dictionary representing the Google Docs API response confirming the application of the bullet list style.
612
+
666
613
  Raises:
667
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
668
- RequestException: When there are network connectivity issues or API endpoint problems
669
-
614
+ HTTPError: Raised when the API request to update the document fails (e.g., invalid document ID or insufficient permissions).
615
+ RequestException: Raised on network issues or problems reaching the API endpoint.
616
+
670
617
  Tags:
671
- bullets, list, paragraph, document, api, google-docs, batch, content-management
618
+ bullets, list, paragraph, document, api, google-docs, batch, content-management, important
672
619
  """
673
620
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
674
-
675
- # Build the range object
676
621
  range_obj = {"startIndex": start_index, "endIndex": end_index}
677
-
678
- # Add optional parameters if provided
679
622
  if segment_id is not None:
680
623
  range_obj["segmentId"] = segment_id
681
624
  if tab_id is not None:
682
625
  range_obj["tabId"] = tab_id
683
-
684
626
  batch_update_data = {
685
627
  "requests": [
686
628
  {
@@ -691,7 +633,6 @@ class GoogleDocsApp(APIApplication):
691
633
  }
692
634
  ]
693
635
  }
694
-
695
636
  response = self._post(url, data=batch_update_data)
696
637
  return self._handle_response(response)
697
638
 
@@ -704,47 +645,42 @@ class GoogleDocsApp(APIApplication):
704
645
  tab_id: str = None,
705
646
  ) -> dict[str, Any]:
706
647
  """
707
- Removes bullet points or numbering from paragraphs within a specified range in a Google Document. This function reverts list formatting via the batch update API, acting as the direct counterpart to `apply_list_style` and preserving the underlying text content, unlike `delete_content_range`.
708
-
648
+ Removes bullet points or numbering from paragraphs within a specified index range in a Google Document. This reverts list formatting to normal text while preserving content, acting as the inverse operation to the `apply_list_style` function.
649
+
709
650
  Args:
710
- document_id: The unique identifier of the Google Document to be updated
711
- start_index: The zero-based start index of the range to remove bullets from
712
- end_index: The zero-based end index of the range to remove bullets from (exclusive)
713
- segment_id: The segment ID for the range (optional)
714
- tab_id: The tab ID for the range (optional)
715
-
651
+ document_id: The unique identifier of the Google Document to be updated.
652
+ start_index: The zero-based start index of the range to remove bullets from.
653
+ end_index: The zero-based end index of the range to remove bullets from (exclusive).
654
+ segment_id: Optional segment ID specifying a subset of the document where the range applies.
655
+ tab_id: Optional tab ID specifying a particular tab within the document where the range applies.
656
+
716
657
  Returns:
717
- A dictionary containing the Google Docs API response after performing the delete bullets operation
718
-
658
+ A dictionary containing the Google Docs API response after performing the delete bullets operation.
659
+
719
660
  Raises:
720
- HTTPError: When the API request fails, such as invalid document_id or insufficient permissions
721
- RequestException: When there are network connectivity issues or API endpoint problems
722
-
661
+ HTTPError: Raised when the API request fails due to invalid document ID, insufficient permissions, or other server-side errors.
662
+ RequestException: Raised when there are network connectivity issues or problems accessing the API endpoint.
663
+
723
664
  Tags:
724
665
  bullets, delete, remove, list, paragraph, document, api, google-docs, batch, content-management
725
666
  """
726
667
  url = f"{self.base_api_url}/{document_id}:batchUpdate"
727
-
728
- # Build the range object
729
668
  range_obj = {"startIndex": start_index, "endIndex": end_index}
730
-
731
- # Add optional parameters if provided
732
669
  if segment_id is not None:
733
670
  range_obj["segmentId"] = segment_id
734
671
  if tab_id is not None:
735
672
  range_obj["tabId"] = tab_id
736
-
737
673
  batch_update_data = {
738
674
  "requests": [{"deleteParagraphBullets": {"range": range_obj}}]
739
675
  }
740
-
741
676
  response = self._post(url, data=batch_update_data)
742
677
  return self._handle_response(response)
743
678
 
744
679
  def list_tools(self):
745
680
  return [
746
681
  self.create_document,
747
- self.get_document,
682
+ # self.get_document,
683
+ self.get_document_content,
748
684
  self.insert_text,
749
685
  self.apply_text_style,
750
686
  self.delete_content_range,
@@ -24,8 +24,8 @@ class ZenquotesApp(APIApplication):
24
24
  url = "https://zenquotes.io/api/random"
25
25
  response = self._get(url)
26
26
  data = response.json()
27
- quote_data = data[0]
28
- return f"{quote_data['q']} - {quote_data['a']}"
27
+ quote = data[0]
28
+ return {"quote" : quote["q"], "author" : quote["a"]}
29
29
 
30
30
  def list_tools(self):
31
31
  return [self.get_random_quote]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp-applications
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: A Universal MCP Application: universal_mcp_applications
5
5
  Project-URL: Homepage, https://github.com/universal-mcp/applications
6
6
  Project-URL: Repository, https://github.com/universal-mcp/applications
@@ -25,7 +25,7 @@ universal_mcp/applications/braze/__init__.py,sha256=9HSB9jg_Ws55dLcTh2qEtLNHMFnR
25
25
  universal_mcp/applications/braze/app.py,sha256=dJSivDLvc002IPdusKNvLWqIz035j3bRQw6FFXve2Ns,175855
26
26
  universal_mcp/applications/browser_use/README.md,sha256=xLlNi7R94GfykFnUrxR9WN4G4cyG-VxHKEeTnGFdk10,13
27
27
  universal_mcp/applications/browser_use/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- universal_mcp/applications/browser_use/app.py,sha256=B6gjBv5tvKJW5vZ02svoV93jWvTL0-lqTAddZh8Mc3k,2786
28
+ universal_mcp/applications/browser_use/app.py,sha256=n4K598QcQTF2e8ukme8kXh63lS8mIwNKqTZS1AVb554,2587
29
29
  universal_mcp/applications/cal_com_v2/README.md,sha256=V7M5cx_Rhbj54mCj4LudO1g61UYlA5Ur65wWG1d6n2U,21047
30
30
  universal_mcp/applications/cal_com_v2/__init__.py,sha256=OOTUXThnSL6bsOfTs4B0h-zKDo6b3LxL98JQlpZifCE,29
31
31
  universal_mcp/applications/cal_com_v2/app.py,sha256=d38htmRGXJ_mNJdMbGQIwvkyAV0t8uiacvaKt7ymD_k,220974
@@ -105,7 +105,7 @@ universal_mcp/applications/google_calendar/__init__.py,sha256=qxVxf_Q5lOdxXRHzmE
105
105
  universal_mcp/applications/google_calendar/app.py,sha256=FZptXBLsRo4Rp2kRrVJO_dM3Wr8G0XyMXLHWfPya80Q,25884
106
106
  universal_mcp/applications/google_docs/README.md,sha256=KDy_X4SRELegE5sEdixAP0YeXZOXdADTX2D-tAUlCJM,4512
107
107
  universal_mcp/applications/google_docs/__init__.py,sha256=U0pWagxnj0VD-AcKNd8eS0orzaMmlUOgvW9vkYBNH40,31
108
- universal_mcp/applications/google_docs/app.py,sha256=j5xhZNW20sEBEG0VGgRky-_UzeegaH0DGQQA9VnmzO4,33127
108
+ universal_mcp/applications/google_docs/app.py,sha256=lPmvTzLvc-o90EKQ6kynY84O-HEZiZEScyWIyexTnxY,34129
109
109
  universal_mcp/applications/google_drive/README.md,sha256=Kmg7LLaDW-7bnsgdVimwxc5SdUf2uA9Fv8zIMXVa-Uc,15393
110
110
  universal_mcp/applications/google_drive/__init__.py,sha256=DTyed4ADcCmALSyPT8whjXoosPXl3m-i8JrilPJ3ijU,32
111
111
  universal_mcp/applications/google_drive/app.py,sha256=J81m8OBjE0552GGWsIfgM4idFjjZfPEOsjk0ZVeJzgM,257259
@@ -275,8 +275,8 @@ universal_mcp/applications/youtube/__init__.py,sha256=HuPQYpxmH_duCaVBXIE_fm-XzS
275
275
  universal_mcp/applications/youtube/app.py,sha256=eqgqe0b53W9Mj0FZGW3ZqY3xkGF4NbOykD-Vh9nUAWc,75427
276
276
  universal_mcp/applications/zenquotes/README.md,sha256=FJyoTGRCaZjF_bsCBqg1CrYcvIfuUG_Qk616G1wjhF8,512
277
277
  universal_mcp/applications/zenquotes/__init__.py,sha256=C5nEHZ3Xy6nYUarq0BqQbbJnHs0UtSlqhk0DqmvWiHk,58
278
- universal_mcp/applications/zenquotes/app.py,sha256=uztmp-VPUsBPR1sAgy2Q95CQBQ8RXLTz-52rjE5B1Z8,1299
279
- universal_mcp_applications-0.1.22.dist-info/METADATA,sha256=ahp5fJp3zC2YiEu6k2mWT7QJbRJ4z4qWH7SngSjCXE8,2956
280
- universal_mcp_applications-0.1.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
281
- universal_mcp_applications-0.1.22.dist-info/licenses/LICENSE,sha256=NweDZVPslBAZFzlgByF158b85GR0f5_tLQgq1NS48To,1063
282
- universal_mcp_applications-0.1.22.dist-info/RECORD,,
278
+ universal_mcp/applications/zenquotes/app.py,sha256=7xIEnSZWAGYu5583Be2ZjSCtLUAfMWRzucSpp7hw_h4,1299
279
+ universal_mcp_applications-0.1.24.dist-info/METADATA,sha256=WcvhSK6ZVRfoATJtf8wtM_kmcDhW0sr2c8NZ5iiNlpc,2956
280
+ universal_mcp_applications-0.1.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
281
+ universal_mcp_applications-0.1.24.dist-info/licenses/LICENSE,sha256=NweDZVPslBAZFzlgByF158b85GR0f5_tLQgq1NS48To,1063
282
+ universal_mcp_applications-0.1.24.dist-info/RECORD,,