YugabyteDB MCP Server

Permite que los LLMs interactúen directamente con una base de datos YugabyteDB.

Documentación

Servidor MCP de YugabyteDB

Un servidor MCP para YugabyteDB y PostgreSQL: permite que los LLM (Claude Desktop, Cursor, Windsurf, etc.) resuman esquemas, ejecuten consultas de solo lectura y ejecuten sentencias de escritura detrás de una capa de protección configurable.

Características

  • summarize_database — lista tablas con columnas y recuentos de filas para un esquema (solo lectura)
  • run_read_only_query — ejecuta un SELECT bajo BEGIN READ ONLY; los resultados se devuelven como JSON (solo lectura)
  • run_write_query — INSERT/UPDATE/DELETE/MERGE/TRUNCATE/DDL controlados por una lista de bloqueo de protección (destructivo, deshabilitado por defecto — habilítalo con --enable-write-query o YB_MCP_ENABLE_WRITE_QUERY=true)

Defensa en profundidad: la herramienta de escritura está anotada con destructiveHint: true, por lo que Claude Desktop muestra un aviso de confirmación antes de cada llamada, incluso cuando las protecciones permitirían que la sentencia pase.

OAuth opcional (AWS Cognito) y validación del encabezado Origin para implementaciones remotas autohospedadas.

Requisitos previos

  • Python 3.10+
  • uv (recomendado) o pip
  • Una base de datos YugabyteDB o PostgreSQL accesible
  • Un cliente MCP (Claude Desktop, Cursor, Windsurf, etc.)

Instalación

Tres opciones de instalación, aproximadamente en el orden en que los usuarios finales las usarán:

# uvx — no install at all; fetches and runs on demand. Handy for one-off use
# and also the form the MCPB Desktop extension uses internally.
uvx yugabytedb-mcp-server --help

# pipx — installs to an isolated venv, puts the script on $PATH.
pipx install yugabytedb-mcp-server

# uv tool — same idea, uv-managed.
uv tool install yugabytedb-mcp-server

# pip — system-level or current-venv install.
pip install yugabytedb-mcp-server

Después de cualquiera de las instalaciones persistentes (pipx / uv tool / pip), verifica con:

yugabytedb-mcp --help
# or, equivalently:
yugabytedb-mcp-server --help

Ambos scripts de consola están registrados y apuntan al mismo punto de entrada: yugabytedb-mcp es la forma corta, yugabytedb-mcp-server coincide con el nombre del paquete y es lo que uvx resuelve por defecto.

Nota de prelanzamiento: mientras v2 esté en candidato de lanzamiento (por ejemplo, 2.0.0rc2), las instalaciones predeterminadas no lo seleccionarán. Por ahora, instala con una versión explícita (pipx install yugabytedb-mcp-server==2.0.0rc2) o con --pip-args='--pre'. Esto desaparecerá una vez que 2.0.0 estable se publique.

Para desarrollo desde el código fuente, consulta Desarrollo a continuación.

Configuración

Variable de entornoIndicador CLIRequeridoDescripción
YUGABYTEDB_URL--yugabytedb-urlSíCadena de conexión libpq (por ejemplo, host=… port=5433 dbname=… user=… password=…).
YB_MCP_TRANSPORT--transportNostdio (predeterminado) o http.
YB_MCP_STATELESS_HTTP--stateless-httpNotrue habilita Streamable-HTTP sin estado — requerido para implementaciones autohospedadas con múltiples réplicas.
YB_MCP_REQUIRE_WHERE_ON_UPDATE--require-where-on-updateNoRechaza UPDATE sin cláusula WHERE. Predeterminado false.
YB_MCP_REQUIRE_WHERE_ON_DELETE--require-where-on-deleteNoRechaza DELETE sin cláusula WHERE. Predeterminado false.
YB_MCP_ENABLE_WRITE_QUERY--enable-write-queryNoHabilita la herramienta run_write_query. Predeterminado false (herramienta de escritura deshabilitada).
MCP_AUTH_PROVIDER--mcp-auth-providerNocognito o oidc. Déjalo sin configurar para deshabilitar la autenticación. La configuración completa de OIDC/Cognito y el mapeo de identidad por usuario están documentados en OIDC.md.
MCP_HOST--hostNoHost de enlace para el transporte HTTP. Predeterminado 127.0.0.1 (loopback). Configúralo en 0.0.0.0 para exponer en todas las interfaces — la autenticación se vuelve obligatoria en ese caso (ver MCP_AUTH_PROVIDER).
MCP_BASE_URL—Cuando la autenticación está habilitadaURL base pública a la que el servidor es accesible (por ejemplo, https://mcp.example.com).
MCP_ALLOWED_ORIGINS—NoLista de permitidos separada por comas de valores de Origin para la defensa contra DNS-rebinding. No distingue mayúsculas y minúsculas (RFC 6454). Predeterminado a MCP_BASE_URL.
MCP_ALLOW_UNAUTHENTICATED—NoVía de escape para ejecutar el modo HTTP en un host que no sea loopback sin autenticación. Solo para desarrollo; el inicio registra una ADVERTENCIA prominente.
YB_LOG_LEVEL—NoNivel de registro para la familia de registradores yugabytedb-mcp (predeterminado INFO).
YB_AWS_SSL_ROOT_CERT_SECRET_ARN--yb-aws-ssl-root-cert-secret-arnNoARN de un secreto de AWS Secrets Manager que contiene el certificado raíz TLS de YugabyteDB.
YB_AWS_SSL_ROOT_CERT_KEY--yb-aws-ssl-root-cert-keyNoClave JSON dentro del secreto cuando almacena múltiples certificados.
YB_AWS_SSL_ROOT_CERT_SECRET_REGION--yb-aws-ssl-root-cert-secret-regionNoRegión de AWS del secreto.
YB_SSL_ROOT_CERT_PATH--yb-ssl-root-cert-pathNoDónde escribir el certificado obtenido. Predeterminado /tmp/yb-root.crt.

Para autenticación OIDC/Cognito, mapeo de SET ROLE por usuario, el formato del archivo de mapa de identidad y el atajo /auth/login — consulta OIDC.md.

Una plantilla de inicio está en .env.example.

Inicio rápido — Claude Desktop

Dos formas de conectarlo. La primera usa uvx y no requiere instalación alguna — solo uv. La segunda asume que ya has ejecutado pipx install (o equivalente) y tienes el script yugabytedb-mcp en $PATH.

Opción 1 — vía uvx (sin instalación):

{
  "mcpServers": {
    "yugabytedb": {
      "command": "uvx",
      "args": ["yugabytedb-mcp-server"],
      "env": {
        "YUGABYTEDB_URL": "host=… port=5433 dbname=… user=… password=…"
      }
    }
  }
}

Opción 2 — vía un script instalado:

Después de pipx install yugabytedb-mcp-server (o uv tool install …):

{
  "mcpServers": {
    "yugabytedb": {
      "command": "yugabytedb-mcp",
      "env": {
        "YUGABYTEDB_URL": "host=… port=5433 dbname=… user=… password=…"
      }
    }
  }
}

Ubicaciones de claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Reinicia Claude Desktop. Las tres herramientas aparecerán con títulos e insignias de sugerencias (iconos de solo lectura en las herramientas de lectura, un aviso de confirmación antes de cada llamada a run_write_query).

Mientras 2.0.0rc2 sea la única versión publicada, el fragmento uvx necesita ["yugabytedb-mcp-server@2.0.0rc2"] en los argumentos (o ["--pre", "yugabytedb-mcp-server"]). Drop the explicit version once 2.0.0 estable esté disponible.

Otros clientes MCP

El mismo enfoque funciona con Cursor (Configuración → MCP → Agregar un nuevo servidor MCP global) y Windsurf (Configuración → Cascade → Servidores MCP → Agregar servidor personalizado) — usa la forma uvx o la forma de script instalado de arriba.

Para MCP Inspector contra un servidor en modo HTTP:

YUGABYTEDB_URL="…" yugabytedb-mcp --transport http
# in another shell:
npx @modelcontextprotocol/inspector
# In the GUI: URL http://localhost:8000/mcp, transport Streamable-HTTP

Herramientas

HerramientaTítuloSugerenciasQué hace
summarize_database(schema='public')"Resumir esquema de base de datos y recuentos de filas"readOnlyHint: trueLista tablas en schema con columnas y recuentos de filas
run_read_only_query(query)"Ejecutar una consulta SQL de solo lectura"readOnlyHint: trueEnvuelve la consulta en BEGIN READ ONLY y devuelve filas como JSON
run_write_query(query)"Ejecutar una consulta SQL de escritura (con protecciones)"destructiveHint: trueValida la consulta contra la lista de bloqueo de protección, luego ejecuta. Deshabilitada por defecto — requiere --enable-write-query.

Protecciones para run_write_query

Las siguientes clases de sentencias se rechazan antes de la ejecución:

  • DROP DATABASE/SCHEMA, ALTER DATABASE, CREATE DATABASE
  • Operaciones de roles/privilegios: GRANT, REVOKE, CREATE/ALTER/DROP ROLE, CREATE/ALTER/DROP USER
  • Código almacenado que puede ejecutarse bajo el propietario (SECURITY DEFINER): CREATE FUNCTION, CREATE PROCEDURE, ALTER FUNCTION, ALTER PROCEDURE
  • Sistema de archivos / ejecución de código: COPY TO/FROM, LOAD, DO $$ … $$ anónimo, CREATE EXTENSION
  • Configuración del servidor: ALTER SYSTEM, RESET ALL
  • Funciones integradas peligrosas: pg_sleep, pg_read_file, pg_write_file, lo_import, lo_export, dblink
  • Aislamiento de esquemas: SET search_path, CREATE SCHEMA
  • Consultas de múltiples sentencias (cualquier cosa con un punto y coma separador)
  • Meta-comandos psql (\c, \d, \!)
  • Opcionalmente UPDATE / DELETE sin cláusula WHERE

El tiempo de ejecución de INSERT / UPDATE / DELETE / DDL está limitado por YB_MCP_STATEMENT_TIMEOUT_MS (SET LOCAL statement_timeout aplicado a cada escritura) — un INSERT … SELECT descontrolado o un INSERT … VALUES amplio se elimina por la base de datos, no por un límite estático de filas.

CREATE TABLE … AS SELECT y SELECT … INTO son copias de filas ilimitadas estructuralmente similares pero están intencionalmente permitidas — son la forma común de materializar una instantánea desde una consulta.

Esta lista es de buena fe, no exhaustiva. destructiveHint: true es la segunda línea de defensa.

Modo remoto autohospedado

Para implementaciones multiusuario o compartidas, ejecuta el servidor como Streamable HTTP detrás de un proxy inverso con TLS, con OAuth de Cognito (u OIDC genérico) controlando el acceso. La configuración completa — configuración del proveedor, mapeo de SET ROLE por usuario, el formato del archivo de mapa de identidad, el atajo /auth/login y las pautas de seguridad — está en OIDC.md.

Seguro por defecto: desde la corrección, el modo HTTP se enlaza a 127.0.0.1 por defecto y se niega a iniciar cuando ambas condiciones son verdaderas:

  • El host de enlace no es loopback (MCP_HOST configurado en 0.0.0.0 o una dirección específica)
  • No hay proveedor de autenticación configurado (MCP_AUTH_PROVIDER sin configurar)

Para una implementación compartida / en red, configura tanto MCP_HOST=0.0.0.0 como MCP_AUTH_PROVIDER:

export MCP_HOST=0.0.0.0                # expose beyond loopback (default: 127.0.0.1)
export MCP_AUTH_PROVIDER=cognito
export MCP_BASE_URL=https://mcp.example.com
export COGNITO_USER_POOL_ID=us-west-2_XXXXXXXX
export COGNITO_AWS_REGION=us-west-2
export COGNITO_CLIENT_ID=…
export COGNITO_CLIENT_SECRET=…
export YUGABYTEDB_URL=…
export MCP_ALLOWED_ORIGINS=https://mcp.example.com,https://claude.ai

yugabytedb-mcp --transport http --stateless-http

Para uso solo de desarrollo sin autenticación en 0.0.0.0, configura MCP_ALLOW_UNAUTHENTICATED=true — el servidor se inicia con una ADVERTENCIA prominente. No uses esto en producción.

Comportamiento:

  • Las solicitudes a /mcp sin un token Bearer válido devuelven 401.
  • Las solicitudes con un encabezado Origin no permitido devuelven 403 (defensa contra DNS-rebinding).
  • /ping no está autenticado y es adecuado para sondas de actividad.
  • /auth/login expone un atajo de email+contraseña de Cognito → token (detalles en OIDC.md).
  • --stateless-http es requerido para implementaciones con múltiples réplicas — sin él, el estado de la sesión MCP vive en la memoria del proceso y el balanceo de carga round-robin rompe las sesiones.

AWS Secrets Manager para certificados TLS

Si el certificado raíz TLS de tu base de datos está almacenado en AWS Secrets Manager, el servidor puede obtenerlo y usarlo automáticamente. Se admite PEM en texto plano; también paquetes con clave JSON (configura YB_AWS_SSL_ROOT_CERT_KEY para elegir uno).

yugabytedb-mcp \
  --yugabytedb-url "host=… port=5433 dbname=… user=… password=… sslmode=verify-full" \
  --yb-aws-ssl-root-cert-secret-arn arn:aws:secretsmanager:us-east-1:…:secret:my-cert \
  --yb-aws-ssl-root-cert-secret-region us-east-1

Docker

docker build -t mcp/yugabytedb .
docker run -p 8000:8000 -e YUGABYTEDB_URL="…" mcp/yugabytedb yugabytedb-mcp --transport http

Seguridad

  • Todo el SQL se ejecuta mediante consultas parametrizadas; la entrada del usuario nunca se interpola en cadenas de sentencias.
  • La herramienta de escritura está deshabilitada por defecto — debe habilitarse explícitamente con --enable-write-query.
  • La lista de protección de la herramienta de escritura (arriba) bloquea las clases de sentencias de mayor riesgo.
  • destructiveHint: true asegura que Claude Desktop muestre una confirmación por llamada para operaciones de escritura.
  • Cuando la autenticación OIDC está activa, SET ROLE por usuario aplica límites de privilegios a nivel de base de datos por llamador. Los nombres de roles se citan de forma segura con psycopg.sql.Identifier.
  • El transporte HTTP requiere un token Bearer válido cuando MCP_AUTH_PROVIDER está configurado.
  • El transporte HTTP valida el encabezado Origin contra MCP_ALLOWED_ORIGINS (predeterminado a MCP_BASE_URL).
  • HTTPS es responsabilidad del operador — termina TLS en un proxy inverso (nginx, ALB, etc.) frente al servidor.
  • Ejecuta con un rol de base de datos de privilegios mínimos (rol de solo lectura para implementaciones solo con run_read_only_query; de lo contrario, un rol limitado a los esquemas objetivo, sin superusuario).

Reporta problemas de seguridad de forma privada a support@yugabyte.com — por favor no abras problemas públicos de GitHub para vulnerabilidades.

Política de privacidad

Se aplica la política de privacidad de Yugabyte: https://www.yugabyte.com/privacy-policy/

Este servidor MCP no transmite telemetría. Todo el acceso a la base de datos permanece entre Claude (tu cliente MCP) y tu instancia de YugabyteDB a través de la cadena de conexión que proporcionas. El servidor registra localmente en stderr (controlado por YB_LOG_LEVEL) — no hay agregación de registros remota integrada.

Desarrollo

git clone git@github.com:yugabyte/yugabytedb-mcp-server.git
cd yugabytedb-mcp-server
uv sync
uv run yugabytedb-mcp --help

Nota: ya no hay un src/server.py que puedas ejecutar directamente. El diseño del paquete se reorganizó para la distribución en PyPI (punto de entrada + espacio de nombres), por lo que los módulos ahora viven bajo src/yugabytedb_mcp_server/. Siempre invoca a través del script de consola yugabytedb-mcp (registrado por uv sync / pip install) — ejecutar el archivo del módulo con python omitiría el mecanismo de importación del paquete y rompería las importaciones relativas.

Comandos equivalentes:

uv run yugabytedb-mcp                 # uses the console script
uv run python -m yugabytedb_mcp_server # uses the __main__.py shim

Probando el conector localmente en Claude Desktop

Dos rutas, dependiendo de qué tan cerca de la experiencia de instalación de producción quieras estar:

Más rápido — sin compilación MCPB, solo apunta Claude Desktop al punto de entrada local. Después de uv sync, el script yugabytedb-mcp está en tu $PATH (a través del venv activo). Agrega esto a tu claude_desktop_config.json:

{
  "mcpServers": {
    "yugabytedb-dev": {
      "command": "/absolute/path/to/repo/.venv/bin/yugabytedb-mcp",
      "env": {
        "YUGABYTEDB_URL": "host=localhost port=5433 dbname=yugabyte user=yugabyte password=yugabyte",
        "YB_LOG_LEVEL": "DEBUG"
      }
    }
  }
}

Reinicia Claude Desktop. Usa ~/Library/Logs/Claude/mcp-server-yugabytedb-dev.log (macOS) para inspeccionar la salida de depuración. Esto omite el empaquetado MCPB por completo y es el bucle correcto para iterar en el código de las herramientas. Más cerca de producción: crea un .mcpb y arrástralo a Claude Desktop. Requiere la CLI de MCPB:

npm install -g @modelcontextprotocol/mcpb-cli   # one-time
mcpb validate manifest.json                      # static check
mcpb pack .                                      # produces yugabytedb-mcp-server-<version>.mcpb

Arrastra el .mcpb resultante a Claude Desktop: la interfaz del instalador del conector se encarga del resto, solicitando los valores de user_config definidos en manifest.json. La ruta de .mcpb es la más cercana a lo que los revisores ejercitarán. Nota: el mcp_config del manifiesto ejecuta uvx yugabytedb-mcp-server, que obtiene el paquete de PyPI en el primer lanzamiento. Asegúrate de que la versión referenciada por tu .mcpb esté publicada antes de compartir el paquete.

Pruebas

# unit tests (no DB, no network)
uv run pytest tests/test_guardrails.py tests/test_auth.py tests/test_identity_mapping.py

# integration tests (require a reachable Postgres-compatible DB)
YUGABYTEDB_URL="host=… port=… …" uv run pytest tests/

Consulta tests/README.md para la tabla de cobertura y la receta manual de prueba de humo con Cognito.

Solución de problemas

  • spawn yugabytedb-mcp ENOENT desde Claude Desktop → asegúrate de que el directorio de instalación esté en el PATH que Claude Desktop ve; pipx ensurepath o crea un enlace simbólico del punto de entrada en /usr/local/bin.
  • La lista de herramientas está vacía en el cliente MCP → reinicia el cliente; revisa la salida de YB_LOG_LEVEL=DEBUG para detectar errores de conexión durante el ciclo de vida.
  • "Transacción inválida o expirada" / "Cliente no registrado" en modo HTTP+OAuth con múltiples réplicas → consulta la sección remota autoalojada; --stateless-http es obligatorio para múltiples réplicas.

Licencia

Licencia Apache 2.0.