universal-mcp-applications 0.1.1__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 (268) hide show
  1. universal_mcp/applications/ahrefs/README.md +51 -0
  2. universal_mcp/applications/ahrefs/__init__.py +1 -0
  3. universal_mcp/applications/ahrefs/app.py +2291 -0
  4. universal_mcp/applications/airtable/README.md +22 -0
  5. universal_mcp/applications/airtable/__init__.py +1 -0
  6. universal_mcp/applications/airtable/app.py +479 -0
  7. universal_mcp/applications/apollo/README.md +44 -0
  8. universal_mcp/applications/apollo/__init__.py +1 -0
  9. universal_mcp/applications/apollo/app.py +1847 -0
  10. universal_mcp/applications/asana/README.md +199 -0
  11. universal_mcp/applications/asana/__init__.py +1 -0
  12. universal_mcp/applications/asana/app.py +9509 -0
  13. universal_mcp/applications/aws-s3/README.md +0 -0
  14. universal_mcp/applications/aws-s3/__init__.py +1 -0
  15. universal_mcp/applications/aws-s3/app.py +552 -0
  16. universal_mcp/applications/bill/README.md +0 -0
  17. universal_mcp/applications/bill/__init__.py +1 -0
  18. universal_mcp/applications/bill/app.py +8705 -0
  19. universal_mcp/applications/box/README.md +307 -0
  20. universal_mcp/applications/box/__init__.py +1 -0
  21. universal_mcp/applications/box/app.py +15987 -0
  22. universal_mcp/applications/braze/README.md +106 -0
  23. universal_mcp/applications/braze/__init__.py +1 -0
  24. universal_mcp/applications/braze/app.py +4754 -0
  25. universal_mcp/applications/cal-com-v2/README.md +150 -0
  26. universal_mcp/applications/cal-com-v2/__init__.py +1 -0
  27. universal_mcp/applications/cal-com-v2/app.py +5541 -0
  28. universal_mcp/applications/calendly/README.md +53 -0
  29. universal_mcp/applications/calendly/__init__.py +1 -0
  30. universal_mcp/applications/calendly/app.py +1436 -0
  31. universal_mcp/applications/canva/README.md +43 -0
  32. universal_mcp/applications/canva/__init__.py +1 -0
  33. universal_mcp/applications/canva/app.py +941 -0
  34. universal_mcp/applications/clickup/README.md +135 -0
  35. universal_mcp/applications/clickup/__init__.py +1 -0
  36. universal_mcp/applications/clickup/app.py +5009 -0
  37. universal_mcp/applications/coda/README.md +108 -0
  38. universal_mcp/applications/coda/__init__.py +1 -0
  39. universal_mcp/applications/coda/app.py +3671 -0
  40. universal_mcp/applications/confluence/README.md +198 -0
  41. universal_mcp/applications/confluence/__init__.py +1 -0
  42. universal_mcp/applications/confluence/app.py +6273 -0
  43. universal_mcp/applications/contentful/README.md +17 -0
  44. universal_mcp/applications/contentful/__init__.py +1 -0
  45. universal_mcp/applications/contentful/app.py +364 -0
  46. universal_mcp/applications/crustdata/README.md +25 -0
  47. universal_mcp/applications/crustdata/__init__.py +1 -0
  48. universal_mcp/applications/crustdata/app.py +586 -0
  49. universal_mcp/applications/dialpad/README.md +202 -0
  50. universal_mcp/applications/dialpad/__init__.py +1 -0
  51. universal_mcp/applications/dialpad/app.py +5949 -0
  52. universal_mcp/applications/digitalocean/README.md +463 -0
  53. universal_mcp/applications/digitalocean/__init__.py +1 -0
  54. universal_mcp/applications/digitalocean/app.py +20835 -0
  55. universal_mcp/applications/domain-checker/README.md +13 -0
  56. universal_mcp/applications/domain-checker/__init__.py +1 -0
  57. universal_mcp/applications/domain-checker/app.py +265 -0
  58. universal_mcp/applications/e2b/README.md +12 -0
  59. universal_mcp/applications/e2b/__init__.py +1 -0
  60. universal_mcp/applications/e2b/app.py +187 -0
  61. universal_mcp/applications/elevenlabs/README.md +88 -0
  62. universal_mcp/applications/elevenlabs/__init__.py +1 -0
  63. universal_mcp/applications/elevenlabs/app.py +3235 -0
  64. universal_mcp/applications/exa/README.md +15 -0
  65. universal_mcp/applications/exa/__init__.py +1 -0
  66. universal_mcp/applications/exa/app.py +221 -0
  67. universal_mcp/applications/falai/README.md +17 -0
  68. universal_mcp/applications/falai/__init__.py +1 -0
  69. universal_mcp/applications/falai/app.py +331 -0
  70. universal_mcp/applications/figma/README.md +49 -0
  71. universal_mcp/applications/figma/__init__.py +1 -0
  72. universal_mcp/applications/figma/app.py +1090 -0
  73. universal_mcp/applications/firecrawl/README.md +20 -0
  74. universal_mcp/applications/firecrawl/__init__.py +1 -0
  75. universal_mcp/applications/firecrawl/app.py +514 -0
  76. universal_mcp/applications/fireflies/README.md +25 -0
  77. universal_mcp/applications/fireflies/__init__.py +1 -0
  78. universal_mcp/applications/fireflies/app.py +506 -0
  79. universal_mcp/applications/fpl/README.md +23 -0
  80. universal_mcp/applications/fpl/__init__.py +1 -0
  81. universal_mcp/applications/fpl/app.py +1327 -0
  82. universal_mcp/applications/fpl/utils/api.py +142 -0
  83. universal_mcp/applications/fpl/utils/fixtures.py +629 -0
  84. universal_mcp/applications/fpl/utils/helper.py +982 -0
  85. universal_mcp/applications/fpl/utils/league_utils.py +546 -0
  86. universal_mcp/applications/fpl/utils/position_utils.py +68 -0
  87. universal_mcp/applications/ghost-content/README.md +25 -0
  88. universal_mcp/applications/ghost-content/__init__.py +1 -0
  89. universal_mcp/applications/ghost-content/app.py +654 -0
  90. universal_mcp/applications/github/README.md +1049 -0
  91. universal_mcp/applications/github/__init__.py +1 -0
  92. universal_mcp/applications/github/app.py +50600 -0
  93. universal_mcp/applications/gong/README.md +63 -0
  94. universal_mcp/applications/gong/__init__.py +1 -0
  95. universal_mcp/applications/gong/app.py +2297 -0
  96. universal_mcp/applications/google-ads/README.md +0 -0
  97. universal_mcp/applications/google-ads/__init__.py +1 -0
  98. universal_mcp/applications/google-ads/app.py +23 -0
  99. universal_mcp/applications/google-calendar/README.md +21 -0
  100. universal_mcp/applications/google-calendar/__init__.py +1 -0
  101. universal_mcp/applications/google-calendar/app.py +574 -0
  102. universal_mcp/applications/google-docs/README.md +25 -0
  103. universal_mcp/applications/google-docs/__init__.py +1 -0
  104. universal_mcp/applications/google-docs/app.py +760 -0
  105. universal_mcp/applications/google-drive/README.md +68 -0
  106. universal_mcp/applications/google-drive/__init__.py +1 -0
  107. universal_mcp/applications/google-drive/app.py +4936 -0
  108. universal_mcp/applications/google-gemini/README.md +25 -0
  109. universal_mcp/applications/google-gemini/__init__.py +1 -0
  110. universal_mcp/applications/google-gemini/app.py +663 -0
  111. universal_mcp/applications/google-mail/README.md +31 -0
  112. universal_mcp/applications/google-mail/__init__.py +1 -0
  113. universal_mcp/applications/google-mail/app.py +1354 -0
  114. universal_mcp/applications/google-searchconsole/README.md +21 -0
  115. universal_mcp/applications/google-searchconsole/__init__.py +1 -0
  116. universal_mcp/applications/google-searchconsole/app.py +320 -0
  117. universal_mcp/applications/google-sheet/README.md +36 -0
  118. universal_mcp/applications/google-sheet/__init__.py +1 -0
  119. universal_mcp/applications/google-sheet/app.py +1941 -0
  120. universal_mcp/applications/hashnode/README.md +20 -0
  121. universal_mcp/applications/hashnode/__init__.py +1 -0
  122. universal_mcp/applications/hashnode/app.py +455 -0
  123. universal_mcp/applications/heygen/README.md +44 -0
  124. universal_mcp/applications/heygen/__init__.py +1 -0
  125. universal_mcp/applications/heygen/app.py +961 -0
  126. universal_mcp/applications/http-tools/README.md +16 -0
  127. universal_mcp/applications/http-tools/__init__.py +1 -0
  128. universal_mcp/applications/http-tools/app.py +153 -0
  129. universal_mcp/applications/hubspot/README.md +239 -0
  130. universal_mcp/applications/hubspot/__init__.py +1 -0
  131. universal_mcp/applications/hubspot/app.py +416 -0
  132. universal_mcp/applications/jira/README.md +600 -0
  133. universal_mcp/applications/jira/__init__.py +1 -0
  134. universal_mcp/applications/jira/app.py +28804 -0
  135. universal_mcp/applications/klaviyo/README.md +313 -0
  136. universal_mcp/applications/klaviyo/__init__.py +1 -0
  137. universal_mcp/applications/klaviyo/app.py +11236 -0
  138. universal_mcp/applications/linkedin/README.md +15 -0
  139. universal_mcp/applications/linkedin/__init__.py +1 -0
  140. universal_mcp/applications/linkedin/app.py +243 -0
  141. universal_mcp/applications/mailchimp/README.md +281 -0
  142. universal_mcp/applications/mailchimp/__init__.py +1 -0
  143. universal_mcp/applications/mailchimp/app.py +10937 -0
  144. universal_mcp/applications/markitdown/README.md +12 -0
  145. universal_mcp/applications/markitdown/__init__.py +1 -0
  146. universal_mcp/applications/markitdown/app.py +63 -0
  147. universal_mcp/applications/miro/README.md +151 -0
  148. universal_mcp/applications/miro/__init__.py +1 -0
  149. universal_mcp/applications/miro/app.py +5429 -0
  150. universal_mcp/applications/ms-teams/README.md +42 -0
  151. universal_mcp/applications/ms-teams/__init__.py +1 -0
  152. universal_mcp/applications/ms-teams/app.py +1823 -0
  153. universal_mcp/applications/neon/README.md +74 -0
  154. universal_mcp/applications/neon/__init__.py +1 -0
  155. universal_mcp/applications/neon/app.py +2018 -0
  156. universal_mcp/applications/notion/README.md +30 -0
  157. universal_mcp/applications/notion/__init__.py +1 -0
  158. universal_mcp/applications/notion/app.py +527 -0
  159. universal_mcp/applications/openai/README.md +22 -0
  160. universal_mcp/applications/openai/__init__.py +1 -0
  161. universal_mcp/applications/openai/app.py +759 -0
  162. universal_mcp/applications/outlook/README.md +20 -0
  163. universal_mcp/applications/outlook/__init__.py +1 -0
  164. universal_mcp/applications/outlook/app.py +444 -0
  165. universal_mcp/applications/perplexity/README.md +12 -0
  166. universal_mcp/applications/perplexity/__init__.py +1 -0
  167. universal_mcp/applications/perplexity/app.py +65 -0
  168. universal_mcp/applications/pipedrive/README.md +284 -0
  169. universal_mcp/applications/pipedrive/__init__.py +1 -0
  170. universal_mcp/applications/pipedrive/app.py +12924 -0
  171. universal_mcp/applications/posthog/README.md +132 -0
  172. universal_mcp/applications/posthog/__init__.py +1 -0
  173. universal_mcp/applications/posthog/app.py +7125 -0
  174. universal_mcp/applications/reddit/README.md +135 -0
  175. universal_mcp/applications/reddit/__init__.py +1 -0
  176. universal_mcp/applications/reddit/app.py +4652 -0
  177. universal_mcp/applications/replicate/README.md +18 -0
  178. universal_mcp/applications/replicate/__init__.py +1 -0
  179. universal_mcp/applications/replicate/app.py +495 -0
  180. universal_mcp/applications/resend/README.md +40 -0
  181. universal_mcp/applications/resend/__init__.py +1 -0
  182. universal_mcp/applications/resend/app.py +881 -0
  183. universal_mcp/applications/retell/README.md +21 -0
  184. universal_mcp/applications/retell/__init__.py +1 -0
  185. universal_mcp/applications/retell/app.py +333 -0
  186. universal_mcp/applications/rocketlane/README.md +70 -0
  187. universal_mcp/applications/rocketlane/__init__.py +1 -0
  188. universal_mcp/applications/rocketlane/app.py +4346 -0
  189. universal_mcp/applications/semanticscholar/README.md +25 -0
  190. universal_mcp/applications/semanticscholar/__init__.py +1 -0
  191. universal_mcp/applications/semanticscholar/app.py +482 -0
  192. universal_mcp/applications/semrush/README.md +44 -0
  193. universal_mcp/applications/semrush/__init__.py +1 -0
  194. universal_mcp/applications/semrush/app.py +2081 -0
  195. universal_mcp/applications/sendgrid/README.md +362 -0
  196. universal_mcp/applications/sendgrid/__init__.py +1 -0
  197. universal_mcp/applications/sendgrid/app.py +9752 -0
  198. universal_mcp/applications/sentry/README.md +186 -0
  199. universal_mcp/applications/sentry/__init__.py +1 -0
  200. universal_mcp/applications/sentry/app.py +7471 -0
  201. universal_mcp/applications/serpapi/README.md +14 -0
  202. universal_mcp/applications/serpapi/__init__.py +1 -0
  203. universal_mcp/applications/serpapi/app.py +293 -0
  204. universal_mcp/applications/sharepoint/README.md +0 -0
  205. universal_mcp/applications/sharepoint/__init__.py +1 -0
  206. universal_mcp/applications/sharepoint/app.py +215 -0
  207. universal_mcp/applications/shopify/README.md +321 -0
  208. universal_mcp/applications/shopify/__init__.py +1 -0
  209. universal_mcp/applications/shopify/app.py +15392 -0
  210. universal_mcp/applications/shortcut/README.md +128 -0
  211. universal_mcp/applications/shortcut/__init__.py +1 -0
  212. universal_mcp/applications/shortcut/app.py +4478 -0
  213. universal_mcp/applications/slack/README.md +0 -0
  214. universal_mcp/applications/slack/__init__.py +1 -0
  215. universal_mcp/applications/slack/app.py +570 -0
  216. universal_mcp/applications/spotify/README.md +91 -0
  217. universal_mcp/applications/spotify/__init__.py +1 -0
  218. universal_mcp/applications/spotify/app.py +2526 -0
  219. universal_mcp/applications/supabase/README.md +87 -0
  220. universal_mcp/applications/supabase/__init__.py +1 -0
  221. universal_mcp/applications/supabase/app.py +2970 -0
  222. universal_mcp/applications/tavily/README.md +12 -0
  223. universal_mcp/applications/tavily/__init__.py +1 -0
  224. universal_mcp/applications/tavily/app.py +51 -0
  225. universal_mcp/applications/trello/README.md +266 -0
  226. universal_mcp/applications/trello/__init__.py +1 -0
  227. universal_mcp/applications/trello/app.py +10875 -0
  228. universal_mcp/applications/twillo/README.md +0 -0
  229. universal_mcp/applications/twillo/__init__.py +1 -0
  230. universal_mcp/applications/twillo/app.py +269 -0
  231. universal_mcp/applications/twitter/README.md +100 -0
  232. universal_mcp/applications/twitter/__init__.py +1 -0
  233. universal_mcp/applications/twitter/api_segments/__init__.py +0 -0
  234. universal_mcp/applications/twitter/api_segments/api_segment_base.py +51 -0
  235. universal_mcp/applications/twitter/api_segments/compliance_api.py +122 -0
  236. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +255 -0
  237. universal_mcp/applications/twitter/api_segments/dm_events_api.py +140 -0
  238. universal_mcp/applications/twitter/api_segments/likes_api.py +159 -0
  239. universal_mcp/applications/twitter/api_segments/lists_api.py +395 -0
  240. universal_mcp/applications/twitter/api_segments/openapi_json_api.py +34 -0
  241. universal_mcp/applications/twitter/api_segments/spaces_api.py +309 -0
  242. universal_mcp/applications/twitter/api_segments/trends_api.py +40 -0
  243. universal_mcp/applications/twitter/api_segments/tweets_api.py +1403 -0
  244. universal_mcp/applications/twitter/api_segments/usage_api.py +40 -0
  245. universal_mcp/applications/twitter/api_segments/users_api.py +1498 -0
  246. universal_mcp/applications/twitter/app.py +46 -0
  247. universal_mcp/applications/unipile/README.md +28 -0
  248. universal_mcp/applications/unipile/__init__.py +1 -0
  249. universal_mcp/applications/unipile/app.py +829 -0
  250. universal_mcp/applications/whatsapp/README.md +23 -0
  251. universal_mcp/applications/whatsapp/__init__.py +1 -0
  252. universal_mcp/applications/whatsapp/app.py +595 -0
  253. universal_mcp/applications/whatsapp-business/README.md +34 -0
  254. universal_mcp/applications/whatsapp-business/__init__.py +1 -0
  255. universal_mcp/applications/whatsapp-business/app.py +1065 -0
  256. universal_mcp/applications/wrike/README.md +46 -0
  257. universal_mcp/applications/wrike/__init__.py +1 -0
  258. universal_mcp/applications/wrike/app.py +1583 -0
  259. universal_mcp/applications/youtube/README.md +57 -0
  260. universal_mcp/applications/youtube/__init__.py +1 -0
  261. universal_mcp/applications/youtube/app.py +1696 -0
  262. universal_mcp/applications/zenquotes/README.md +12 -0
  263. universal_mcp/applications/zenquotes/__init__.py +1 -0
  264. universal_mcp/applications/zenquotes/app.py +31 -0
  265. universal_mcp_applications-0.1.1.dist-info/METADATA +172 -0
  266. universal_mcp_applications-0.1.1.dist-info/RECORD +268 -0
  267. universal_mcp_applications-0.1.1.dist-info/WHEEL +4 -0
  268. universal_mcp_applications-0.1.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,20 @@
1
+ # OutlookApp MCP Server
2
+
3
+ An MCP Server for the OutlookApp API.
4
+
5
+ ## 🛠️ Tool List
6
+
7
+ This is automatically generated from OpenAPI schema for the OutlookApp API.
8
+
9
+
10
+ | Tool | Description |
11
+ |------|-------------|
12
+ | `users_message_reply` | Replies to a specific message for a user using the POST method, accepting JSON content in the request body and returning status codes indicating success or error. |
13
+ | `user_send_mail` | Sends an email on behalf of the specified user, accepting the email details as JSON in the request body and returning a 204 No Content response on success. |
14
+ | `user_get_mail_folder` | Retrieves a specific mail folder for a specified user using optional query parameters to include hidden folders or select/expand properties. |
15
+ | `user_list_message` | Retrieves a list of messages for a user, allowing optional filtering and sorting of results based on parameters such as includeHiddenMessages, search, filter, top, skip, orderby, select, and expand. |
16
+ | `user_get_message` | Retrieves a specific message for a user, optionally including hidden messages, selecting specific fields, or expanding related data. |
17
+ | `user_delete_message` | Deletes a specific message for a given user using the DELETE method and optional If-Match header for conditional requests. |
18
+ | `user_message_list_attachment` | Retrieves attachments associated with a specified user's message, supporting filtering, pagination, and field selection via query parameters. |
19
+ | `get_user_id` | Retrieves the current user. |
20
+ | `get_from_url` | Makes a GET request to a full @odata.nextLink or @odata.deltaLink URL. |
@@ -0,0 +1 @@
1
+ from .app import OutlookApp
@@ -0,0 +1,444 @@
1
+ from typing import Any
2
+ from urllib.parse import parse_qs, urlparse
3
+
4
+ from universal_mcp.applications.application import APIApplication
5
+ from universal_mcp.integrations import Integration
6
+
7
+
8
+ class OutlookApp(APIApplication):
9
+ def __init__(self, integration: Integration = None, **kwargs) -> None:
10
+ super().__init__(name="outlook", integration=integration, **kwargs)
11
+ self.base_url = "https://graph.microsoft.com/v1.0"
12
+
13
+ def users_message_reply(
14
+ self,
15
+ message_id: str,
16
+ user_id: str | None = None,
17
+ comment: str | None = None,
18
+ message: dict[str, Any] | None = None,
19
+ ) -> Any:
20
+ """
21
+ Replies to a specific message for a user using the POST method, accepting JSON content in the request body and returning status codes indicating success or error.
22
+
23
+ Args:
24
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
25
+ message_id (string): message-id
26
+ comment (string): A comment to include in the reply. Example: 'Thank you for your email. Here is my reply.'.
27
+ message (object): A message object to specify additional properties for the reply, such as attachments. Example: {'subject': 'RE: Project Update', 'body': {'contentType': 'Text', 'content': 'Thank you for the update. Looking forward to the next steps.'}, 'toRecipients': [{'emailAddress': {'address': 'alice@contoso.com'}}], 'attachments': [{'@odata.type': '#microsoft.graph.fileAttachment', 'name': 'agenda.pdf', 'contentType': 'application/pdf', 'contentBytes': 'SGVsbG8gV29ybGQh'}]}.
28
+
29
+ Returns:
30
+ Any: Success
31
+
32
+ Raises:
33
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
34
+
35
+ Tags:
36
+ users.message, important
37
+ """
38
+ # If user_id is not provided, get it automatically
39
+ if user_id is None:
40
+ user_info = self.get_user_id()
41
+ user_id = user_info.get("userPrincipalName")
42
+ if not user_id:
43
+ raise ValueError(
44
+ "Could not retrieve user ID from get_user_id response."
45
+ )
46
+ if message_id is None:
47
+ raise ValueError("Missing required parameter 'message-id'.")
48
+ request_body_data = None
49
+ request_body_data = {
50
+ "comment": comment,
51
+ "message": message,
52
+ }
53
+ request_body_data = {
54
+ k: v for k, v in request_body_data.items() if v is not None
55
+ }
56
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}/reply"
57
+ query_params = {}
58
+ response = self._post(
59
+ url,
60
+ data=request_body_data,
61
+ params=query_params,
62
+ content_type="application/json",
63
+ )
64
+ return self._handle_response(response)
65
+
66
+ def user_send_mail(
67
+ self,
68
+ message: dict[str, Any],
69
+ user_id: str | None = None,
70
+ saveToSentItems: bool | None = None,
71
+ ) -> Any:
72
+ """
73
+ Sends an email on behalf of the specified user, accepting the email details as JSON in the request body and returning a 204 No Content response on success.
74
+
75
+ Args:
76
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
77
+ message (object): message Example: {'subject': 'Meet for lunch?', 'body': {'contentType': 'Text', 'content': 'The new cafeteria is open.'}, 'toRecipients': [{'emailAddress': {'address': 'frannis@contoso.com'}}], 'ccRecipients': [{'emailAddress': {'address': 'danas@contoso.com'}}], 'bccRecipients': [{'emailAddress': {'address': 'bccuser@contoso.com'}}], 'attachments': [{'@odata.type': '#microsoft.graph.fileAttachment', 'name': 'attachment.txt', 'contentType': 'text/plain', 'contentBytes': 'SGVsbG8gV29ybGQh'}]}.
78
+ saveToSentItems (boolean): saveToSentItems Example: 'False'.
79
+
80
+ Returns:
81
+ Any: Success
82
+
83
+ Raises:
84
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
85
+
86
+ Tags:
87
+ users.user.Actions, important
88
+ """
89
+ # If user_id is not provided, get it automatically
90
+ if user_id is None:
91
+ user_info = self.get_user_id()
92
+ user_id = user_info.get("userPrincipalName")
93
+ if not user_id:
94
+ raise ValueError(
95
+ "Could not retrieve user ID from get_user_id response."
96
+ )
97
+ request_body_data = None
98
+ request_body_data = {
99
+ "message": message,
100
+ "saveToSentItems": saveToSentItems,
101
+ }
102
+ request_body_data = {
103
+ k: v for k, v in request_body_data.items() if v is not None
104
+ }
105
+ url = f"{self.base_url}/users/{user_id}/sendMail"
106
+ query_params = {}
107
+ response = self._post(
108
+ url,
109
+ data=request_body_data,
110
+ params=query_params,
111
+ content_type="application/json",
112
+ )
113
+ return self._handle_response(response)
114
+
115
+ def user_get_mail_folder(
116
+ self,
117
+ mailFolder_id: str,
118
+ user_id: str | None = None,
119
+ includeHiddenFolders: str | None = None,
120
+ select: list[str] | None = None,
121
+ expand: list[str] | None = None,
122
+ ) -> Any:
123
+ """
124
+ Retrieves a specific mail folder for a specified user using optional query parameters to include hidden folders or select/expand properties.
125
+
126
+ Args:
127
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
128
+ mailFolder_id (string): mailFolder-id
129
+ includeHiddenFolders (string): Include Hidden Folders
130
+ select (array): Select properties to be returned
131
+ expand (array): Expand related entities
132
+
133
+ Returns:
134
+ Any: Retrieved navigation property
135
+
136
+ Raises:
137
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
138
+
139
+ Tags:
140
+ users.mailFolder, important
141
+ """
142
+ # If user_id is not provided, get it automatically
143
+ if user_id is None:
144
+ user_info = self.get_user_id()
145
+ user_id = user_info.get("userPrincipalName")
146
+ if not user_id:
147
+ raise ValueError(
148
+ "Could not retrieve user ID from get_user_id response."
149
+ )
150
+ if mailFolder_id is None:
151
+ raise ValueError("Missing required parameter 'mailFolder-id'.")
152
+ url = f"{self.base_url}/users/{user_id}/mailFolders/{mailFolder_id}"
153
+ query_params = {
154
+ k: v
155
+ for k, v in [
156
+ ("includeHiddenFolders", includeHiddenFolders),
157
+ ("$select", select),
158
+ ("$expand", expand),
159
+ ]
160
+ if v is not None
161
+ }
162
+ response = self._get(url, params=query_params)
163
+ return self._handle_response(response)
164
+
165
+ def user_list_message(
166
+ self,
167
+ user_id: str | None = None,
168
+ select: list[str] = ["bodyPreview"],
169
+ includeHiddenMessages: bool | None = None,
170
+ top: int | None = None,
171
+ skip: int | None = None,
172
+ search: str | None = None,
173
+ filter: str | None = None,
174
+ count: bool | None = None,
175
+ orderby: list[str] | None = None,
176
+ expand: list[str] | None = None,
177
+ ) -> dict[str, Any]:
178
+ """
179
+ Retrieves a list of messages for a user, allowing optional filtering and sorting of results based on parameters such as includeHiddenMessages, search, filter, top, skip, orderby, select, and expand.
180
+
181
+ Args:
182
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
183
+ select (list): Select properties to be returned. Defaults to ['bodyPreview'].
184
+ Example: [
185
+ 'id', 'categories', 'receivedDateTime', 'sentDateTime', 'hasAttachments', 'internetMessageId',
186
+ 'subject', 'body', 'bodyPreview', 'importance', 'parentFolderId', 'conversationId',
187
+ 'conversationIndex', 'isDeliveryReceiptRequested', 'isReadReceiptRequested', 'isRead', 'isDraft',
188
+ 'webLink', 'inferenceClassification', 'sender', 'from', 'toRecipients', 'ccRecipients',
189
+ 'bccRecipients', 'replyTo', 'flag', 'attachments', 'extensions', 'mentions', 'uniqueBody'
190
+ ]
191
+ includeHiddenMessages (boolean): Include Hidden Messages
192
+ top (integer): Specify the number of items to be included in the result Example: '50'.
193
+ skip (integer): Specify the number of items to skip in the result Example: '10'.
194
+ search (string): Search items by search phrases
195
+ filter (string): Filter items by property values
196
+ count (boolean): Include count of items
197
+ orderby (array): Order items by property values
198
+ expand (array): Expand related entities
199
+
200
+ Returns:
201
+ dict[str, Any]: Retrieved collection
202
+
203
+ Raises:
204
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
205
+
206
+ Tags:
207
+ users.message, important
208
+ """
209
+ # If user_id is not provided, get it automatically
210
+ if user_id is None:
211
+ user_info = self.get_user_id()
212
+ user_id = user_info.get("userPrincipalName")
213
+ if not user_id:
214
+ raise ValueError(
215
+ "Could not retrieve user ID from get_user_id response."
216
+ )
217
+
218
+ url = f"{self.base_url}/users/{user_id}/messages"
219
+
220
+ # Handle list parameters by joining with commas
221
+ select_str = ",".join(select) if select else None
222
+ orderby_str = ",".join(orderby) if orderby else None
223
+ expand_str = ",".join(expand) if expand else None
224
+
225
+ query_params = {
226
+ k: v
227
+ for k, v in [
228
+ ("includeHiddenMessages", includeHiddenMessages),
229
+ ("$top", top),
230
+ ("$skip", skip),
231
+ ("$search", search),
232
+ ("$filter", filter),
233
+ ("$count", count),
234
+ ("$orderby", orderby_str),
235
+ ("$select", select_str),
236
+ ("$expand", expand_str),
237
+ ]
238
+ if v is not None
239
+ }
240
+
241
+ response = self._get(url, params=query_params)
242
+ return self._handle_response(response)
243
+
244
+ def user_get_message(
245
+ self,
246
+ message_id: str,
247
+ user_id: str | None = None,
248
+ includeHiddenMessages: str | None = None,
249
+ select: list[str] | None = None,
250
+ expand: list[str] | None = None,
251
+ ) -> Any:
252
+ """
253
+ Retrieves a specific message for a user, optionally including hidden messages, selecting specific fields, or expanding related data.
254
+
255
+ Args:
256
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
257
+ message_id (string): message-id
258
+ includeHiddenMessages (string): Include Hidden Messages
259
+ select (array): Select properties to be returned
260
+ expand (array): Expand related entities
261
+
262
+ Returns:
263
+ Any: Retrieved navigation property
264
+
265
+ Raises:
266
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
267
+
268
+ Tags:
269
+ users.message, important
270
+ """
271
+ # If user_id is not provided, get it automatically
272
+ if user_id is None:
273
+ user_info = self.get_user_id()
274
+ user_id = user_info.get("userPrincipalName")
275
+ if not user_id:
276
+ raise ValueError(
277
+ "Could not retrieve user ID from get_user_id response."
278
+ )
279
+ if message_id is None:
280
+ raise ValueError("Missing required parameter 'message-id'.")
281
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}"
282
+ query_params = {
283
+ k: v
284
+ for k, v in [
285
+ ("includeHiddenMessages", includeHiddenMessages),
286
+ ("$select", select),
287
+ ("$expand", expand),
288
+ ]
289
+ if v is not None
290
+ }
291
+ response = self._get(url, params=query_params)
292
+ return self._handle_response(response)
293
+
294
+ def user_delete_message(
295
+ self, message_id: str, user_id: str | None = None
296
+ ) -> Any:
297
+ """
298
+ Deletes a specific message for a given user using the DELETE method and optional If-Match header for conditional requests.
299
+
300
+ Args:
301
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
302
+ message_id (string): message-id
303
+
304
+ Returns:
305
+ Any: Success
306
+
307
+ Raises:
308
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
309
+
310
+ Tags:
311
+ users.message, important
312
+ """
313
+ # If user_id is not provided, get it automatically
314
+ if user_id is None:
315
+ user_info = self.get_user_id()
316
+ user_id = user_info.get("userPrincipalName")
317
+ if not user_id:
318
+ raise ValueError(
319
+ "Could not retrieve user ID from get_user_id response."
320
+ )
321
+ if message_id is None:
322
+ raise ValueError("Missing required parameter 'message-id'.")
323
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}"
324
+ query_params = {}
325
+ response = self._delete(url, params=query_params)
326
+ return self._handle_response(response)
327
+
328
+ def user_message_list_attachment(
329
+ self,
330
+ message_id: str,
331
+ user_id: str | None = None,
332
+ top: int | None = None,
333
+ skip: int | None = None,
334
+ search: str | None = None,
335
+ filter: str | None = None,
336
+ count: bool | None = None,
337
+ orderby: list[str] | None = None,
338
+ select: list[str] | None = None,
339
+ expand: list[str] | None = None,
340
+ ) -> dict[str, Any]:
341
+ """
342
+ Retrieves attachments associated with a specified user's message, supporting filtering, pagination, and field selection via query parameters.
343
+
344
+ Args:
345
+ user_id (string, optional): user-id. If not provided, will automatically get the current user's ID.
346
+ message_id (string): message-id
347
+ top (integer): Show only the first n items Example: '50'.
348
+ skip (integer): Skip the first n items
349
+ search (string): Search items by search phrases
350
+ filter (string): Filter items by property values
351
+ count (boolean): Include count of items
352
+ orderby (array): Order items by property values
353
+ select (array): Select properties to be returned
354
+ expand (array): Expand related entities
355
+
356
+ Returns:
357
+ dict[str, Any]: Retrieved collection
358
+
359
+ Raises:
360
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
361
+
362
+ Tags:
363
+ users.message, important
364
+ """
365
+ # If user_id is not provided, get it automatically
366
+ if user_id is None:
367
+ user_info = self.get_user_id()
368
+ user_id = user_info.get("userPrincipalName")
369
+ if not user_id:
370
+ raise ValueError(
371
+ "Could not retrieve user ID from get_user_id response."
372
+ )
373
+ if message_id is None:
374
+ raise ValueError("Missing required parameter 'message-id'.")
375
+ url = f"{self.base_url}/users/{user_id}/messages/{message_id}/attachments"
376
+ query_params = {
377
+ k: v
378
+ for k, v in [
379
+ ("$top", top),
380
+ ("$skip", skip),
381
+ ("$search", search),
382
+ ("$filter", filter),
383
+ ("$count", count),
384
+ ("$orderby", orderby),
385
+ ("$select", select),
386
+ ("$expand", expand),
387
+ ]
388
+ if v is not None
389
+ }
390
+ response = self._get(url, params=query_params)
391
+ return self._handle_response(response)
392
+
393
+ def get_user_id(
394
+ self,
395
+ ) -> dict[str, Any]:
396
+ """
397
+ Retrieves the current user.
398
+
399
+
400
+ Returns:
401
+ dict[str, Any]: Current user information
402
+
403
+ Raises:
404
+ HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
405
+
406
+ Tags:
407
+ me, important
408
+ """
409
+ url = f"{self.base_url}/me"
410
+ query_params = {
411
+ "$select": "userPrincipalName",
412
+ }
413
+ response = self._get(url, params=query_params)
414
+ return self._handle_response(response)
415
+
416
+ def get_from_url(self, url: str) -> dict[str, Any]:
417
+ """
418
+ Makes a GET request to a full @odata.nextLink or @odata.deltaLink URL.
419
+ """
420
+ if not url:
421
+ raise ValueError("Missing required parameter 'url'.")
422
+ if not url.startswith(self.base_url):
423
+ raise ValueError(
424
+ f"The provided URL '{url}' does not start with the expected base URL '{self.base_url}'."
425
+ )
426
+ relative_part = url[len(self.base_url) :]
427
+ parsed_relative = urlparse(relative_part)
428
+ path_only = parsed_relative.path
429
+ params = {k: v[0] for k, v in parse_qs(parsed_relative.query).items()}
430
+ response = self._get(path_only, params=params)
431
+ return self._handle_response(response)
432
+
433
+ def list_tools(self):
434
+ return [
435
+ self.users_message_reply,
436
+ self.user_send_mail,
437
+ self.user_get_mail_folder,
438
+ self.user_list_message,
439
+ self.user_get_message,
440
+ self.user_delete_message,
441
+ self.user_message_list_attachment,
442
+ self.get_user_id,
443
+ self.get_from_url,
444
+ ]
@@ -0,0 +1,12 @@
1
+ # Perplexity MCP Server
2
+
3
+ An MCP Server for the Perplexity API.
4
+
5
+ ## 🛠️ Tool List
6
+
7
+ This is automatically generated from OpenAPI schema for the Perplexity API.
8
+
9
+
10
+ | Tool | Description |
11
+ |------|-------------|
12
+ | `chat` | Initiates a chat completion request to generate AI responses using various models with customizable parameters. |
@@ -0,0 +1 @@
1
+ from .app import PerplexityApp
@@ -0,0 +1,65 @@
1
+ from typing import Any, Literal
2
+
3
+ from universal_mcp.applications.application import APIApplication
4
+ from universal_mcp.integrations import Integration
5
+
6
+
7
+ class PerplexityApp(APIApplication):
8
+ def __init__(self, integration: Integration | None = None) -> None:
9
+ super().__init__(name="perplexity", integration=integration)
10
+ self.base_url = "https://api.perplexity.ai"
11
+
12
+ def chat(
13
+ self,
14
+ query: str,
15
+ model: Literal[
16
+ "r1-1776",
17
+ "sonar",
18
+ "sonar-pro",
19
+ "sonar-reasoning",
20
+ "sonar-reasoning-pro",
21
+ "sonar-deep-research",
22
+ ] = "sonar",
23
+ temperature: float = 1,
24
+ system_prompt: str = "Be precise and concise.",
25
+ ) -> dict[str, Any] | str:
26
+ """
27
+ Initiates a chat completion request to generate AI responses using various models with customizable parameters.
28
+
29
+ Args:
30
+ query: The input text/prompt to send to the chat model
31
+ model: The model to use for chat completion. Options include 'r1-1776', 'sonar', 'sonar-pro', 'sonar-reasoning', 'sonar-reasoning-pro', 'sonar-deep-research'. Defaults to 'sonar'
32
+ temperature: Controls randomness in the model's output. Higher values make output more random, lower values more deterministic. Defaults to 1
33
+ system_prompt: Initial system message to guide the model's behavior. Defaults to 'Be precise and concise.'
34
+
35
+ Returns:
36
+ A dictionary containing the generated content and citations, with keys 'content' (str) and 'citations' (list), or a string in some cases
37
+
38
+ Raises:
39
+ AuthenticationError: Raised when API authentication fails due to missing or invalid credentials
40
+ HTTPError: Raised when the API request fails or returns an error status
41
+
42
+ Tags:
43
+ chat, generate, ai, completion, important
44
+ """
45
+ endpoint = f"{self.base_url}/chat/completions"
46
+ messages = []
47
+ if system_prompt:
48
+ messages.append({"role": "system", "content": system_prompt})
49
+ messages.append({"role": "user", "content": query})
50
+ payload = {
51
+ "model": model,
52
+ "messages": messages,
53
+ "temperature": temperature,
54
+ # "max_tokens": 512,
55
+ }
56
+ data = self._post(endpoint, data=payload)
57
+ response = data.json()
58
+ content = response["choices"][0]["message"]["content"]
59
+ citations = response.get("citations", [])
60
+ return {"content": content, "citations": citations}
61
+
62
+ def list_tools(self):
63
+ return [
64
+ self.chat,
65
+ ]