universal-mcp 0.1.13rc1__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.
- {universal_mcp-0.1.13rc1.dist-info → universal_mcp-0.1.13rc2.dist-info}/METADATA +1 -1
- universal_mcp-0.1.13rc2.dist-info/RECORD +38 -0
- universal_mcp/applications/ahrefs/README.md +0 -76
- universal_mcp/applications/ahrefs/__init__.py +0 -0
- universal_mcp/applications/ahrefs/app.py +0 -2291
- universal_mcp/applications/cal_com_v2/README.md +0 -175
- universal_mcp/applications/cal_com_v2/__init__.py +0 -0
- universal_mcp/applications/cal_com_v2/app.py +0 -5390
- universal_mcp/applications/calendly/README.md +0 -78
- universal_mcp/applications/calendly/__init__.py +0 -0
- universal_mcp/applications/calendly/app.py +0 -1195
- universal_mcp/applications/clickup/README.md +0 -160
- universal_mcp/applications/clickup/__init__.py +0 -0
- universal_mcp/applications/clickup/app.py +0 -5009
- universal_mcp/applications/coda/README.md +0 -133
- universal_mcp/applications/coda/__init__.py +0 -0
- universal_mcp/applications/coda/app.py +0 -3671
- universal_mcp/applications/curstdata/README.md +0 -50
- universal_mcp/applications/curstdata/__init__.py +0 -0
- universal_mcp/applications/curstdata/app.py +0 -551
- universal_mcp/applications/e2b/README.md +0 -37
- universal_mcp/applications/e2b/app.py +0 -65
- universal_mcp/applications/elevenlabs/README.md +0 -84
- universal_mcp/applications/elevenlabs/__init__.py +0 -0
- universal_mcp/applications/elevenlabs/app.py +0 -1402
- universal_mcp/applications/falai/README.md +0 -42
- universal_mcp/applications/falai/__init__.py +0 -0
- universal_mcp/applications/falai/app.py +0 -332
- universal_mcp/applications/figma/README.md +0 -74
- universal_mcp/applications/figma/__init__.py +0 -0
- universal_mcp/applications/figma/app.py +0 -1261
- universal_mcp/applications/firecrawl/README.md +0 -45
- universal_mcp/applications/firecrawl/app.py +0 -268
- universal_mcp/applications/github/README.md +0 -47
- universal_mcp/applications/github/app.py +0 -429
- universal_mcp/applications/gong/README.md +0 -88
- universal_mcp/applications/gong/__init__.py +0 -0
- universal_mcp/applications/gong/app.py +0 -2297
- universal_mcp/applications/google_calendar/app.py +0 -442
- universal_mcp/applications/google_docs/README.md +0 -40
- universal_mcp/applications/google_docs/app.py +0 -88
- universal_mcp/applications/google_drive/README.md +0 -44
- universal_mcp/applications/google_drive/app.py +0 -286
- universal_mcp/applications/google_mail/README.md +0 -47
- universal_mcp/applications/google_mail/app.py +0 -664
- universal_mcp/applications/google_sheet/README.md +0 -42
- universal_mcp/applications/google_sheet/app.py +0 -150
- universal_mcp/applications/heygen/README.md +0 -69
- universal_mcp/applications/heygen/__init__.py +0 -0
- universal_mcp/applications/heygen/app.py +0 -956
- universal_mcp/applications/mailchimp/README.md +0 -306
- universal_mcp/applications/mailchimp/__init__.py +0 -0
- universal_mcp/applications/mailchimp/app.py +0 -10937
- universal_mcp/applications/markitdown/app.py +0 -44
- universal_mcp/applications/neon/README.md +0 -99
- universal_mcp/applications/neon/__init__.py +0 -0
- universal_mcp/applications/neon/app.py +0 -1924
- universal_mcp/applications/notion/README.md +0 -55
- universal_mcp/applications/notion/__init__.py +0 -0
- universal_mcp/applications/notion/app.py +0 -527
- universal_mcp/applications/perplexity/README.md +0 -37
- universal_mcp/applications/perplexity/app.py +0 -65
- universal_mcp/applications/reddit/README.md +0 -45
- universal_mcp/applications/reddit/app.py +0 -379
- universal_mcp/applications/replicate/README.md +0 -65
- universal_mcp/applications/replicate/__init__.py +0 -0
- universal_mcp/applications/replicate/app.py +0 -980
- universal_mcp/applications/resend/README.md +0 -38
- universal_mcp/applications/resend/app.py +0 -37
- universal_mcp/applications/retell_ai/README.md +0 -46
- universal_mcp/applications/retell_ai/__init__.py +0 -0
- universal_mcp/applications/retell_ai/app.py +0 -333
- universal_mcp/applications/rocketlane/README.md +0 -42
- universal_mcp/applications/rocketlane/__init__.py +0 -0
- universal_mcp/applications/rocketlane/app.py +0 -194
- universal_mcp/applications/serpapi/README.md +0 -37
- universal_mcp/applications/serpapi/app.py +0 -73
- universal_mcp/applications/shortcut/README.md +0 -153
- universal_mcp/applications/shortcut/__init__.py +0 -0
- universal_mcp/applications/shortcut/app.py +0 -3880
- universal_mcp/applications/spotify/README.md +0 -116
- universal_mcp/applications/spotify/__init__.py +0 -0
- universal_mcp/applications/spotify/app.py +0 -2526
- universal_mcp/applications/supabase/README.md +0 -112
- universal_mcp/applications/supabase/__init__.py +0 -0
- universal_mcp/applications/supabase/app.py +0 -2970
- universal_mcp/applications/tavily/README.md +0 -38
- universal_mcp/applications/tavily/app.py +0 -51
- universal_mcp/applications/wrike/README.md +0 -71
- universal_mcp/applications/wrike/__init__.py +0 -0
- universal_mcp/applications/wrike/app.py +0 -1372
- universal_mcp/applications/youtube/README.md +0 -82
- universal_mcp/applications/youtube/__init__.py +0 -0
- universal_mcp/applications/youtube/app.py +0 -1428
- universal_mcp/applications/zenquotes/README.md +0 -37
- universal_mcp/applications/zenquotes/app.py +0 -31
- universal_mcp-0.1.13rc1.dist-info/RECORD +0 -132
- {universal_mcp-0.1.13rc1.dist-info → universal_mcp-0.1.13rc2.dist-info}/WHEEL +0 -0
- {universal_mcp-0.1.13rc1.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
|