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.

CI License: MIT Python 3.10+ MCP

English · 简体中文


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?

  • Solo lectura por diseño. Las escrituras son estructuralmente imposibles: no existe ninguna ruta execute que 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

HerramientaDescripció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)

  1. Aplicación de solo SELECT — solo se permiten sentencias SELECT.
  2. Detección de patrones de inyección — bloquea inyecciones UNION, ofuscación con comentarios y ataques de múltiples sentencias.
  3. 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

ModoCaso de usoEnv
stdio (predeterminado)Cliente y servidor en la misma máquinaMCP_TRANSPORT=stdio
streamable-httpClientes remotos a través de HTTPMCP_TRANSPORT=streamable-http
sseStreaming basado en navegador / unidireccionalMCP_TRANSPORT=sse
VariablePredeterminadoDescripción
MCP_TRANSPORTstdioModo de transporte
MCP_HOST0.0.0.0Host de escucha (solo http/sse)
MCP_PORT8080Puerto 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.