universal-mcp-applications 0.1.21__py3-none-any.whl → 0.1.23__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.

Files changed (78) hide show
  1. universal_mcp/applications/BEST_PRACTICES.md +166 -0
  2. universal_mcp/applications/airtable/app.py +0 -1
  3. universal_mcp/applications/apollo/app.py +0 -1
  4. universal_mcp/applications/aws_s3/app.py +40 -39
  5. universal_mcp/applications/browser_use/README.md +1 -0
  6. universal_mcp/applications/browser_use/__init__.py +0 -0
  7. universal_mcp/applications/browser_use/app.py +71 -0
  8. universal_mcp/applications/calendly/app.py +125 -125
  9. universal_mcp/applications/canva/app.py +95 -99
  10. universal_mcp/applications/confluence/app.py +0 -1
  11. universal_mcp/applications/contentful/app.py +4 -5
  12. universal_mcp/applications/domain_checker/app.py +11 -15
  13. universal_mcp/applications/e2b/app.py +4 -4
  14. universal_mcp/applications/elevenlabs/app.py +18 -15
  15. universal_mcp/applications/exa/app.py +17 -17
  16. universal_mcp/applications/falai/app.py +28 -29
  17. universal_mcp/applications/file_system/app.py +9 -9
  18. universal_mcp/applications/firecrawl/app.py +36 -36
  19. universal_mcp/applications/fireflies/app.py +55 -56
  20. universal_mcp/applications/fpl/app.py +49 -50
  21. universal_mcp/applications/ghost_content/app.py +0 -1
  22. universal_mcp/applications/github/app.py +41 -43
  23. universal_mcp/applications/google_calendar/app.py +40 -39
  24. universal_mcp/applications/google_docs/app.py +168 -232
  25. universal_mcp/applications/google_drive/app.py +212 -215
  26. universal_mcp/applications/google_gemini/app.py +1 -5
  27. universal_mcp/applications/google_mail/app.py +91 -90
  28. universal_mcp/applications/google_searchconsole/app.py +29 -29
  29. universal_mcp/applications/google_sheet/app.py +115 -115
  30. universal_mcp/applications/hashnode/README.md +6 -3
  31. universal_mcp/applications/hashnode/app.py +174 -25
  32. universal_mcp/applications/http_tools/app.py +10 -11
  33. universal_mcp/applications/hubspot/__init__.py +1 -1
  34. universal_mcp/applications/hubspot/api_segments/api_segment_base.py +36 -7
  35. universal_mcp/applications/hubspot/api_segments/crm_api.py +368 -368
  36. universal_mcp/applications/hubspot/api_segments/marketing_api.py +115 -115
  37. universal_mcp/applications/hubspot/app.py +131 -72
  38. universal_mcp/applications/jira/app.py +0 -1
  39. universal_mcp/applications/linkedin/app.py +20 -20
  40. universal_mcp/applications/markitdown/app.py +10 -5
  41. universal_mcp/applications/ms_teams/app.py +123 -123
  42. universal_mcp/applications/openai/app.py +40 -39
  43. universal_mcp/applications/outlook/app.py +32 -32
  44. universal_mcp/applications/perplexity/app.py +4 -4
  45. universal_mcp/applications/reddit/app.py +69 -70
  46. universal_mcp/applications/resend/app.py +116 -117
  47. universal_mcp/applications/rocketlane/app.py +0 -1
  48. universal_mcp/applications/scraper/__init__.py +1 -1
  49. universal_mcp/applications/scraper/app.py +80 -81
  50. universal_mcp/applications/serpapi/app.py +14 -14
  51. universal_mcp/applications/sharepoint/app.py +19 -20
  52. universal_mcp/applications/shopify/app.py +0 -1
  53. universal_mcp/applications/slack/app.py +48 -48
  54. universal_mcp/applications/tavily/app.py +4 -4
  55. universal_mcp/applications/twitter/api_segments/compliance_api.py +13 -15
  56. universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +20 -20
  57. universal_mcp/applications/twitter/api_segments/dm_events_api.py +12 -12
  58. universal_mcp/applications/twitter/api_segments/likes_api.py +12 -12
  59. universal_mcp/applications/twitter/api_segments/lists_api.py +37 -39
  60. universal_mcp/applications/twitter/api_segments/spaces_api.py +24 -24
  61. universal_mcp/applications/twitter/api_segments/trends_api.py +4 -4
  62. universal_mcp/applications/twitter/api_segments/tweets_api.py +105 -105
  63. universal_mcp/applications/twitter/api_segments/usage_api.py +4 -4
  64. universal_mcp/applications/twitter/api_segments/users_api.py +136 -136
  65. universal_mcp/applications/twitter/app.py +6 -2
  66. universal_mcp/applications/unipile/app.py +90 -97
  67. universal_mcp/applications/whatsapp/app.py +53 -54
  68. universal_mcp/applications/whatsapp/audio.py +39 -35
  69. universal_mcp/applications/whatsapp/whatsapp.py +176 -154
  70. universal_mcp/applications/whatsapp_business/app.py +92 -92
  71. universal_mcp/applications/yahoo_finance/app.py +105 -63
  72. universal_mcp/applications/youtube/app.py +193 -196
  73. universal_mcp/applications/zenquotes/__init__.py +2 -0
  74. universal_mcp/applications/zenquotes/app.py +5 -5
  75. {universal_mcp_applications-0.1.21.dist-info → universal_mcp_applications-0.1.23.dist-info}/METADATA +2 -1
  76. {universal_mcp_applications-0.1.21.dist-info → universal_mcp_applications-0.1.23.dist-info}/RECORD +78 -74
  77. {universal_mcp_applications-0.1.21.dist-info → universal_mcp_applications-0.1.23.dist-info}/WHEEL +0 -0
  78. {universal_mcp_applications-0.1.21.dist-info → universal_mcp_applications-0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,6 @@
1
- import yfinance as yf
2
1
  from typing import Any
2
+
3
+ import yfinance as yf
3
4
  from universal_mcp.applications.application import APIApplication
4
5
  from universal_mcp.integrations import Integration
5
6
 
@@ -16,31 +17,31 @@ class YahooFinanceApp(APIApplication):
16
17
  def get_stock_info(self, symbol: str) -> dict[str, Any]:
17
18
  """
18
19
  Gets real-time stock information including current price, market cap, financial ratios, and company details.
19
-
20
+
20
21
  Args:
21
22
  symbol: Stock ticker symbol (e.g., 'AAPL', 'GOOGL', 'MSFT')
22
-
23
+
23
24
  Returns:
24
25
  Complete dictionary with all available stock data fields from Yahoo Finance
25
-
26
+
26
27
  Raises:
27
28
  ValueError: Invalid or empty symbol
28
29
  KeyError: Stock symbol not found
29
30
  ConnectionError: Network or API issues
30
-
31
+
31
32
  Tags:
32
33
  stock, info, real-time, price, financials, company-data, important
33
34
  """
34
35
  if not symbol:
35
36
  raise ValueError("Stock symbol cannot be empty")
36
-
37
+
37
38
  symbol = symbol.upper().strip()
38
39
  ticker = yf.Ticker(symbol)
39
-
40
+
40
41
  info = ticker.info
41
- if not info or info.get('regularMarketPrice') is None:
42
+ if not info or info.get("regularMarketPrice") is None:
42
43
  raise KeyError(f"Stock symbol '{symbol}' not found or invalid")
43
-
44
+
44
45
  return info
45
46
 
46
47
  def get_stock_history(
@@ -49,75 +50,94 @@ class YahooFinanceApp(APIApplication):
49
50
  period: str = "1mo",
50
51
  interval: str = "1d",
51
52
  start_date: str | None = None,
52
- end_date: str | None = None
53
- )-> Any:
53
+ end_date: str | None = None,
54
+ ) -> dict:
54
55
  """
55
56
  Gets historical price data for a stock with OHLCV data, dividends, and stock splits.
56
-
57
+
57
58
  Args:
58
59
  symbol: Stock ticker symbol (e.g., 'AAPL', 'GOOGL', 'MSFT')
59
60
  period: Time period ('1d', '5d', '1mo', '3mo', '6mo', '1y', '2y', '5y', '10y', 'ytd', 'max')
60
61
  interval: Data interval ('1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1wk', '1mo', '3mo')
61
62
  start_date: Start date in 'YYYY-MM-DD' format (overrides period)
62
63
  end_date: End date in 'YYYY-MM-DD' format (used with start_date)
63
-
64
+
64
65
  Returns:
65
- Complete DataFrame with Open, High, Low, Close, Volume, Dividends, Stock Splits columns
66
-
66
+ Dictionary with historical stock data, dates as string keys
67
+
67
68
  Tags:
68
69
  stock, history, ohlcv, price-data, time-series, important
69
70
  """
70
71
  if not symbol:
71
72
  raise ValueError("Stock symbol cannot be empty")
72
-
73
+
73
74
  symbol = symbol.upper().strip()
74
75
  ticker = yf.Ticker(symbol)
76
+
77
+ df = ticker.history(
78
+ period=period, interval=interval, start=start_date, end=end_date
79
+ )
75
80
 
76
- return ticker.history(period=period, interval=interval, start=start_date, end=end_date)
81
+ try:
82
+ data = df.to_dict("index") # type: ignore
83
+ if data:
84
+ converted_data = {}
85
+ for key, value in data.items():
86
+ if hasattr(key, 'strftime'):
87
+ converted_key = key.strftime('%Y-%m-%d')
88
+ else:
89
+ converted_key = str(key)
90
+ converted_data[converted_key] = value
91
+ return converted_data
92
+ return data
93
+ except:
94
+ return {}
77
95
 
78
- def get_stock_news(self, symbol: str, limit: int = 10)-> list[Any]:
96
+ def get_stock_news(self, symbol: str, limit: int = 10) -> list[Any]:
79
97
  """
80
98
  Gets latest news articles for a stock from Yahoo Finance.
81
-
99
+
82
100
  Args:
83
101
  symbol: Stock ticker symbol (e.g., 'AAPL', 'GOOGL', 'MSFT')
84
102
  limit: Maximum number of articles to return (1-50). Defaults to 10
85
-
103
+
86
104
  Returns:
87
105
  Raw list of news articles from Yahoo Finance
88
-
106
+
89
107
  Tags:
90
108
  stock, news, articles, sentiment, important
91
109
  """
92
110
  if not symbol:
93
111
  raise ValueError("Stock symbol cannot be empty")
94
-
112
+
95
113
  symbol = symbol.upper().strip()
96
114
  ticker = yf.Ticker(symbol)
97
-
115
+
98
116
  news = ticker.news
99
117
  return news[:limit] if news else []
100
118
 
101
- def get_financial_statements(self, symbol: str, statement_type: str = "income") -> dict:
119
+ def get_financial_statements(
120
+ self, symbol: str, statement_type: str = "income"
121
+ ) -> dict:
102
122
  """
103
123
  Gets financial statements for a stock from Yahoo Finance.
104
-
124
+
105
125
  Args:
106
126
  symbol: Stock ticker symbol (e.g., 'AAPL', 'GOOGL', 'MSFT')
107
127
  statement_type: Type of statement ('income', 'balance', 'cashflow', 'earnings'). Defaults to 'income'
108
-
128
+
109
129
  Returns:
110
130
  Dictionary with financial statement data
111
-
131
+
112
132
  Tags:
113
133
  stock, financial-statements, earnings, important
114
134
  """
115
135
  if not symbol:
116
136
  raise ValueError("Stock symbol cannot be empty")
117
-
137
+
118
138
  symbol = symbol.upper().strip()
119
139
  ticker = yf.Ticker(symbol)
120
-
140
+
121
141
  if statement_type == "income":
122
142
  df = ticker.income_stmt
123
143
  elif statement_type == "balance":
@@ -128,96 +148,121 @@ class YahooFinanceApp(APIApplication):
128
148
  df = ticker.earnings
129
149
  else:
130
150
  df = ticker.income_stmt
131
-
151
+
132
152
  try:
133
- return df.to_dict('dict') # type: ignore
153
+ data = df.to_dict("dict") # type: ignore
154
+ if data:
155
+ converted_data = {}
156
+ for key, value in data.items():
157
+ if hasattr(key, 'strftime'):
158
+ converted_key = key.strftime('%Y-%m-%d')
159
+ else:
160
+ converted_key = str(key)
161
+ converted_data[converted_key] = value
162
+ return converted_data
163
+ return data
134
164
  except:
135
165
  return {}
136
166
 
137
- def get_stock_recommendations(self, symbol: str, rec_type: str = "recommendations") -> list[dict]:
167
+ def get_stock_recommendations(
168
+ self, symbol: str, rec_type: str = "recommendations"
169
+ ) -> list[dict]:
138
170
  """
139
171
  Gets analyst recommendations for a stock from Yahoo Finance.
140
-
172
+
141
173
  Args:
142
174
  symbol: Stock ticker symbol (e.g., 'AAPL', 'GOOGL', 'MSFT')
143
175
  rec_type: Type of recommendation data ('recommendations', 'upgrades_downgrades'). Defaults to 'recommendations'
144
-
176
+
145
177
  Returns:
146
178
  List of dictionaries with analyst recommendation data
147
-
179
+
148
180
  Tags:
149
181
  stock, recommendations, analyst-ratings, important
150
182
  """
151
183
  if not symbol:
152
184
  raise ValueError("Stock symbol cannot be empty")
153
-
185
+
154
186
  symbol = symbol.upper().strip()
155
187
  ticker = yf.Ticker(symbol)
156
-
188
+
157
189
  if rec_type == "upgrades_downgrades":
158
190
  df = ticker.upgrades_downgrades
159
191
  else:
160
192
  df = ticker.recommendations
161
-
193
+
162
194
  try:
163
- return df.to_dict('records') # type: ignore
195
+ return df.to_dict("records") # type: ignore
164
196
  except:
165
197
  return []
166
198
 
167
- def search(self, query: str, max_results: int = 10, news_count: int = 5, include_research: bool = False) -> dict[str, Any]:
199
+ def search(
200
+ self,
201
+ query: str,
202
+ max_results: int = 10,
203
+ news_count: int = 5,
204
+ include_research: bool = False,
205
+ ) -> dict[str, Any]:
168
206
  """
169
207
  Search Yahoo Finance for quotes, news, and research using yfinance Search.
170
-
208
+
171
209
  Args:
172
210
  query: Search query (company name, ticker symbol, or keyword)
173
211
  max_results: Maximum number of quote results to return. Defaults to 10
174
212
  news_count: Number of news articles to return. Defaults to 5
175
213
  include_research: Whether to include research data. Defaults to False
176
-
214
+
177
215
  Returns:
178
216
  Dictionary containing quotes, news, and optionally research data
179
-
217
+
180
218
  Tags:
181
219
  search, quotes, news, research, important
182
220
  """
183
221
  if not query:
184
222
  raise ValueError("Search query cannot be empty")
185
-
186
- search = yf.Search(query, max_results=max_results, news_count=news_count, include_research=include_research)
187
-
223
+
224
+ search = yf.Search(
225
+ query,
226
+ max_results=max_results,
227
+ news_count=news_count,
228
+ include_research=include_research,
229
+ )
230
+
188
231
  result = {}
189
232
  for attr in dir(search):
190
- if not attr.startswith('_'):
233
+ if not attr.startswith("_"):
191
234
  try:
192
235
  value = getattr(search, attr)
193
- if not callable(value):
236
+ if not callable(value):
194
237
  result[attr] = value
195
238
  except:
196
239
  continue
197
-
240
+
198
241
  return result
199
242
 
200
- def lookup_ticker(self, query: str, lookup_type: str = "all", count: int = 25) -> list[dict]:
243
+ def lookup_ticker(
244
+ self, query: str, lookup_type: str = "all", count: int = 25
245
+ ) -> list[dict]:
201
246
  """
202
247
  Look up ticker symbols by type using yfinance Lookup.
203
-
248
+
204
249
  Args:
205
250
  query: Search query for ticker lookup
206
251
  lookup_type: Type of lookup ('all', 'stock', 'mutualfund', 'etf', 'index', 'future', 'currency', 'cryptocurrency'). Defaults to 'all'
207
252
  count: Maximum number of results to return. Defaults to 25
208
-
253
+
209
254
  Returns:
210
255
  List of dictionaries with ticker lookup results
211
-
256
+
212
257
  Tags:
213
258
  lookup, ticker, symbols, important
214
259
  """
215
260
  if not query:
216
261
  raise ValueError("Lookup query cannot be empty")
217
-
262
+
218
263
  try:
219
264
  lookup = yf.Lookup(query)
220
-
265
+
221
266
  if lookup_type == "stock":
222
267
  results = lookup.get_stock(count=count)
223
268
  elif lookup_type == "mutualfund":
@@ -234,17 +279,14 @@ class YahooFinanceApp(APIApplication):
234
279
  results = lookup.get_cryptocurrency(count=count)
235
280
  else: # default to 'all'
236
281
  results = lookup.get_all(count=count)
237
-
282
+
238
283
  try:
239
- return results.to_dict('records') # type: ignore
284
+ return results.to_dict("records") # type: ignore
240
285
  except:
241
286
  return []
242
-
287
+
243
288
  except Exception as e:
244
- return [{
245
- "query": query,
246
- "error": f"Lookup failed: {str(e)}"
247
- }]
289
+ return [{"query": query, "error": f"Lookup failed: {str(e)}"}]
248
290
 
249
291
  def list_tools(self):
250
292
  return [
@@ -255,4 +297,4 @@ class YahooFinanceApp(APIApplication):
255
297
  self.get_stock_recommendations,
256
298
  self.search,
257
299
  self.lookup_ticker,
258
- ]
300
+ ]