universal-mcp 0.1.12__py3-none-any.whl → 0.1.13rc2__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 (109) hide show
  1. universal_mcp/applications/__init__.py +51 -7
  2. universal_mcp/cli.py +109 -17
  3. universal_mcp/integrations/__init__.py +1 -1
  4. universal_mcp/integrations/integration.py +79 -0
  5. universal_mcp/servers/README.md +79 -0
  6. universal_mcp/servers/server.py +17 -29
  7. universal_mcp/stores/README.md +74 -0
  8. universal_mcp/stores/store.py +0 -2
  9. universal_mcp/templates/README.md.j2 +93 -0
  10. universal_mcp/templates/api_client.py.j2 +27 -0
  11. universal_mcp/tools/README.md +86 -0
  12. universal_mcp/tools/tools.py +1 -1
  13. universal_mcp/utils/agentr.py +90 -0
  14. universal_mcp/utils/api_generator.py +166 -208
  15. universal_mcp/utils/openapi.py +221 -321
  16. universal_mcp/utils/singleton.py +23 -0
  17. {universal_mcp-0.1.12.dist-info → universal_mcp-0.1.13rc2.dist-info}/METADATA +16 -41
  18. universal_mcp-0.1.13rc2.dist-info/RECORD +38 -0
  19. universal_mcp/applications/ahrefs/README.md +0 -76
  20. universal_mcp/applications/ahrefs/__init__.py +0 -0
  21. universal_mcp/applications/ahrefs/app.py +0 -2291
  22. universal_mcp/applications/cal_com_v2/README.md +0 -175
  23. universal_mcp/applications/cal_com_v2/__init__.py +0 -0
  24. universal_mcp/applications/cal_com_v2/app.py +0 -5390
  25. universal_mcp/applications/calendly/README.md +0 -78
  26. universal_mcp/applications/calendly/__init__.py +0 -0
  27. universal_mcp/applications/calendly/app.py +0 -1195
  28. universal_mcp/applications/clickup/README.md +0 -160
  29. universal_mcp/applications/clickup/__init__.py +0 -0
  30. universal_mcp/applications/clickup/app.py +0 -5009
  31. universal_mcp/applications/coda/README.md +0 -133
  32. universal_mcp/applications/coda/__init__.py +0 -0
  33. universal_mcp/applications/coda/app.py +0 -3671
  34. universal_mcp/applications/e2b/README.md +0 -37
  35. universal_mcp/applications/e2b/app.py +0 -65
  36. universal_mcp/applications/elevenlabs/README.md +0 -84
  37. universal_mcp/applications/elevenlabs/__init__.py +0 -0
  38. universal_mcp/applications/elevenlabs/app.py +0 -1402
  39. universal_mcp/applications/falai/README.md +0 -42
  40. universal_mcp/applications/falai/__init__.py +0 -0
  41. universal_mcp/applications/falai/app.py +0 -332
  42. universal_mcp/applications/figma/README.md +0 -74
  43. universal_mcp/applications/figma/__init__.py +0 -0
  44. universal_mcp/applications/figma/app.py +0 -1261
  45. universal_mcp/applications/firecrawl/README.md +0 -45
  46. universal_mcp/applications/firecrawl/app.py +0 -268
  47. universal_mcp/applications/github/README.md +0 -47
  48. universal_mcp/applications/github/app.py +0 -429
  49. universal_mcp/applications/gong/README.md +0 -88
  50. universal_mcp/applications/gong/__init__.py +0 -0
  51. universal_mcp/applications/gong/app.py +0 -2297
  52. universal_mcp/applications/google_calendar/app.py +0 -442
  53. universal_mcp/applications/google_docs/README.md +0 -40
  54. universal_mcp/applications/google_docs/app.py +0 -88
  55. universal_mcp/applications/google_drive/README.md +0 -44
  56. universal_mcp/applications/google_drive/app.py +0 -286
  57. universal_mcp/applications/google_mail/README.md +0 -47
  58. universal_mcp/applications/google_mail/app.py +0 -664
  59. universal_mcp/applications/google_sheet/README.md +0 -42
  60. universal_mcp/applications/google_sheet/app.py +0 -150
  61. universal_mcp/applications/hashnode/app.py +0 -81
  62. universal_mcp/applications/hashnode/prompt.md +0 -23
  63. universal_mcp/applications/heygen/README.md +0 -69
  64. universal_mcp/applications/heygen/__init__.py +0 -0
  65. universal_mcp/applications/heygen/app.py +0 -956
  66. universal_mcp/applications/mailchimp/README.md +0 -306
  67. universal_mcp/applications/mailchimp/__init__.py +0 -0
  68. universal_mcp/applications/mailchimp/app.py +0 -10937
  69. universal_mcp/applications/markitdown/app.py +0 -44
  70. universal_mcp/applications/notion/README.md +0 -55
  71. universal_mcp/applications/notion/__init__.py +0 -0
  72. universal_mcp/applications/notion/app.py +0 -527
  73. universal_mcp/applications/perplexity/README.md +0 -37
  74. universal_mcp/applications/perplexity/app.py +0 -65
  75. universal_mcp/applications/reddit/README.md +0 -45
  76. universal_mcp/applications/reddit/app.py +0 -379
  77. universal_mcp/applications/replicate/README.md +0 -65
  78. universal_mcp/applications/replicate/__init__.py +0 -0
  79. universal_mcp/applications/replicate/app.py +0 -980
  80. universal_mcp/applications/resend/README.md +0 -38
  81. universal_mcp/applications/resend/app.py +0 -37
  82. universal_mcp/applications/retell_ai/README.md +0 -46
  83. universal_mcp/applications/retell_ai/__init__.py +0 -0
  84. universal_mcp/applications/retell_ai/app.py +0 -333
  85. universal_mcp/applications/rocketlane/README.md +0 -42
  86. universal_mcp/applications/rocketlane/__init__.py +0 -0
  87. universal_mcp/applications/rocketlane/app.py +0 -194
  88. universal_mcp/applications/serpapi/README.md +0 -37
  89. universal_mcp/applications/serpapi/app.py +0 -73
  90. universal_mcp/applications/spotify/README.md +0 -116
  91. universal_mcp/applications/spotify/__init__.py +0 -0
  92. universal_mcp/applications/spotify/app.py +0 -2526
  93. universal_mcp/applications/supabase/README.md +0 -112
  94. universal_mcp/applications/supabase/__init__.py +0 -0
  95. universal_mcp/applications/supabase/app.py +0 -2970
  96. universal_mcp/applications/tavily/README.md +0 -38
  97. universal_mcp/applications/tavily/app.py +0 -51
  98. universal_mcp/applications/wrike/README.md +0 -71
  99. universal_mcp/applications/wrike/__init__.py +0 -0
  100. universal_mcp/applications/wrike/app.py +0 -1372
  101. universal_mcp/applications/youtube/README.md +0 -82
  102. universal_mcp/applications/youtube/__init__.py +0 -0
  103. universal_mcp/applications/youtube/app.py +0 -1428
  104. universal_mcp/applications/zenquotes/README.md +0 -37
  105. universal_mcp/applications/zenquotes/app.py +0 -31
  106. universal_mcp/integrations/agentr.py +0 -112
  107. universal_mcp-0.1.12.dist-info/RECORD +0 -119
  108. {universal_mcp-0.1.12.dist-info → universal_mcp-0.1.13rc2.dist-info}/WHEEL +0 -0
  109. {universal_mcp-0.1.12.dist-info → universal_mcp-0.1.13rc2.dist-info}/entry_points.txt +0 -0
@@ -1,286 +0,0 @@
1
- from typing import Any
2
-
3
- import httpx
4
- from loguru import logger
5
-
6
- from universal_mcp.applications.application import APIApplication
7
- from universal_mcp.integrations import Integration
8
-
9
-
10
- class GoogleDriveApp(APIApplication):
11
- """
12
- Application for interacting with Google Drive API.
13
- Provides tools to manage files, folders, and access Drive information.
14
- """
15
-
16
- def __init__(self, integration: Integration | None = None) -> None:
17
- super().__init__(name="google-drive", integration=integration)
18
- self.base_url = "https://www.googleapis.com/drive/v3"
19
-
20
- def get_drive_info(self) -> dict[str, Any]:
21
- """
22
- Retrieves detailed information about the user's Google Drive storage and account.
23
-
24
- Returns:
25
- A dictionary containing Drive information including storage quota (usage, limit) and user details (name, email, etc.).
26
-
27
- Raises:
28
- HTTPError: If the API request fails or returns an error status code
29
- ConnectionError: If there are network connectivity issues
30
- AuthenticationError: If the authentication credentials are invalid or expired
31
-
32
- Tags:
33
- get, info, storage, drive, quota, user, api, important
34
- """
35
- url = f"{self.base_url}/about"
36
- params = {"fields": "storageQuota,user"}
37
- response = self._get(url, params=params)
38
- return response.json()
39
-
40
- def list_files(
41
- self, page_size: int = 10, query: str = None, order_by: str = None
42
- ) -> dict[str, Any]:
43
- """
44
- Lists and retrieves files from Google Drive with optional filtering, pagination, and sorting.
45
-
46
- Args:
47
- page_size: Maximum number of files to return per page (default: 10)
48
- query: Optional search query string using Google Drive query syntax (e.g., "mimeType='image/jpeg'")
49
- order_by: Optional field name to sort results by, with optional direction (e.g., "modifiedTime desc")
50
-
51
- Returns:
52
- Dictionary containing a list of files and metadata, including 'files' array and optional 'nextPageToken' for pagination
53
-
54
- Raises:
55
- HTTPError: Raised when the API request fails or returns an error status code
56
- RequestException: Raised when network connectivity issues occur during the API request
57
-
58
- Tags:
59
- list, files, search, google-drive, pagination, important
60
- """
61
- url = f"{self.base_url}/files"
62
- params = {
63
- "pageSize": page_size,
64
- }
65
- if query:
66
- params["q"] = query
67
- if order_by:
68
- params["orderBy"] = order_by
69
- response = self._get(url, params=params)
70
- response.raise_for_status()
71
- return response.json()
72
-
73
- def get_file(self, file_id: str) -> dict[str, Any]:
74
- """
75
- Retrieves detailed metadata for a specific file using its ID.
76
-
77
- Args:
78
- file_id: String identifier of the file whose metadata should be retrieved
79
-
80
- Returns:
81
- Dictionary containing the file's metadata including properties such as name, size, type, and other attributes
82
-
83
- Raises:
84
- HTTPError: When the API request fails due to invalid file_id or network issues
85
- JSONDecodeError: When the API response cannot be parsed as JSON
86
-
87
- Tags:
88
- retrieve, file, metadata, get, api, important
89
- """
90
- url = f"{self.base_url}/files/{file_id}"
91
- response = self._get(url)
92
- return response.json()
93
-
94
- def delete_file(self, file_id: str) -> dict[str, Any]:
95
- """
96
- Deletes a specified file from Google Drive and returns a status message.
97
-
98
- Args:
99
- file_id: The unique identifier string of the file to be deleted from Google Drive
100
-
101
- Returns:
102
- A dictionary containing either a success message {'message': 'File deleted successfully'} or an error message {'error': 'error description'}
103
-
104
- Raises:
105
- Exception: When the DELETE request fails due to network issues, invalid file_id, insufficient permissions, or other API errors
106
-
107
- Tags:
108
- delete, file-management, google-drive, api, important
109
- """
110
- url = f"{self.base_url}/files/{file_id}"
111
- try:
112
- self._delete(url)
113
- return {"message": "File deleted successfully"}
114
- except Exception as e:
115
- return {"error": str(e)}
116
-
117
- def create_file_from_text(
118
- self,
119
- file_name: str,
120
- text_content: str,
121
- parent_id: str = None,
122
- mime_type: str = "text/plain",
123
- ) -> dict[str, Any]:
124
- """
125
- Creates a new file in Google Drive with specified text content and returns the file's metadata.
126
-
127
- Args:
128
- file_name: Name of the file to create on Google Drive
129
- text_content: Plain text content to be written to the file
130
- parent_id: Optional ID of the parent folder where the file will be created
131
- mime_type: MIME type of the file (defaults to 'text/plain')
132
-
133
- Returns:
134
- Dictionary containing metadata of the created file including ID, name, and other Google Drive file properties
135
-
136
- Raises:
137
- HTTPStatusError: Raised when the API request fails during file creation or content upload
138
- UnicodeEncodeError: Raised when the text_content cannot be encoded in UTF-8
139
-
140
- Tags:
141
- create, file, upload, drive, text, important, storage, document
142
- """
143
- metadata = {"name": file_name, "mimeType": mime_type}
144
- if parent_id:
145
- metadata["parents"] = [parent_id]
146
- create_url = f"{self.base_url}/files"
147
- create_response = self._post(create_url, data=metadata)
148
- file_data = create_response.json()
149
- file_id = file_data.get("id")
150
- upload_url = f"https://www.googleapis.com/upload/drive/v3/files/{file_id}?uploadType=media"
151
- upload_headers = self._get_headers()
152
- upload_headers["Content-Type"] = f"{mime_type}; charset=utf-8"
153
- upload_response = httpx.patch(
154
- upload_url, headers=upload_headers, content=text_content.encode("utf-8")
155
- )
156
- upload_response.raise_for_status()
157
- response_data = upload_response.json()
158
- return response_data
159
-
160
- def find_folder_id_by_name(self, folder_name: str) -> str | None:
161
- """
162
- Searches for and retrieves a Google Drive folder's ID using its name.
163
-
164
- Args:
165
- folder_name: The name of the folder to search for in Google Drive
166
-
167
- Returns:
168
- str | None: The folder's ID if a matching folder is found, None if no folder is found or if an error occurs
169
-
170
- Raises:
171
- Exception: Caught internally and logged when API requests fail or response parsing errors occur
172
-
173
- Tags:
174
- search, find, google-drive, folder, query, api, utility
175
- """
176
- query = f"mimeType='application/vnd.google-apps.folder' and name='{folder_name}' and trashed=false"
177
- try:
178
- response = self._get(
179
- f"{self.base_url}/files",
180
- params={"q": query, "fields": "files(id,name)"},
181
- )
182
- files = response.json().get("files", [])
183
- return files[0]["id"] if files else None
184
- except Exception as e:
185
- logger.error(f"Error finding folder ID by name: {e}")
186
- return None
187
-
188
- def create_folder(self, folder_name: str, parent_id: str = None) -> dict[str, Any]:
189
- """
190
- Creates a new folder in Google Drive with optional parent folder specification
191
-
192
- Args:
193
- folder_name: Name of the folder to create
194
- parent_id: ID or name of the parent folder. Can be either a folder ID string or a folder name that will be automatically looked up
195
-
196
- Returns:
197
- Dictionary containing the created folder's metadata including its ID, name, and other Drive-specific information
198
-
199
- Raises:
200
- ValueError: Raised when a parent folder name is provided but cannot be found in Google Drive
201
-
202
- Tags:
203
- create, folder, drive, storage, important, management
204
- """
205
- import re
206
-
207
- metadata = {
208
- "name": folder_name,
209
- "mimeType": "application/vnd.google-apps.folder",
210
- }
211
- if parent_id:
212
- if not re.match(r"^[a-zA-Z0-9_-]{28,33}$", parent_id):
213
- found_id = self.find_folder_id_by_name(parent_id)
214
- if found_id:
215
- metadata["parents"] = [found_id]
216
- else:
217
- raise ValueError(
218
- f"Could not find parent folder with name: {parent_id}"
219
- )
220
- else:
221
- metadata["parents"] = [parent_id]
222
- url = f"{self.base_url}/files"
223
- params = {"supportsAllDrives": "true"}
224
- response = self._post(url, data=metadata, params=params)
225
- return response.json()
226
-
227
- def upload_a_file(
228
- self,
229
- file_name: str,
230
- file_path: str,
231
- parent_id: str = None,
232
- mime_type: str = None,
233
- ) -> dict[str, Any]:
234
- """
235
- Uploads a file to Google Drive by creating a file metadata entry and uploading the binary content.
236
-
237
- Args:
238
- file_name: Name to give the file on Google Drive
239
- file_path: Path to the local file to upload
240
- parent_id: Optional ID of the parent folder to create the file in
241
- mime_type: MIME type of the file (e.g., 'image/jpeg', 'image/png', 'application/pdf')
242
-
243
- Returns:
244
- Dictionary containing the uploaded file's metadata from Google Drive
245
-
246
- Raises:
247
- FileNotFoundError: When the specified file_path does not exist or is not accessible
248
- HTTPError: When the API request fails or returns an error status code
249
- IOError: When there are issues reading the file content
250
-
251
- Tags:
252
- upload, file-handling, google-drive, api, important, binary, storage
253
- """
254
- metadata = {"name": file_name, "mimeType": mime_type}
255
- if parent_id:
256
- metadata["parents"] = [parent_id]
257
- create_url = f"{self.base_url}/files"
258
- create_response = self._post(create_url, data=metadata)
259
- file_data = create_response.json()
260
- file_id = file_data.get("id")
261
- with open(file_path, "rb") as file_content:
262
- binary_content = file_content.read()
263
-
264
- upload_url = f"https://www.googleapis.com/upload/drive/v3/files/{file_id}?uploadType=media"
265
- upload_headers = self._get_headers()
266
- upload_headers["Content-Type"] = mime_type
267
-
268
- upload_response = httpx.patch(
269
- upload_url, headers=upload_headers, content=binary_content
270
- )
271
- upload_response.raise_for_status()
272
- response_data = upload_response.json()
273
- return response_data
274
-
275
- def list_tools(self):
276
- """Returns a list of methods exposed as tools."""
277
- return [
278
- self.get_drive_info,
279
- self.list_files,
280
- self.create_file_from_text,
281
- self.upload_a_file,
282
- self.find_folder_id_by_name,
283
- self.create_folder,
284
- self.get_file,
285
- self.delete_file,
286
- ]
@@ -1,47 +0,0 @@
1
-
2
- # Google Mail MCP Server
3
-
4
- An MCP Server for the Google Mail 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 Google Mail 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
- | create_draft | Create a draft email |
25
- | create_label | Create a new Gmail label |
26
- | get_draft | Get a specific draft email by ID |
27
- | get_message | Get a specific email message by ID |
28
- | get_profile | Retrieve the user's Gmail profile information. |
29
- | list_drafts | List drafts in the user's mailbox |
30
- | list_labels | List all labels in the user's Gmail account |
31
- | list_messages | List messages in the user's mailbox |
32
- | send_draft | Send an existing draft email |
33
- | send_email | Send an email |
34
- | validate | Function for validate |
35
-
36
-
37
-
38
- ## Usage
39
-
40
- - Login to AgentR
41
- - Follow the quickstart guide to setup MCP Server for your client
42
- - Visit Apps Store and enable the Google Mail app
43
- - Restart the MCP Server
44
-
45
- ### Local Development
46
-
47
- - Follow the README to test with the local MCP Server