MongoDB Movie Database FastMCP Tools

Un servidor para consultar y analizar la base de datos de películas sample_mflix de MongoDB.

Documentación

MongoDB Movie Database FastMCP Tools

Este proyecto proporciona un script de Python que expone un conjunto de herramientas potentes para consultar y analizar una base de datos de películas MongoDB (específicamente el conjunto de datos sample_mflix) utilizando la librería fastmcp. Estas herramientas están diseñadas para integrarse fácilmente con modelos de lenguaje grandes (LLMs), agentes de IA o cualquier otro sistema que requiera acceso estructurado y programático a datos de películas.

Tabla de Contenidos

Características

  • Búsqueda Integral de Películas: Encuentra películas por título, género, actores, directores, guionistas, año o varios umbrales de calificación.
  • Recuperación Flexible de Datos: Especifica campos a devolver (projection_fields) y controla la ordenación (sort_by, sort_order_asc).
  • Conteo de Películas: Cuenta rápidamente películas que coinciden con criterios específicos.
  • Cálculo de Calificación Promedio: Calcula calificaciones promedio de IMDb, Metacritic o Rotten Tomatoes para conjuntos de películas filtrados.
  • Amigable para LLMs: Diseñado con fastmcp para crear una API robusta y autodocumentada fácilmente consumible por LLMs. Incluye manejo especial para argumentos de lista convertidos a cadena, abordando formatos de salida comunes de LLMs.
  • Integración Robusta con MongoDB: Utiliza pymongo para operaciones de base de datos eficientes y confiables.

Requisitos Previos

Antes de ejecutar este proyecto, asegúrate de tener lo siguiente:

  • Python 3.7+: Descargar Python
  • Instancia de MongoDB: Una instancia de MongoDB en ejecución (local o alojada en la nube como MongoDB Atlas).
  • Conjunto de Datos sample_mflix: La base de datos sample_mflix y su colección movies deben estar cargadas en tu instancia de MongoDB.

Opcionalmente

  • Claude Desktop
{
  "mcpServers": {
    "Movie Database": {
      "command": "uv",
      "args": [
        "run",
        "--with",
        "fastmcp, pymongo",
        "fastmcp",
        "run",
        "<path to>/movie-mcp/movie-mcp.py",
        "<mongo connection string URI>"
      ]
    }
  }
}

Configuración de MongoDB

Esta aplicación se conecta a la base de datos sample_mflix y específicamente a la colección movies.

Si estás usando MongoDB Atlas:

  1. Inicia sesión en tu cuenta de MongoDB Atlas.
  2. Navega a tu clúster.
  3. Ve a la pestaña "..." (generalmente Data o Load Sample Data).
  4. Haz clic en "Load Sample Dataset" y selecciona sample_mflix. Esto importará automáticamente los datos necesarios.

Si estás usando una instancia local de MongoDB: Puedes descargar el conjunto de datos sample_mflix de los recursos oficiales de MongoDB (por ejemplo, como parte de los materiales del curso de MongoDB University o directamente de sus repositorios de datos de muestra) e importarlo usando mongoimport.

Instalación

  1. Clona el repositorio:
git clone https://github.com/patw/movie-mcp.git
cd movie-mcp
  1. Instala las dependencias:
pip install -r requirements.txt

Uso

El script espera la URI de conexión de MongoDB como argumento de línea de comandos.

  1. Ejecuta el script:
python movie_tools.py "mongodb://localhost:27017/"

O, si usas una cadena de conexión de MongoDB Atlas:

python movie_tools.py "mongodb+srv://user:pass@clusterdomain/?retryWrites=true&w=majority"

Reemplaza user, pass y clusterdomain con tus credenciales reales de MongoDB Atlas y los detalles del clúster.

  1. Servidor FastMCP: Una vez en ejecución, el script iniciará un servidor fastmcp. Este servidor expone las herramientas definidas (por ejemplo, find_movies, count_movies) a través de un endpoint HTTP local (por defecto http://127.0.0.1:8000/tools). Luego puedes interactuar con estas herramientas programáticamente, típicamente desde un agente LLM u otro script de Python.

Ejemplo de cómo un LLM u otro programa podría llamar a estas herramientas (conceptualmente):

# This is pseudo-code representing how an LLM agent might interact
# In a real scenario, you'd use a client library for fastmcp or direct HTTP requests.

# Example: Find movies by Bill Murray
tool_call = {
"tool_name": "find_movies",
"args": {
"actors": ["Bill Murray"],
"limit": 5,
"projection_fields": ["title", "year", "imdb.rating"]
}
}
# result = make_tool_call(tool_call)
# print(result)

# Example: Count romantic comedies from the 90s
tool_call = {
"tool_name": "count_movies",
"args": {
"genres": ["Comedy", "Romance"],
"start_year": 1990,
"end_year": 1999
}
}
# result = make_tool_call(tool_call)
# print(result)

Herramientas FastMCP

Esta sección detalla las funciones expuestas como herramientas por fastmcp.

find_movies

Encuentra películas basándose en una variedad de criterios, con opciones para ordenar y limitar resultados.

def find_movies(
title: Optional[str] = None,
genres: Optional[Union[List[str], str]] = None,
actors: Optional[Union[List[str], str]] = None,
directors: Optional[Union[List[str], str]] = None,
writers: Optional[Union[List[str], str]] = None,
year: Optional[int] = None,
start_year: Optional[int] = None,
end_year: Optional[int] = None,
min_imdb_rating: Optional[float] = None,
min_metacritic_rating: Optional[int] = None,
min_tomatoes_viewer_rating: Optional[float] = None,
min_tomatoes_critic_rating: Optional[float] = None,
rated_mpaa: Optional[str] = None,
sort_by: Optional[str] = "imdb.rating",
sort_order_asc: bool = False,
limit: int = 10,
projection_fields: Optional[List[str]] = None
) -> List[Dict[str, Any]]:

Argumentos:

  • title (str, opcional): Título de la película (coincidencia parcial sin distinción de mayúsculas/minúsculas).
  • genres (List[str] o str, opcional): Lista de géneros; la película debe coincidir con todos los géneros especificados. Si se pasa una sola cadena (por ejemplo, "Comedy"), se trata como una lista de uno.
  • actors (List[str] o str, opcional): Lista de nombres de actores; la película debe incluir a todos los actores especificados (coincidencia parcial sin distinción de mayúsculas/minúsculas para cada nombre dentro de la lista de reparto). Si se pasa una sola cadena, se trata como una lista de uno.
  • directors (List[str] o str, opcional): Lista de nombres de directores; la película debe estar dirigida por todos los directores especificados (coincidencia parcial sin distinción de mayúsculas/minúsculas para cada nombre). Si se pasa una sola cadena, se trata como una lista de uno.
  • writers (List[str] o str, opcional): Lista de nombres de guionistas; la película debe incluir a todos los guionistas especificados (coincidencia parcial sin distinción de mayúsculas/minúsculas para cada nombre). Si se pasa una sola cadena, se trata como una lista de uno.
  • year (int, opcional): Año de estreno exacto.
  • start_year (int, opcional): Inicio de un rango de años de estreno (inclusive).
  • end_year (int, opcional): Fin de un rango de años de estreno (inclusive).
  • min_imdb_rating (float, opcional): Calificación mínima de IMDb (por ejemplo, 7.5).
  • min_metacritic_rating (int, opcional): Puntuación mínima de Metacritic (por ejemplo, 70).
  • min_tomatoes_viewer_rating (float, opcional): Calificación mínima de espectadores de Rotten Tomatoes (por ejemplo, 3.5).
  • min_tomatoes_critic_rating (float, opcional): Calificación mínima de críticos de Rotten Tomatoes (por ejemplo, 7.0).
  • rated_mpaa (str, opcional): Clasificación MPAA (por ejemplo, "R", "PG-13"). Coincidencia exacta sin distinción de mayúsculas/minúsculas.
  • sort_by (str, opcional): Campo por el cual ordenar los resultados. Puede ser una ruta de MongoDB (por ejemplo, "imdb.rating", "year", "title") o una clave corta ("imdb", "metacritic", "tomatoes_viewer", "tomatoes_critic", "imdb_votes", "tomatoes_viewer_num_reviews", "tomatoes_critic_num_reviews"). El valor predeterminado es 'imdb.rating'.
  • sort_order_asc (bool, opcional): Orden de clasificación. False para descendente (predeterminado, por ejemplo, mejor calificadas primero), True para ascendente (por ejemplo, peor calificadas primero).
  • limit (int, opcional): Número máximo de resultados a devolver. El valor predeterminado es 10. Usa 0 para sin límite.
  • projection_fields (List[str], opcional): Campos específicos a devolver para cada película (por ejemplo, ["title", "year"]). El valor predeterminado es un conjunto estándar (title, year, plot, imdb.rating, genres).

Devuelve:

  • List[Dict[str, Any]]: Una lista de documentos de películas (o campos especificados). Devuelve una lista vacía si ninguna película coincide con los criterios o si ocurre un error.

count_movies

Cuenta películas basándose en los criterios especificados.

def count_movies(
title: Optional[str] = None,
genres: Optional[Union[List[str], str]] = None,
actors: Optional[Union[List[str], str]] = None,
directors: Optional[Union[List[str], str]] = None,
writers: Optional[Union[List[str], str]] = None,
year: Optional[int] = None,
start_year: Optional[int] = None,
end_year: Optional[int] = None,
min_imdb_rating: Optional[float] = None,
min_metacritic_rating: Optional[int] = None,
min_tomatoes_viewer_rating: Optional[float] = None,
min_tomatoes_critic_rating: Optional[float] = None,
rated_mpaa: Optional[str] = None
) -> int:

Argumentos: (Los mismos que los argumentos de filtrado para la herramienta find_movies)

Devuelve:

  • int: El número de películas que coinciden con los criterios. Devuelve 0 si ocurre un error.

get_average_rating

Calcula la calificación promedio para películas que coinciden con los criterios, para un tipo de calificación específico.

def get_average_rating(
rating_field_key: str,
genres: Optional[Union[List[str], str]] = None,
actors: Optional[Union[List[str], str]] = None,
directors: Optional[Union[List[str], str]] = None,
writers: Optional[Union[List[str], str]] = None,
year: Optional[int] = None,
start_year: Optional[int] = None,
end_year: Optional[int] = None
) -> Optional[Dict[str, Any]]:

Argumentos:

  • rating_field_key (str): La clave para la fuente de calificación (por ejemplo, "imdb", "metacritic", "tomatoes_viewer", "tomatoes_critic").
  • (Otros argumentos de filtrado son similares a los de find_movies/count_movies, excluyendo title, min_ratings y rated_mpaa ya que son menos comunes para cálculos de promedio amplios).

Devuelve:

  • Optional[Dict[str, Any]]: Un diccionario que contiene 'average_rating' (float, redondeado a 2 decimales) y 'movie_count' (int). Devuelve None si el rating_field_key es inválido, o un diccionario con None average_rating y 0 count si ninguna película coincide o si ocurre un error.

Contribuciones

¡Las contribuciones son bienvenidas! Si tienes sugerencias de mejoras, nuevas funciones o correcciones de errores, por favor abre un issue o envía un pull request.

Licencia

Este proyecto es de código abierto bajo la Licencia MIT. Consulta el archivo LICENSE para más detalles.