Thoth
Un servidor MCP seguro y de solo lectura para consultar fuentes de datos MySQL, PostgreSQL y Redis.
Documentación
Thoth MCP
Un servidor MCP de solo lectura y con prioridad en la seguridad, diseñado para que asistentes de IA consulten MySQL, PostgreSQL y Redis de forma segura.
Cada consulta pasa por un pipeline de seguridad en capas antes de llegar a tu base de datos, para que puedas darle a un asistente de IA acceso a datos sin entregarle un arma cargada.
Tabla de contenidos
- ¿Por qué usar esto?
- Características
- Inicio rápido
- Configuración
- Herramientas MCP
- Seguridad
- Transportes
- Arquitectura
- Desarrollo
- Licencia
¿Por qué usar esto?
- Solo lectura por diseño. Las escrituras son estructuralmente imposibles: no existe ninguna ruta
executeque pueda mutar datos. - Defensa en profundidad. El SQL se valida de tres maneras (aplicación de SELECT → detección de inyección → LIMIT automático). Los comandos de Redis están restringidos a una lista blanca explícita.
- Los secretos nunca salen de tu configuración. Las contraseñas se cargan desde variables de entorno y se eliminan de los registros y mensajes de error.
- Un servidor, muchas fuentes de datos. Conecta todas tus bases de datos a través de un único endpoint MCP.
- Funciona con cualquier cliente MCP — Claude Code, Cursor, Windsurf y cualquier otra herramienta que hable MCP.
Características
- Consulta múltiples instancias de MySQL, PostgreSQL y Redis a través de un solo servidor
- Seguridad SQL en tres capas (aplicación de SELECT + detección de inyección + LIMIT automático)
- Lista blanca de comandos Redis (solo comandos de lectura explícitamente seguros)
- Salida en Markdown para un uso eficiente del contexto de IA
- Transportes stdio, SSE y streamable-http
- Stack de Docker Compose con datos de ejemplo para desarrollo local
Inicio rápido
Requisitos
- Python 3.10+
- Docker y Docker Compose (opcional, para despliegue en contenedores)
Instalar y ejecutar localmente
# Clone
git clone https://github.com/pennxiv/thoth-mcp.git
cd thoth-mcp
# Set up a virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install
pip install -e ".[dev]"
# Point at your datasources and run
export THOTH_DATASOURCES_FILE=config/datasources.yaml
python -m thoth_mcp
Ejecutar con Docker
# Starts the server in streamable-http mode on port 8080
docker compose up -d --build
# Connect from any machine on your network:
# http://<server-ip>:8080/mcp
Conecta tu cliente MCP
Claude Code (~/.claude.json o proyecto .mcp.json):
{
"mcpServers": {
"thoth": {
"url": "http://<server-ip>:8080/mcp",
"transport": "streamable-http"
}
}
}
Cursor / Windsurf (.cursor/mcp.json):
{
"mcpServers": {
"thoth": {
"url": "http://<server-ip>:8080/mcp",
"transport": "streamable-http"
}
}
}
Para uso solo local, configura el cliente para lanzar el servidor a través de stdio — sin necesidad de exposición HTTP.
Configuración
Crea un archivo datasources.yaml (o establece THOTH_DATASOURCES_FILE para apuntar a uno):
mysql:
prod_db:
host: mysql.example.com
port: 3306
user: readonly_user
password: ${MYSQL_PROD_PASSWORD} # overridden via environment variable
database: production
min_pool_size: 1
max_pool_size: 10
redis:
cache:
host: redis.example.com
port: 6379
db: 0
min_pool_size: 1
max_pool_size: 10
Suministro de secretos
Las contraseñas nunca deben vivir en archivos de configuración. Sobrescríbelas mediante variables de entorno usando el patrón THOTH_<TYPE>__<NAME>__PASSWORD:
export THOTH_MYSQL__PROD_DB__PASSWORD=secret123
export THOTH_POSTGRES__WAREHOUSE__PASSWORD=another_secret
export THOTH_REDIS__CACHE__PASSWORD=redis_secret
Consulta config/datasources.yaml para ver un ejemplo completo con los tres tipos de fuentes de datos.
Herramientas MCP
| Herramienta | Descripción |
|---|---|
query_mysql(datasource, sql) | Ejecuta una consulta SELECT contra una fuente de datos MySQL |
list_tables(datasource) | Lista todas las tablas en una fuente de datos MySQL |
describe_table(datasource, table) | Muestra los detalles de las columnas de una tabla MySQL |
query_postgres(datasource, sql) | Ejecuta una consulta SELECT contra una fuente de datos PostgreSQL |
list_tables_postgres(datasource) | Lista todas las tablas en una fuente de datos PostgreSQL (esquema público) |
describe_table_postgres(datasource, table) | Muestra los detalles de las columnas de una tabla PostgreSQL |
query_redis(datasource, command, args?) | Ejecuta un comando Redis seguro de solo lectura |
list_datasources() | Lista todas las fuentes de datos MySQL, PostgreSQL y Redis configuradas |
Seguridad
Este servidor está construido bajo la premisa de que todo lo que llegue a la base de datos debe ser de solo lectura y libre de inyecciones.
Seguridad SQL (defensa en tres capas)
- Aplicación de solo SELECT — solo se permiten sentencias SELECT.
- Detección de patrones de inyección — bloquea inyecciones UNION, ofuscación con comentarios y ataques de múltiples sentencias.
- Inyección automática de LIMIT — las consultas sin cláusula LIMIT reciben un límite predeterminado (100 filas) para evitar escaneos ilimitados.
Seguridad Redis
Solo se permiten estos comandos de solo lectura: GET, HGET, HGETALL, LRANGE, SMEMBERS, TTL, TYPE, LLEN, SCARD, EXISTS, HEXISTS, SRANDMEMBER, ZCARD, ZSCORE, ZRANGE.
Comandos como SET, DEL, KEYS y FLUSHALL están explícitamente bloqueados.
Saneamiento de errores
Los mensajes de error nunca exponen nombres de host, IPs, cadenas de conexión ni credenciales. Esto se mantiene incluso cuando falla la configuración de la conexión o la ejecución de la consulta.
Exposición de red
Cuando se ejecuta en modo streamable-http o sse, el servidor escucha en 0.0.0.0:8080 por defecto. Colócalo detrás de límites de red autenticados — no lo expongas directamente a internet público sin autenticación adicional. Consulta SECURITY.md.
Transportes
| Modo | Caso de uso | Env |
|---|---|---|
stdio (predeterminado) | Cliente y servidor en la misma máquina | MCP_TRANSPORT=stdio |
streamable-http | Clientes remotos a través de HTTP | MCP_TRANSPORT=streamable-http |
sse | Streaming basado en navegador / unidireccional | MCP_TRANSPORT=sse |
| Variable | Predeterminado | Descripción |
|---|---|---|
MCP_TRANSPORT | stdio | Modo de transporte |
MCP_HOST | 0.0.0.0 | Host de escucha (solo http/sse) |
MCP_PORT | 8080 | Puerto de escucha (solo http/sse) |
THOTH_API_TOKEN | (sin establecer) | Token Bearer requerido para clientes HTTP (solo http/sse) |
El modo SSE expone /sse (conexiones de clientes) y /messages/ (endpoint POST).
Autenticación con token API
Cuando se sirve a través de transportes HTTP (streamable-http o sse) deberías
establecer THOTH_API_TOKEN para proteger el servidor. Con un token establecido, cada solicitud
MCP debe llevar un encabezado Authorization: Bearer <token>; las solicitudes sin
un token válido se rechazan con 401 Unauthorized. El endpoint /health está
siempre abierto para sondas de monitoreo.
# On the server
export THOTH_API_TOKEN=$(openssl rand -hex 32) # generate a strong token
export MCP_TRANSPORT=streamable-http
export MCP_PORT=8080
python -m thoth_mcp
# On the client (curl)
curl -H "Authorization: Bearer <token>" http://server:8080/mcp
Cuando THOTH_API_TOKEN no está establecido, la autenticación está deshabilitada — adecuado para
uso local stdio, pero nunca expongas una instancia HTTP sin autenticación a
internet público.
Arquitectura
┌──────────────────────────────────────────────────────────────┐
│ FastMCP Server │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ MySQL Tools │ │PostgreSQL │ │ Redis Tools │ │
│ │ │ │Tools │ │ │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌──────▼───────┐ ┌──────▼──────┐ │
│ │ MySQL Pool │ │PostgreSQL │ │ Redis Pool │ │
│ │ Manager │ │Pool Manager │ │ Manager │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ │ │ │ ┌──────────┐ │
│ ┌──────▼──────┐ ┌──────▼───────┐ ┌──────▼──────┐ │
│ │ SQL Safety │ │ SQL Safety │ │Redis Safety │ │
│ └──────┬──────┘ └──────┬───────┘ └──────┬──────┘ │
│ └───────────────┴────────────────┴───│ Config │ │
│ └──────────┘ │
└──────────────────────────────────────────────────────────────┘
│ │ │
┌────▼────┐ ┌────▼─────┐ ┌────▼────┐
│ MySQL │ │PostgreSQL│ │ Redis │
│ DB │ │ DB │ │Instance │
└─────────┘ └──────────┘ └─────────┘
Desarrollo
# Run the test suite
pytest tests/ -v
# Run a single test file
pytest tests/test_mysql_tools.py -v
# Run with coverage
pytest tests/ --cov=src/thoth_mcp --cov-report=html
# Lint
ruff check src/ tests/
Consulta CONTRIBUTING.md para las pautas de contribución y CHANGELOG.md para el historial de versiones.
Estructura del proyecto
thoth-mcp/
├── src/thoth_mcp/
│ ├── config.py # Configuration loading
│ ├── server.py # FastMCP server assembly
│ ├── __main__.py # Entry point
│ ├── db/ # Connection pool managers (mysql, postgresql, redis)
│ ├── tools/ # MCP tools (mysql, postgresql, redis, discovery)
│ └── utils/ # Safety layers, formatters, logging
├── tests/ # Test suite
├── docker/ # Docker seed data
├── config/ # Example configurations
└── pyproject.toml
Licencia
Licencia MIT — consulta LICENSE.