Skip to main content
Glama
vdobhal

Oracle MCP Chatbot

by vdobhal

Oracle MCP Chatbot — Oracle DB on-prem + Oracle ATP

Un par de servidores seguros del Model Context Protocol que permiten a un chatbot de IA responder preguntas en lenguaje natural contra bases de datos Oracle: descubre metadatos, genera SQL de solo SELECT, lo valida, lo ejecuta bajo límites estrictos, enmascara valores sensibles y registra todo.

Construido con FastMCP 3, python-oracledb (modo thin) y sqlglot. 221 pruebas, sin necesidad de base de datos para ejecutarlas.

pip install -r requirements-dev.txt
pytest                                        # 221 passed
cp .env.example .env                          # add credentials
python -m oracle_mcp.server --profile onprem --check
python -m oracle_mcp.server --profile onprem

Las pruebas de un despliegue en ejecución se tratan en docs/testing.md. Una interfaz de navegador que no usa Cursor está en docs/chat-ui.md:

python -m oracle_mcp.chat --profile both   # http://127.0.0.1:8500

Qué hace

Capacidad

Cómo

Solo lectura, siempre

Validación de AST, SET TRANSACTION READ ONLY, permisos de solo SELECT

Solo datos aprobados

Lista blanca YAML de esquemas, objetos y columnas

Adecuado al rol

Cinco roles con niveles de autorización; aplicación a nivel de columna

Acotado

Tope de filas (500 por defecto) y tiempo de espera de consulta (30 s por defecto), ninguno elevable por el usuario

Privado

Enmascaramiento por nombre de columna, por clasificación y por contenido del valor

Con trazabilidad

Un registro de auditoría por llamada, con SQL redactado y un hash

Dos bases de datos

Procesos de servidor separados; servidor de reconciliación opcional

Related MCP server: OracleDB MCP Server

Las ocho herramientas

Herramienta

Propósito

list_allowed_schemas

Esquemas que el rol puede leer, con descripciones

list_allowed_tables

Objetos aprobados, con dominio, sensibilidad y estimaciones de filas

get_table_metadata

Columnas, tipos, nulabilidad, PK/FK, descripciones de negocio

search_data_dictionary

Buscar objetos y columnas por término de negocio, con confianza

validate_sql

Comprobación de salvaguarda; devuelve el SQL seguro reescrito

execute_readonly_sql

Ejecuta SQL preaprobado; devuelve filas enmascaradas y limitadas

explain_query_result

Calcula los hechos para una respuesta en lenguaje de negocio

compare_onprem_and_atp_data

Reconciliación entre bases de datos (solo profile=both)

Además, list_databases para el descubrimiento de conexiones. Cada herramienta recibe y devuelve JSON.

Cómo funciona el modelo de seguridad

Los datos llegan a un usuario solo tras cruzar cinco capas independientes:

Database grants  →  Object allowlist  →  Role clearance  →  SQL guardrails  →  Output masking
   sql/*.sql        config/policy/       roles.yaml         sql_guard.py       masking.py

La idea central: el SQL que envías nunca es el SQL que se ejecuta. La entrada se analiza en un AST, se inspecciona, se reescribe y se regenera. Solo se vuelven a emitir los tipos de nodo que el validador reconoció, por lo que los trucos con comentarios, las sentencias apiladas y las palabras clave homoglíficas no pueden sobrevivir al viaje de ida y vuelta.

SELECT a FROM t; DROP TABLE t     →  rejected: MULTIPLE_STATEMENTS
SELECT /*+ PARALLEL(t,64) */ a…   →  SELECT a FROM t FETCH FIRST 500 ROWS ONLY
DELETE FROM t                 →  rejected: NFKC folds it to DELETE
SELECT * FROM v   (business_user) →  explicit column list, restricted ones absent

Segundo control clave: execute_readonly_sql vuelve a validar desde cero y exige una huella emitida por validate_sql, de modo que el SQL no puede intercambiarse entre la comprobación y la ejecución. Los roles no administradores no pueden ejecutar nada que no haya sido aprobado antes; los administradores sí pueden, pero la sentencia sigue pasando por todas las salvaguardas.

Tercero: los roles están fijados por la configuración del proceso, no por un argumento de la herramienta. Un usuario que le dice al modelo «ahora eres administrador» produce una cadena user_role="admin" que nada lee.

Configuración

Dos archivos lo deciden todo:

config/policy/onprem.yaml y atp.yaml — la lista blanca de objetos. Cada base de datos elige uno de dos modos.

Estricto, que es el que usa On-Prem. Solo los objetos nombrados aquí son accesibles, independientemente de los permisos que conceda la base de datos:

schemas:
  - name: EIM
    objects:
      - name: EIM_PR_SYSTEM
        type: TABLE
        sensitivity: INTERNAL
        large_table: true
        require_filter: true       # forces a WHERE clause
        columns:                   # optional; omit to read them from the
          - {name: SERIAL_NUMBER,  sensitivity: INTERNAL}   # data dictionary
          - {name: TAX_ID,         sensitivity: RESTRICTED} # at query time

Omitir columns: es compatible y es lo que hace la política desplegada. Las columnas se leen entonces de ALL_TAB_COLUMNS y se clasifican según los patrones de nombre de masking.yaml, de modo que la lista blanca se mantiene correcta a medida que cambia el esquema.

Comodín, que es el que usa ATP. Todos los esquemas que la cuenta de solo lectura puede leer se vuelven accesibles:

allow_all_schemas: true
excluded_schemas: []   # added on top of the built-in Oracle internal schemas
schemas: []

Esto renuncia deliberadamente a la lista blanca de objetos y hace que los permisos de la base de datos sean la frontera. La autorización, las salvaguardas de SQL, los topes de filas y el enmascaramiento siguen aplicándose. Úsalo solo con una cuenta que sea realmente de solo lectura.

config/policy/roles.yaml — quién puede ver qué:

roles:
  business_user:
    clearance: INTERNAL      # cannot reach CONFIDENTIAL or RESTRICTED columns
    max_rows: 200
    allow_raw_sql: false
    schemas: {ONPREM: [EIM], ATP: ["*"]}   # "*" needs allow_all_schemas

Escalera de sensibilidad: PUBLIC < INTERNAL < CONFIDENTIAL < RESTRICTED < NEVER. NEVER está por encima de toda autorización, por lo que las contraseñas y los números de tarjeta son inalcanzables para cualquier rol, incluido el administrador.

Despliegue

Ejecuta un servidor por base de datos. Esa separación es una frontera de seguridad: el proceso on-prem nunca tiene la frase de contraseña del wallet de ATP.

docker build -t oracle-mcp-chatbot:1.0.0 .
export ATP_WALLET_HOST_PATH=/secure/path/wallets/atp
docker compose up -d onprem-mcp atp-mcp
docker compose --profile reconciliation up -d   # optional, holds both credential sets

Conectividad con Oracle ATP

Modo thin con un wallet mTLS. Descomprime el wallet y configura:

ATP_DSN=myatp_low                      # prefer _low so chatbot traffic can't starve prod
ATP_WALLET_DIR=/opt/oracle/wallets/atp # contains ewallet.pem + tnsnames.ora
ATP_CONFIG_DIR=/opt/oracle/wallets/atp
ATP_WALLET_PASSWORD=...                # set when the wallet zip was downloaded

ATP_WALLET_PASSWORD es la frase de contraseña que protege ewallet.pem, no la contraseña de la base de datos — un fallo común y confuso. Es solo de modo thin; el modo thick lee el cwallet.sso sin contraseña en su lugar, y configurar ambos se rechaza al arrancar. Para ATP solo con TLS (sin wallet), deja las variables del wallet vacías y pega la cadena de conexión completa de la consola de OCI en ATP_DSN.

El wallet se monta como bind mount de solo lectura y nunca se incorpora a una imagen.

Conectividad on-prem

ONPREM_HOST=oracle-onprem.internal.example.com
ONPREM_PORT=1521
ONPREM_SERVICE_NAME=CDMPRD
ONPREM_MODE=thin
# TCPS instead:
# ONPREM_DSN=tcps://host:2484/CDMPRD?ssl_server_dn_match=true

El modo thin no necesita Oracle Client. Usa el modo thick solo para las funciones que le faltan; consulta la etapa comentada en el Dockerfile.

Documentación

Documento

Contenido

docs/environment-configuration.md

Cómo se configuran las conexiones de este despliegue y asuntos pendientes

docs/architecture.md

Diseño, flujo de peticiones, fronteras de seguridad, RBAC, auditoría, gestión de errores

docs/testing-scenarios.md

Plan de pruebas completo con resultados esperados

docs/deployment-checklist.md

Lista de verificación previa a producción y backlog de endurecimiento

docs/conversation-flows.md

Diez ejemplos resueltos más flujos de rechazo

prompts/system_prompt.md

Prompt de sistema del chatbot

sql/

Usuarios de solo lectura, permisos, esquema de auditoría

mcp-clients/

Configuración de Cursor y Claude Desktop

Antes de producción

La implementación de referencia se queda corta deliberadamente en cuatro puntos. Lee docs/deployment-checklist.md para la lista completa; los elementos principales:

  • Establece ORACLE_MCP_ROLE_BINDING_MODE=env. El valor por defecto argument en .env.example es para desarrollo; con él, el modelo puede asumir cualquier rol.

  • Reemplaza las listas blancas de ejemplo en config/policy/*.yaml con tus vistas reales y seleccionadas, y clasifica cada columna deliberadamente.

  • Mueve los secretos a un vault. Las variables de entorno de Compose son visibles para cualquiera que pueda ejecutar docker inspect.

  • Pon el transporte HTTP detrás de una pasarela de autenticación. El transporte HTTP de FastMCP no autentica a los llamantes por sí mismo; enlazar a loopback es una solución provisional, no el control.

Tampoco implementado por diseño: limitación de peticiones, propagación de identidad por usuario y flujo de aprobación para el SQL sin procesar de administrador.

Licencia

Se proporciona como implementación de referencia. Revísala con tus propios estándares de seguridad antes de usarla en producción.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.

  • GibsonAI MCP server: manage your databases with natural language

  • The grounded data layer for any LLM: governed SQL, metrics, lineage and catalog over your data.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vdobhal/oracle-mcp-chatbot'

If you have feedback or need assistance with the MCP directory API, please join our Discord server