""" MCP Server v2 (transporte stdio) — RAG sobre ESL e ISLP. Diferencia con v1: la base ChromaDB se obtiene de un dataset HF Hub (ver `rag_books_mcp.tools` para la resolución de la ruta). """ from mcp.server.fastmcp import FastMCP from rag_books_mcp.tools import ( cite_foundation as _cite_foundation, get_section as _get_section, list_available_topics as _list_available_topics, search_theory as _search_theory, ) mcp = FastMCP( "rag-books-mcp-v2", instructions=( "RAG sobre los libros ESL e ISLP. v2: base vectorial ChromaDB cargada " "desde un dataset publicado en HF Hub (separación código/datos)." ), ) @mcp.tool() def search_theory(query: str, book: str = "both", top_k: int = 5) -> str: """Busca fragmentos relevantes en ESL/ISLP usando búsqueda semántica. Args: query: Consulta en lenguaje natural (ej: "bias-variance tradeoff"). book: "esl", "islp" o "both" (default: "both"). top_k: Número de resultados (1-10, default: 5). """ return _search_theory(query=query, book=book, top_k=top_k) @mcp.tool() def get_section(book: str, chapter: str, section: str = "", max_chunks: int = 5) -> str: """Recupera una sección específica de ESL o ISLP por referencia exacta. Args: book: "esl" o "islp". chapter: Nombre del capítulo (búsqueda parcial soportada). section: Nombre de la sección dentro del capítulo (opcional). max_chunks: Máximo de chunks a devolver (default: 5). """ return _get_section(book=book, chapter=chapter, section=section, max_chunks=max_chunks) @mcp.tool() def cite_foundation(topic: str, detail_level: str = "medium") -> str: """Fundamentación teórica de un tema citando ambos libros (ESL + ISLP). Args: topic: Tema a fundamentar (ej: "ridge regression", "bagging"). detail_level: "brief", "medium" (default) o "deep". """ return _cite_foundation(topic=topic, detail_level=detail_level) @mcp.tool() def list_available_topics() -> str: """Lista los capítulos y temas indexados en la base de conocimiento.""" return _list_available_topics() def main(): """Punto de entrada del MCP server (stdio).""" mcp.run(transport="stdio") if __name__ == "__main__": main()