arcticaurora commited on
Commit
4b6713b
·
verified ·
1 Parent(s): ff7963e

Update tools/trakt.py

Browse files
Files changed (1) hide show
  1. tools/trakt.py +134 -23
tools/trakt.py CHANGED
@@ -7,9 +7,36 @@ mcp = FastMCP("Trakt")
7
 
8
  @mcp.tool()
9
  def get_trending_movies(limit: int = 10) -> Dict:
10
- """Get trending movies from Trakt"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  if limit < 1 or limit > 50:
12
- limit = 10
13
 
14
  try:
15
  url = "https://api.trakt.tv/movies/trending"
@@ -17,6 +44,12 @@ def get_trending_movies(limit: int = 10) -> Dict:
17
  "Content-Type": "application/json",
18
  "trakt-api-version": "2"
19
  }
 
 
 
 
 
 
20
  params = {"limit": limit}
21
 
22
  response = requests.get(url, headers=headers, params=params, timeout=10)
@@ -27,9 +60,9 @@ def get_trending_movies(limit: int = 10) -> Dict:
27
  for item in data:
28
  movie = item.get("movie", {})
29
  movies.append({
30
- "title": movie.get("title", "Unknown"),
31
- "year": movie.get("year", "Unknown"),
32
- "rating": movie.get("rating", 0),
33
  "votes": movie.get("votes", 0),
34
  "watchers": item.get("watchers", 0)
35
  })
@@ -42,14 +75,41 @@ def get_trending_movies(limit: int = 10) -> Dict:
42
  except requests.exceptions.RequestException as e:
43
  return {
44
  "status": "error",
45
- "error": f"Failed to fetch trending movies: {str(e)}"
 
46
  }
47
 
48
  @mcp.tool()
49
  def get_popular_shows(limit: int = 10) -> Dict:
50
- """Get popular TV shows from Trakt"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  if limit < 1 or limit > 50:
52
- limit = 10
53
 
54
  try:
55
  url = "https://api.trakt.tv/shows/popular"
@@ -57,6 +117,12 @@ def get_popular_shows(limit: int = 10) -> Dict:
57
  "Content-Type": "application/json",
58
  "trakt-api-version": "2"
59
  }
 
 
 
 
 
 
60
  params = {"limit": limit}
61
 
62
  response = requests.get(url, headers=headers, params=params, timeout=10)
@@ -66,11 +132,11 @@ def get_popular_shows(limit: int = 10) -> Dict:
66
  shows = []
67
  for show in data:
68
  shows.append({
69
- "title": show.get("title", "Unknown"),
70
- "year": show.get("year", "Unknown"),
71
- "rating": show.get("rating", 0),
72
  "votes": show.get("votes", 0),
73
- "network": show.get("network", "Unknown")
74
  })
75
 
76
  return {
@@ -81,20 +147,52 @@ def get_popular_shows(limit: int = 10) -> Dict:
81
  except requests.exceptions.RequestException as e:
82
  return {
83
  "status": "error",
84
- "error": f"Failed to fetch popular shows: {str(e)}"
 
85
  }
86
 
87
  @mcp.tool()
88
  def search_movies(query: str, limit: int = 5) -> Dict:
89
- """Search for movies on Trakt"""
90
- if not query.strip():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  return {
92
  "status": "error",
93
- "error": "Search query cannot be empty"
 
94
  }
95
 
96
  if limit < 1 or limit > 20:
97
- limit = 5
98
 
99
  try:
100
  url = "https://api.trakt.tv/search/movie"
@@ -102,6 +200,12 @@ def search_movies(query: str, limit: int = 5) -> Dict:
102
  "Content-Type": "application/json",
103
  "trakt-api-version": "2"
104
  }
 
 
 
 
 
 
105
  params = {
106
  "query": query.strip(),
107
  "limit": limit
@@ -114,23 +218,30 @@ def search_movies(query: str, limit: int = 5) -> Dict:
114
  movies = []
115
  for item in data:
116
  movie = item.get("movie", {})
 
 
 
 
 
117
  movies.append({
118
- "title": movie.get("title", "Unknown"),
119
- "year": movie.get("year", "Unknown"),
120
- "rating": movie.get("rating", 0),
121
- "overview": movie.get("overview", "No description available")[:200]
122
  })
123
 
124
  return {
125
  "status": "success",
126
- "query": query,
127
  "count": len(movies),
128
  "movies": movies
129
  }
130
  except requests.exceptions.RequestException as e:
131
  return {
132
  "status": "error",
133
- "error": f"Failed to search movies: {str(e)}"
 
 
134
  }
135
 
136
  if __name__ == "__main__":
 
7
 
8
  @mcp.tool()
9
  def get_trending_movies(limit: int = 10) -> Dict:
10
+ """Get currently trending movies from Trakt.tv.
11
+
12
+ Args:
13
+ limit (int, optional): Maximum number of trending movies to return.
14
+ Must be between 1-50. Defaults to 10.
15
+ Values outside range are clamped to 1-50.
16
+
17
+ Returns:
18
+ Dict: Trending movies information containing:
19
+ - status (str): "success" or "error"
20
+ - count (int): Number of movies returned
21
+ - movies (List[Dict]): List of trending movies, each containing:
22
+ - title (str): Movie title
23
+ - year (int): Release year
24
+ - rating (float): Trakt user rating (0-10 scale)
25
+ - votes (int): Number of user votes
26
+ - watchers (int): Number of people currently watching
27
+ - error (str, optional): Error message if status is "error"
28
+
29
+ Examples:
30
+ get_trending_movies() returns top 10 trending movies
31
+ get_trending_movies(5) returns top 5 trending movies
32
+ get_trending_movies(100) returns 50 movies (clamped to maximum)
33
+
34
+ Note:
35
+ Uses Trakt.tv public API. No API key required for basic trending data.
36
+ For enhanced features, set TRAKT_API_KEY environment variable.
37
+ """
38
  if limit < 1 or limit > 50:
39
+ limit = max(1, min(50, limit))
40
 
41
  try:
42
  url = "https://api.trakt.tv/movies/trending"
 
44
  "Content-Type": "application/json",
45
  "trakt-api-version": "2"
46
  }
47
+
48
+ # Add API key if available for enhanced data
49
+ api_key = os.getenv("TRAKT_API_KEY")
50
+ if api_key:
51
+ headers["trakt-api-key"] = api_key
52
+
53
  params = {"limit": limit}
54
 
55
  response = requests.get(url, headers=headers, params=params, timeout=10)
 
60
  for item in data:
61
  movie = item.get("movie", {})
62
  movies.append({
63
+ "title": movie.get("title", "Unknown Title"),
64
+ "year": movie.get("year", 0),
65
+ "rating": round(movie.get("rating", 0), 1),
66
  "votes": movie.get("votes", 0),
67
  "watchers": item.get("watchers", 0)
68
  })
 
75
  except requests.exceptions.RequestException as e:
76
  return {
77
  "status": "error",
78
+ "error": f"Failed to fetch trending movies: {str(e)}",
79
+ "message": "Check internet connection and try again"
80
  }
81
 
82
  @mcp.tool()
83
  def get_popular_shows(limit: int = 10) -> Dict:
84
+ """Get popular TV shows from Trakt.tv.
85
+
86
+ Args:
87
+ limit (int, optional): Maximum number of popular shows to return.
88
+ Must be between 1-50. Defaults to 10.
89
+ Values outside range are clamped to 1-50.
90
+
91
+ Returns:
92
+ Dict: Popular shows information containing:
93
+ - status (str): "success" or "error"
94
+ - count (int): Number of shows returned
95
+ - shows (List[Dict]): List of popular TV shows, each containing:
96
+ - title (str): Show title
97
+ - year (int): First air year
98
+ - rating (float): Trakt user rating (0-10 scale)
99
+ - votes (int): Number of user votes
100
+ - network (str): Original broadcast network
101
+ - error (str, optional): Error message if status is "error"
102
+
103
+ Examples:
104
+ get_popular_shows() returns top 10 popular shows
105
+ get_popular_shows(15) returns top 15 popular shows
106
+ get_popular_shows(0) returns 1 show (clamped to minimum)
107
+
108
+ Note:
109
+ Uses Trakt.tv public API. Enhanced data available with TRAKT_API_KEY.
110
+ """
111
  if limit < 1 or limit > 50:
112
+ limit = max(1, min(50, limit))
113
 
114
  try:
115
  url = "https://api.trakt.tv/shows/popular"
 
117
  "Content-Type": "application/json",
118
  "trakt-api-version": "2"
119
  }
120
+
121
+ # Add API key if available
122
+ api_key = os.getenv("TRAKT_API_KEY")
123
+ if api_key:
124
+ headers["trakt-api-key"] = api_key
125
+
126
  params = {"limit": limit}
127
 
128
  response = requests.get(url, headers=headers, params=params, timeout=10)
 
132
  shows = []
133
  for show in data:
134
  shows.append({
135
+ "title": show.get("title", "Unknown Title"),
136
+ "year": show.get("year", 0),
137
+ "rating": round(show.get("rating", 0), 1),
138
  "votes": show.get("votes", 0),
139
+ "network": show.get("network", "Unknown Network")
140
  })
141
 
142
  return {
 
147
  except requests.exceptions.RequestException as e:
148
  return {
149
  "status": "error",
150
+ "error": f"Failed to fetch popular shows: {str(e)}",
151
+ "message": "Check internet connection and try again"
152
  }
153
 
154
  @mcp.tool()
155
  def search_movies(query: str, limit: int = 5) -> Dict:
156
+ """Search for movies by title on Trakt.tv.
157
+
158
+ Args:
159
+ query (str): Movie title or partial title to search for. Cannot be empty.
160
+ Examples: "Inception", "Star Wars", "Marvel", "Batman"
161
+ limit (int, optional): Maximum number of search results to return.
162
+ Must be between 1-20. Defaults to 5.
163
+ Values outside range are clamped to 1-20.
164
+
165
+ Returns:
166
+ Dict: Search results containing:
167
+ - status (str): "success" or "error"
168
+ - query (str): The search term that was used
169
+ - count (int): Number of movies found
170
+ - movies (List[Dict]): List of matching movies, each containing:
171
+ - title (str): Movie title
172
+ - year (int): Release year
173
+ - rating (float): Trakt user rating (0-10 scale)
174
+ - overview (str): Plot description (truncated to 200 characters)
175
+ - error (str, optional): Error message if status is "error"
176
+
177
+ Examples:
178
+ search_movies("Inception") finds movies matching "Inception"
179
+ search_movies("Star Wars", 3) finds 3 Star Wars related movies
180
+ search_movies("Marvel") finds Marvel movies with default limit of 5
181
+ search_movies("") returns error for empty query
182
+
183
+ Note:
184
+ Search is case-insensitive and matches partial titles.
185
+ Enhanced search results available with TRAKT_API_KEY.
186
+ """
187
+ if not query or not query.strip():
188
  return {
189
  "status": "error",
190
+ "error": "Search query cannot be empty",
191
+ "message": "Please provide a movie title or partial title to search for"
192
  }
193
 
194
  if limit < 1 or limit > 20:
195
+ limit = max(1, min(20, limit))
196
 
197
  try:
198
  url = "https://api.trakt.tv/search/movie"
 
200
  "Content-Type": "application/json",
201
  "trakt-api-version": "2"
202
  }
203
+
204
+ # Add API key if available
205
+ api_key = os.getenv("TRAKT_API_KEY")
206
+ if api_key:
207
+ headers["trakt-api-key"] = api_key
208
+
209
  params = {
210
  "query": query.strip(),
211
  "limit": limit
 
218
  movies = []
219
  for item in data:
220
  movie = item.get("movie", {})
221
+ overview = movie.get("overview", "No description available")
222
+ # Truncate overview to 200 characters
223
+ if len(overview) > 200:
224
+ overview = overview[:197] + "..."
225
+
226
  movies.append({
227
+ "title": movie.get("title", "Unknown Title"),
228
+ "year": movie.get("year", 0),
229
+ "rating": round(movie.get("rating", 0), 1),
230
+ "overview": overview
231
  })
232
 
233
  return {
234
  "status": "success",
235
+ "query": query.strip(),
236
  "count": len(movies),
237
  "movies": movies
238
  }
239
  except requests.exceptions.RequestException as e:
240
  return {
241
  "status": "error",
242
+ "query": query.strip(),
243
+ "error": f"Failed to search movies: {str(e)}",
244
+ "message": "Check internet connection and try again"
245
  }
246
 
247
  if __name__ == "__main__":