Skip to main content
Glama
tonderflash

Movie Search MCP Server

by tonderflash

search_movies

Search for movies by title and optional year using the MCP server, retrieving detailed information to streamline your film discovery process.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
titleYesMovie title to search for
yearNoMovie year (optional)

Implementation Reference

  • src/index.ts:23-82 (registration)
    Full registration of the 'search_movies' MCP tool, including input schema, handler logic that formats search results into a markdown-like text response, and error handling.
    server.tool( "search_movies", { title: z.string().describe("Movie title to search for"), year: z.string().optional().describe("Movie year (optional)"), }, async ({ title, year }) => { try { const results = await searchMovies(title, year); if (results.length === 0) { return { content: [ { type: "text", text: `No movies found with title "${title}"${ year ? ` from year ${year}` : "" }.`, }, ], }; } let response = `🎬 **Found ${results.length} movies for "${title}":**\n\n`; results.forEach((movie, index) => { response += `${index + 1}. **${movie.title}** (${movie.year})\n`; response += ` - ID: ${movie.id}\n`; response += ` - Source: ${movie.source.toUpperCase()}\n`; if (movie.poster !== "N/A") { response += ` - Poster: ${movie.poster}\n`; } response += "\n"; }); response += '\n💡 *Use "get_movie_details" with the ID for more information.*'; return { content: [ { type: "text", text: response, }, ], }; } catch (error) { return { content: [ { type: "text", text: `❌ Error searching movies: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], }; } } );
  • The handler function executing the core tool logic: calls the searchMovies helper, processes results, formats a rich text response with movie list, or handles empty/error cases.
    async ({ title, year }) => { try { const results = await searchMovies(title, year); if (results.length === 0) { return { content: [ { type: "text", text: `No movies found with title "${title}"${ year ? ` from year ${year}` : "" }.`, }, ], }; } let response = `🎬 **Found ${results.length} movies for "${title}":**\n\n`; results.forEach((movie, index) => { response += `${index + 1}. **${movie.title}** (${movie.year})\n`; response += ` - ID: ${movie.id}\n`; response += ` - Source: ${movie.source.toUpperCase()}\n`; if (movie.poster !== "N/A") { response += ` - Poster: ${movie.poster}\n`; } response += "\n"; }); response += '\n💡 *Use "get_movie_details" with the ID for more information.*'; return { content: [ { type: "text", text: response, }, ], }; } catch (error) { return { content: [ { type: "text", text: `❌ Error searching movies: ${ error instanceof Error ? error.message : "Unknown error" }`, }, ], }; } }
  • Zod input schema defining parameters for the search_movies tool.
    { title: z.string().describe("Movie title to search for"), year: z.string().optional().describe("Movie year (optional)"), },
  • Core helper function that performs parallel searches on OMDb and TMDb APIs, combines results, deduplicates by title (case-insensitive), and limits to 20 unique movies.
    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 }
  • Helper for searching movies specifically using 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 []; } }
  • Helper for searching movies specifically using 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 []; } }

Other Tools

Related Tools

Latest Blog Posts

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