Skip to main content
Glama
tismajo

UVG Library MCP Server

by tismajo
README.md
# Servidor MCP de Biblioteca UVG

Servidor local basado en **Model Context Protocol (MCP)** para consultar un catálogo bibliográfico almacenado en MySQL. Expone herramientas para buscar libros, generar referencias en formato APA 7, reservar ejemplares y encontrar alternativas disponibles.

El servidor utiliza transporte **STDIO**, por lo que está diseñado para ser iniciado y administrado por un anfitrión MCP, como un chatbot, un cliente desarrollado con el SDK de MCP o MCP Inspector.

## Funcionalidades

El servidor expone cuatro herramientas:

| Herramienta | Propósito | Modifica la base de datos |
| --- | --- | --- |
| `buscar_libros_tool` | Busca libros por texto o tema y muestra disponibilidad. | No |
| `obtener_cita_apa_tool` | Obtiene los datos del libro y genera una referencia APA 7. | No |
| `reservar_libro_tool` | Crea una reserva y asigna un ejemplar disponible. | Sí |
| `buscar_alternativas_tool` | Busca libros del mismo tema que tengan ejemplares disponibles. | No |

## Estructura del repositorio

```text
uvg-library-mcp/
├── mcp_servers/
│   ├── __init__.py
│   └── local_library/
│       ├── __init__.py
│       ├── db_connection.py
│       ├── server.py
│       └── tools.py
├── db/
│   ├── 01.sql
│   └── 02.sql
├── tests/
│   └── test_tools.py
├── .env.example
├── .gitignore
├── requirements.txt
└── README.md
```

## Requisitos

- Python 3.11 o superior.
- MySQL 8.0 o superior.
- `pip` y soporte para entornos virtuales.
- Node.js es opcional y solo se necesita para probar el servidor con MCP Inspector.

## Instalación

### 1. Clonar el repositorio

```bash
git clone https://github.com/USUARIO/uvg-library-mcp.git
cd uvg-library-mcp
```

Reemplace `USUARIO` por el propietario real del repositorio.

### 2. Crear un entorno virtual

Windows PowerShell:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
```

Linux o macOS:

```bash
python3 -m venv .venv
source .venv/bin/activate
```

### 3. Instalar las dependencias

```bash
python -m pip install --upgrade pip
pip install -r requirements.txt
```

El archivo `requirements.txt` debe incluir, como mínimo:

```text
mcp>=1.28,<2
pymysql
python-dotenv
```

## Preparación de MySQL

Los scripts incluidos están pensados para ejecutarse sobre una base vacía:

- `db/01.sql`: crea tablas, relaciones, restricciones e índices.
- `db/02.sql`: agrega los datos de demostración.

### 1. Crear la base y el usuario

Abra el cliente de MySQL con una cuenta administrativa:

```bash
mysql -u root -p
```

Ejecute lo siguiente y sustituya `CONTRASENA_SEGURA` por una contraseña local:

```sql
CREATE DATABASE librarydb
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

CREATE USER IF NOT EXISTS 'libraryu'@'localhost'
  IDENTIFIED BY 'CONTRASENA_SEGURA';

GRANT ALL PRIVILEGES ON librarydb.*
  TO 'libraryu'@'localhost';

FLUSH PRIVILEGES;
USE librarydb;
```

### 2. Ejecutar los scripts

Desde la consola de MySQL, utilice rutas absolutas con barras `/`:

```sql
SOURCE C:/ruta/al/repositorio/uvg-library-mcp/db/01.sql;
SOURCE C:/ruta/al/repositorio/uvg-library-mcp/db/02.sql;
```

En Linux o macOS puede usar, por ejemplo:

```sql
SOURCE /ruta/al/repositorio/uvg-library-mcp/db/01.sql;
SOURCE /ruta/al/repositorio/uvg-library-mcp/db/02.sql;
```

Compruebe que se cargaron los datos:

```sql
SELECT id, titulo FROM libro;
SELECT id, codigo_inventario, estado FROM ejemplar;
EXIT;
```

> Los scripts no deben ejecutarse repetidamente sobre la misma base sin limpiarla, porque contienen identificadores y valores únicos de demostración.

## Variables de entorno

Copie el archivo de ejemplo:

Windows PowerShell:

```powershell
Copy-Item .env.example .env
```

Linux o macOS:

```bash
cp .env.example .env
```

Configure `.env` con los datos creados anteriormente:

```env
DB_HOST=localhost
DB_PORT=3306
DB_NAME=librarydb
DB_USER=libraryu
DB_PASSWORD=CONTRASENA_SEGURA
```

No publique `.env`. El repositorio debe contener únicamente `.env.example`, sin credenciales reales.

## Verificar la conexión con MySQL

Desde la raíz del repositorio y con el entorno virtual activo:

```bash
python -m mcp_servers.local_library.db_connection
```

El resultado esperado es similar a:

```text
Conexión exitosa a MySQL.
Biblioteca encontrada: Biblioteca Central UVG
```

## Ejecutar el servidor MCP

```bash
python -m mcp_servers.local_library.server
```

El proceso puede quedar esperando sin imprimir mensajes. Esto es normal: con transporte STDIO, el servidor espera solicitudes JSON-RPC enviadas por un cliente MCP. Para detenerlo manualmente, presione `Ctrl+C`.

No escriba mensajes de depuración en la salida estándar del servidor, ya que podrían interferir con la comunicación JSON-RPC. Para diagnóstico se recomienda utilizar la salida de error estándar o un archivo de logs.

## Herramientas disponibles

### `buscar_libros_tool`

Busca libros por palabras del título o la descripción y, opcionalmente, por tema.

Parámetros:

| Parámetro | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `query` | `string` | No | Texto que se buscará en el título o descripción. |
| `tema` | `string` | No | Nombre o fragmento del tema bibliográfico. |

Ejemplos conceptuales:

```json
{
  "query": "bases de datos"
}
```

```json
{
  "tema": "Redes"
}
```

Retorna los datos de los libros encontrados y la cantidad de ejemplares disponibles.

### `obtener_cita_apa_tool`

Consulta el título, año, edición, editorial y autores del libro para generar una referencia en formato APA 7.

| Parámetro | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `libro_id` | `integer` | Sí | Identificador del libro en la base de datos. |

Ejemplo:

```json
{
  "libro_id": 3
}
```

Respuesta de ejemplo:

```text
Kurose, J. & Ross, K. (2017). Redes de Computadoras: Un Enfoque Descendente (6a ed.). Addison-Wesley.
```

Esta herramienta solo ejecuta consultas de lectura; no modifica la base de datos.

### `reservar_libro_tool`

Crea una reserva para un usuario. Si existe un ejemplar disponible, lo asigna y cambia su estado a `RESERVADO`; de lo contrario, la reserva queda pendiente.

| Parámetro | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `usuario_id` | `integer` | Sí | Identificador del usuario. |
| `libro_id` | `integer` | Sí | Identificador del libro. |

Ejemplo:

```json
{
  "usuario_id": 1,
  "libro_id": 3
}
```

Esta herramienta modifica las tablas `reserva` y `ejemplar`. Se recomienda probarla únicamente con una base de desarrollo.

### `buscar_alternativas_tool`

Busca otros libros asociados con los mismos temas y que posean ejemplares disponibles.

| Parámetro | Tipo | Obligatorio | Descripción |
| --- | --- | --- | --- |
| `libro_id` | `integer` | Sí | Libro para el que se desean alternativas. |

Ejemplo:

```json
{
  "libro_id": 4
}
```

## Probar con MCP Inspector

Este paso es opcional y requiere Node.js. Desde la raíz del repositorio:

Windows PowerShell:

```powershell
npx -y @modelcontextprotocol/inspector .\.venv\Scripts\python.exe -m mcp_servers.local_library.server
```

Linux o macOS:

```bash
npx -y @modelcontextprotocol/inspector ./.venv/bin/python -m mcp_servers.local_library.server
```

MCP Inspector abrirá una interfaz desde la que se puede inicializar la conexión, consultar `tools/list` y ejecutar cada herramienta.

Pruebas recomendadas:

1. Ejecutar `buscar_libros_tool` con `tema = Redes`.
2. Tomar el ID de uno de los resultados.
3. Ejecutar `obtener_cita_apa_tool` con ese ID.
4. Ejecutar `buscar_alternativas_tool` con el ID `4`.
5. Ejecutar `reservar_libro_tool` con `usuario_id = 1` en una base de pruebas.

## Configuración en un anfitrión MCP

Ejemplo genérico de configuración para un cliente que inicie servidores mediante STDIO:

```json
{
  "servers": {
    "library": {
      "transport": "stdio",
      "command": "C:/ruta/al/repositorio/uvg-library-mcp/.venv/Scripts/python.exe",
      "args": [
        "-m",
        "mcp_servers.local_library.server"
      ],
      "cwd": "C:/ruta/al/repositorio/uvg-library-mcp"
    }
  }
}
```

En Linux o macOS, cambie `command` por la ruta a `.venv/bin/python`.

La configuración exacta puede variar según el anfitrión utilizado. El proceso siempre debe iniciarse desde la raíz del repositorio o utilizarla como directorio de trabajo para que Python pueda resolver el paquete `mcp_servers`.

## Ejecutar pruebas

Con el entorno virtual activo y MySQL configurado:

```bash
python -m unittest discover -s tests -v
```

Las pruebas que crean reservas modifican la base de datos. Utilice una base exclusiva para desarrollo o restablezca los datos después de ejecutarlas.

## Solución de problemas

### `DB_PASSWORD is required`

Verifique que exista `.env` en la raíz del repositorio y que contenga una línea válida:

```env
DB_PASSWORD=su_contraseña
```

### `Access denied for user`

El usuario, la contraseña o el host no coinciden con la cuenta configurada en MySQL. Pruebe primero:

```bash
mysql -u libraryu -p -h localhost librarydb
```

### `Can't connect to MySQL server`

Confirme que MySQL esté iniciado, que escuche en el puerto configurado y que ningún firewall bloquee la conexión.

### `No module named mcp_servers`

Ejecute el comando desde la raíz del repositorio, no desde `mcp_servers/local_library`:

```bash
python -m mcp_servers.local_library.server
```

### El proceso parece quedarse detenido

Un servidor MCP por STDIO permanece esperando mensajes del cliente. Esto es el comportamiento esperado y no significa que esté bloqueado.

### Caracteres incorrectos en Windows

Use una terminal con UTF-8:

```powershell
chcp 65001
$env:PYTHONUTF8="1"
```

## Seguridad y limitaciones

- No incluya contraseñas ni claves en el código fuente.
- No publique el archivo `.env`.
- Use una base de datos de desarrollo para probar reservas.
- Restrinja los permisos del usuario MySQL únicamente a `librarydb`.
- El servidor utiliza STDIO y no abre un puerto de red por sí mismo.
- El formato APA generado depende de la calidad de los datos almacenados.
- Este catálogo contiene datos de demostración y no representa necesariamente el inventario real de la Universidad del Valle de Guatemala.

## Tecnologías utilizadas

- Python
- MCP Python SDK / FastMCP
- JSON-RPC
- MySQL
- PyMySQL
- python-dotenv

## Uso académico

Proyecto desarrollado para el curso **CC3067 Redes** de la Universidad del Valle de Guatemala. Si se reutiliza código o documentación de terceros, deben conservarse las referencias y atribuciones correspondientes.