Skip to main content
Glama

Movie Search MCP Server

by tonderflash
MIT License
3
movie-apis.ts8.47 kB
import fetch from "node-fetch"; import { OMDbMovie, OMDbSearchResult, TMDbMovie, TMDbSearchResult, TMDbMovieDetails, MovieInfo, SearchResult, } from "./types.js"; const OMDB_API_KEY = process.env.OMDB_API_KEY || "demo"; // Usar 'demo' para testing limitado const TMDB_API_KEY = process.env.TMDB_API_KEY || ""; const OMDB_BASE_URL = "http://www.omdbapi.com/"; const TMDB_BASE_URL = "https://api.themoviedb.org/3"; /** * Buscar películas usando OMDb API */ export async function searchMoviesOMDb( title: string, year?: string ): Promise<SearchResult[]> { try { const params = new URLSearchParams({ apikey: OMDB_API_KEY, s: title, type: "movie", }); if (year) { params.append("y", year); } const response = await fetch(`${OMDB_BASE_URL}?${params}`); const data = (await response.json()) as OMDbSearchResult; if (data.Response === "False") { return []; } return data.Search.map((movie) => ({ title: movie.Title, year: movie.Year, id: movie.imdbID, type: movie.Type, poster: movie.Poster, source: "omdb" as const, })); } catch (error) { console.error("Error searching movies in OMDb:", error); return []; } } /** * Obtener detalles de película usando OMDb API */ export async function getMovieDetailsOMDb( imdbId: string ): Promise<MovieInfo | null> { try { const params = new URLSearchParams({ apikey: OMDB_API_KEY, i: imdbId, plot: "full", }); const response = await fetch(`${OMDB_BASE_URL}?${params}`); const data = (await response.json()) as OMDbMovie; if (data.Response === "False") { return null; } return { title: data.Title, year: data.Year, director: data.Director, actors: data.Actors, plot: data.Plot, genre: data.Genre, rating: data.imdbRating, poster: data.Poster, imdbId: data.imdbID, runtime: data.Runtime, language: data.Language, country: data.Country, awards: data.Awards, boxOffice: data.BoxOffice, source: "omdb", }; } catch (error) { console.error("Error getting movie details from OMDb:", error); return null; } } /** * Buscar películas usando TMDb API */ export async function searchMoviesTMDb( title: string, year?: string ): Promise<SearchResult[]> { if (!TMDB_API_KEY) { return []; } try { const params = new URLSearchParams({ api_key: TMDB_API_KEY, query: title, language: "en-US", }); if (year) { params.append("year", year); } const response = await fetch(`${TMDB_BASE_URL}/search/movie?${params}`); const data = (await response.json()) as TMDbSearchResult; return data.results.slice(0, 10).map((movie) => ({ title: movie.title, year: movie.release_date ? movie.release_date.split("-")[0] : "", id: movie.id.toString(), type: "movie", poster: movie.poster_path ? `https://image.tmdb.org/t/p/w500${movie.poster_path}` : "N/A", source: "tmdb" as const, })); } catch (error) { console.error("Error searching movies in TMDb:", error); return []; } } /** * Obtener detalles de película usando TMDb API */ export async function getMovieDetailsTMDb( tmdbId: string ): Promise<MovieInfo | null> { if (!TMDB_API_KEY) { return null; } try { const params = new URLSearchParams({ api_key: TMDB_API_KEY, language: "en-US", append_to_response: "credits", }); const response = await fetch(`${TMDB_BASE_URL}/movie/${tmdbId}?${params}`); const data = (await response.json()) as TMDbMovieDetails & { credits?: any; }; const director = data.credits?.crew?.find((person: any) => person.job === "Director") ?.name || "N/A"; const actors = data.credits?.cast ?.slice(0, 5) .map((actor: any) => actor.name) .join(", ") || "N/A"; return { title: data.title, year: data.release_date ? data.release_date.split("-")[0] : "", director: director, actors: actors, plot: data.overview, genre: data.genres.map((g) => g.name).join(", "), rating: data.vote_average.toString(), poster: data.poster_path ? `https://image.tmdb.org/t/p/w500${data.poster_path}` : "N/A", imdbId: data.imdb_id, runtime: data.runtime ? `${data.runtime} min` : "N/A", language: data.original_language, country: data.production_countries.map((c) => c.name).join(", "), awards: "N/A", // TMDb no proporciona premios directamente boxOffice: data.revenue ? `$${data.revenue.toLocaleString()}` : "N/A", source: "tmdb", }; } catch (error) { console.error("Error getting movie details from TMDb:", error); return null; } } /** * Buscar películas en ambas APIs y combinar resultados */ export async function searchMovies( title: string, year?: string ): Promise<SearchResult[]> { const [omdbResults, tmdbResults] = await Promise.all([ searchMoviesOMDb(title, year), searchMoviesTMDb(title, year), ]); // Combinar resultados y eliminar duplicados por título const allResults = [...omdbResults, ...tmdbResults]; const uniqueResults = allResults.filter( (movie, index, self) => index === self.findIndex((m) => m.title.toLowerCase() === movie.title.toLowerCase()) ); return uniqueResults.slice(0, 20); // Limitar a 20 resultados } /** * Obtener detalles de película de cualquier API */ export async function getMovieDetails( id: string, source: "omdb" | "tmdb" = "omdb" ): Promise<MovieInfo | null> { if (source === "omdb") { return await getMovieDetailsOMDb(id); } else { return await getMovieDetailsTMDb(id); } } /** * Obtener recomendaciones de películas por género usando TMDb */ export async function getMovieRecommendations( genre?: string ): Promise<SearchResult[]> { if (!TMDB_API_KEY) { return []; } try { let endpoint = `${TMDB_BASE_URL}/movie/popular`; const params = new URLSearchParams({ api_key: TMDB_API_KEY, language: "en-US", page: "1", }); if (genre) { // Basic genre mapping const genreMap: { [key: string]: string } = { action: "28", adventure: "12", animation: "16", comedy: "35", crime: "80", documentary: "99", drama: "18", family: "10751", fantasy: "14", history: "36", horror: "27", music: "10402", mystery: "9648", romance: "10749", "science fiction": "878", "sci-fi": "878", thriller: "53", war: "10752", western: "37", }; const genreId = genreMap[genre.toLowerCase()]; if (genreId) { endpoint = `${TMDB_BASE_URL}/discover/movie`; params.append("with_genres", genreId); } } const response = await fetch(`${endpoint}?${params}`); const data = (await response.json()) as TMDbSearchResult; return data.results.slice(0, 10).map((movie) => ({ title: movie.title, year: movie.release_date ? movie.release_date.split("-")[0] : "", id: movie.id.toString(), type: "movie", poster: movie.poster_path ? `https://image.tmdb.org/t/p/w500${movie.poster_path}` : "N/A", source: "tmdb" as const, })); } catch (error) { console.error("Error getting movie recommendations:", error); return []; } } /** * Buscar películas populares/trending */ export async function getTrendingMovies(): Promise<SearchResult[]> { if (!TMDB_API_KEY) { return []; } try { const params = new URLSearchParams({ api_key: TMDB_API_KEY, language: "en-US", }); const response = await fetch( `${TMDB_BASE_URL}/trending/movie/week?${params}` ); const data = (await response.json()) as TMDbSearchResult; return data.results.slice(0, 15).map((movie) => ({ title: movie.title, year: movie.release_date ? movie.release_date.split("-")[0] : "", id: movie.id.toString(), type: "movie", poster: movie.poster_path ? `https://image.tmdb.org/t/p/w500${movie.poster_path}` : "N/A", source: "tmdb" as const, })); } catch (error) { console.error("Error getting trending movies:", error); return []; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tonderflash/movie-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server