universal-mcp 0.1.8rc1__py3-none-any.whl → 0.1.8rc3__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 (52) hide show
  1. universal_mcp/__init__.py +0 -2
  2. universal_mcp/analytics.py +75 -0
  3. universal_mcp/applications/application.py +28 -5
  4. universal_mcp/applications/calendly/README.md +78 -0
  5. universal_mcp/applications/calendly/app.py +1207 -0
  6. universal_mcp/applications/coda/README.md +133 -0
  7. universal_mcp/applications/coda/__init__.py +0 -0
  8. universal_mcp/applications/coda/app.py +3704 -0
  9. universal_mcp/applications/e2b/app.py +12 -7
  10. universal_mcp/applications/firecrawl/app.py +27 -0
  11. universal_mcp/applications/github/app.py +127 -85
  12. universal_mcp/applications/google_calendar/app.py +62 -127
  13. universal_mcp/applications/google_docs/app.py +48 -35
  14. universal_mcp/applications/google_drive/app.py +119 -96
  15. universal_mcp/applications/google_mail/app.py +124 -34
  16. universal_mcp/applications/google_sheet/app.py +90 -74
  17. universal_mcp/applications/markitdown/app.py +9 -8
  18. universal_mcp/applications/notion/app.py +254 -134
  19. universal_mcp/applications/perplexity/app.py +16 -14
  20. universal_mcp/applications/reddit/app.py +94 -85
  21. universal_mcp/applications/resend/app.py +12 -5
  22. universal_mcp/applications/serpapi/app.py +11 -4
  23. universal_mcp/applications/tavily/app.py +11 -8
  24. universal_mcp/applications/wrike/README.md +71 -0
  25. universal_mcp/applications/wrike/__init__.py +0 -0
  26. universal_mcp/applications/wrike/app.py +1384 -0
  27. universal_mcp/applications/youtube/README.md +82 -0
  28. universal_mcp/applications/youtube/__init__.py +0 -0
  29. universal_mcp/applications/youtube/app.py +1446 -0
  30. universal_mcp/applications/zenquotes/app.py +12 -2
  31. universal_mcp/exceptions.py +9 -2
  32. universal_mcp/integrations/__init__.py +24 -1
  33. universal_mcp/integrations/integration.py +133 -28
  34. universal_mcp/logger.py +3 -56
  35. universal_mcp/servers/__init__.py +6 -14
  36. universal_mcp/servers/server.py +205 -150
  37. universal_mcp/stores/__init__.py +7 -2
  38. universal_mcp/stores/store.py +103 -40
  39. universal_mcp/tools/__init__.py +3 -0
  40. universal_mcp/tools/adapters.py +43 -0
  41. universal_mcp/tools/func_metadata.py +213 -0
  42. universal_mcp/tools/tools.py +342 -0
  43. universal_mcp/utils/docgen.py +325 -119
  44. universal_mcp/utils/docstring_parser.py +179 -0
  45. universal_mcp/utils/dump_app_tools.py +33 -23
  46. universal_mcp/utils/openapi.py +229 -46
  47. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc3.dist-info}/METADATA +8 -4
  48. universal_mcp-0.1.8rc3.dist-info/RECORD +75 -0
  49. universal_mcp-0.1.8rc1.dist-info/RECORD +0 -58
  50. /universal_mcp/{utils/bridge.py → applications/calendly/__init__.py} +0 -0
  51. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc3.dist-info}/WHEEL +0 -0
  52. {universal_mcp-0.1.8rc1.dist-info → universal_mcp-0.1.8rc3.dist-info}/entry_points.txt +0 -0
universal_mcp/__init__.py CHANGED
@@ -1,2 +0,0 @@
1
- def hello() -> str:
2
- return "Hello from universal-mcp!"
@@ -0,0 +1,75 @@
1
+ import os
2
+ import uuid
3
+ from functools import lru_cache
4
+ from importlib.metadata import version
5
+
6
+ import posthog
7
+ from loguru import logger
8
+
9
+
10
+ class Analytics:
11
+ _instance = None
12
+
13
+ def __new__(cls):
14
+ if cls._instance is None:
15
+ cls._instance = super().__new__(cls)
16
+ cls._instance._initialize()
17
+ return cls._instance
18
+
19
+ def _initialize(self):
20
+ """Initialize the Analytics singleton"""
21
+ posthog.host = "https://us.i.posthog.com"
22
+ posthog.api_key = "phc_6HXMDi8CjfIW0l04l34L7IDkpCDeOVz9cOz1KLAHXh8"
23
+ self.enabled = os.getenv("TELEMETRY_DISABLED", "false").lower() != "true"
24
+ self.user_id = str(uuid.uuid4())[:8]
25
+
26
+ @staticmethod
27
+ @lru_cache(maxsize=1)
28
+ def get_version():
29
+ """
30
+ Get the version of the Universal MCP
31
+ """
32
+ try:
33
+ return version("universal_mcp")
34
+ except ImportError:
35
+ return "unknown"
36
+
37
+ def track_app_loaded(self, app_name: str):
38
+ """Track when the app is loaded"""
39
+ if not self.enabled:
40
+ return
41
+ try:
42
+ properties = {
43
+ "version": self.get_version(),
44
+ "app_name": app_name,
45
+ }
46
+ posthog.capture(self.user_id, "app_loaded", properties)
47
+ except Exception as e:
48
+ logger.error(f"Failed to track app_loaded event: {e}")
49
+
50
+ def track_tool_called(
51
+ self, tool_name: str, status: str, error: str = None, user_id=None
52
+ ):
53
+ """Track when a tool is called
54
+
55
+ Args:
56
+ tool_name: Name of the tool being called
57
+ status: Status of the tool call (success/error)
58
+ error: Error message if status is error
59
+ user_id: Optional user ID to track
60
+ """
61
+ if not self.enabled:
62
+ return
63
+ try:
64
+ properties = {
65
+ "tool_name": tool_name,
66
+ "status": status,
67
+ "error": error,
68
+ "version": self.get_version(),
69
+ }
70
+ posthog.capture(self.user_id, "tool_called", properties)
71
+ except Exception as e:
72
+ logger.error(f"Failed to track tool_called event: {e}")
73
+
74
+
75
+ analytics = Analytics()
@@ -27,6 +27,7 @@ class APIApplication(Application):
27
27
 
28
28
  def __init__(self, name: str, integration: Integration = None, **kwargs):
29
29
  super().__init__(name, **kwargs)
30
+ self.default_timeout = 30
30
31
  self.integration = integration
31
32
 
32
33
  def _get_headers(self):
@@ -35,7 +36,9 @@ class APIApplication(Application):
35
36
  def _get(self, url, params=None):
36
37
  try:
37
38
  headers = self._get_headers()
38
- response = httpx.get(url, headers=headers, params=params)
39
+ response = httpx.get(
40
+ url, headers=headers, params=params, timeout=self.default_timeout
41
+ )
39
42
  response.raise_for_status()
40
43
  return response
41
44
  except NotAuthorizedError as e:
@@ -48,7 +51,13 @@ class APIApplication(Application):
48
51
  def _post(self, url, data, params=None):
49
52
  try:
50
53
  headers = self._get_headers()
51
- response = httpx.post(url, headers=headers, json=data, params=params)
54
+ response = httpx.post(
55
+ url,
56
+ headers=headers,
57
+ json=data,
58
+ params=params,
59
+ timeout=self.default_timeout,
60
+ )
52
61
  response.raise_for_status()
53
62
  return response
54
63
  except NotAuthorizedError as e:
@@ -66,7 +75,13 @@ class APIApplication(Application):
66
75
  def _put(self, url, data, params=None):
67
76
  try:
68
77
  headers = self._get_headers()
69
- response = httpx.put(url, headers=headers, json=data, params=params)
78
+ response = httpx.put(
79
+ url,
80
+ headers=headers,
81
+ json=data,
82
+ params=params,
83
+ timeout=self.default_timeout,
84
+ )
70
85
  response.raise_for_status()
71
86
  return response
72
87
  except NotAuthorizedError as e:
@@ -79,7 +94,9 @@ class APIApplication(Application):
79
94
  def _delete(self, url, params=None):
80
95
  try:
81
96
  headers = self._get_headers()
82
- response = httpx.delete(url, headers=headers, params=params)
97
+ response = httpx.delete(
98
+ url, headers=headers, params=params, timeout=self.default_timeout
99
+ )
83
100
  response.raise_for_status()
84
101
  return response
85
102
  except NotAuthorizedError as e:
@@ -92,7 +109,13 @@ class APIApplication(Application):
92
109
  def _patch(self, url, data, params=None):
93
110
  try:
94
111
  headers = self._get_headers()
95
- response = httpx.patch(url, headers=headers, json=data, params=params)
112
+ response = httpx.patch(
113
+ url,
114
+ headers=headers,
115
+ json=data,
116
+ params=params,
117
+ timeout=self.default_timeout,
118
+ )
96
119
  response.raise_for_status()
97
120
  return response
98
121
  except NotAuthorizedError as e:
@@ -0,0 +1,78 @@
1
+
2
+ # Calendly MCP Server
3
+
4
+ An MCP Server for the Calendly API.
5
+
6
+ ## Supported Integrations
7
+
8
+ - AgentR
9
+ - API Key (Coming Soon)
10
+ - OAuth (Coming Soon)
11
+
12
+ ## Tools
13
+
14
+ This is automatically generated from OpenAPI schema for the Calendly API.
15
+
16
+ ## Supported Integrations
17
+
18
+ This tool can be integrated with any service that supports HTTP requests.
19
+
20
+ ## Tool List
21
+
22
+ | Tool | Description |
23
+ |------|-------------|
24
+ | list_event_invitees | Retrieves a list of invitees for a specific scheduled event, optionally filtered and paginated by status, email, sorting order, and paging parameters. |
25
+ | get_event | Retrieves the details of a scheduled event given its UUID. |
26
+ | get_event_invitee | Retrieves details about a specific invitee for a given scheduled event. |
27
+ | list_events | Retrieves a list of scheduled events filtered by optional user, organization, invitee email, status, date range, sorting, and pagination criteria. |
28
+ | get_event_type | Retrieves the event type details for the specified UUID from the API. |
29
+ | list_user_sevent_types | Retrieves a list of user event types with optional filtering, sorting, and pagination parameters. |
30
+ | get_user | Retrieves detailed user information for a given UUID from the remote API. |
31
+ | get_current_user | Retrieves information about the currently authenticated user from the API. |
32
+ | list_organization_invitations | Retrieves a paginated list of invitations for a specified organization, with optional filtering and sorting. |
33
+ | invite_user_to_organization | Sends an invitation to a specified email address to join an organization identified by its UUID. |
34
+ | get_organization_invitation | Retrieves a specific invitation for an organization using its unique identifiers. |
35
+ | revoke_user_sorganization_invitation | Revokes a user's invitation to an organization by deleting the specified invitation resource. |
36
+ | get_organization_membership | Retrieves the membership information for a specified organization membership UUID. |
37
+ | remove_user_from_organization | Removes a user from the organization by deleting their membership using the specified UUID. |
38
+ | list_organization_memberships | Retrieves a list of organization memberships, optionally filtered by pagination, email, organization, or user parameters. |
39
+ | get_webhook_subscription | Retrieves the details of a webhook subscription identified by its UUID. |
40
+ | delete_webhook_subscription | Deletes a webhook subscription identified by its UUID. |
41
+ | list_webhook_subscriptions | Retrieves a list of webhook subscriptions, optionally filtered and paginated based on input criteria. |
42
+ | create_webhook_subscription | Creates a new webhook subscription with the specified parameters and returns the subscription details as a dictionary. |
43
+ | create_single_use_scheduling_link | Creates a single-use scheduling link by sending a POST request with optional restrictions. |
44
+ | delete_invitee_data | Deletes invitee data for the specified email addresses by sending a POST request to the data compliance API. |
45
+ | delete_scheduled_event_data | Deletes scheduled event data within the specified time range by sending a deletion request to the data compliance service. |
46
+ | get_invitee_no_show | Retrieves details about an invitee who did not show up for a scheduled event, identified by a unique UUID. |
47
+ | delete_invitee_no_show | Deletes an invitee no-show record identified by the given UUID. |
48
+ | create_invitee_no_show | Creates an invitee no-show record by sending a POST request to the invitee_no_shows endpoint. |
49
+ | get_group | Retrieves information for a group identified by its UUID from the server. |
50
+ | list_groups | Retrieves a list of groups from the API, optionally filtered by organization and paginated using a page token and count. |
51
+ | get_group_relationship | Retrieves the relationship information for a group specified by UUID from the API. |
52
+ | list_group_relationships | Retrieves a list of group relationships from the server, optionally filtered by pagination and various group ownership parameters. |
53
+ | get_routing_form | Retrieves a routing form by its unique identifier from the server. |
54
+ | list_routing_forms | Retrieves a paginated list of routing forms from the API, optionally filtered and sorted by organization, count, page token, or sort order. |
55
+ | get_routing_form_submission | Retrieves a routing form submission by its unique identifier (UUID) from the configured API endpoint. |
56
+ | list_routing_form_submissions | Retrieves a list of routing form submissions, optionally filtered and paginated based on provided parameters. |
57
+ | list_event_type_available_times | Retrieves available times for a specified event type within an optional date and time range. |
58
+ | list_activity_log_entries | Retrieves a list of activity log entries with optional filtering, sorting, and pagination. |
59
+ | create_share | Creates a new share with the specified configuration parameters by making a POST request to the shares API endpoint. |
60
+ | list_user_busy_times | Retrieves a list of busy time intervals for a specified user within an optional date range. |
61
+ | get_user_availability_schedule | Retrieves the availability schedule for a user identified by the given UUID. |
62
+ | list_user_availability_schedules | Retrieves a list of user availability schedules from the API, optionally filtering by a specific user. |
63
+ | list_event_type_hosts | Retrieves a list of event type hosts based on provided filter, count, and pagination parameters. |
64
+ | create_one_off_event_type | Creates a one-off event type with specified parameters and returns the created event type details. |
65
+ | get_sample_webhook_data | Retrieves sample webhook data from the API using optional filtering parameters. |
66
+
67
+
68
+
69
+ ## Usage
70
+
71
+ - Login to AgentR
72
+ - Follow the quickstart guide to setup MCP Server for your client
73
+ - Visit Apps Store and enable the Calendly app
74
+ - Restart the MCP Server
75
+
76
+ ### Local Development
77
+
78
+ - Follow the README to test with the local MCP Server