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.
- universal_mcp/applications/application.py +6 -5
- universal_mcp/applications/calendly/README.md +78 -0
- universal_mcp/applications/calendly/app.py +954 -0
- universal_mcp/applications/e2b/app.py +18 -12
- universal_mcp/applications/firecrawl/app.py +28 -1
- universal_mcp/applications/github/app.py +150 -107
- universal_mcp/applications/google_calendar/app.py +72 -137
- universal_mcp/applications/google_docs/app.py +35 -15
- universal_mcp/applications/google_drive/app.py +84 -55
- universal_mcp/applications/google_mail/app.py +143 -53
- universal_mcp/applications/google_sheet/app.py +61 -38
- universal_mcp/applications/markitdown/app.py +12 -11
- universal_mcp/applications/notion/app.py +199 -89
- universal_mcp/applications/perplexity/app.py +17 -15
- universal_mcp/applications/reddit/app.py +110 -101
- universal_mcp/applications/resend/app.py +14 -7
- universal_mcp/applications/serpapi/app.py +13 -6
- universal_mcp/applications/tavily/app.py +13 -10
- universal_mcp/applications/wrike/README.md +71 -0
- universal_mcp/applications/wrike/__init__.py +0 -0
- universal_mcp/applications/wrike/app.py +1044 -0
- universal_mcp/applications/youtube/README.md +82 -0
- universal_mcp/applications/youtube/__init__.py +0 -0
- universal_mcp/applications/youtube/app.py +986 -0
- universal_mcp/applications/zenquotes/app.py +13 -3
- universal_mcp/exceptions.py +8 -2
- universal_mcp/integrations/__init__.py +15 -1
- universal_mcp/integrations/integration.py +132 -27
- universal_mcp/servers/__init__.py +6 -15
- universal_mcp/servers/server.py +209 -153
- universal_mcp/stores/__init__.py +7 -2
- universal_mcp/stores/store.py +103 -42
- universal_mcp/tools/__init__.py +3 -0
- universal_mcp/tools/adapters.py +40 -0
- universal_mcp/tools/func_metadata.py +214 -0
- universal_mcp/tools/tools.py +285 -0
- universal_mcp/utils/docgen.py +277 -123
- universal_mcp/utils/docstring_parser.py +156 -0
- universal_mcp/utils/openapi.py +149 -40
- {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/METADATA +7 -3
- universal_mcp-0.1.8rc2.dist-info/RECORD +71 -0
- universal_mcp-0.1.8rc1.dist-info/RECORD +0 -58
- /universal_mcp/{utils/bridge.py → applications/calendly/__init__.py} +0 -0
- {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/WHEEL +0 -0
- {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc2.dist-info}/entry_points.txt +0 -0
universal_mcp/utils/openapi.py
CHANGED
@@ -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
|
202
|
-
func_name = re.sub(r'_an([^
|
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
|
-
#
|
304
|
+
|
305
|
+
# Handle array type request body differently
|
306
|
+
request_body_params = []
|
229
307
|
if has_body:
|
230
|
-
if
|
231
|
-
|
232
|
-
|
233
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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
|
-
| `
|
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,,
|
File without changes
|
File without changes
|
File without changes
|