universal-mcp-applications 0.1.3__py3-none-any.whl → 0.1.5__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.
Potentially problematic release.
This version of universal-mcp-applications might be problematic. Click here for more details.
- universal_mcp/applications/google_drive/app.py +1 -67
- universal_mcp/applications/scraper/README.md +15 -0
- universal_mcp/applications/scraper/__init__.py +1 -0
- universal_mcp/applications/scraper/app.py +190 -0
- {universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/METADATA +2 -1
- {universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/RECORD +8 -5
- {universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -4751,71 +4751,7 @@ class GoogleDriveApp(APIApplication):
|
|
|
4751
4751
|
except ValueError:
|
|
4752
4752
|
return None
|
|
4753
4753
|
|
|
4754
|
-
|
|
4755
|
-
self, channel: str | None = None
|
|
4756
|
-
) -> dict[str, Any]:
|
|
4757
|
-
"""
|
|
4758
|
-
List all members of a channel
|
|
4759
|
-
|
|
4760
|
-
Args:
|
|
4761
|
-
channel (string): Specifies the channel for which to retrieve conversation members; must be a valid channel identifier. Example: '{{channelId}}'.
|
|
4762
|
-
|
|
4763
|
-
Returns:
|
|
4764
|
-
dict[str, Any]: Success Response
|
|
4765
|
-
|
|
4766
|
-
Raises:
|
|
4767
|
-
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
4768
|
-
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
4769
|
-
|
|
4770
|
-
Tags:
|
|
4771
|
-
Google Drive API Use Cases, Share file access to a slack channel
|
|
4772
|
-
"""
|
|
4773
|
-
url = f"{self.base_url}/api/conversations.members"
|
|
4774
|
-
query_params = {k: v for k, v in [("channel", channel)] if v is not None}
|
|
4775
|
-
response = self._get(url, params=query_params)
|
|
4776
|
-
response.raise_for_status()
|
|
4777
|
-
if (
|
|
4778
|
-
response.status_code == 204
|
|
4779
|
-
or not response.content
|
|
4780
|
-
or not response.text.strip()
|
|
4781
|
-
):
|
|
4782
|
-
return None
|
|
4783
|
-
try:
|
|
4784
|
-
return response.json()
|
|
4785
|
-
except ValueError:
|
|
4786
|
-
return None
|
|
4787
|
-
|
|
4788
|
-
def fetch_user_email(self, user: str | None = None) -> dict[str, Any]:
|
|
4789
|
-
"""
|
|
4790
|
-
Fetch User Email
|
|
4791
|
-
|
|
4792
|
-
Args:
|
|
4793
|
-
user (string): Specifies the user identifier to retrieve information for; the value should be a unique string. Example: '{{currentUserId}}'.
|
|
4794
|
-
|
|
4795
|
-
Returns:
|
|
4796
|
-
dict[str, Any]: Fetch User Email
|
|
4797
|
-
|
|
4798
|
-
Raises:
|
|
4799
|
-
HTTPError: Raised when the API request fails (e.g., non-2XX status code).
|
|
4800
|
-
JSONDecodeError: Raised if the response body cannot be parsed as JSON.
|
|
4801
|
-
|
|
4802
|
-
Tags:
|
|
4803
|
-
Google Drive API Use Cases, Share file access to a slack channel
|
|
4804
|
-
"""
|
|
4805
|
-
url = f"{self.base_url}/api/users.info"
|
|
4806
|
-
query_params = {k: v for k, v in [("user", user)] if v is not None}
|
|
4807
|
-
response = self._get(url, params=query_params)
|
|
4808
|
-
response.raise_for_status()
|
|
4809
|
-
if (
|
|
4810
|
-
response.status_code == 204
|
|
4811
|
-
or not response.content
|
|
4812
|
-
or not response.text.strip()
|
|
4813
|
-
):
|
|
4814
|
-
return None
|
|
4815
|
-
try:
|
|
4816
|
-
return response.json()
|
|
4817
|
-
except ValueError:
|
|
4818
|
-
return None
|
|
4754
|
+
|
|
4819
4755
|
|
|
4820
4756
|
def grant_google_drive_access(
|
|
4821
4757
|
self,
|
|
@@ -4930,8 +4866,6 @@ class GoogleDriveApp(APIApplication):
|
|
|
4930
4866
|
self.get_aspecific_revision,
|
|
4931
4867
|
self.permanently_delete_afile_version,
|
|
4932
4868
|
self.update_arevision,
|
|
4933
|
-
self.list_all_members_of_achannel,
|
|
4934
|
-
self.fetch_user_email,
|
|
4935
4869
|
self.grant_google_drive_access,
|
|
4936
4870
|
self.move_files,
|
|
4937
4871
|
]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# ScraperApp MCP Server
|
|
2
|
+
|
|
3
|
+
An MCP Server for the ScraperApp API.
|
|
4
|
+
|
|
5
|
+
## 🛠️ Tool List
|
|
6
|
+
|
|
7
|
+
This is automatically generated from OpenAPI schema for the ScraperApp API.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
| Tool | Description |
|
|
11
|
+
|------|-------------|
|
|
12
|
+
| `linkedin_post_search` | Performs a LinkedIn search for posts. |
|
|
13
|
+
| `linkedin_list_all_posts` | Lists all LinkedIn posts for a given user identifier |
|
|
14
|
+
| `linkedin_retrieve_profile` | Retrieves a specific LinkedIn user profile by its identifier. |
|
|
15
|
+
| `linkedin_list_post_comments` | Lists all comments from a specific LinkedIn post. Can also list replies to a specific comment. |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .app import ScraperApp
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dotenv import load_dotenv
|
|
3
|
+
load_dotenv()
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from universal_mcp.applications.application import APIApplication
|
|
8
|
+
from universal_mcp.integrations import Integration
|
|
9
|
+
from universal_mcp.agentr.integration import AgentrIntegration
|
|
10
|
+
from universal_mcp_unipile.app import UnipileApp
|
|
11
|
+
from typing import Any, Optional
|
|
12
|
+
|
|
13
|
+
class ScraperApp(APIApplication):
|
|
14
|
+
"""
|
|
15
|
+
Application for interacting with LinkedIn API.
|
|
16
|
+
Provides a simplified interface for LinkedIn search operations.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
20
|
+
"""
|
|
21
|
+
Initialize the ScraperApp.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
integration: The integration configuration containing credentials and other settings.
|
|
25
|
+
It is expected that the integration provides the necessary credentials
|
|
26
|
+
for LinkedIn API access.
|
|
27
|
+
"""
|
|
28
|
+
super().__init__(name="scraper", **kwargs)
|
|
29
|
+
self.api_key = os.getenv("SCRAPER_API")
|
|
30
|
+
self.account_id = os.getenv("ACCOUNT_ID")
|
|
31
|
+
|
|
32
|
+
if self.api_key:
|
|
33
|
+
self.integration = AgentrIntegration(name="unipile", api_key=self.api_key, base_url="https://api.agentr.dev")
|
|
34
|
+
self._unipile_app = UnipileApp(integration=self.integration)
|
|
35
|
+
else:
|
|
36
|
+
self.integration = None
|
|
37
|
+
self._unipile_app = None
|
|
38
|
+
|
|
39
|
+
def linkedin_post_search(
|
|
40
|
+
self,
|
|
41
|
+
category: str = "posts",
|
|
42
|
+
api: str = "classic",
|
|
43
|
+
cursor: Optional[str] = None,
|
|
44
|
+
limit: Optional[int] = None,
|
|
45
|
+
keywords: Optional[str] = None,
|
|
46
|
+
sort_by: Optional[str] = None,
|
|
47
|
+
date_posted: Optional[str] = None,
|
|
48
|
+
content_type: Optional[str] = None,
|
|
49
|
+
) -> dict[str, Any]:
|
|
50
|
+
"""
|
|
51
|
+
Performs a LinkedIn search for posts.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
category: Type of search to perform (defaults to "posts").
|
|
55
|
+
api: Which LinkedIn API to use - "classic" or "sales_navigator".
|
|
56
|
+
cursor: Pagination cursor for the next page of entries.
|
|
57
|
+
limit: Number of items to return (up to 50 for Classic search).
|
|
58
|
+
keywords: Keywords to search for.
|
|
59
|
+
sort_by: How to sort the results, e.g., "relevance" or "date".
|
|
60
|
+
date_posted: Filter posts by when they were posted.
|
|
61
|
+
content_type: Filter by the type of content in the post. Example: "videos", "images", "live_videos", "collaborative_articles", "documents"
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
A dictionary containing search results and pagination details.
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
httpx.HTTPError: If the API request fails.
|
|
68
|
+
|
|
69
|
+
Tags:
|
|
70
|
+
linkedin, search, posts, api, scrapper, important
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
return self._unipile_app.search(
|
|
74
|
+
account_id=self.account_id,
|
|
75
|
+
category=category,
|
|
76
|
+
api=api,
|
|
77
|
+
cursor=cursor,
|
|
78
|
+
limit=limit,
|
|
79
|
+
keywords=keywords,
|
|
80
|
+
sort_by=sort_by,
|
|
81
|
+
date_posted=date_posted,
|
|
82
|
+
content_type=content_type,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def linkedin_list_all_posts(
|
|
86
|
+
self,
|
|
87
|
+
identifier: str,
|
|
88
|
+
cursor: Optional[str] = None,
|
|
89
|
+
limit: Optional[int] = None,
|
|
90
|
+
) -> dict[str, Any]:
|
|
91
|
+
"""
|
|
92
|
+
Lists all LinkedIn posts for a given user identifier
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
identifier: The entity's provider internal ID (LinkedIn ID).starts with ACo for users, while for companies it's a series of numbers.
|
|
96
|
+
cursor: Pagination cursor for the next page of entries.
|
|
97
|
+
limit: Number of items to return (1-100, though spec allows up to 250).
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
A dictionary containing a list of post objects and pagination details.
|
|
101
|
+
|
|
102
|
+
Raises:
|
|
103
|
+
httpx.HTTPError: If the API request fails.
|
|
104
|
+
|
|
105
|
+
Tags:
|
|
106
|
+
linkedin, post, list, user_posts, company_posts, content, api, important
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
return self._unipile_app.list_user_posts(
|
|
110
|
+
identifier=identifier,
|
|
111
|
+
account_id=self.account_id,
|
|
112
|
+
cursor=cursor,
|
|
113
|
+
limit=limit,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def linkedin_retrieve_profile(
|
|
117
|
+
self,
|
|
118
|
+
identifier: str,
|
|
119
|
+
) -> dict[str, Any]:
|
|
120
|
+
"""
|
|
121
|
+
Retrieves a specific LinkedIn user profile by its identifier.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
identifier: Can be the provider's internal id OR the provider's public id of the requested user.
|
|
125
|
+
For example, for https://www.linkedin.com/in/manojbajaj95/, the identifier is "manojbajaj95".
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
A dictionary containing the user's profile details.
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
httpx.HTTPError: If the API request fails.
|
|
132
|
+
|
|
133
|
+
Tags:
|
|
134
|
+
linkedin, user, profile, retrieve, get, api, important
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
return self._unipile_app.retrieve_profile(
|
|
138
|
+
identifier=identifier,
|
|
139
|
+
account_id=self.account_id,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def linkedin_list_post_comments(
|
|
144
|
+
self,
|
|
145
|
+
post_id: str,
|
|
146
|
+
comment_id: Optional[str] = None,
|
|
147
|
+
cursor: Optional[str] = None,
|
|
148
|
+
limit: Optional[int] = None,
|
|
149
|
+
) -> dict[str, Any]:
|
|
150
|
+
"""
|
|
151
|
+
Lists all comments from a specific LinkedIn post. Can also list replies to a specific comment.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
post_id: The social ID of the post. Example rn:li:activity:7342082869034393600
|
|
155
|
+
comment_id: If provided, retrieves replies to this comment ID instead of top-level comments.
|
|
156
|
+
cursor: Pagination cursor.
|
|
157
|
+
limit: Number of comments to return.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
A dictionary containing a list of comment objects and pagination details.
|
|
161
|
+
|
|
162
|
+
Raises:
|
|
163
|
+
httpx.HTTPError: If the API request fails.
|
|
164
|
+
|
|
165
|
+
Tags:
|
|
166
|
+
linkedin, post, comment, list, content, api, important
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
return self._unipile_app.list_post_comments(
|
|
170
|
+
post_id=post_id,
|
|
171
|
+
account_id=self.account_id,
|
|
172
|
+
comment_id=comment_id,
|
|
173
|
+
cursor=cursor,
|
|
174
|
+
limit=limit,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def list_tools(self):
|
|
179
|
+
"""
|
|
180
|
+
Returns a list of available tools/functions in this application.
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
A list of functions that can be used as tools.
|
|
184
|
+
"""
|
|
185
|
+
return [
|
|
186
|
+
self.linkedin_post_search,
|
|
187
|
+
self.linkedin_list_all_posts,
|
|
188
|
+
self.linkedin_retrieve_profile,
|
|
189
|
+
self.linkedin_list_post_comments,
|
|
190
|
+
]
|
{universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: universal-mcp-applications
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A Universal MCP Application: universal_mcp_applications
|
|
5
5
|
Project-URL: Homepage, https://github.com/universal-mcp/applications
|
|
6
6
|
Project-URL: Repository, https://github.com/universal-mcp/applications
|
|
@@ -34,6 +34,7 @@ Requires-Dist: replicate>=1.0.6
|
|
|
34
34
|
Requires-Dist: requests>=2.31.0
|
|
35
35
|
Requires-Dist: resend>=2.10.0
|
|
36
36
|
Requires-Dist: twilio>=9.8.0
|
|
37
|
+
Requires-Dist: universal-mcp-unipile>=0.1.13
|
|
37
38
|
Requires-Dist: universal-mcp>=0.1.24rc17
|
|
38
39
|
Provides-Extra: dev
|
|
39
40
|
Requires-Dist: pre-commit; extra == 'dev'
|
{universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/RECORD
RENAMED
|
@@ -103,7 +103,7 @@ universal_mcp/applications/google_docs/__init__.py,sha256=U0pWagxnj0VD-AcKNd8eS0
|
|
|
103
103
|
universal_mcp/applications/google_docs/app.py,sha256=ep5eIupbXO5SZDHFfUbX9qyQVCFfF5nXTK9IPdiRnic,30094
|
|
104
104
|
universal_mcp/applications/google_drive/README.md,sha256=HNTQCqBU0wlmJEIgrlW1j3bKya5XtR7mvemcgPHJFD0,4089
|
|
105
105
|
universal_mcp/applications/google_drive/__init__.py,sha256=DTyed4ADcCmALSyPT8whjXoosPXl3m-i8JrilPJ3ijU,32
|
|
106
|
-
universal_mcp/applications/google_drive/app.py,sha256=
|
|
106
|
+
universal_mcp/applications/google_drive/app.py,sha256=IlYwUxGRo7ISKGeWzWpc_0r4ewDo-rXLPChyMOxAc_Q,248993
|
|
107
107
|
universal_mcp/applications/google_gemini/README.md,sha256=o5cWenioUnNhn7L2fxwPLasBXzQ7mNmYp-aLLj9bHzY,2042
|
|
108
108
|
universal_mcp/applications/google_gemini/__init__.py,sha256=KZWdPU74VKBBabLpAcPNEPRPLFk8v2i0ULnT4wVHM9U,33
|
|
109
109
|
universal_mcp/applications/google_gemini/app.py,sha256=lIBHubFPvlNgj6z9qBWiTWvQLUVYcGAQSgwpIjdTGI4,6375
|
|
@@ -186,6 +186,9 @@ universal_mcp/applications/retell/app.py,sha256=ysvyfDBHynl5AkKT7YRaQsEeMPivMPla
|
|
|
186
186
|
universal_mcp/applications/rocketlane/README.md,sha256=o8-N0RFEOzpUrQDerIGvFp7yXLX8KTmngupFhid9XN0,2986
|
|
187
187
|
universal_mcp/applications/rocketlane/__init__.py,sha256=jl3PjnTvPdjnbFXJgLywSlE4kHrKZiFMGaf-EaDsj80,31
|
|
188
188
|
universal_mcp/applications/rocketlane/app.py,sha256=Re5-OoUWIIxL_ZJZ_RpEqz82hymgAWtdcOSJtJFzzs0,240690
|
|
189
|
+
universal_mcp/applications/scraper/README.md,sha256=ys9f2dRHGsnFkauAuGdBo3_Z_51PRn2cqGlnEv8kjPI,590
|
|
190
|
+
universal_mcp/applications/scraper/__init__.py,sha256=RnkyFDeNR1tOsY_PskHdv4C8AYRbcjMt7KyYQWiGGD8,27
|
|
191
|
+
universal_mcp/applications/scraper/app.py,sha256=9selCbdp4SqlruypHHu0ydwzmB2VNFUwy8QAMoOilAo,6422
|
|
189
192
|
universal_mcp/applications/semanticscholar/README.md,sha256=JpLY_698pvstgoNfQ5Go8C8ehQ-o68uFDX5kr86upK0,2834
|
|
190
193
|
universal_mcp/applications/semanticscholar/__init__.py,sha256=eR36chrc0pbBsSE1GadvmQH0OmtKnSC91xbE7HcDPf0,36
|
|
191
194
|
universal_mcp/applications/semanticscholar/app.py,sha256=OHTFkR-IwRU5Rvb1bEu7XmRHikht3hEgZxszLQu6kFI,22234
|
|
@@ -264,7 +267,7 @@ universal_mcp/applications/youtube/app.py,sha256=hhKqnbXvMAyOW3LOqp-ODPdIuQorr1n
|
|
|
264
267
|
universal_mcp/applications/zenquotes/README.md,sha256=x1mZHjNKD4WOgsIhedcbbaR1nvbt794GSrKud1tSLD0,296
|
|
265
268
|
universal_mcp/applications/zenquotes/__init__.py,sha256=IkASLYaZiHJXlkGwEMk1HgIq5GwEZp5GhAIiJyjBd3g,30
|
|
266
269
|
universal_mcp/applications/zenquotes/app.py,sha256=6v8trNWjxbixdlEyaM-gJbfY8z9ZAmkIzSUks_fbsT4,1076
|
|
267
|
-
universal_mcp_applications-0.1.
|
|
268
|
-
universal_mcp_applications-0.1.
|
|
269
|
-
universal_mcp_applications-0.1.
|
|
270
|
-
universal_mcp_applications-0.1.
|
|
270
|
+
universal_mcp_applications-0.1.5.dist-info/METADATA,sha256=GYEtFJps_4QUJRJVXW2UXGsIEO2H5Wb2p4XQVyQar34,3963
|
|
271
|
+
universal_mcp_applications-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
272
|
+
universal_mcp_applications-0.1.5.dist-info/licenses/LICENSE,sha256=NweDZVPslBAZFzlgByF158b85GR0f5_tLQgq1NS48To,1063
|
|
273
|
+
universal_mcp_applications-0.1.5.dist-info/RECORD,,
|
{universal_mcp_applications-0.1.3.dist-info → universal_mcp_applications-0.1.5.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|