universal-mcp 0.1.8rc1__py3-none-any.whl → 0.1.8rc2__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 (45) hide show
  1. universal_mcp/applications/application.py +6 -5
  2. universal_mcp/applications/calendly/README.md +78 -0
  3. universal_mcp/applications/calendly/app.py +954 -0
  4. universal_mcp/applications/e2b/app.py +18 -12
  5. universal_mcp/applications/firecrawl/app.py +28 -1
  6. universal_mcp/applications/github/app.py +150 -107
  7. universal_mcp/applications/google_calendar/app.py +72 -137
  8. universal_mcp/applications/google_docs/app.py +35 -15
  9. universal_mcp/applications/google_drive/app.py +84 -55
  10. universal_mcp/applications/google_mail/app.py +143 -53
  11. universal_mcp/applications/google_sheet/app.py +61 -38
  12. universal_mcp/applications/markitdown/app.py +12 -11
  13. universal_mcp/applications/notion/app.py +199 -89
  14. universal_mcp/applications/perplexity/app.py +17 -15
  15. universal_mcp/applications/reddit/app.py +110 -101
  16. universal_mcp/applications/resend/app.py +14 -7
  17. universal_mcp/applications/serpapi/app.py +13 -6
  18. universal_mcp/applications/tavily/app.py +13 -10
  19. universal_mcp/applications/wrike/README.md +71 -0
  20. universal_mcp/applications/wrike/__init__.py +0 -0
  21. universal_mcp/applications/wrike/app.py +1044 -0
  22. universal_mcp/applications/youtube/README.md +82 -0
  23. universal_mcp/applications/youtube/__init__.py +0 -0
  24. universal_mcp/applications/youtube/app.py +986 -0
  25. universal_mcp/applications/zenquotes/app.py +13 -3
  26. universal_mcp/exceptions.py +8 -2
  27. universal_mcp/integrations/__init__.py +15 -1
  28. universal_mcp/integrations/integration.py +132 -27
  29. universal_mcp/servers/__init__.py +6 -15
  30. universal_mcp/servers/server.py +209 -153
  31. universal_mcp/stores/__init__.py +7 -2
  32. universal_mcp/stores/store.py +103 -42
  33. universal_mcp/tools/__init__.py +3 -0
  34. universal_mcp/tools/adapters.py +40 -0
  35. universal_mcp/tools/func_metadata.py +214 -0
  36. universal_mcp/tools/tools.py +285 -0
  37. universal_mcp/utils/docgen.py +277 -123
  38. universal_mcp/utils/docstring_parser.py +156 -0
  39. universal_mcp/utils/openapi.py +149 -40
  40. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/METADATA +7 -3
  41. universal_mcp-0.1.8rc2.dist-info/RECORD +71 -0
  42. universal_mcp-0.1.8rc1.dist-info/RECORD +0 -58
  43. /universal_mcp/{utils/bridge.py → applications/calendly/__init__.py} +0 -0
  44. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/WHEEL +0 -0
  45. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/entry_points.txt +0 -0
@@ -70,6 +70,33 @@ def determine_return_type(operation: dict[str, Any]) -> str:
70
70
  return "Any"
71
71
 
72
72
 
73
+ def resolve_schema_reference(reference, schema):
74
+ """
75
+ Resolve a JSON schema reference to its target schema.
76
+
77
+ Args:
78
+ reference (str): The reference string (e.g., '#/components/schemas/User')
79
+ schema (dict): The complete OpenAPI schema that contains the reference
80
+
81
+ Returns:
82
+ dict: The resolved schema, or None if not found
83
+ """
84
+ if not reference.startswith('#/'):
85
+ return None
86
+
87
+ # Split the reference path and navigate through the schema
88
+ parts = reference[2:].split('/')
89
+ current = schema
90
+
91
+ for part in parts:
92
+ if part in current:
93
+ current = current[part]
94
+ else:
95
+ return None
96
+
97
+ return current
98
+
99
+
73
100
  def generate_api_client(schema):
74
101
  """
75
102
  Generate a Python API client class from an OpenAPI schema.
@@ -130,7 +157,7 @@ def generate_api_client(schema):
130
157
  if method in ["get", "post", "put", "delete", "patch", "options", "head"]:
131
158
  operation = path_info[method]
132
159
  method_code, func_name = generate_method_code(
133
- path, method, operation, tool_name
160
+ path, method, operation, schema, tool_name
134
161
  )
135
162
  methods.append(method_code)
136
163
  method_names.append(func_name)
@@ -164,7 +191,7 @@ def generate_api_client(schema):
164
191
  return class_code
165
192
 
166
193
 
167
- def generate_method_code(path, method, operation, tool_name=None):
194
+ def generate_method_code(path, method, operation, full_schema, tool_name=None):
168
195
  """
169
196
  Generate the code for a single API method.
170
197
 
@@ -172,6 +199,7 @@ def generate_method_code(path, method, operation, tool_name=None):
172
199
  path (str): The API path (e.g., '/users/{user_id}').
173
200
  method (str): The HTTP method (e.g., 'get').
174
201
  operation (dict): The operation details from the schema.
202
+ full_schema (dict): The complete OpenAPI schema, used for reference resolution.
175
203
  tool_name (str, optional): The name of the tool/app to prefix the function name with.
176
204
 
177
205
  Returns:
@@ -196,10 +224,11 @@ def generate_method_code(path, method, operation, tool_name=None):
196
224
  name_parts.append(part)
197
225
  func_name = "_".join(name_parts).replace("-", "_").lower()
198
226
 
199
-
200
-
201
- func_name = re.sub(r'_a([^_])', r'_a_\1', func_name) # Fix for patterns like retrieve_ablock
202
- func_name = re.sub(r'_an([^_])', r'_an_\1', func_name) # Fix for patterns like create_anitem
227
+ # Only fix isolated 'a' and 'an' as articles, not when they're part of words
228
+ func_name = re.sub(r'_a([^_a-z])', r'_a_\1', func_name) # Fix for patterns like retrieve_ablock -> retrieve_a_block
229
+ func_name = re.sub(r'_a$', r'_a', func_name) # Don't change if 'a' is at the end of the name
230
+ func_name = re.sub(r'_an([^_a-z])', r'_an_\1', func_name) # Fix for patterns like create_anitem -> create_an_item
231
+ func_name = re.sub(r'_an$', r'_an', func_name) # Don't change if 'an' is at the end of the name
203
232
 
204
233
  # Get parameters and request body
205
234
  # Filter out header parameters
@@ -207,16 +236,64 @@ def generate_method_code(path, method, operation, tool_name=None):
207
236
  has_body = "requestBody" in operation
208
237
  body_required = has_body and operation["requestBody"].get("required", False)
209
238
 
239
+ # Check if the requestBody has actual content or is empty
240
+ has_empty_body = False
241
+ if has_body:
242
+ request_body_content = operation["requestBody"].get("content", {})
243
+ if not request_body_content or all(not content for content_type, content in request_body_content.items()):
244
+ has_empty_body = True
245
+ has_body = False # Treat it as if it doesn't have a body for property extraction
246
+
247
+ # Extract request body schema properties and required fields
248
+ required_fields = []
249
+ request_body_properties = {}
250
+ is_array_body = False
251
+ array_items_schema = None
252
+
253
+ if has_body:
254
+ for content_type, content in operation["requestBody"].get("content", {}).items():
255
+ if content_type.startswith("application/json") and "schema" in content:
256
+ schema = content["schema"]
257
+
258
+ # Resolve schema reference if present
259
+ if "$ref" in schema:
260
+ ref_schema = resolve_schema_reference(schema["$ref"], full_schema)
261
+ if ref_schema:
262
+ schema = ref_schema
263
+
264
+ # Check if the schema is an array type
265
+ if schema.get("type") == "array":
266
+ is_array_body = True
267
+ array_items_schema = schema.get("items", {})
268
+ # Try to resolve any reference in items
269
+ if "$ref" in array_items_schema:
270
+ array_items_schema = resolve_schema_reference(array_items_schema["$ref"], full_schema)
271
+ else:
272
+ # Extract required fields from schema
273
+ if "required" in schema:
274
+ required_fields = schema["required"]
275
+ # Extract properties from schema
276
+ if "properties" in schema:
277
+ request_body_properties = schema["properties"]
278
+
279
+ # Check for nested references in properties
280
+ for prop_name, prop_schema in request_body_properties.items():
281
+ if "$ref" in prop_schema:
282
+ ref_prop_schema = resolve_schema_reference(prop_schema["$ref"], full_schema)
283
+ if ref_prop_schema:
284
+ request_body_properties[prop_name] = ref_prop_schema
285
+ break
286
+
210
287
  # Build function arguments
211
288
  required_args = []
212
289
  optional_args = []
213
290
 
214
-
291
+ # Add path parameters
215
292
  for param_name in path_params_in_url:
216
293
  if param_name not in required_args:
217
294
  required_args.append(param_name)
218
295
 
219
-
296
+ # Add query parameters
220
297
  for param in parameters:
221
298
  param_name = param["name"]
222
299
  if param_name not in required_args:
@@ -224,13 +301,42 @@ def generate_method_code(path, method, operation, tool_name=None):
224
301
  required_args.append(param_name)
225
302
  else:
226
303
  optional_args.append(f"{param_name}=None")
227
-
228
- # Add request body parameter
304
+
305
+ # Handle array type request body differently
306
+ request_body_params = []
229
307
  if has_body:
230
- if body_required:
231
- required_args.append("request_body")
232
- else:
233
- optional_args.append("request_body=None")
308
+ if is_array_body:
309
+ # For array request bodies, add a single parameter for the entire array
310
+ array_param_name = "items"
311
+ # Try to get a better name from the operation or path
312
+ if func_name.endswith("_list_input"):
313
+ array_param_name = func_name.replace("_list_input", "")
314
+ elif "List" in func_name:
315
+ array_param_name = func_name.split("List")[0].lower() + "_list"
316
+
317
+ # Make the array parameter required if the request body is required
318
+ if body_required:
319
+ required_args.append(array_param_name)
320
+ else:
321
+ optional_args.append(f"{array_param_name}=None")
322
+
323
+ # Remember this is an array param
324
+ request_body_params = [array_param_name]
325
+ elif request_body_properties:
326
+ # For object request bodies, add individual properties as parameters
327
+ for prop_name in request_body_properties:
328
+ if prop_name in required_fields:
329
+ request_body_params.append(prop_name)
330
+ if prop_name not in required_args:
331
+ required_args.append(prop_name)
332
+ else:
333
+ request_body_params.append(prop_name)
334
+ if f"{prop_name}=None" not in optional_args:
335
+ optional_args.append(f"{prop_name}=None")
336
+
337
+ # If request body is present but empty (content: {}), add a generic request_body parameter
338
+ if has_empty_body:
339
+ optional_args.append("request_body=None")
234
340
 
235
341
  # Combine required and optional arguments
236
342
  args = required_args + optional_args
@@ -245,19 +351,31 @@ def generate_method_code(path, method, operation, tool_name=None):
245
351
 
246
352
  # Validate required parameters including path parameters
247
353
  for param_name in required_args:
248
- if param_name != "request_body": # Skip validation for request body as it's handled separately
249
- body_lines.append(f" if {param_name} is None:")
250
- body_lines.append(
251
- f" raise ValueError(\"Missing required parameter '{param_name}'\")"
252
- )
253
-
254
- # Validate required body
255
- if has_body and body_required:
256
- body_lines.append(" if request_body is None:")
354
+ body_lines.append(f" if {param_name} is None:")
257
355
  body_lines.append(
258
- ' raise ValueError("Missing required request body")'
356
+ f" raise ValueError(\"Missing required parameter '{param_name}'\")"
259
357
  )
260
358
 
359
+ # Build request body (handle array and object types differently)
360
+ if has_body:
361
+ if is_array_body:
362
+ # For array request bodies, use the array parameter directly
363
+ body_lines.append(" # Use items array directly as request body")
364
+ body_lines.append(f" request_body = {request_body_params[0]}")
365
+ elif request_body_properties:
366
+ # For object request bodies, build the request body from individual parameters
367
+
368
+ body_lines.append(" request_body = {")
369
+
370
+ for prop_name in request_body_params:
371
+ # Only include non-None values in the request body
372
+ body_lines.append(f" '{prop_name}': {prop_name},")
373
+
374
+ body_lines.append(" }")
375
+
376
+
377
+ body_lines.append(" request_body = {k: v for k, v in request_body.items() if v is not None}")
378
+
261
379
  # Format URL directly with path parameters
262
380
  url_line = f' url = f"{{self.base_url}}{path}"'
263
381
  body_lines.append(url_line)
@@ -276,30 +394,21 @@ def generate_method_code(path, method, operation, tool_name=None):
276
394
 
277
395
  # Make HTTP request using the proper method
278
396
  method_lower = method.lower()
397
+ # For empty request bodies, use the request_body parameter directly if provided
398
+ request_body_arg = "request_body" if has_empty_body else "{}" if not has_body else "request_body"
399
+
279
400
  if method_lower == "get":
280
401
  body_lines.append(" response = self._get(url, params=query_params)")
281
402
  elif method_lower == "post":
282
- if has_body:
283
- body_lines.append(" response = self._post(url, data=request_body, params=query_params)")
284
- else:
285
- body_lines.append(" response = self._post(url, data={}, params=query_params)")
403
+ body_lines.append(f" response = self._post(url, data={request_body_arg}, params=query_params)")
286
404
  elif method_lower == "put":
287
- if has_body:
288
- body_lines.append(" response = self._put(url, data=request_body, params=query_params)")
289
- else:
290
- body_lines.append(" response = self._put(url, data={}, params=query_params)")
405
+ body_lines.append(f" response = self._put(url, data={request_body_arg}, params=query_params)")
291
406
  elif method_lower == "patch":
292
- if has_body:
293
- body_lines.append(" response = self._patch(url, data=request_body, params=query_params)")
294
- else:
295
- body_lines.append(" response = self._patch(url, data={}, params=query_params)")
407
+ body_lines.append(f" response = self._patch(url, data={request_body_arg}, params=query_params)")
296
408
  elif method_lower == "delete":
297
409
  body_lines.append(" response = self._delete(url, params=query_params)")
298
410
  else:
299
- if has_body:
300
- body_lines.append(f" response = self._{method_lower}(url, data=request_body, params=query_params)")
301
- else:
302
- body_lines.append(f" response = self._{method_lower}(url, data={{}}, params=query_params)")
411
+ body_lines.append(f" response = self._{method_lower}(url, data={request_body_arg}, params=query_params)")
303
412
 
304
413
  # Handle response
305
414
  body_lines.append(" response.raise_for_status()")
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp
3
- Version: 0.1.8rc1
3
+ Version: 0.1.8rc2
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
7
7
  Requires-Dist: keyring>=25.6.0
8
8
  Requires-Dist: litellm>=1.30.7
9
9
  Requires-Dist: loguru>=0.7.3
10
- Requires-Dist: mcp>=1.5.0
10
+ Requires-Dist: mcp>=1.6.0
11
11
  Requires-Dist: posthog>=3.24.0
12
12
  Requires-Dist: pydantic-settings>=2.8.1
13
13
  Requires-Dist: pydantic>=2.11.1
@@ -155,12 +155,16 @@ Universal MCP comes with several pre-built applications:
155
155
  | `firecrawl` | Scrape/crawl web pages, search | API Key (via Integration) |
156
156
  | `github` | Interact with GitHub repos, issues, PRs | OAuth (AgentR) |
157
157
  | `google-calendar`| Manage Google Calendar events | OAuth (AgentR) |
158
+ | `google-docs` | Create and manage Google Docs documents | OAuth (AgentR) |
159
+ | `google-drive` | Manage Google Drive files and folders | OAuth (AgentR) |
158
160
  | `google-mail` | Read and send Gmail emails | OAuth (AgentR) |
161
+ | `google-sheet` | Manage Google Sheets spreadsheets | OAuth (AgentR) |
159
162
  | `markitdown` | Convert web pages/files to Markdown | None |
160
163
  | `notion` | Interact with Notion pages/databases | OAuth (AgentR) |
164
+ | `perplexity` | Interact with Perplexity AI models | API Key (via Integration) |
161
165
  | `reddit` | Interact with Reddit posts/comments | OAuth (AgentR) |
162
166
  | `resend` | Send emails via Resend API | API Key (via Integration) |
163
- | `serp` | Perform web searches via SerpApi | API Key (via Integration) |
167
+ | `serpapi` | Perform web searches via SerpApi | API Key (via Integration) |
164
168
  | `tavily` | Advanced web search & research API | API Key (via Integration) |
165
169
  | `zenquotes` | Get inspirational quotes | None |
166
170
 
@@ -0,0 +1,71 @@
1
+ universal_mcp/__init__.py,sha256=2gdHpHaDDcsRjZjJ01FLN-1iidN_wbDAolNpxhGoFB4,59
2
+ universal_mcp/cli.py,sha256=DG-Qxc5vQIdbhAIQuU7bKKJuRGzwyOigjfCKSWBRhBI,5258
3
+ universal_mcp/config.py,sha256=sJaPI4q51CDPPG0z32rMJiE7a64eaa9nxbjJgYnaFA4,838
4
+ universal_mcp/exceptions.py,sha256=SCvFg88w-xA6Fct3yBXl6czFVTmaKA71l_oue2shLME,372
5
+ universal_mcp/logger.py,sha256=W6A868vyvpdkEQ4Dd0rWdC_7ErSxSQ1z2uxCb77IM8Y,2015
6
+ universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ universal_mcp/applications/__init__.py,sha256=qeWnbdIudyMR7ST4XTc0gpEM9o6TsM1ZnZ92dMAPSBA,754
8
+ universal_mcp/applications/application.py,sha256=DyFDIkQvDi8kHSzSWGKDw5Oe3mxjNPwr5m9Tqbm2NgA,3583
9
+ universal_mcp/applications/calendly/README.md,sha256=85m3XXLPhQ99oghl8SeazCZ2fjBR81-f1y_mjjhx2B0,5911
10
+ universal_mcp/applications/calendly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ universal_mcp/applications/calendly/app.py,sha256=LL5yeBTqMgqXN234C1hlyBEuZANCAKCUnxRDNfitAoM,48074
12
+ universal_mcp/applications/e2b/README.md,sha256=S4lTp-vEZ8VTCKPXqjUXu5nYlUMAF8lw8CQyBGPgxjs,700
13
+ universal_mcp/applications/e2b/app.py,sha256=U4-KjcZrKFEMO4sBwH4PR3H94c7NfqUpoFXtIGO9y54,3201
14
+ universal_mcp/applications/firecrawl/README.md,sha256=KAWe_TQbrc9eA6bSyde5dapMP1CNvarVItV_YJH3d_0,1430
15
+ universal_mcp/applications/firecrawl/app.py,sha256=WeO4Jsk5odCx40MYALLVdBMWVXqTb00KXb9aiPu-9js,10062
16
+ universal_mcp/applications/github/README.md,sha256=6ID-__gUJ5ZxzAS_OjzmoUAag1LamSvEB75DHcj3m-g,1294
17
+ universal_mcp/applications/github/app.py,sha256=1EGnCS-QuAJsxwI__RC0vD6PzNLx01byy0Kk_mOTjaY,18482
18
+ universal_mcp/applications/google_calendar/app.py,sha256=gszk_3qqb4R5wWhL7Xs9Uwwwlm15C2iJeBY-PHRXhHo,19920
19
+ universal_mcp/applications/google_docs/README.md,sha256=SyOgJG-XU0FXhrVukvg9mxwin73mpqaCOT6rDJ64Klk,909
20
+ universal_mcp/applications/google_docs/app.py,sha256=37bx4o-fLp7k4L-KZte0q3fLndNVWVaInjH-oNIEqwA,4390
21
+ universal_mcp/applications/google_drive/README.md,sha256=YlN8IT12oO8zVMib1MlTYRBGNP7rzW_KyVAZyyxKvME,1192
22
+ universal_mcp/applications/google_drive/app.py,sha256=FAvJmgc7uPa-c2TvSh868PoiViyWjxGGbsoChJpB934,12286
23
+ universal_mcp/applications/google_mail/README.md,sha256=LL6TjjmwEqyuRVvIfCh-I_PlWp9ciCZOdJC0LafGZYc,1185
24
+ universal_mcp/applications/google_mail/app.py,sha256=Od4MZH6aa_dOZFasQfTOGa-xY1xm-8MmkBpFfX_Jb5M,28219
25
+ universal_mcp/applications/google_sheet/README.md,sha256=yW1b_qlb_pbIJzCxZc58581kKzC5vyP8Mj4iwXgidtQ,1108
26
+ universal_mcp/applications/google_sheet/app.py,sha256=BFzEm6u9bpRzA1NmPjL8Hbxlf8P8EMaq7XfhdFx_WWE,7296
27
+ universal_mcp/applications/markitdown/app.py,sha256=RJ1RcPeklV-dlHH0MWA3NowFiTmsRo3ppd5PATYcghI,1868
28
+ universal_mcp/applications/notion/README.md,sha256=45NmPOmSQv99qBvWdwmnV5vbaYc9_8vq8I-FA7veVAA,2600
29
+ universal_mcp/applications/notion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ universal_mcp/applications/notion/app.py,sha256=ur5IEs7nbO4NncO3MAegeZS5cHZgvOkqxfRBITHnT0k,21352
31
+ universal_mcp/applications/perplexity/README.md,sha256=QGV1iReH5p-Np7vvkZsVHxxDKQ0YaitHEwomNmGEyQs,732
32
+ universal_mcp/applications/perplexity/app.py,sha256=ux1llcJJHu6JJJOllZbuMdkViv6q1PnQ2Ya5hZQpy1I,3839
33
+ universal_mcp/applications/reddit/README.md,sha256=YVbJ1RN6NWlB-P6w2LxCk_DuUWl7mwaKZScY-mIMnNc,1271
34
+ universal_mcp/applications/reddit/app.py,sha256=9mM-bU3YqtkfyTxLxW_WOUxaC1OKi-Q1ksjKqkgEnJ8,16004
35
+ universal_mcp/applications/resend/README.md,sha256=k-sb2UwbFvDPEz6qQPLWd2cJj8hDx5f3NW7dz2jAfjI,719
36
+ universal_mcp/applications/resend/app.py,sha256=2H9y_kRerdX84VEKu-1aBDWyYFxlOSiEbnIT16HNJmg,2008
37
+ universal_mcp/applications/serpapi/README.md,sha256=hX4VeT2iL_67ZsMhKd60DAujQCh9K3IdHroHIq808RY,691
38
+ universal_mcp/applications/serpapi/app.py,sha256=M1oNUNjcRn_KOIUe8wVg-eN5OFeuhcxS3C2DejqN5BU,3952
39
+ universal_mcp/applications/tavily/README.md,sha256=cNg4EwX5wBbkDpPtNBNC3A_GxglfSVhdAJuweSrXN20,721
40
+ universal_mcp/applications/tavily/app.py,sha256=4Xi9-uSa6ke9Onr8YG5ovZMtYI8zDhAMjEqWXTPm7_c,2634
41
+ universal_mcp/applications/wrike/README.md,sha256=4EHVPlA8B_dzTA1-HQQqp89z6QL37RTyD2l6DD7vG9E,5156
42
+ universal_mcp/applications/wrike/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ universal_mcp/applications/wrike/app.py,sha256=cjPmDHmuSY0QgNKHxitwyAennzpc1vgz94TRB9xdAHQ,57778
44
+ universal_mcp/applications/youtube/README.md,sha256=NHqIm6QvXQK7I2oZ8hUwfjLDS4_eSK9NPeFbuGIbmhg,5405
45
+ universal_mcp/applications/youtube/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ universal_mcp/applications/youtube/app.py,sha256=m32MaqOtNhWR3LFi5TjcnQ3huFUT6x5DTV4EKKVdyVQ,52859
47
+ universal_mcp/applications/zenquotes/README.md,sha256=wA3hjqjrkrczQaffpwyolSKq6gXmkLgeHx6_EQrYEOY,709
48
+ universal_mcp/applications/zenquotes/app.py,sha256=mKX0fLdAv_a_m3o8ZKUA2ayiQbLk9Mxfa8jgkNmgcxI,1109
49
+ universal_mcp/integrations/README.md,sha256=lTAPXO2nivcBe1q7JT6PRa6v9Ns_ZersQMIdw-nmwEA,996
50
+ universal_mcp/integrations/__init__.py,sha256=M8chg9JsfC14OWvyu8Est5_jZGRrsEDImxyfl2TpGRI,933
51
+ universal_mcp/integrations/agentr.py,sha256=l0mo79oeDML19udFfoCo9lyhbDAf0X94_lnpOgbTrb0,3331
52
+ universal_mcp/integrations/integration.py,sha256=igOZNGJQQKR4Q0FSol21H_Orf3Vmlslg8eWoahHWr4U,9727
53
+ universal_mcp/servers/__init__.py,sha256=FmRcHdDPQWTfovZjt_-e1b9bHk8-wQkSQNfvPMDTec4,472
54
+ universal_mcp/servers/server.py,sha256=pNLrfog-oemL4WiiOdcWASEQxLZL8560FOiTjJx_i-8,8748
55
+ universal_mcp/stores/__init__.py,sha256=quvuwhZnpiSLuojf0NfmBx2xpaCulv3fbKtKaSCEmuM,603
56
+ universal_mcp/stores/store.py,sha256=dmqXCyS36umPXD7iRnU9KYX4KTM4rkIiekGGtCg9ygg,6800
57
+ universal_mcp/tools/__init__.py,sha256=3G2UHjEbkZAdAPp7qDIV9lq7_HY1eX5rm4bBEW1_X8c,71
58
+ universal_mcp/tools/adapters.py,sha256=Hdxqrid3NrAxNGHlMXycNOSdhQA_eluJbalCwhue6H4,923
59
+ universal_mcp/tools/func_metadata.py,sha256=Ax7MCE-RuM6IPvX4jj386SRFHakHMzn461GJ48p5aIE,7946
60
+ universal_mcp/tools/tools.py,sha256=_AGc8LpmjT6v_wcNZWaPcaNOMVBQ2qGG67e2gRaUJAk,11532
61
+ universal_mcp/utils/__init__.py,sha256=8wi4PGWu-SrFjNJ8U7fr2iFJ1ktqlDmSKj1xYd7KSDc,41
62
+ universal_mcp/utils/api_generator.py,sha256=-wRBpLVfJQXy1R-8FpDNs6b8_eeekVDuPc_uwjSGgiY,8883
63
+ universal_mcp/utils/docgen.py,sha256=KBMb1fv67zjqCtNSmpkkICQtLgK_yUxTwMcQIHJgbY8,20923
64
+ universal_mcp/utils/docstring_parser.py,sha256=82IBBGY-T9hrsoeF-hD8ABWY0caPjkCbS7KZtgU60Sw,6499
65
+ universal_mcp/utils/dump_app_tools.py,sha256=cLB9SumKsbs-rXJ_02lpMyyNkOmKZ57gekhCjhAlcHg,2009
66
+ universal_mcp/utils/installation.py,sha256=3vy9ZLjQj1xpSAOyWpOanBr7o5DtffzWB5JAjN0Jjtk,3757
67
+ universal_mcp/utils/openapi.py,sha256=lZ55gAByt93r5oZdM11PhmRoFbZK9TJTZBD0TwQo-3E,18524
68
+ universal_mcp-0.1.8rc2.dist-info/METADATA,sha256=DbCePKSZbLFml5dgzg3p1BkDbVLJGl4T_QYJnR0wPqw,11283
69
+ universal_mcp-0.1.8rc2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
70
+ universal_mcp-0.1.8rc2.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
71
+ universal_mcp-0.1.8rc2.dist-info/RECORD,,
@@ -1,58 +0,0 @@
1
- universal_mcp/__init__.py,sha256=2gdHpHaDDcsRjZjJ01FLN-1iidN_wbDAolNpxhGoFB4,59
2
- universal_mcp/cli.py,sha256=DG-Qxc5vQIdbhAIQuU7bKKJuRGzwyOigjfCKSWBRhBI,5258
3
- universal_mcp/config.py,sha256=sJaPI4q51CDPPG0z32rMJiE7a64eaa9nxbjJgYnaFA4,838
4
- universal_mcp/exceptions.py,sha256=Zp2_v_m3L7GDAmD1ZyuwFtY6ngapdhxuIygrvpZAQtM,271
5
- universal_mcp/logger.py,sha256=W6A868vyvpdkEQ4Dd0rWdC_7ErSxSQ1z2uxCb77IM8Y,2015
6
- universal_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- universal_mcp/applications/__init__.py,sha256=qeWnbdIudyMR7ST4XTc0gpEM9o6TsM1ZnZ92dMAPSBA,754
8
- universal_mcp/applications/application.py,sha256=dqp8lgIi2xhY62imwo7C6769URQtNmqd6Ok6PiTr6wc,3399
9
- universal_mcp/applications/e2b/README.md,sha256=S4lTp-vEZ8VTCKPXqjUXu5nYlUMAF8lw8CQyBGPgxjs,700
10
- universal_mcp/applications/e2b/app.py,sha256=l7oRmxIuVglA1v9EtYqx_rlvYjUZz7GShmI_VLEQLjI,2979
11
- universal_mcp/applications/firecrawl/README.md,sha256=KAWe_TQbrc9eA6bSyde5dapMP1CNvarVItV_YJH3d_0,1430
12
- universal_mcp/applications/firecrawl/app.py,sha256=aPYx3uCsrR6CHz0RERE0ikHMbzwbhKE-SDkF5DVZLiQ,9572
13
- universal_mcp/applications/github/README.md,sha256=6ID-__gUJ5ZxzAS_OjzmoUAag1LamSvEB75DHcj3m-g,1294
14
- universal_mcp/applications/github/app.py,sha256=L201f5MSx1YVx0nqgduZ5gyHPZdX0UfcEhPmDWiWK6s,13686
15
- universal_mcp/applications/google_calendar/app.py,sha256=g_3vrsM2ltwpTySgC5I4SYg47n4UJiYigECO0ax1EHM,19134
16
- universal_mcp/applications/google_docs/README.md,sha256=SyOgJG-XU0FXhrVukvg9mxwin73mpqaCOT6rDJ64Klk,909
17
- universal_mcp/applications/google_docs/app.py,sha256=RGpk4xW6u2rA62zkjsokDbhff3bk_bGt261ToQlAQNY,3157
18
- universal_mcp/applications/google_drive/README.md,sha256=YlN8IT12oO8zVMib1MlTYRBGNP7rzW_KyVAZyyxKvME,1192
19
- universal_mcp/applications/google_drive/app.py,sha256=PUK19kZlYNWn3_4Us1179_gc6o_565B4hsfxUleeR68,9546
20
- universal_mcp/applications/google_mail/README.md,sha256=LL6TjjmwEqyuRVvIfCh-I_PlWp9ciCZOdJC0LafGZYc,1185
21
- universal_mcp/applications/google_mail/app.py,sha256=VXeD3_TRgYIUDFUzDPCKgR47XvovxLFulD-HG22hls8,22716
22
- universal_mcp/applications/google_sheet/README.md,sha256=yW1b_qlb_pbIJzCxZc58581kKzC5vyP8Mj4iwXgidtQ,1108
23
- universal_mcp/applications/google_sheet/app.py,sha256=zYsi_vTpJ-BtBPH6rQFRfwAJJkN_d8DJm6tFUzJBOSw,5399
24
- universal_mcp/applications/markitdown/app.py,sha256=Gh12f1dW6DA_AW5DuStbCkOR7KtyJp8VEjdTaIicrRI,1996
25
- universal_mcp/applications/notion/README.md,sha256=45NmPOmSQv99qBvWdwmnV5vbaYc9_8vq8I-FA7veVAA,2600
26
- universal_mcp/applications/notion/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- universal_mcp/applications/notion/app.py,sha256=XpLnmeXj0Gnf_RYHlbAFnwtSCTYsrNzk6MSMSyDmHGQ,17283
28
- universal_mcp/applications/perplexity/README.md,sha256=QGV1iReH5p-Np7vvkZsVHxxDKQ0YaitHEwomNmGEyQs,732
29
- universal_mcp/applications/perplexity/app.py,sha256=q3FUnSHwq-_HnIUTYuxVdKmNJ5p0b-Aj3vZ0ZrP7Mg4,3494
30
- universal_mcp/applications/reddit/README.md,sha256=YVbJ1RN6NWlB-P6w2LxCk_DuUWl7mwaKZScY-mIMnNc,1271
31
- universal_mcp/applications/reddit/app.py,sha256=leU__w5VxX1vMK-kfuy-dvY97Pn8Mn80X2payVshirU,13562
32
- universal_mcp/applications/resend/README.md,sha256=k-sb2UwbFvDPEz6qQPLWd2cJj8hDx5f3NW7dz2jAfjI,719
33
- universal_mcp/applications/resend/app.py,sha256=fl_0U61Rm0fqz1lCxPiuGRkl2x0meafp6kMZbshD7wo,1733
34
- universal_mcp/applications/serpapi/README.md,sha256=hX4VeT2iL_67ZsMhKd60DAujQCh9K3IdHroHIq808RY,691
35
- universal_mcp/applications/serpapi/app.py,sha256=r4V8lty348X5hGQyP4DfG89hHRI68SnxYd6sFgTBjcY,3464
36
- universal_mcp/applications/tavily/README.md,sha256=cNg4EwX5wBbkDpPtNBNC3A_GxglfSVhdAJuweSrXN20,721
37
- universal_mcp/applications/tavily/app.py,sha256=K5TLh6OSQ7w792poupZidzgbWotrIyEsu7YnGzPRX0w,2123
38
- universal_mcp/applications/zenquotes/README.md,sha256=wA3hjqjrkrczQaffpwyolSKq6gXmkLgeHx6_EQrYEOY,709
39
- universal_mcp/applications/zenquotes/app.py,sha256=nidRGwVORIU25QGCCbjDIv1UNFUj5nWA3qqK4JP0Tdg,621
40
- universal_mcp/integrations/README.md,sha256=lTAPXO2nivcBe1q7JT6PRa6v9Ns_ZersQMIdw-nmwEA,996
41
- universal_mcp/integrations/__init__.py,sha256=8e11JZyctaR9CmlNkfEZ6HhGDvhlvf9iug2wdjb5pwY,270
42
- universal_mcp/integrations/agentr.py,sha256=l0mo79oeDML19udFfoCo9lyhbDAf0X94_lnpOgbTrb0,3331
43
- universal_mcp/integrations/integration.py,sha256=X8COgD8vg1bKUq4-0ytkMytk1eEaDF1O2JLvu3ewgFk,5828
44
- universal_mcp/servers/__init__.py,sha256=dgRW_khG537GeLKC5_U5jhxCuu1L_1YeTujeDg0601E,654
45
- universal_mcp/servers/server.py,sha256=iVyb_4KM3S6ppjDhWAnUdo0B8qugmnVe9utneUYJUgA,6771
46
- universal_mcp/stores/__init__.py,sha256=Sc4AWtee_qtK5hpEVUAH2XM_6EBhcfikQXWiGXdNfes,560
47
- universal_mcp/stores/store.py,sha256=CNOnmKeOCkSU2ZA9t12AIWJcmqZZX_LSyZaV8FQf8Xk,4545
48
- universal_mcp/utils/__init__.py,sha256=8wi4PGWu-SrFjNJ8U7fr2iFJ1ktqlDmSKj1xYd7KSDc,41
49
- universal_mcp/utils/api_generator.py,sha256=-wRBpLVfJQXy1R-8FpDNs6b8_eeekVDuPc_uwjSGgiY,8883
50
- universal_mcp/utils/bridge.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
- universal_mcp/utils/docgen.py,sha256=yK6Ijo8G-wHPU3E1AnFpnXS9vXt2j9FM77w0etTaNOA,12639
52
- universal_mcp/utils/dump_app_tools.py,sha256=cLB9SumKsbs-rXJ_02lpMyyNkOmKZ57gekhCjhAlcHg,2009
53
- universal_mcp/utils/installation.py,sha256=3vy9ZLjQj1xpSAOyWpOanBr7o5DtffzWB5JAjN0Jjtk,3757
54
- universal_mcp/utils/openapi.py,sha256=ud_ZB7_60BcS1Vao7ESKDqo0gry9JN5wzy-CFssrjm8,13140
55
- universal_mcp-0.1.8rc1.dist-info/METADATA,sha256=aIw8d3MEmmQdznN6OagpdSAMxLVaCPPJgCpbqxSkw3U,10851
56
- universal_mcp-0.1.8rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
- universal_mcp-0.1.8rc1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
58
- universal_mcp-0.1.8rc1.dist-info/RECORD,,