universal-mcp 0.1.23rc2__py3-none-any.whl → 0.1.24rc3__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/agentr/__init__.py +6 -0
- universal_mcp/agentr/agentr.py +30 -0
- universal_mcp/{utils/agentr.py → agentr/client.py} +22 -7
- universal_mcp/agentr/integration.py +104 -0
- universal_mcp/agentr/registry.py +91 -0
- universal_mcp/agentr/server.py +51 -0
- universal_mcp/agents/__init__.py +6 -0
- universal_mcp/agents/auto.py +576 -0
- universal_mcp/agents/base.py +88 -0
- universal_mcp/agents/cli.py +27 -0
- universal_mcp/agents/codeact/__init__.py +243 -0
- universal_mcp/agents/codeact/sandbox.py +27 -0
- universal_mcp/agents/codeact/test.py +15 -0
- universal_mcp/agents/codeact/utils.py +61 -0
- universal_mcp/agents/hil.py +104 -0
- universal_mcp/agents/llm.py +10 -0
- universal_mcp/agents/react.py +58 -0
- universal_mcp/agents/simple.py +40 -0
- universal_mcp/agents/utils.py +111 -0
- universal_mcp/analytics.py +44 -14
- universal_mcp/applications/__init__.py +42 -75
- universal_mcp/applications/application.py +187 -133
- universal_mcp/applications/sample/app.py +245 -0
- universal_mcp/cli.py +14 -231
- universal_mcp/client/oauth.py +122 -18
- universal_mcp/client/token_store.py +62 -3
- universal_mcp/client/{client.py → transport.py} +127 -48
- universal_mcp/config.py +189 -49
- universal_mcp/exceptions.py +54 -6
- universal_mcp/integrations/__init__.py +0 -18
- universal_mcp/integrations/integration.py +185 -168
- universal_mcp/servers/__init__.py +2 -14
- universal_mcp/servers/server.py +84 -258
- universal_mcp/stores/store.py +126 -93
- universal_mcp/tools/__init__.py +3 -0
- universal_mcp/tools/adapters.py +20 -11
- universal_mcp/tools/func_metadata.py +1 -1
- universal_mcp/tools/manager.py +38 -53
- universal_mcp/tools/registry.py +41 -0
- universal_mcp/tools/tools.py +24 -3
- universal_mcp/types.py +10 -0
- universal_mcp/utils/common.py +245 -0
- universal_mcp/utils/installation.py +3 -4
- universal_mcp/utils/openapi/api_generator.py +71 -17
- universal_mcp/utils/openapi/api_splitter.py +0 -1
- universal_mcp/utils/openapi/cli.py +669 -0
- universal_mcp/utils/openapi/filters.py +114 -0
- universal_mcp/utils/openapi/openapi.py +315 -23
- universal_mcp/utils/openapi/postprocessor.py +275 -0
- universal_mcp/utils/openapi/preprocessor.py +63 -8
- universal_mcp/utils/openapi/test_generator.py +287 -0
- universal_mcp/utils/prompts.py +634 -0
- universal_mcp/utils/singleton.py +4 -1
- universal_mcp/utils/testing.py +196 -8
- universal_mcp-0.1.24rc3.dist-info/METADATA +68 -0
- universal_mcp-0.1.24rc3.dist-info/RECORD +70 -0
- universal_mcp/applications/README.md +0 -122
- universal_mcp/client/__main__.py +0 -30
- universal_mcp/client/agent.py +0 -96
- universal_mcp/integrations/README.md +0 -25
- universal_mcp/servers/README.md +0 -79
- universal_mcp/stores/README.md +0 -74
- universal_mcp/tools/README.md +0 -86
- universal_mcp-0.1.23rc2.dist-info/METADATA +0 -283
- universal_mcp-0.1.23rc2.dist-info/RECORD +0 -51
- /universal_mcp/{utils → tools}/docstring_parser.py +0 -0
- {universal_mcp-0.1.23rc2.dist-info → universal_mcp-0.1.24rc3.dist-info}/WHEEL +0 -0
- {universal_mcp-0.1.23rc2.dist-info → universal_mcp-0.1.24rc3.dist-info}/entry_points.txt +0 -0
- {universal_mcp-0.1.23rc2.dist-info → universal_mcp-0.1.24rc3.dist-info}/licenses/LICENSE +0 -0
universal_mcp/analytics.py
CHANGED
@@ -8,6 +8,14 @@ from loguru import logger
|
|
8
8
|
|
9
9
|
|
10
10
|
class Analytics:
|
11
|
+
"""A singleton class for tracking analytics events using PostHog.
|
12
|
+
|
13
|
+
This class handles the initialization of the PostHog client and provides
|
14
|
+
methods to track key events such as application loading and tool execution.
|
15
|
+
Telemetry can be disabled by setting the TELEMETRY_DISABLED environment
|
16
|
+
variable to "true".
|
17
|
+
"""
|
18
|
+
|
11
19
|
_instance = None
|
12
20
|
|
13
21
|
def __new__(cls):
|
@@ -17,7 +25,13 @@ class Analytics:
|
|
17
25
|
return cls._instance
|
18
26
|
|
19
27
|
def _initialize(self):
|
20
|
-
"""
|
28
|
+
"""Initializes the PostHog client and sets up analytics properties.
|
29
|
+
|
30
|
+
This internal method configures the PostHog API key and host.
|
31
|
+
It also determines if analytics should be enabled based on the
|
32
|
+
TELEMETRY_DISABLED environment variable and generates a unique
|
33
|
+
user ID.
|
34
|
+
"""
|
21
35
|
posthog.host = "https://us.i.posthog.com"
|
22
36
|
posthog.api_key = "phc_6HXMDi8CjfIW0l04l34L7IDkpCDeOVz9cOz1KLAHXh8"
|
23
37
|
self.enabled = os.getenv("TELEMETRY_DISABLED", "false").lower() != "true"
|
@@ -26,24 +40,36 @@ class Analytics:
|
|
26
40
|
@staticmethod
|
27
41
|
@lru_cache(maxsize=1)
|
28
42
|
def get_version():
|
29
|
-
"""
|
30
|
-
|
43
|
+
"""Retrieves the installed version of the universal_mcp package.
|
44
|
+
|
45
|
+
Uses importlib.metadata to get the package version.
|
46
|
+
Caches the result for efficiency.
|
47
|
+
|
48
|
+
Returns:
|
49
|
+
str: The package version string, or "unknown" if not found.
|
31
50
|
"""
|
32
51
|
try:
|
33
52
|
return version("universal_mcp")
|
34
|
-
except ImportError:
|
53
|
+
except ImportError: # Should be PackageNotFoundError, but matching existing code
|
35
54
|
return "unknown"
|
36
55
|
|
37
56
|
def track_app_loaded(self, app_name: str):
|
38
|
-
"""
|
57
|
+
"""Tracks an event when an application is successfully loaded.
|
58
|
+
|
59
|
+
This event helps understand which applications are being utilized.
|
60
|
+
|
61
|
+
Args:
|
62
|
+
app_name (str): The name of the application that was loaded.
|
63
|
+
"""
|
39
64
|
if not self.enabled:
|
40
65
|
return
|
41
66
|
try:
|
42
67
|
properties = {
|
43
68
|
"version": self.get_version(),
|
44
69
|
"app_name": app_name,
|
70
|
+
"user_id": self.user_id,
|
45
71
|
}
|
46
|
-
posthog.capture(
|
72
|
+
posthog.capture("app_loaded", properties=properties)
|
47
73
|
except Exception as e:
|
48
74
|
logger.error(f"Failed to track app_loaded event: {e}")
|
49
75
|
|
@@ -52,16 +78,19 @@ class Analytics:
|
|
52
78
|
tool_name: str,
|
53
79
|
app_name: str,
|
54
80
|
status: str,
|
55
|
-
error: str = None,
|
56
|
-
user_id=None,
|
81
|
+
error: str | None = None,
|
57
82
|
):
|
58
|
-
"""
|
83
|
+
"""Tracks an event when a tool is called within an application.
|
84
|
+
|
85
|
+
This event provides insights into tool usage patterns, success rates,
|
86
|
+
and potential errors.
|
59
87
|
|
60
88
|
Args:
|
61
|
-
tool_name:
|
62
|
-
|
63
|
-
|
64
|
-
|
89
|
+
tool_name (str): The name of the tool that was called.
|
90
|
+
app_name (str): The name of the application the tool belongs to.
|
91
|
+
status (str): The status of the tool call (e.g., "success", "error").
|
92
|
+
error (str, optional): The error message if the tool call failed.
|
93
|
+
Defaults to None.
|
65
94
|
"""
|
66
95
|
if not self.enabled:
|
67
96
|
return
|
@@ -72,8 +101,9 @@ class Analytics:
|
|
72
101
|
"status": status,
|
73
102
|
"error": error,
|
74
103
|
"version": self.get_version(),
|
104
|
+
"user_id": self.user_id,
|
75
105
|
}
|
76
|
-
posthog.capture(
|
106
|
+
posthog.capture("tool_called", properties=properties)
|
77
107
|
except Exception as e:
|
78
108
|
logger.error(f"Failed to track tool_called event: {e}")
|
79
109
|
|
@@ -1,9 +1,3 @@
|
|
1
|
-
import importlib
|
2
|
-
import os
|
3
|
-
import subprocess
|
4
|
-
import sys
|
5
|
-
from pathlib import Path
|
6
|
-
|
7
1
|
from loguru import logger
|
8
2
|
|
9
3
|
from universal_mcp.applications.application import (
|
@@ -11,92 +5,65 @@ from universal_mcp.applications.application import (
|
|
11
5
|
BaseApplication,
|
12
6
|
GraphQLApplication,
|
13
7
|
)
|
8
|
+
from universal_mcp.config import AppConfig
|
14
9
|
from universal_mcp.utils.common import (
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
load_app_from_local_file,
|
11
|
+
load_app_from_local_folder,
|
12
|
+
load_app_from_package,
|
13
|
+
load_app_from_remote_file,
|
14
|
+
load_app_from_remote_zip,
|
19
15
|
)
|
20
16
|
|
21
|
-
UNIVERSAL_MCP_HOME = Path.home() / ".universal-mcp" / "packages"
|
22
|
-
|
23
|
-
if not UNIVERSAL_MCP_HOME.exists():
|
24
|
-
UNIVERSAL_MCP_HOME.mkdir(parents=True, exist_ok=True)
|
25
|
-
|
26
|
-
# set python path to include the universal-mcp home directory
|
27
|
-
sys.path.append(str(UNIVERSAL_MCP_HOME))
|
28
|
-
|
29
|
-
|
30
|
-
# Name are in the format of "app-name", eg, google-calendar
|
31
|
-
# Class name is NameApp, eg, GoogleCalendarApp
|
32
|
-
|
33
17
|
app_cache: dict[str, type[BaseApplication]] = {}
|
34
18
|
|
35
19
|
|
36
|
-
def
|
20
|
+
def app_from_slug(slug: str) -> type[BaseApplication]:
|
37
21
|
"""
|
38
|
-
|
22
|
+
Dynamically resolve and return the application class based on slug.
|
39
23
|
"""
|
40
|
-
|
41
|
-
uv_executable = str(Path(uv_path) / "uv") if uv_path else "uv"
|
42
|
-
logger.info(f"Using uv executable: {uv_executable}")
|
43
|
-
cmd = [
|
44
|
-
uv_executable,
|
45
|
-
"pip",
|
46
|
-
"install",
|
47
|
-
"--upgrade",
|
48
|
-
repository_path,
|
49
|
-
"--target",
|
50
|
-
str(UNIVERSAL_MCP_HOME),
|
51
|
-
]
|
52
|
-
logger.debug(f"Installing package '{package_name}' with command: {' '.join(cmd)}")
|
53
|
-
try:
|
54
|
-
result = subprocess.run(cmd, capture_output=True, text=True)
|
55
|
-
if result.stdout:
|
56
|
-
logger.info(f"Command stdout: {result.stdout}")
|
57
|
-
if result.stderr:
|
58
|
-
logger.info(f"Command stderr: {result.stderr}")
|
59
|
-
result.check_returncode()
|
60
|
-
except subprocess.CalledProcessError as e:
|
61
|
-
logger.error(f"Installation failed for '{package_name}': {e}")
|
62
|
-
if e.stdout:
|
63
|
-
logger.error(f"Command stdout: {e.stdout}")
|
64
|
-
if e.stderr:
|
65
|
-
logger.error(f"Command stderr: {e.stderr}")
|
66
|
-
raise ModuleNotFoundError(f"Installation failed for package '{package_name}'") from e
|
67
|
-
else:
|
68
|
-
logger.debug(f"Package {package_name} installed successfully")
|
24
|
+
return app_from_config(AppConfig(name=slug, source_type="package"))
|
69
25
|
|
70
26
|
|
71
|
-
def
|
27
|
+
def app_from_config(config: AppConfig) -> type[BaseApplication]:
|
72
28
|
"""
|
73
|
-
Dynamically resolve and return the application class
|
74
|
-
Attempts installation from GitHub if the package is not found locally.
|
29
|
+
Dynamically resolve and return the application class based on AppConfig.
|
75
30
|
"""
|
76
|
-
if
|
77
|
-
return app_cache[
|
78
|
-
|
79
|
-
|
80
|
-
package_name = get_default_package_name(slug)
|
81
|
-
repository_path = get_default_repository_path(slug)
|
82
|
-
logger.debug(f"Resolving app for slug '{slug}' → module '{module_path}', class '{class_name}'")
|
31
|
+
if config.name in app_cache:
|
32
|
+
return app_cache[config.name]
|
33
|
+
|
34
|
+
app_class = None
|
83
35
|
try:
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
36
|
+
match config.source_type:
|
37
|
+
case "package":
|
38
|
+
app_class = load_app_from_package(config)
|
39
|
+
case "local_folder":
|
40
|
+
app_class = load_app_from_local_folder(config)
|
41
|
+
case "remote_zip":
|
42
|
+
app_class = load_app_from_remote_zip(config)
|
43
|
+
case "remote_file":
|
44
|
+
app_class = load_app_from_remote_file(config)
|
45
|
+
case "local_file":
|
46
|
+
app_class = load_app_from_local_file(config)
|
47
|
+
case _:
|
48
|
+
raise ValueError(f"Unsupported source_type: {config.source_type}")
|
49
|
+
|
94
50
|
except Exception as e:
|
95
|
-
|
51
|
+
logger.error(
|
52
|
+
f"Failed to load application '{config.name}' from source '{config.source_type}': {e}",
|
53
|
+
exc_info=True,
|
54
|
+
)
|
55
|
+
raise
|
56
|
+
|
57
|
+
if not app_class:
|
58
|
+
raise ImportError(f"Could not load application class for '{config.name}'")
|
59
|
+
|
60
|
+
logger.debug(f"Loaded class '{app_class.__name__}' for app '{config.name}'")
|
61
|
+
app_cache[config.name] = app_class
|
62
|
+
return app_class
|
96
63
|
|
97
64
|
|
98
65
|
__all__ = [
|
99
|
-
"
|
66
|
+
"app_from_config",
|
100
67
|
"BaseApplication",
|
101
68
|
"APIApplication",
|
102
69
|
"GraphQLApplication",
|