MySQL MCP
Servidor MCP para MySQL/MariaDB: inspección de esquemas, consultas y manipulación de datos para asistentes de IA
Documentación
Servidor MySQL MCP
Una implementación de servidor de Protocolo de Contexto de Modelo (MCP) de alta calidad para bases de datos MySQL. Este servidor permite que asistentes de IA como Claude interactúen con bases de datos MySQL a través de un protocolo estandarizado.
Versión: 0.2.0 | Protocolo: MCP 2025-03-26 | Rust: 1.70+ | Estado: Listo para producción
Tabla de Contenidos
- Características
- Instalación
- Inicio Rápido (5 Minutos)
- Uso
- Herramientas Disponibles
- Función de Contexto de Base de Datos
- Consideraciones de Seguridad
- Arquitectura
- Solución de Problemas
- Desarrollo
- Guía de Implementación
- Contribuciones
- Licencia
- Soporte
Características
- Inspección de Esquemas: Recupera esquemas de tablas e información de estructura
- Ejecución de Consultas: Ejecuta consultas SQL (solo lectura por defecto por seguridad)
- Manipulación de Datos: Operaciones de inserción, actualización y eliminación
- Contexto de Base de Datos: Especifica qué base de datos usar en cada consulta
- Controles de Seguridad: Restricciones de consultas configurables para prevenir operaciones peligrosas
- Gestión de Conexiones: Manejo robusto de conexiones con lógica de reintentos y agrupación
- Manejo de Errores: Reporte integral de errores con mensajes detallados
- Protocolo JSON-RPC 2.0: Comunicación estandarizada a través de stdio
Instalación
Requisitos Previos
- Rust 1.70+
- MySQL 5.7+ o MariaDB 10.2+
- Acceso a una base de datos MySQL
Compilación desde el Código Fuente
git clone <repository-url>
cd mcp-server-mysql
cargo build --release
El binario compilado estará disponible en target/release/mcp-server-mysql.
Desde el Paquete de Versión
# Extract the package
tar -xzf mcp-server-mysql-v0.2.0-linux-x86_64.tar.gz
# Move binary to system path (optional)
sudo cp mcp-server-mysql /usr/local/bin/
# Verify installation
mcp-server-mysql --version
Inicio Rápido (5 Minutos)
Paso 1: Compilar el Servidor
cargo build --release
El binario estará en target/release/mcp-server-mysql
Paso 2: Probar la Conexión
./target/release/mcp-server-mysql \
--host localhost \
--username root \
--password yourpassword \
--database testdb
Deberías ver: "MCP MySQL Server started and ready to accept connections"
Paso 3: Configurar Claude Desktop
Edita tu archivo de configuración de Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Añade esta configuración:
{
"mcpServers": {
"mysql": {
"command": "/absolute/path/to/mcp-server-mysql",
"args": [
"--host", "localhost",
"--port", "3306",
"--username", "your_username",
"--password", "your_password",
"--database", "your_database"
]
}
}
}
Nota de Seguridad: Para uso en producción, considera usar variables de entorno o una solución segura de gestión de secretos en lugar de codificar contraseñas en el archivo de configuración.
Paso 4: Reiniciar Claude Desktop
Cierra y vuelve a abrir Claude Desktop por completo. Deberías ver un pequeño ícono de martillo indicando que el servidor MCP está conectado.
Paso 5: ¡Pruébalo!
Pregúntale a Claude:
- "¿Puedes mostrarme el esquema de la tabla users en mi base de datos MySQL?"
- "Consulta la base de datos y muéstrame las primeras 10 filas de la tabla products"
- "¿Qué tablas hay en mi base de datos?"
Uso
Argumentos de Línea de Comandos
mcp-server-mysql \
--host localhost \
--port 3306 \
--username your_username \
--password your_password \
--database your_database \
--allow-dangerous-queries false
Referencia de Argumentos
| Argumento | Descripción | Valor Predeterminado | Requerido |
|---|---|---|---|
--host | Hostname del servidor MySQL | localhost | No |
--port | Puerto del servidor MySQL | 3306 | No |
--username | Nombre de usuario de MySQL | - | Sí |
--password | Contraseña de MySQL | (vacía) | No |
--database | Nombre de la base de datos a la que conectarse | - | Sí |
--allow-dangerous-queries | Permitir consultas INSERT/UPDATE/DELETE | false | No |
Configuración con Claude Desktop
Añade esta configuración a tu archivo de configuración de Claude Desktop:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mysql": {
"command": "/path/to/mcp-server-mysql",
"args": [
"--host", "localhost",
"--port", "3306",
"--username", "your_username",
"--password", "your_password",
"--database", "your_database"
]
}
}
}
Herramientas Disponibles
1. mysql (Inspección de Esquemas)
Recupera información del esquema de la base de datos para tablas.
Parámetros:
table_name(cadena): Nombre de la tabla a inspeccionar, o"all-tables"para obtener todos los esquemas de tablas
Ejemplo:
{
"table_name": "users"
}
Devuelve:
- Información de columnas (nombre, tipo, nullable, valores predeterminados, claves)
- Información de índices
- Restricciones de tablas
2. query (Ejecución de SQL)
Ejecuta consultas SQL en la base de datos.
Parámetros:
query(cadena): Consulta SQL a ejecutardatabase(cadena, opcional): Nombre de la base de datos a usar para esta consulta específica
Ejemplo:
{
"query": "SELECT * FROM users WHERE active = 1 LIMIT 10",
"database": "my_database"
}
Seguridad:
- Por defecto, solo se permiten consultas SELECT
- Usa la bandera
--allow-dangerous-queriespara habilitar INSERT/UPDATE/DELETE - Las palabras clave peligrosas están bloqueadas a menos que se habiliten explícitamente
3. insert (Insertar Datos)
Inserta datos en una tabla especificada.
Parámetros:
table_name(cadena): Nombre de la tabladata(objeto): Pares clave-valor de nombres de columnas y valores
Ejemplo:
{
"table_name": "users",
"data": {
"username": "john_doe",
"email": "john@example.com",
"active": true
}
}
Devuelve: ID de la última inserción
4. update (Actualizar Datos)
Actualiza datos en una tabla especificada según condiciones.
Parámetros:
table_name(cadena): Nombre de la tabladata(objeto): Pares clave-valor de columnas a actualizarconditions(objeto): Pares clave-valor para la cláusula WHERE
Ejemplo:
{
"table_name": "users",
"data": {
"email": "newemail@example.com",
"updated_at": "2024-01-15 10:30:00"
},
"conditions": {
"id": 123
}
}
Devuelve: Número de filas afectadas
5. delete (Eliminar Datos)
Elimina datos de una tabla especificada según condiciones.
Parámetros:
table_name(cadena): Nombre de la tablaconditions(objeto): Pares clave-valor para la cláusula WHERE
Ejemplo:
{
"table_name": "users",
"conditions": {
"id": 123
}
}
Devuelve: Número de filas afectadas
Advertencia: ¡Siempre especifica condiciones para evitar eliminar todas las filas!
Función de Contexto de Base de Datos
El Problema
Anteriormente, el contexto de la base de datos no se mantenía entre consultas:
-- Query 1
USE dev_database; -- Succeeds
-- Query 2 (new connection from pool)
SELECT * FROM my_table; -- ❌ Fails: context was lost
La Solución
Usa el parámetro opcional database en cada consulta:
{
"query": "SELECT * FROM my_table",
"database": "dev_database"
}
Beneficios
- Explícito y Claro: Sabes exactamente qué base de datos usa cada consulta
- Sin Estado Oculto: Cada consulta es independiente
- Compatibilidad Retroactiva: Las consultas existentes sin el parámetro siguen funcionando
- Sin Condiciones de Carrera: Cada consulta obtiene su propia conexión
- Fácil de Usar: Solo añade
"database": "name"a los argumentos de la consulta
Ejemplos de Uso
Consulta Básica con Parámetro de Base de Datos
{
"query": "SELECT * FROM crm_sites LIMIT 10",
"database": "dev_smartConnect_za"
}
Consulta Sin Parámetro de Base de Datos (Usa la Predeterminada)
{
"query": "SELECT * FROM users WHERE active = 1"
}
Usa la base de datos especificada en el argumento de inicio --database.
Múltiples Bases de Datos en la Misma Sesión
// Query database 1
{
"query": "SELECT COUNT(*) FROM customers",
"database": "production_db"
}
// Query database 2
{
"query": "SELECT COUNT(*) FROM test_data",
"database": "test_db"
}
Antes vs Después
Antes (Se requerían nombres completamente calificados):
SELECT * FROM dev_smartConnect_za.crm_sites
JOIN dev_smartConnect_za.crm_orgs ON ...
WHERE dev_smartConnect_za.crm_sites.active = 1;
Después (Limpio y simple):
{
"query": "SELECT * FROM crm_sites JOIN crm_orgs ON ... WHERE active = 1",
"database": "dev_smartConnect_za"
}
Escenarios Comunes
Escenario 1: Proyecto de Una Sola Base de Datos
Establece la base de datos predeterminada y omite el parámetro:
# Startup
--database my_project_db
# Query (no database parameter needed)
{
"query": "SELECT * FROM users"
}
Escenario 2: Proyecto de Múltiples Bases de Datos
Especifica la base de datos para cada consulta:
// Customer database
{ "query": "...", "database": "customers_db" }
// Orders database
{ "query": "...", "database": "orders_db" }
// Analytics database
{ "query": "...", "database": "analytics_db" }
Manejo de Errores
Código de Error -32005: Fallo en la Adquisición de Conexión
Cause: Connection pool exhausted
Solution: Retry after a moment
Código de Error -32006: Fallo en el Cambio de Contexto de Base de Datos
Cause: Database doesn't exist or user lacks permissions
Solution: Verify database exists and user has access
Mejores Prácticas
✅ HACER
- Especifica la base de datos explícitamente para consultas de producción
- Usa nombres descriptivos de bases de datos en tus consultas
- Prueba con
SELECT DATABASE()para verificar el contexto - Agrupa las consultas por base de datos para mayor claridad
❌ NO HACER
- Mezclar nombres calificados y no calificados en la misma consulta
- Asumir persistencia: especifica la base de datos en cada consulta
- Usar caracteres especiales en los nombres de bases de datos si es posible
- Olvidar verificar los permisos de usuario para todas las bases de datos
Consideraciones de Seguridad
Modo de Solo Lectura (Predeterminado)
Por defecto, el servidor opera en modo de solo lectura, permitiendo únicamente consultas SELECT. Esto evita la modificación o eliminación accidental de datos.
Modo de Consultas Peligrosas
Habilita operaciones de escritura con --allow-dangerous-queries:
mcp-server-mysql --username user --password pass --database mydb --allow-dangerous-queries true
¡Úsalo con precaución! Esto habilita:
- Sentencias INSERT
- Sentencias UPDATE
- Sentencias DELETE
- Otras operaciones potencialmente destructivas
Protección contra Inyección SQL
- Los nombres de tablas se validan para contener solo caracteres alfanuméricos y guiones bajos
- Todos los valores de datos se parametrizan usando sentencias preparadas
- Los nombres de bases de datos se escapan reemplazando los acentos graves con acentos graves dobles
- No se realiza concatenación de SQL sin procesar
Seguridad de la Conexión
- Soporta conexiones SSL/TLS estándar de MySQL
- Las cadenas de conexión se pueden configurar de forma segura
- Las contraseñas se pueden proporcionar mediante variables de entorno
- Considera usar usuarios de base de datos dedicados con permisos limitados
Seguridad en la Implementación de Producción
-
Usa un usuario de base de datos dedicado:
CREATE USER 'mcp_user'@'localhost' IDENTIFIED BY 'secure_password'; GRANT SELECT ON your_database.* TO 'mcp_user'@'localhost'; FLUSH PRIVILEGES; -
Habilita el acceso de escritura solo cuando sea necesario:
--allow-dangerous-queries true # Use with caution! -
Usa variables de entorno (mejora futura): Considera envolver el binario en un script de shell que lea las variables de entorno.
Arquitectura
Descripción General del Sistema
┌─────────────────────────────────────────────────────┐
│ MCP Client (e.g., Claude) │
│ Sends: {query, database} │
└────────────────────────┬────────────────────────────┘
│ JSON-RPC 2.0 (stdio)
▼
┌─────────────────────────────────────────────────────┐
│ MCP MySQL Server (Rust) │
│ │
│ execute_query(query, database, pool) │
│ ├─ If database param: │
│ │ ├─ Acquire connection from pool │
│ │ ├─ Execute: USE `database` │
│ │ └─ Execute: [user's query] │
│ └─ Else: │
│ └─ Execute query on pool (default database) │
└────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ MySQL Connection Pool (5 connections) │
└────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ MySQL/MariaDB Server │
└─────────────────────────────────────────────────────┘
Secuencia: Consulta con Parámetro de Base de Datos
Client MCP Server Connection Pool MySQL Server
│ │ │ │
│ query + │ │ │
│ database │ │ │
├────────────────>│ │ │
│ │ │ │
│ │ acquire() │ │
│ ├───────────────────>│ │
│ │ <connection> │ │
│ │<───────────────────┤ │
│ │ │ │
│ │ USE database │ │
│ ├────────────────────┼─────────────────>│
│ │ OK │ │
│ │<────────────────────┼──────────────────┤
│ │ │ │
│ │ SELECT query │ │
│ ├────────────────────┼─────────────────>│
│ │ Results │ │
│ │<────────────────────┼──────────────────┤
│ │ │ │
│ │ release() │ │
│ ├───────────────────>│ │
│ Results │ │ │
│<────────────────┤ │ │
Gestión del Pool de Conexiones
Pool (5 connections)
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐
│ C1 │ │ C2 │ │ C3 │ │ C4 │ │ C5 │
└────┘ └────┘ └────┘ └────┘ └────┘
Key Properties:
• Each query gets its own connection instance
• Database context is set per connection, per query
• No state persists between queries
• Fully thread-safe and concurrent
Detalles Técnicos
- Versión del Protocolo: MCP 2025-03-26
- Transporte: stdio (JSON-RPC 2.0)
- Agrupación de Conexiones: Máximo 5 conexiones
- Lógica de Reintentos: Reconexión automática en fallos transitorios
- Sobrecarga de Rendimiento: ~50-200 microsegundos por consulta con parámetro de base de datos
Solución de Problemas
Fallos de Conexión
Si encuentras errores de conexión:
-
Verifica que MySQL esté en ejecución:
mysql -h localhost -u your_username -p -
Verifica las credenciales:
- Asegúrate de que el nombre de usuario y la contraseña sean correctos
- Confirma que el usuario tenga acceso a la base de datos especificada
-
Verifica el acceso a la red:
- Verifica que el host y el puerto sean correctos
- Asegúrate de que ningún firewall esté bloqueando la conexión
-
Revisa los registros del servidor:
- El servidor registra en stderr
- Busca mensajes de error detallados
Errores Comunes
"Database connection failed"
- El servidor MySQL puede no estar en ejecución
- Configuración incorrecta de host/puerto
- Problemas de conectividad de red
"Only SELECT queries are allowed"
- Estás intentando ejecutar una consulta de escritura en modo de solo lectura
- Añade
--allow-dangerous-queries truesi se necesita acceso de escritura
"No database selected"
- La base de datos especificada no existe
- El usuario no tiene acceso a la base de datos
- Verifica con
SHOW DATABASES;para ver las bases de datos disponibles
"Table doesn't exist"
- Verifica que estás consultando la base de datos correcta
- Añade el parámetro
databasesi usas múltiples bases de datos - Usa
SELECT DATABASE()para verificar el contexto actual
"Failed to acquire connection"
- El pool de conexiones está agotado
- Espera un momento y reintenta
La herramienta no aparece en Claude Desktop
- Verifica que la ruta al binario sea absoluta (no relativa)
- Revisa los registros de Claude Desktop para ver errores
- Reinicia Claude Desktop por completo (no solo recargar)
- Asegúrate de que el proceso del servidor se inicie sin errores cuando se ejecuta manualmente
Desarrollo
Estructura del Proyecto
mcp-server-mysql/
├── src/
│ ├── main.rs # Main server implementation
│ ├── config.rs # Configuration handling
│ ├── db.rs # Database operations
│ ├── rpc.rs # RPC protocol handling
│ └── server.rs # Server initialization
├── tests/ # Test files
├── Cargo.toml # Rust dependencies
├── Cargo.lock # Locked dependency versions
└── README.md # This file
Compilación para Desarrollo
cargo build
cargo run -- --help
Ejecución de Pruebas
cargo test
Calidad del Código
# Format code
cargo fmt
# Run linter
cargo clippy
# Check for issues
cargo check
Convenciones de Desarrollo
El proyecto sigue las mejores prácticas estándar de Rust:
- Formato de código:
cargo fmt - Linting:
cargo clippy - Pruebas:
cargo test
Guía de Implementación
Implementación Rápida
1. Probar la Conexión
./mcp-server-mysql \
--username your_user \
--password your_pass \
--database your_db
Presiona Ctrl+C para salir después de ver "MCP MySQL Server started".
2. Configurar Claude Desktop
Edita tu archivo de configuración de Claude y añade la configuración del servidor (consulta la sección de Inicio Rápido).
3. Reiniciar Claude Desktop
Cierra y vuelve a abrir Claude Desktop por completo.
Consejos para Implementación en Producción
Rendimiento
- El binario está optimizado con la bandera
--release - La agrupación de conexiones está configurada (máximo 5 conexiones)
- Lógica de reintento automático para fallos transitorios
Monitoreo
Los registros del servidor van a stderr. Captúralos con:
./mcp-server-mysql --username user --password pass --database db 2>> server.log
Niveles de registro:
INFO: Eventos de conexión, llamadas a herramientasDEBUG: Información detallada de consultasWARN: Problemas no fatalesERROR: Fallos y errores
Servicio Systemd (Opcional)
Para implementaciones de larga duración, crea /etc/systemd/system/mcp-mysql.service:
[Unit]
Description=MySQL MCP Server
After=network.target mysql.service
[Service]
Type=simple
User=mcp-user
ExecStart=/usr/local/bin/mcp-server-mysql --username mcp_user --password secret --database production
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Habilita e inicia:
sudo systemctl enable mcp-mysql
sudo systemctl start mcp-mysql
sudo systemctl status mcp-mysql
Actualización
# Backup current version
cp /usr/local/bin/mcp-server-mysql /usr/local/bin/mcp-server-mysql.backup
# Replace with new version
cp mcp-server-mysql /usr/local/bin/
# Restart services
sudo systemctl restart mcp-mysql # If using systemd
# Or restart Claude Desktop
Reversión
# Restore previous version
cp /usr/local/bin/mcp-server-mysql.backup /usr/local/bin/mcp-server-mysql
# Or checkout previous git tag
git checkout v0.1.0
cargo build --release
Contribuciones
¡Las contribuciones son bienvenidas! Por favor asegúrate de:
- Que el código siga las mejores prácticas de Rust
- Que todas las pruebas pasen
- Que la documentación esté actualizada
- Que los mensajes de commit sean claros y descriptivos
Licencia
Apache-2.0
Soporte
Para problemas, preguntas o contribuciones, abre un issue en el repositorio del proyecto.
Versión: 0.2.0 | Fecha de Lanzamiento: 2025-01-XX | Protocolo: MCP 2025-03-26 | Plataforma: Linux x86_64 | Estado: Listo para Producción ✅