oracle-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@oracle-mcp-serverlist tables in the VENTAS schema on the facturacion connection"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
oracle-mcp-server
Repositorio: github.com/ElvinCooper/oracle-mcp-server
Oracle Database MCP Server: servidor MCP (Model Context Protocol) en
Python que permite a agentes de IA y clientes compatibles con MCP
interactuar con bases Oracle Database a través de python-oracledb.
A Python-based Model Context Protocol (MCP) server that enables AI coding agents and MCP-compatible clients to interact with Oracle Database environments through python-oracledb.
Usa python-oracledb en modo thick con Oracle Instant Client, con
soporte orientado a entornos Oracle antiguos, incluido Oracle 11g (el modo
thin del driver solo soporta Oracle 12.1+; las versiones posteriores dependen
del soporte del propio driver). Ver Notas sobre Oracle 11g y modo thick.
Soporta múltiples conexiones a Oracle y funciona con cualquier cliente MCP: opencode, Claude Code, Cursor, Codex, Continue.dev, etc.
⚡ Quick Start (puesta en marcha rápida)
# 1. Clonar o copiar el proyecto
cd C:\ruta\oracle-mcp-server
# 2. Ejecutar setup (crea .venv, instala dependencias, copia .env)
.\setup.ps1
# 3. Editar .env con tus credenciales Oracle
notepad .env
# 4. Iniciar el servidor
.\.venv\Scripts\oracle-mcpSi ves Pools Oracle listos en la salida, ya está funcionando.
Requisitos: Python 3.10+ y Oracle Instant Client instalado.
Related MCP server: Mini Oracle MCP Server
Tools expuestas
Tool | Descripción |
| Lista tablas de un schema (o del usuario actual) |
| Devuelve columnas, tipo de dato, nulabilidad, longitud |
| Ejecuta un |
| Ejecuta |
| Lista todas las conexiones a Oracle disponibles |
Parámetro connection: Todas las tools anteriores (excepto
list_connections) aceptan un parámetro opcional connection para especificar
a qué base de datos conectar. Si no se especifica, usa la primera conexión de
la lista (conexión por defecto).
Parámetros adicionales:
list_tables(schema, connection):schemaes el owner en mayúsculas (ej.VENTAS); si se omite, lista las tablas del usuario actual.describe_table(table_name, schema, connection):schemaindica el owner si la tabla pertenece a otro usuario.run_query(sql, max_rows, connection):max_rowslimita las filas devueltas en la llamada (por defecto usa el_MAX_ROWSde la conexión). El resultado incluyerow_count,truncated(si quedaron filas sin devolver) ylimit_applied.
Seguridad
Operaciones de lectura (read-only)
run_query está diseñada para operaciones de lectura y valida cada
consulta: exige que la sentencia comience con SELECT o WITH y rechaza
múltiples sentencias separadas por ;, bloqueando por diseño intentos de
inyección con sentencias de escritura encadenadas.
Operaciones de escritura (write operations)
execute_statement ejecuta INSERT/UPDATE/DELETE/DDL y está bloqueada por
defecto. Habilitarla requiere dos condiciones explícitas:
Configuración:
ORACLE_CONN_<NOMBRE>_ALLOW_WRITE=true(oORACLE_ALLOW_WRITE=trueen modo legacy), definida por conexión.Llamada: pasar
confirm=trueen cada invocación.
El permiso se configura de forma explícita y auditable en cada conexión, y
además se confirma en cada uso (un doble seguro). Habilitar operaciones de
escritura debe ser una decisión consciente: por defecto todas las
conexiones son de solo lectura y se recomienda conservar ALLOW_WRITE=false
salvo que una conexión específica realmente lo requiera.
Credenciales
Las credenciales viven en variables de entorno (o en el archivo .env), nunca
hardcodeadas en el código, y en este documento se muestran únicamente
placeholders de ejemplo (your_user, your_password).
1. Requisitos previos
Python 3.10+
Oracle Instant Client ya instalado (dijiste que ya lo tienes disponible). Necesitas la ruta del directorio con
libclntsh.so(Linux/Mac) ooci.dll(Windows), por ejemplo/opt/oracle/instantclient_11_2.Acceso de red al listener de Oracle (host:puerto) y un SID o service_name.
2. Instalación
La instalación se realiza con el script .\setup.ps1 (Windows), que crea
el .venv, instala las dependencias y copia .env desde .env.example.
Automática (Windows)
cd C:\ruta\oracle-mcp-server
.\setup.ps1Manual (Windows / Linux / Mac)
cd oracle-mcp-server
python3 -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
pip install -e .Nota de versiones: el proyecto usa la API de MCP 1.x (
mcp.server.fastmcp). Tantopyproject.tomlcomorequirements.txtfijanmcp>=1.6.0,<2para evitar que una instalación resuelvamcp2.x (que eliminó esa API). Si en tu entorno aparecemcp2.x, reinstala con el pin:pip install -e ".[dev]"(opip install "mcp>=1.6.0,<2").
3. Configuración
Opción A: Múltiples conexiones (Recomendado)
Copia .env.example a .env y completa tus datos:
cp .env.example .envFormato para múltiples conexiones:
# Lista de conexiones (nombres separados por comas)
ORACLE_CONNECTIONS=facturacion,clinica
# Conexion "facturacion"
ORACLE_CONN_FACTURACION_USER=your_user
ORACLE_CONN_FACTURACION_PASSWORD=your_password
ORACLE_CONN_FACTURACION_HOST=your_oracle_host
ORACLE_CONN_FACTURACION_PORT=1521
ORACLE_CONN_FACTURACION_SID=ORCL
ORACLE_CONN_FACTURACION_CLIENT_LIB_DIR=/opt/oracle/instantclient_11_2
ORACLE_CONN_FACTURACION_ALLOW_WRITE=false
ORACLE_CONN_FACTURACION_MAX_ROWS=200
# Conexion "clinica"
ORACLE_CONN_CLINICA_USER=your_user
ORACLE_CONN_CLINICA_PASSWORD=your_password
ORACLE_CONN_CLINICA_HOST=your_oracle_host
ORACLE_CONN_CLINICA_PORT=1521
ORACLE_CONN_CLINICA_SID=ORCL
ORACLE_CONN_CLINICA_CLIENT_LIB_DIR=/opt/oracle/instantclient_11_2Opción B: Una sola conexión (Legacy - Retrocompatible)
Si ORACLE_CONNECTIONS no está definido, el servidor busca variables legacy:
ORACLE_USER=your_user
ORACLE_PASSWORD=your_password
ORACLE_HOST=your_oracle_host
ORACLE_PORT=1521
ORACLE_SID=ORCL
ORACLE_CLIENT_LIB_DIR=/opt/oracle/instantclient_11_2
ORACLE_ALLOW_WRITE=false
ORACLE_MAX_ROWS=200Variables por conexión
Variable | Descripción | Default |
| Usuario de Oracle | (requerido) |
| Contraseña | (requerido) |
| Host del servidor | (requerido) |
| Puerto | 1521 |
| SID de Oracle | - |
| Service name | - |
| Ruta al Instant Client | - |
| Habilitar escritura | false |
| Límite de filas por query | 200 |
| Timeout conexión (seg) | 10 |
| Mínimo conexiones en pool | 1 |
| Máximo conexiones en pool | 4 |
Convención de Nombres de Variables
Regla de oro: El nombre de la conexión en ORACLE_CONNECTIONS define los
nombres de todas las variables de entorno asociadas.
Paso | Ejemplo |
Nombre en |
|
Convertir a MAYÚSCULAS |
|
Agregar prefijo |
|
Agregar sufijo |
|
ORACLE_CONNECTIONS: "facturacion,afp_pruebas"
↓ ↓
"facturacion" "afp_pruebas"
↓ ↓
ORACLE_CONN_FACTURACION_* ORACLE_CONN_AFP_PRUEBAS_*Convención Recomendada para Nombres
Para mantener consistencia y facilitar el mantenimiento:
Tipo de Base | Ejemplo de Nombre | Variable |
Producción |
|
|
Desarrollo |
|
|
Pruebas |
|
|
Por área funcional |
|
|
Recomendaciones:
Usar snake_case (minúsculas con guión bajo):
mi_conexionSin espacios:
afp_pruebasen lugar deAFP PruebasNombres descriptivos: que indiquen el propósito de la conexión
Evitar caracteres especiales: solo letras, números y guión bajo
Fuentes de Variables de Entorno
Las variables pueden provenir de múltiples fuentes (por orden de prioridad):
Variables ya definidas en el entorno del proceso (incluye el bloque
environmentdeopencode.jsonc) (mayor prioridad)Variables del sistema Windows (persistente)
Archivo
.env(cargado por python-dotenv desde la raíz del proyecto)
Recomendación: usa una sola fuente de verdad. La opción recomendada es
mantener todas las conexiones en el .env (archivo en .gitignore, sin
credenciales en opencode.jsonc). Para agregar una conexión, añade su nombre a
ORACLE_CONNECTIONS y define sus variables ORACLE_CONN_<NOMBRE>_* en el
mismo archivo.
Tolerancia a configuraciones incompletas: si una conexión en
ORACLE_CONNECTIONS no tiene sus variables obligatorias
(ORACLE_CONN_<NOMBRE>_USER, _PASSWORD, _HOST) o tiene valores inválidos
(p. ej. puerto no numérico), el servidor la omite al arrancar, registra un
warning en consola con el nombre y el motivo, y continúa con las conexiones
válidas. Solo si ninguna conexión es válida, el servidor se detiene con un
error.
Credenciales fuera del .env (variables del sistema)
Si prefieres no guardar credenciales en texto plano dentro del .env, puedes
definir el usuario y la contraseña como variables de entorno del sistema. Es
totalmente opcional: si no defines estas variables, el servidor usa las
del .env como siempre.
Importante: el proceso debe arrancar después de crear la variable. Reinicia la terminal y el cliente MCP para que hereden el nuevo entorno.
Opción A — Variable del sistema con el mismo nombre (recomendada):
El nombre de la variable debe coincidir con el de la conexión
(ORACLE_CONN_<NOMBRE>_USER / ORACLE_CONN_<NOMBRE>_PASSWORD). Estas
variables tienen prioridad sobre las del .env (python-dotenv no sobrescribe
variables ya definidas), por lo que se pueden combinar: los secretos en el
sistema y el resto de la configuración en el .env. Ejemplo para la conexión
facturacion:
# Windows (scope "User": solo tu usuario de Windows)
[Environment]::SetEnvironmentVariable("ORACLE_CONN_FACTURACION_USER", "your_user", "User")
[Environment]::SetEnvironmentVariable("ORACLE_CONN_FACTURACION_PASSWORD", "your_password", "User")# Linux / Mac (agrega a ~/.bashrc o ~/.zshrc y recarga: source ~/.bashrc)
export ORACLE_CONN_FACTURACION_USER="your_user"
export ORACLE_CONN_FACTURACION_PASSWORD="your_password"Opción B — Referencia desde el .env (nombre libre):
Puedes usar un nombre de variable propio en el sistema y referenciarlo desde
el .env con ${VAR}:
ORACLE_CONN_FACTURACION_USER=${ORACLE_FACTURACION_USER}
ORACLE_CONN_FACTURACION_PASSWORD=${ORACLE_FACTURACION_PASSWORD}Los valores de ORACLE_FACTURACION_USER / ORACLE_FACTURACION_PASSWORD se
definen como variables del sistema. Si la variable referenciada no existe,
python-dotenv la deja vacía y el servidor falla con
Faltan variables obligatorias, indicando cuál falta.
Verificar que la variable quedó definida:
[Environment]::GetEnvironmentVariable("ORACLE_CONN_FACTURACION_PASSWORD", "User")echo $ORACLE_CONN_FACTURACION_PASSWORDTambién puedes usar los scripts set-secrets.ps1 (Windows) y set-secrets.sh
(Linux/Mac) incluidos en el proyecto para fijar usuario y contraseña de forma
interactiva.
4. Pruebas
La suite usa pytest y no necesita Oracle: test_server.py sustituye
los pool/cursor de la base por dobles en memoria.
pip install -e ".[dev]" # instala pytest y las dependencias de desarrollo
pytest # o: python -m pytestSon 114 tests que cubren: carga legacy y multi-conexión, omisión de
conexiones incompletas (tolerancia), DSN por SID / SERVICE_NAME, validación
solo-SELECT y doble confirmación de escritura (ALLOW_WRITE + confirm),
serialización de LOBs y las 5 tools del servidor (conexión por defecto,
max_rows y truncado incluidos).
En CI (GitHub Actions) la suite corre en Python 3.10–3.12 y un segundo job
verifica que el paquete se construye con python -m build.
5. Probarlo de forma independiente
Puedes levantar el servidor manualmente para verificar que conecta:
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
python -m oracle_mcp.serverO usando el entry point directo (disponible después de pip install -e .):
oracle-mcp # si el venv está activo
# o desde la ruta absoluta:
.venv/Scripts/oracle-mcp # Windows
.venv/bin/oracle-mcp # Linux/MacSi ves en el log Pools Oracle listos: N seguido de
Conexiones Oracle disponibles: N con la lista de conexiones, la conexión
en thick mode funcionó. El proceso queda esperando mensajes MCP por stdio
(Ctrl+C para salir).
6. Integración con clientes MCP
El servidor se comunica por STDIO (estándar en MCP para procesos locales). Cada cliente MCP tiene su propia configuración; aquí están las más comunes.
Importante: Usa siempre la ruta absoluta al Python del
.venv(así el cliente no depende de que el venv esté activado).
opencode
Define el servidor en el bloque mcp de opencode.json (o ~/.config/opencode/opencode.jsonc):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"oracle": {
"type": "local",
"command": [
"C:/ruta/completa/oracle-mcp-server/.venv/Scripts/python",
"-m",
"oracle_mcp.server"
],
"enabled": true,
"environment": {
"ORACLE_CONNECTIONS": "facturacion,clinica",
"ORACLE_CONN_FACTURACION_USER": "your_user",
"ORACLE_CONN_FACTURACION_PASSWORD": "your_password",
"ORACLE_CONN_FACTURACION_HOST": "your_oracle_host",
"ORACLE_CONN_FACTURACION_PORT": "1521",
"ORACLE_CONN_FACTURACION_SID": "ORCL",
"ORACLE_CONN_FACTURACION_CLIENT_LIB_DIR": "C:/oracle/instantclient_11_2",
"ORACLE_CONN_CLINICA_USER": "your_user",
"ORACLE_CONN_CLINICA_PASSWORD": "your_password",
"ORACLE_CONN_CLINICA_HOST": "your_oracle_host",
"ORACLE_CONN_CLINICA_PORT": "1521",
"ORACLE_CONN_CLINICA_SID": "ORCL",
"ORACLE_CONN_CLINICA_CLIENT_LIB_DIR": "C:/oracle/instantclient_11_2"
}
}
}
}Un archivo de ejemplo (opencode.json.example) está incluido en el proyecto.
Nota de seguridad: el bloque
environmentde arriba incluye credenciales solo con fines de ejemplo. La opción recomendada es omitirenvironmenty definir todas las conexiones en el archivo.env(ver sección 3).
Claude Code
Agrega el servidor en .claude.json (en la raíz del proyecto o global en %USERPROFILE%\.claude\):
{
"mcpServers": {
"oracle": {
"type": "local",
"command": "C:\\ruta\\oracle-mcp-server\\.venv\\Scripts\\python",
"args": ["-m", "oracle_mcp.server"],
"env": {
"ORACLE_CONNECTIONS": "facturacion",
"ORACLE_CONN_FACTURACION_USER": "your_user",
"ORACLE_CONN_FACTURACION_PASSWORD": "your_password",
"ORACLE_CONN_FACTURACION_HOST": "your_oracle_host",
"ORACLE_CONN_FACTURACION_PORT": "1521",
"ORACLE_CONN_FACTURACION_SID": "ORCL",
"ORACLE_CONN_FACTURACION_CLIENT_LIB_DIR": "C:\\oracle\\instantclient_11_2"
}
}
}
}Cursor
En ./cursor/mcp.json del proyecto:
{
"mcpServers": {
"oracle": {
"type": "local",
"command": "C:\\ruta\\oracle-mcp-server\\.venv\\Scripts\\python",
"args": ["-m", "oracle_mcp.server"],
"env": {
"ORACLE_CONNECTIONS": "facturacion",
"ORACLE_CONN_FACTURACION_USER": "your_user",
"ORACLE_CONN_FACTURACION_PASSWORD": "your_password",
"ORACLE_CONN_FACTURACION_HOST": "your_oracle_host",
"ORACLE_CONN_FACTURACION_PORT": "1521",
"ORACLE_CONN_FACTURACION_SID": "ORCL",
"ORACLE_CONN_FACTURACION_CLIENT_LIB_DIR": "C:\\oracle\\instantclient_11_2"
}
}
}
}Otros clientes MCP
Cualquier cliente que soporte servidores MCP tipo local/stdio puede usar la misma configuración base:
Campo | Valor |
command |
|
args |
|
env | Tus variables |
Nota: Si usas .env para las credenciales, el servidor las cargará
automáticamente desde la raíz del proyecto, sin importar el directorio desde
el que se arranque el proceso.
Puntos importantes
Usa la ruta absoluta al Python del
.venvReinicia/recarga el cliente MCP después de editar la configuración
Puedes verificar que el servidor responde con el comando de prueba de la sección 5
7. Uso de múltiples conexiones
Una vez configuradas las conexiones, puedes usarlas en las tools:
# Usar conexión por defecto (primera de la lista)
list_tables()
# Usar conexión específica
list_tables(connection="clinica")
# Query en conexión específica
run_query("SELECT * FROM pacientes", connection="clinica")
# Ver conexiones disponibles
list_connections()8. Notas sobre Oracle 11g y modo thick
oracledb.init_oracle_client(lib_dir=...)se llama una sola vez, antes de abrir cualquier conexión (lo hacedb.pyautomáticamente al arrancar el servidor). Usa elclient_lib_dirde la primera conexión que lo tenga definido.Si se te olvida configurar
CLIENT_LIB_DIRy el Instant Client no está en elPATH/LD_LIBRARY_PATH, oracledb lanzará un error indicando que no encuentra las librerías cliente.11g casi siempre se conecta por SID, no por service_name; por eso el DSN se construye con
oracledb.makedsn(host, port, sid=...)cuando definesSID.Si tu 11g tiene un Oracle Wallet o requiere TNS_ADMIN, puedes exportar
TNS_ADMINenenvironmentdentro deopencode.jsony ajustardb.pypara usardsndirectamente por alias TNS en vez demakedsn.
9. Estructura del proyecto
oracle-mcp-server/
├── LICENSE
├── README.md
├── pyproject.toml
├── requirements.txt
├── setup.ps1 # Script de instalación automática (Windows)
├── .env.example
├── opencode.json.example
├── .github/
│ └── workflows/
│ └── ci.yml # CI: tests (Python 3.10–3.12) y build del paquete
├── src/
│ └── oracle_mcp/
│ ├── __init__.py
│ ├── config.py # Carga de variables de entorno (multi-conexión)
│ ├── db.py # Init thick mode, multipools, validación SELECT-only
│ └── server.py # Servidor MCP (FastMCP) con tools multi-conexión
└── tests/
├── helpers.py # make_connection() con valores por defecto
├── conftest.py # limpia variables ORACLE_*/OX_* entre tests
├── test_config.py # carga de configuración legacy y multi-conexión
├── test_db.py # thick mode, validación, serialización de LOBs
└── test_server.py # tools MCP con pools ficticios10. Solución de Problemas
Problema | Causa Común | Solución |
| Nombre no coincide | Verificar que |
| Variable no definida | Verificar nombre de la variable en Windows o |
| Credenciales erróneas | Verificar valores con |
| Conexión no inicializó | Revisar logs del servidor al iniciar |
| Oracle no accessible | Verificar HOST, PORT y que el listener esté activo |
| SID/SERVICE_NAME incorrecto | Verificar ORACLE_SID o ORACLE_SERVICE_NAME |
11. Próximos pasos sugeridos
Agregar paginación real (cursor/offset) en
run_querysi necesitas recorrer resultados grandes en varias llamadas.Si vas a exponer
execute_statementen un entorno compartido, considera agregar unALLOWED_TABLESo un usuario Oracle con permisos acotados (grant solo sobre las tablas necesarias) en vez de confiar únicamente en la validación de la tool.
12. Licencia
Este proyecto está bajo la licencia MIT (ver LICENSE). Copyright (c) 2026 Elvin Cooper.
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Read-only MCP for identity resolution and write guardrails.
Paid remote MCP for governed database query review, SQL simulation, approvals, and audits.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables interaction with Oracle databases through MCP by executing SELECT queries, describing table structures, and listing available tables with secure, read-only access.312 npm2MIT
- AlicenseNot gradedqualityDmaintenanceMCP server to connect to Oracle databases and run SQL queries (up to 150 rows) via a single 'query' tool.15 npmMIT
- FlicenseNot gradedqualityCmaintenanceA read-only MCP server for Oracle databases that enables SQL queries, schema inspection, and data sampling without requiring OCI client libraries. It supports both TNS alias and direct connection modes with robust security guardrails.-
- FlicenseNot gradedqualityCmaintenanceEnables read-only querying and schema inspection of Oracle Database 10g through MCP tools or a Claude Code skill, with SELECT/WITH enforcement, row limits, timeouts, and audit logging.-