universal-mcp 0.1.1rc1__py3-none-any.whl → 0.1.2__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.
@@ -0,0 +1,32 @@
1
+ # Notion Tool
2
+
3
+ This is automatically generated from OpenAPI schema for the Notion API.
4
+
5
+ ## Supported Integrations
6
+
7
+ This tool can be integrated with any service that supports HTTP requests.
8
+
9
+ ## Tool List
10
+
11
+ | Tool | Description |
12
+ |------|-------------|
13
+ | notion_retrieve_auser | Retrieves user information from the Notion API by user ID. |
14
+ | notion_list_all_users | Fetches and returns a list of all users from the Notion API. |
15
+ | notion_retrieve_your_token_sbot_user | Retrieves the current user's token data from the Notion API. |
16
+ | notion_retrieve_adatabase | Retrieves a Notion database by its unique identifier. |
17
+ | notion_update_adatabase | Updates a Notion database with the given ID and request body data. |
18
+ | notion_query_adatabase | Executes a query on a Notion database using the Notion API. |
19
+ | notion_create_adatabase | Creates a new database in Notion using the provided request body. |
20
+ | notion_create_apage | Creates a new page in Notion by sending a POST request with the specified request body. |
21
+ | notion_retrieve_apage | Retrieves a page from the Notion API using a given page ID. |
22
+ | notion_update_page_properties | Updates the properties of a Notion page identified by a given ID. |
23
+ | notion_retrieve_apage_property_item | Retrieves a specific property item from a page in Notion using the page and property IDs. |
24
+ | notion_retrieve_block_children | Retrieves the child blocks of a specified Notion block. |
25
+ | notion_append_block_children | Appends child blocks to a block in Notion using its API. |
26
+ | notion_retrieve_ablock | Retrieves a block from the Notion API using the specified block ID. |
27
+ | notion_delete_ablock | Deletes a block from the Notion database using the specified block ID. |
28
+ | notion_update_ablock | Updates a block in Notion with the given ID and request body. |
29
+ | notion_search | Executes a search request to the Notion API and returns the response in JSON format. |
30
+ | notion_retrieve_comments | Retrieves comments from a Notion block using the Notion API. |
31
+ | notion_add_comment_to_page | Adds a comment to a specified Notion page using the provided request body. |
32
+
File without changes
@@ -0,0 +1,415 @@
1
+ from typing import Any
2
+
3
+ from universal_mcp.applications import APIApplication
4
+ from universal_mcp.integrations import Integration
5
+
6
+
7
+ class NotionApp(APIApplication):
8
+ def __init__(self, integration: Integration = None, **kwargs) -> None:
9
+ """
10
+ Initializes a new instance of the class with given integration and additional options.
11
+
12
+ Args:
13
+ integration: An optional Integration instance to configure the connection. Defaults to None.
14
+ **kwargs: Additional keyword arguments for configuration.
15
+
16
+ Returns:
17
+ None
18
+ """
19
+ super().__init__(name='notion', integration=integration, **kwargs)
20
+ self.base_url = "https://api.notion.com"
21
+
22
+ def _get_headers(self):
23
+ if not self.integration:
24
+ raise ValueError("Integration not configured for NotionApp")
25
+ credentials = self.integration.get_credentials()
26
+ if "headers" in credentials:
27
+ return credentials["headers"]
28
+ return {
29
+ "Authorization": f"Bearer {credentials['access_token']}",
30
+ "Accept": "application/json",
31
+ "Notion-Version": "2022-06-28",
32
+ }
33
+
34
+ def notion_retrieve_auser(self, id, request_body=None) -> dict[str, Any]:
35
+ """
36
+ Retrieves user information from the Notion API by user ID.
37
+
38
+ Args:
39
+ id: The unique identifier of the user whose information is to be retrieved.
40
+ request_body: A dictionary representing the request body, optional, default is None.
41
+
42
+ Returns:
43
+ A dictionary containing the user's information from the Notion API.
44
+ """
45
+ if id is None:
46
+ raise ValueError("Missing required parameter 'id'")
47
+ url = f"{self.base_url}/v1/users/{id}"
48
+ query_params = {}
49
+ response = self._get(url, params=query_params)
50
+ response.raise_for_status()
51
+ return response.json()
52
+
53
+ def notion_list_all_users(self, ) -> dict[str, Any]:
54
+ """
55
+ Fetches and returns a list of all users from the Notion API.
56
+
57
+ Args:
58
+ None: This method does not take any parameters.
59
+
60
+ Returns:
61
+ A dictionary containing the JSON response from the Notion API, representing all users data.
62
+ """
63
+ url = f"{self.base_url}/v1/users"
64
+ query_params = {}
65
+ response = self._get(url, params=query_params)
66
+ response.raise_for_status()
67
+ return response.json()
68
+
69
+ def notion_retrieve_your_token_sbot_user(self, ) -> dict[str, Any]:
70
+ """
71
+ Retrieves the current user's token data from the Notion API.
72
+
73
+ Args:
74
+ self: Instance of the class containing the necessary configuration and authentication details for accessing the Notion API.
75
+
76
+ Returns:
77
+ A dictionary containing the current user's token information as retrieved from the Notion API.
78
+ """
79
+ url = f"{self.base_url}/v1/users/me"
80
+ query_params = {}
81
+ response = self._get(url, params=query_params)
82
+ response.raise_for_status()
83
+ return response.json()
84
+
85
+ def notion_retrieve_adatabase(self, id) -> dict[str, Any]:
86
+ """
87
+ Retrieves a Notion database by its unique identifier.
88
+
89
+ Args:
90
+ id: A string representing the unique identifier of the Notion database to be retrieved.
91
+
92
+ Returns:
93
+ A dictionary containing the details of the retrieved Notion database.
94
+ """
95
+ if id is None:
96
+ raise ValueError("Missing required parameter 'id'")
97
+ url = f"{self.base_url}/v1/databases/{id}"
98
+ query_params = {}
99
+ response = self._get(url, params=query_params)
100
+ response.raise_for_status()
101
+ return response.json()
102
+
103
+ def notion_update_adatabase(self, id, request_body=None) -> dict[str, Any]:
104
+ """
105
+ Updates a Notion database with the given ID and request body data.
106
+
107
+ Args:
108
+ self: An instance of the class containing configuration and methods for HTTP requests.
109
+ id: A string representing the unique identifier of the Notion database to be updated.
110
+ request_body: An optional dictionary containing the fields and values to update in the database.
111
+
112
+ Returns:
113
+ A dictionary representing the JSON response from the Notion API after updating the database.
114
+ """
115
+ if id is None:
116
+ raise ValueError("Missing required parameter 'id'")
117
+ url = f"{self.base_url}/v1/databases/{id}"
118
+ query_params = {}
119
+ response = self._patch(url, data={}, params=query_params)
120
+ response.raise_for_status()
121
+ return response.json()
122
+
123
+ def notion_query_adatabase(self, id, request_body=None) -> dict[str, Any]:
124
+ """
125
+ Executes a query on a Notion database using the Notion API.
126
+
127
+ Args:
128
+ self: Instance of the class which should contain 'base_url' and '_post' method.
129
+ id: A string representing the unique identifier of the Notion database to query.
130
+ request_body: Optional. A dictionary representing the request body for the query. Defaults to None.
131
+
132
+ Returns:
133
+ A dictionary containing the JSON response from the Notion API after querying the specified database.
134
+ """
135
+ if id is None:
136
+ raise ValueError("Missing required parameter 'id'")
137
+ url = f"{self.base_url}/v1/databases/{id}/query"
138
+ query_params = {}
139
+ json_body = request_body if request_body is not None else None
140
+ response = self._post(url, data=json_body, params=query_params)
141
+ response.raise_for_status()
142
+ return response.json()
143
+
144
+ def notion_create_adatabase(self, request_body=None) -> dict[str, Any]:
145
+ """
146
+ Creates a new database in Notion using the provided request body.
147
+
148
+ Args:
149
+ self: Reference to the current instance of the class.
150
+ request_body: Optional dictionary containing the specifications for creating the Notion database. If None, a default empty request body is used.
151
+
152
+ Returns:
153
+ A dictionary representing the JSON response from the Notion API, containing data about the newly created database.
154
+ """
155
+ url = f"{self.base_url}/v1/databases/"
156
+ query_params = {}
157
+ json_body = request_body if request_body is not None else None
158
+ response = self._post(url, data=json_body, params=query_params)
159
+ response.raise_for_status()
160
+ return response.json()
161
+
162
+ def notion_create_apage(self, request_body=None) -> dict[str, Any]:
163
+ """
164
+ Creates a new page in Notion by sending a POST request with the specified request body.
165
+
166
+ Args:
167
+ request_body: Optional; A dictionary containing the data to create a new page in Notion. Defaults to None.
168
+
169
+ Returns:
170
+ A dictionary containing the JSON response from the Notion API with the details of the newly created page.
171
+ """
172
+ url = f"{self.base_url}/v1/pages/"
173
+ query_params = {}
174
+ json_body = request_body if request_body is not None else None
175
+ response = self._post(url, data=json_body, params=query_params)
176
+ response.raise_for_status()
177
+ return response.json()
178
+
179
+ def notion_retrieve_apage(self, id) -> dict[str, Any]:
180
+ """
181
+ Retrieves a page from the Notion API using a given page ID.
182
+
183
+ Args:
184
+ id: The unique identifier of the Notion page to be retrieved.
185
+
186
+ Returns:
187
+ A dictionary containing the JSON response from the Notion API, representing the page data.
188
+ """
189
+ if id is None:
190
+ raise ValueError("Missing required parameter 'id'")
191
+ url = f"{self.base_url}/v1/pages/{id}"
192
+ query_params = {}
193
+ response = self._get(url, params=query_params)
194
+ response.raise_for_status()
195
+ return response.json()
196
+
197
+ def notion_update_page_properties(self, id, request_body=None) -> dict[str, Any]:
198
+ """
199
+ Updates the properties of a Notion page identified by a given ID.
200
+
201
+ Args:
202
+ self: Instance of the class containing the Notion API credentials and methods.
203
+ id: The unique identifier of the Notion page to update. Must not be None.
204
+ request_body: An optional dictionary representing the request body to be sent with the update request. Defaults to None, indicating no additional properties to update.
205
+
206
+ Returns:
207
+ A dictionary containing the JSON response from the Notion API after the page update request.
208
+ """
209
+ if id is None:
210
+ raise ValueError("Missing required parameter 'id'")
211
+ url = f"{self.base_url}/v1/pages/{id}"
212
+ query_params = {}
213
+ response = self._patch(url, data={}, params=query_params)
214
+ response.raise_for_status()
215
+ return response.json()
216
+
217
+ def notion_retrieve_apage_property_item(self, page_id, property_id) -> dict[str, Any]:
218
+ """
219
+ Retrieves a specific property item from a page in Notion using the page and property IDs.
220
+
221
+ Args:
222
+ page_id: The unique identifier for the Notion page from which the property item should be retrieved.
223
+ property_id: The unique identifier for the property item within the specified page that should be retrieved.
224
+
225
+ Returns:
226
+ A dictionary containing the JSON response from the Notion API representing the requested property item.
227
+ """
228
+ if page_id is None:
229
+ raise ValueError("Missing required parameter 'page_id'")
230
+ if property_id is None:
231
+ raise ValueError("Missing required parameter 'property_id'")
232
+ url = f"{self.base_url}/v1/pages/{page_id}/properties/{property_id}"
233
+ query_params = {}
234
+ response = self._get(url, params=query_params)
235
+ response.raise_for_status()
236
+ return response.json()
237
+
238
+ def notion_retrieve_block_children(self, id, page_size=None) -> dict[str, Any]:
239
+ """
240
+ Retrieves the child blocks of a specified Notion block.
241
+
242
+ Args:
243
+ self: The instance of the class this method belongs to.
244
+ id: The unique identifier of the parent block whose children are to be retrieved.
245
+ page_size: Optional; the number of child blocks to retrieve per request.
246
+
247
+ Returns:
248
+ A dictionary containing the JSON response with details about the child blocks.
249
+ """
250
+ if id is None:
251
+ raise ValueError("Missing required parameter 'id'")
252
+ url = f"{self.base_url}/v1/blocks/{id}/children"
253
+ query_params = {k: v for k, v in [('page_size', page_size)] if v is not None}
254
+ response = self._get(url, params=query_params)
255
+ response.raise_for_status()
256
+ return response.json()
257
+
258
+ def notion_append_block_children(self, id, request_body=None) -> dict[str, Any]:
259
+ """
260
+ Appends child blocks to a block in Notion using its API.
261
+
262
+ Args:
263
+ self: Instance of the class containing Notion API credentials and configuration.
264
+ id: The unique identifier of the parent block to which child blocks are to be appended.
265
+ request_body: An optional dictionary containing the block data to append. Defaults to None.
266
+
267
+ Returns:
268
+ A dictionary representing the response from the Notion API, containing the result of the append operation.
269
+ """
270
+ if id is None:
271
+ raise ValueError("Missing required parameter 'id'")
272
+ url = f"{self.base_url}/v1/blocks/{id}/children"
273
+ query_params = {}
274
+ response = self._patch(url, data={}, params=query_params)
275
+ response.raise_for_status()
276
+ return response.json()
277
+
278
+ def notion_retrieve_ablock(self, id) -> dict[str, Any]:
279
+ """
280
+ Retrieves a block from the Notion API using the specified block ID.
281
+
282
+ Args:
283
+ id: The unique identifier of the block to retrieve from the Notion API. Must be a non-null string.
284
+
285
+ Returns:
286
+ A dictionary containing the block data in JSON format as retrieved from the Notion API.
287
+ """
288
+ if id is None:
289
+ raise ValueError("Missing required parameter 'id'")
290
+ url = f"{self.base_url}/v1/blocks/{id}"
291
+ query_params = {}
292
+ response = self._get(url, params=query_params)
293
+ response.raise_for_status()
294
+ return response.json()
295
+
296
+ def notion_delete_ablock(self, id) -> dict[str, Any]:
297
+ """
298
+ Deletes a block from the Notion database using the specified block ID.
299
+
300
+ Args:
301
+ id: The unique identifier of the block to be deleted. Must not be None.
302
+
303
+ Returns:
304
+ A dictionary containing the JSON response from the Notion API after attempting to delete the block.
305
+ """
306
+ if id is None:
307
+ raise ValueError("Missing required parameter 'id'")
308
+ url = f"{self.base_url}/v1/blocks/{id}"
309
+ query_params = {}
310
+ response = self._delete(url, params=query_params)
311
+ response.raise_for_status()
312
+ return response.json()
313
+
314
+ def notion_update_ablock(self, id, request_body=None) -> dict[str, Any]:
315
+ """
316
+ Updates a block in Notion with the given ID and request body.
317
+
318
+ Args:
319
+ id: The unique identifier of the Notion block to update.
320
+ request_body: The request body containing the updates to be made to the block. Defaults to None if not provided.
321
+
322
+ Returns:
323
+ A dictionary containing the JSON response from the Notion API after the block has been updated.
324
+ """
325
+ if id is None:
326
+ raise ValueError("Missing required parameter 'id'")
327
+ url = f"{self.base_url}/v1/blocks/{id}"
328
+ query_params = {}
329
+ response = self._patch(url, data={}, params=query_params)
330
+ response.raise_for_status()
331
+ return response.json()
332
+
333
+ def notion_search(self, request_body=None) -> dict[str, Any]:
334
+ """
335
+ Executes a search request to the Notion API and returns the response in JSON format.
336
+
337
+ Args:
338
+ request_body: An optional dictionary containing the search parameters for the API request. Defaults to None if not provided.
339
+
340
+ Returns:
341
+ A dictionary containing the response from the Notion API in JSON format.
342
+ """
343
+ url = f"{self.base_url}/v1/search"
344
+ query_params = {}
345
+ json_body = request_body if request_body is not None else None
346
+ response = self._post(url, data=json_body, params=query_params)
347
+ response.raise_for_status()
348
+ return response.json()
349
+
350
+ def notion_retrieve_comments(self, block_id=None, page_size=None, request_body=None) -> dict[str, Any]:
351
+ """
352
+ Retrieves comments from a Notion block using the Notion API.
353
+
354
+ Args:
355
+ block_id: Optional; The ID of the block for which to retrieve comments. If None, it retrieves comments for all blocks available to the user.
356
+ page_size: Optional; The maximum number of comments to retrieve in one request. If None, the default page size will be used.
357
+ request_body: Optional; A dictionary to include additional parameters in the request body. If None, no extra parameters are added.
358
+
359
+ Returns:
360
+ A dictionary containing the JSON response from the Notion API with the comments retrieved.
361
+ """
362
+ url = f"{self.base_url}/v1/comments"
363
+ query_params = {k: v for k, v in [('block_id', block_id), ('page_size', page_size)] if v is not None}
364
+ response = self._get(url, params=query_params)
365
+ response.raise_for_status()
366
+ return response.json()
367
+
368
+ def notion_add_comment_to_page(self, request_body=None) -> dict[str, Any]:
369
+ """
370
+ Adds a comment to a specified Notion page using the provided request body.
371
+
372
+ Args:
373
+ request_body: An optional dictionary containing the details of the comment to be added to the Notion page. If None, no data is sent in the request's body.
374
+
375
+ Returns:
376
+ A dictionary containing the response data from the Notion API, parsed from JSON format.
377
+ """
378
+ url = f"{self.base_url}/v1/comments"
379
+ query_params = {}
380
+ json_body = request_body if request_body is not None else None
381
+ response = self._post(url, data=json_body, params=query_params)
382
+ response.raise_for_status()
383
+ return response.json()
384
+
385
+ def list_tools(self):
386
+ """
387
+ Returns a list of functions that interact with Notion's API for various operations.
388
+
389
+ Args:
390
+ None: This method does not take any parameters.
391
+
392
+ Returns:
393
+ A list of functions that perform specific operations with Notion's API, such as retrieving or updating users, databases, pages, blocks, and comments.
394
+ """
395
+ return [
396
+ self.notion_retrieve_auser,
397
+ self.notion_list_all_users,
398
+ self.notion_retrieve_your_token_sbot_user,
399
+ self.notion_retrieve_adatabase,
400
+ self.notion_update_adatabase,
401
+ self.notion_query_adatabase,
402
+ self.notion_create_adatabase,
403
+ self.notion_create_apage,
404
+ self.notion_retrieve_apage,
405
+ self.notion_update_page_properties,
406
+ self.notion_retrieve_apage_property_item,
407
+ self.notion_retrieve_block_children,
408
+ self.notion_append_block_children,
409
+ self.notion_retrieve_ablock,
410
+ self.notion_delete_ablock,
411
+ self.notion_update_ablock,
412
+ self.notion_search,
413
+ self.notion_retrieve_comments,
414
+ self.notion_add_comment_to_page
415
+ ]
universal_mcp/cli.py CHANGED
@@ -66,7 +66,7 @@ def generate(
66
66
  def docgen(
67
67
  file_path: Path = typer.Argument(..., help="Path to the Python file to process"),
68
68
  model: str = typer.Option(
69
- "anthropic/claude-3-sonnet-20240229",
69
+ "anthropic/claude-3-5-sonnet-20241022",
70
70
  "--model",
71
71
  "-m",
72
72
  help="Model to use for generating docstrings",
@@ -177,6 +177,9 @@ def generate_method_code(path, method, operation, tool_name=None):
177
177
  Returns:
178
178
  tuple: (method_code, func_name) - The Python code for the method and its name.
179
179
  """
180
+ # Extract path parameters from the URL path
181
+ path_params_in_url = re.findall(r'{([^}]+)}', path)
182
+
180
183
  # Determine function name
181
184
  if "operationId" in operation:
182
185
  raw_name = operation["operationId"]
@@ -198,18 +201,28 @@ def generate_method_code(path, method, operation, tool_name=None):
198
201
  func_name = f"{tool_name}_{func_name}"
199
202
 
200
203
  # Get parameters and request body
201
- parameters = operation.get("parameters", [])
204
+ # Filter out header parameters
205
+ parameters = [param for param in operation.get("parameters", []) if param.get("in") != "header"]
202
206
  has_body = "requestBody" in operation
203
207
  body_required = has_body and operation["requestBody"].get("required", False)
204
208
 
205
209
  # Build function arguments
206
210
  required_args = []
207
211
  optional_args = []
212
+
213
+
214
+ for param_name in path_params_in_url:
215
+ if param_name not in required_args:
216
+ required_args.append(param_name)
217
+
218
+
208
219
  for param in parameters:
209
- if param.get("required", False):
210
- required_args.append(param["name"])
211
- else:
212
- optional_args.append(f"{param['name']}=None")
220
+ param_name = param["name"]
221
+ if param_name not in required_args:
222
+ if param.get("required", False):
223
+ required_args.append(param_name)
224
+ else:
225
+ optional_args.append(f"{param_name}=None")
213
226
 
214
227
  # Add request body parameter
215
228
  if has_body:
@@ -229,12 +242,12 @@ def generate_method_code(path, method, operation, tool_name=None):
229
242
  # Build method body
230
243
  body_lines = []
231
244
 
232
- # Validate required parameters
233
- for param in parameters:
234
- if param.get("required", False):
235
- body_lines.append(f" if {param['name']} is None:")
245
+ # Validate required parameters including path parameters
246
+ for param_name in required_args:
247
+ if param_name != "request_body": # Skip validation for request body as it's handled separately
248
+ body_lines.append(f" if {param_name} is None:")
236
249
  body_lines.append(
237
- f" raise ValueError(\"Missing required parameter '{param['name']}'\")"
250
+ f" raise ValueError(\"Missing required parameter '{param_name}'\")"
238
251
  )
239
252
 
240
253
  # Validate required body
@@ -244,15 +257,9 @@ def generate_method_code(path, method, operation, tool_name=None):
244
257
  ' raise ValueError("Missing required request body")'
245
258
  )
246
259
 
247
- # Path parameters
248
- path_params = [p for p in parameters if p["in"] == "path"]
249
- path_params_dict = ", ".join([f"'{p['name']}': {p['name']}" for p in path_params])
250
- body_lines.append(f" path_params = {{{path_params_dict}}}")
251
-
252
- # Format URL
253
- body_lines.append(
254
- f' url = f"{{self.base_url}}{path}".format_map(path_params)'
255
- )
260
+ # Format URL directly with path parameters
261
+ url_line = f' url = f"{{self.base_url}}{path}"'
262
+ body_lines.append(url_line)
256
263
 
257
264
  # Query parameters
258
265
  query_params = [p for p in parameters if p["in"] == "query"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp
3
- Version: 0.1.1rc1
3
+ Version: 0.1.2
4
4
  Summary: Universal MCP acts as a middle ware for your API applications. It can store your credentials, authorize, enable disable apps on the fly and much more.
5
5
  Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -27,6 +27,7 @@ Provides-Extra: playground
27
27
  Requires-Dist: fastapi[standard]>=0.115.12; extra == 'playground'
28
28
  Requires-Dist: langchain-anthropic>=0.3.10; extra == 'playground'
29
29
  Requires-Dist: langchain-mcp-adapters>=0.0.3; extra == 'playground'
30
+ Requires-Dist: langchain-openai>=0.3.12; extra == 'playground'
30
31
  Requires-Dist: langgraph-checkpoint-sqlite>=2.0.6; extra == 'playground'
31
32
  Requires-Dist: langgraph>=0.3.24; extra == 'playground'
32
33
  Requires-Dist: python-dotenv>=1.0.1; extra == 'playground'
@@ -1,5 +1,5 @@
1
1
  universal_mcp/__init__.py,sha256=2gdHpHaDDcsRjZjJ01FLN-1iidN_wbDAolNpxhGoFB4,59
2
- universal_mcp/cli.py,sha256=rLdE1CRiouPIL2nBYv9EInOk_1uJfUBHmakWHBZ0roc,5555
2
+ universal_mcp/cli.py,sha256=7-8LZR9GiCW_iAz040XdgocCm6CvuJwBmKoZpFZDf-I,5557
3
3
  universal_mcp/config.py,sha256=9eb3DDg4PBBr1MlGeBrA4bja3Y6howOH-UKpo7JIbs8,828
4
4
  universal_mcp/exceptions.py,sha256=Zp2_v_m3L7GDAmD1ZyuwFtY6ngapdhxuIygrvpZAQtM,271
5
5
  universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -12,6 +12,9 @@ universal_mcp/applications/github/app.py,sha256=L201f5MSx1YVx0nqgduZ5gyHPZdX0Ufc
12
12
  universal_mcp/applications/google_calendar/app.py,sha256=g_3vrsM2ltwpTySgC5I4SYg47n4UJiYigECO0ax1EHM,19134
13
13
  universal_mcp/applications/google_mail/app.py,sha256=VXeD3_TRgYIUDFUzDPCKgR47XvovxLFulD-HG22hls8,22716
14
14
  universal_mcp/applications/markitdown/app.py,sha256=LV8cvkhmacsal-mJmKL9DH5BMypL9MGHIiCkhal6Jtg,1019
15
+ universal_mcp/applications/notion/README.md,sha256=kmdjfXyoEQyk1UTP3zZiGYj2XdMcWieGjs0iscaQ028,2109
16
+ universal_mcp/applications/notion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ universal_mcp/applications/notion/app.py,sha256=OpoCbGyq3ieNMXHYxaZkqBfjvWRNUwEt3n1-Yj23AyY,17981
15
18
  universal_mcp/applications/reddit/app.py,sha256=leU__w5VxX1vMK-kfuy-dvY97Pn8Mn80X2payVshirU,13562
16
19
  universal_mcp/applications/resend/app.py,sha256=bRo-CRDuk65EUSHOJnbVHWV6TuiUHtedz6FXKRS1ym0,1386
17
20
  universal_mcp/applications/serp/app.py,sha256=hPXu1sBiRZRCCzr4q2uvt54F0-B3aZK2Uz4wfKokkZ4,3131
@@ -30,8 +33,8 @@ universal_mcp/utils/api_generator.py,sha256=-wRBpLVfJQXy1R-8FpDNs6b8_eeekVDuPc_u
30
33
  universal_mcp/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
34
  universal_mcp/utils/docgen.py,sha256=UUjiRcIeb96xbogF96Ujzw3Hdd5ExckOao5rzIpRsBQ,12651
32
35
  universal_mcp/utils/installation.py,sha256=nyuQDl8S6KftjukCOKE4vtiqSzpVO7M5U-W00ivp444,2939
33
- universal_mcp/utils/openapi.py,sha256=A719DaYc7AgN-n_uW868MBmpG_oPvuvMOgUCauInLeY,12629
34
- universal_mcp-0.1.1rc1.dist-info/METADATA,sha256=WzlkXc7fMZooD6COVYEDNBUCYQBFegz-YPMpEhxWhOo,5871
35
- universal_mcp-0.1.1rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
36
- universal_mcp-0.1.1rc1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
37
- universal_mcp-0.1.1rc1.dist-info/RECORD,,
36
+ universal_mcp/utils/openapi.py,sha256=XhCqWI4pUWX9s_-WNPx03EBboe6CjYUaFip1OqZWRRQ,12926
37
+ universal_mcp-0.1.2.dist-info/METADATA,sha256=fGQ1eC4wBti2_acIAMjXlQNmzQ26b8DIktE-uM5Ij6Q,5931
38
+ universal_mcp-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
39
+ universal_mcp-0.1.2.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
40
+ universal_mcp-0.1.2.dist-info/RECORD,,