{"id":51422186,"url":"https://github.com/zademy/mcp-oracle-database","last_synced_at":"2026-07-05T00:30:33.497Z","repository":{"id":368953562,"uuid":"1287659529","full_name":"zademy/mcp-oracle-database","owner":"zademy","description":"MCP server for Oracle Database. Introspect schemas, run SQL/DML, call PL/SQL, and diagnose performance over STDIO — with safety enforced by Oracle's least-privilege model.","archived":false,"fork":false,"pushed_at":"2026-07-02T23:33:34.000Z","size":3508,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-07-03T01:14:47.342Z","etag":null,"topics":["ai-tools","database","java","mcp","mcp-oracle","oracle","spring-boot","sql"],"latest_commit_sha":null,"homepage":"https://zademy.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zademy.png","metadata":{"files":{"readme":"README.es.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-02T22:31:10.000Z","updated_at":"2026-07-03T01:13:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zademy/mcp-oracle-database","commit_stats":null,"previous_names":["zademy/mcp-oracle-database"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/zademy/mcp-oracle-database","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zademy%2Fmcp-oracle-database","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zademy%2Fmcp-oracle-database/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zademy%2Fmcp-oracle-database/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zademy%2Fmcp-oracle-database/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zademy","download_url":"https://codeload.github.com/zademy/mcp-oracle-database/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zademy%2Fmcp-oracle-database/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35140188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","database","java","mcp","mcp-oracle","oracle","spring-boot","sql"],"created_at":"2026-07-05T00:30:32.611Z","updated_at":"2026-07-05T00:30:33.446Z","avatar_url":"https://github.com/zademy.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n[English](README.md) | [Español](README.es.md)\n\n# mcp-oracle-db\n\nUn servidor [MCP](https://modelcontextprotocol.io) para **Oracle Database**,\nconstruido con Spring Boot y Spring AI.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Java](https://img.shields.io/badge/Java-26-orange.svg)](https://openjdk.org/)\n[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-4.1-6DB33F.svg)](https://spring.io/projects/spring-boot)\n[![Spring AI](https://img.shields.io/badge/Spring%20AI-2.0-6DB33F.svg)](https://spring.io/projects/spring-ai)\n[![Oracle JDBC](https://img.shields.io/badge/Oracle%20JDBC-23-red.svg)](https://www.oracle.com/database/)\n[![MCP](https://img.shields.io/badge/MCP-STDIO-blue.svg)](https://modelcontextprotocol.io)\n[![last commit](https://img.shields.io/github/last-commit/zademy/mcp-oracle-db)](https://github.com/zademy/mcp-oracle-db/commits/main)\n[![stars](https://img.shields.io/github/stars/zademy/mcp-oracle-database?style=social)](https://github.com/zademy/mcp-oracle-database/stargazers)\n\nPermite que cualquier cliente compatible con MCP (Claude Desktop, Cursor, Cline,\nContinue, VS Code, Windsurf, …) **introspecte** un esquema de Oracle y **ejecute\nSQL** — de forma segura.\n\n\u003c/div\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"images/info_es.png\"\u003e\u003cimg src=\"images/info_es.png\" width=\"100%\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## ¿Por qué mcp-oracle-db?\n\n- **Seguro por diseño** — la única barrera de seguridad es un **usuario de Oracle\n  de mínimos privilegios**. No hay filtro de SQL en la aplicación; el propio\n  Oracle rechaza cada `CREATE`/`ALTER`/`DROP`/`GRANT`/… con `ORA-01031`.\n- **70 herramientas** de introspección de esquema, diagnóstico de rendimiento,\n  asesoría de índices/consultas, utilidades de datos, DML, explain plan, grafos\n  de esquema, PL/SQL y sistema.\n- **Sin puerto web** — solo transporte STDIO. Nunca se expone un servidor\n  HTTP/SSE.\n- **Virtual threads** — hilos virtuales de Java 26, ideales para JDBC bloqueante.\n- **Sin secretos en el repositorio** — las credenciales provienen de variables\n  de entorno.\n\n**¿Para quién?** DBAs, desarrolladores backend y flujos asistidos por IA que\nnecesitan un acompañante Oracle local y orientado a lectura: explorar un esquema,\ndiagnosticar rendimiento, previsualizar DML y dejar que un LLM ejecute SQL\nad-hoc sin poner en riesgo la estructura de la base.\n\n## Qué hace\n\n**Ejecutado**\n\n- Lecturas de esquema — metadatos, DDL, código fuente PL/SQL, secuencias,\n  restricciones, particiones, diagnóstico de rendimiento vía vistas `V$`.\n- DML — `INSERT`, `UPDATE`, `DELETE`, `MERGE` sobre tablas existentes.\n- Invocación de PL/SQL — `call_procedure` (requiere `GRANT EXECUTE` sobre el\n  objeto).\n- Comentarios de metadatos — `COMMENT ON ...`.\n\n**Rechazado por Oracle** (el usuario de mínimos privilegios no tiene privilegios\nDDL/DCL)\n\n- Todo DDL estructural — todas las formas de `CREATE ...`, `ALTER`, `DROP`,\n  `TRUNCATE`, `RENAME`.\n- Todo DCL — `GRANT`, `REVOKE`, `PURGE`, `FLASHBACK`, `LOCK TABLE`, `AUDIT`,\n  `NOAUDIT`, `ANALYZE`.\n\n## Tabla de contenidos\n\n- [¿Por qué mcp-oracle-db?](#por-qué-mcp-oracle-db)\n- [Qué hace](#qué-hace)\n- [Requisitos](#requisitos)\n- [Inicio rápido](#inicio-rápido)\n  - [1. Crea el usuario de Oracle de mínimos privilegios](#1-crea-el-usuario-de-oracle-de-mínimos-privilegios)\n  - [2. Configura las credenciales (variables de entorno)](#2-configura-las-credenciales-variables-de-entorno)\n  - [3. Compila](#3-compila)\n  - [4. Conecta tu cliente MCP (STDIO)](#4-conecta-tu-cliente-mcp-stdio)\n  - [Primera sesión rápida](#primera-sesión-rápida)\n- [Configuración de clientes MCP](#configuración-de-clientes-mcp)\n- [Referencia de configuración](#referencia-de-configuración)\n- [Auditoría SQL](#auditoría-sql)\n- [Arquitectura](#arquitectura)\n- [Referencia de herramientas](#referencia-de-herramientas)\n- [Modelo de seguridad](#modelo-de-seguridad)\n- [Pruebas](#pruebas)\n- [Resolución de problemas y preguntas frecuentes](#resolución-de-problemas-y-preguntas-frecuentes)\n- [Limitaciones y notas](#limitaciones-y-notas)\n- [Contribuir y flujo de agentes](#contribuir-y-flujo-de-agentes)\n- [Licencia](#licencia)\n\n## Requisitos\n\n- **JDK 26**\n- **Apache Maven 3.9+** (alcanza con el wrapper `mvnw` incluido)\n- **Oracle Database 12c+** (probado con drivers 19c / 23ai)\n- Un **cliente MCP** que hable STDIO (Claude Desktop, Cursor, Cline, Continue,\n  VS Code, Windsurf, …)\n\n## Inicio rápido\n\n### 1. Crea el usuario de Oracle de mínimos privilegios\n\nEjecuta `db/setup_least_privilege_user.sql` como DBA. Edita primero los\nmarcadores `\u0026`.\n\n```bash\n# Linux / macOS\nsqlplus system/\u003ccontraseña-dba\u003e@//\u003chost\u003e:1521/\u003cservicio\u003e @db/setup_least_privilege_user.sql\n```\n\n```cmd\n:: Windows (cmd / PowerShell)\nsqlplus system/\u003ccontraseña-dba\u003e@//\u003chost\u003e:1521/\u003cservicio\u003e @db\\setup_least_privilege_user.sql\n```\n\nCrea un usuario con `CREATE SESSION`, `SELECT_CATALOG_ROLE` y privilegios\n`SELECT`/`INSERT`/`UPDATE`/`DELETE` por objeto sobre las tablas del esquema\nobjetivo (además de `SELECT` sobre vistas y secuencias). Otorga deliberadamente\n**sin** DDL y **sin** cuota de tablespace.\n\n### 2. Configura las credenciales (variables de entorno)\n\n| Variable             | Significado                                           | Ejemplo                                     |\n| -------------------- | ----------------------------------------------------- | ------------------------------------------- |\n| `ORACLE_DB_URL`      | URL JDBC thin                                         | `jdbc:oracle:thin:@//db.host:1521/ORCLPDB1` |\n| `ORACLE_DB_USERNAME` | Usuario de mínimos privilegios del paso 1             | `mcp_user`                                  |\n| `ORACLE_DB_PASSWORD` | Contraseña de ese usuario                             | `s3cret`                                    |\n| `ORACLE_POOL_SIZE`   | Tamaño máx. del pool HikariCP (opcional, default `7`) | `7`                                         |\n\n\u003e **¿Qué esquema usa el servidor?** No existe un ajuste `schema`. En Oracle el\n\u003e esquema equivale al usuario conectado, así que el esquema por defecto es el\n\u003e `ORACLE_DB_USERNAME` que configures. Como el servidor introspecta a través de\n\u003e las vistas `ALL_*`, puede ver **cualquier** esquema donde ese usuario tenga\n\u003e privilegios — pasa el esquema deseado como parámetro de la herramienta (p. ej.\n\u003e `list_tables(schema=\"HR\")`). Qué esquemas son visibles se controla\n\u003e totalmente con los privilegios de `db/setup_least_privilege_user.sql`.\n\n### 3. Compila\n\n```bash\n# Linux / macOS\n./mvnw clean package -DskipTests\n```\n\n```powershell\n# Windows (PowerShell)\n.\\mvnw.cmd clean package -DskipTests\n```\n\nEsto produce `target/mcp-oracle-db-0.0.1-SNAPSHOT.jar` (jar ejecutable de Spring\nBoot).\n\n### 4. Conecta tu cliente MCP (STDIO)\n\nEl bloque JSON mostrado abajo es el estándar de facto usado por Claude Desktop,\nCursor, Cline, Windsurf y Continue. Consulta\n[Configuración de clientes MCP](#configuración-de-clientes-mcp) para la ruta\nexacta del archivo según el cliente.\n\n```json\n{\n  \"mcpServers\": {\n    \"oracle-db\": {\n      \"command\": \"/ruta/hacia/jdk/bin/java\",\n      \"args\": [\"-jar\", \"/ruta/absoluta/mcp-oracle-db-0.0.1-SNAPSHOT.jar\"],\n      \"env\": {\n        \"ORACLE_DB_URL\": \"jdbc:oracle:thin:@//db.host:1521/ORCLPDB1\",\n        \"ORACLE_DB_USERNAME\": \"mcp_user\",\n        \"ORACLE_DB_PASSWORD\": \"s3cret\"\n      }\n    }\n  }\n}\n```\n\nReinicia el cliente tras guardar. Verifica con la herramienta `test_connection`,\nque reporta la versión, nombre, usuario actual, esquema actual e instancia.\n\n### Primera sesión rápida\n\nUna vez que el cliente muestre el servidor conectado, prueba en este orden:\n\n1. **`test_connection`** — confirma conectividad y el usuario/esquema conectado.\n2. **`list_tables(schema=\"HR\")`** — ve las tablas a las que tienes acceso.\n3. **`describe_table(schema=\"HR\", table=\"EMPLOYEES\")`** — columnas, tipos, nulabilidad.\n4. **`get_sample_data(schema=\"HR\", table=\"EMPLOYEES\")`** — primeras N filas, sin riesgo.\n5. **`run_query(sql=\"SELECT department_id, COUNT(*) FROM \\\"HR\\\".\\\"EMPLOYEES\\\" GROUP BY department_id\")`**\n   — SQL ad-hoc, acotado por `max-rows`.\n\n## Configuración de clientes MCP\n\nTodos los clientes STDIO comparten el mismo bloque de servidor mostrado en el\n[paso 4](#4-conecta-tu-cliente-mcp-stdio). Solo difieren en **dónde** se lee\nese bloque:\n\n| Cliente                   | Archivo de configuración                                                                                                        | Clave / notas                           |\n| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |\n| **Claude Desktop**        | macOS `~/Library/Application Support/Claude/claude_desktop_config.json` · Windows `%APPDATA%\\Claude\\claude_desktop_config.json` | `\"mcpServers\"`                          |\n| **Cursor**                | `.cursor/mcp.json` (proyecto) o `~/.cursor/mcp.json` (global)                                                                   | `\"mcpServers\"`                          |\n| **Cline** (VS Code)       | `…/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`                                                       | `\"mcpServers\"`, pon `\"disabled\": false` |\n| **Windsurf**              | `~/.codeium/windsurf/mcp_config.json` (Windows: `%USERPROFILE%\\.codeium\\windsurf\\mcp_config.json`)                              | `\"mcpServers\"`                          |\n| **Continue**              | `~/.continue/config.yaml` (o `.continue/config.json` en el repo)                                                                | `\"mcpServers\"`                          |\n| **VS Code** (MCP, 1.102+) | `.vscode/mcp.json` en el workspace                                                                                              | usa `\"servers\"` con `\"type\": \"stdio\"`   |\n\n\u003e Las rutas pueden cambiar entre versiones del cliente — ante la duda, revisa la\n\u003e documentación del cliente. Lo importante es que el bloque `command` / `args` /\n\u003e `env` es idéntico para todos.\n\n**Nota de VS Code** — su esquema usa `servers` en lugar de `mcpServers`, y cada\nentrada requiere `\"type\": \"stdio\"`:\n\n```json\n{\n  \"servers\": {\n    \"oracle-db\": {\n      \"type\": \"stdio\",\n      \"command\": \"/ruta/hacia/jdk/bin/java\",\n      \"args\": [\"-jar\", \"/ruta/absoluta/mcp-oracle-db-0.0.1-SNAPSHOT.jar\"],\n      \"env\": {\n        \"ORACLE_DB_URL\": \"jdbc:oracle:thin:@//db.host:1521/ORCLPDB1\",\n        \"ORACLE_DB_USERNAME\": \"mcp_user\",\n        \"ORACLE_DB_PASSWORD\": \"s3cret\"\n      }\n    }\n  }\n}\n```\n\n## Referencia de configuración\n\nEl ajuste opcional vive en `application.yaml` bajo `oracle.mcp`:\n\n| Propiedad               | Significado                                   | Default |\n| ----------------------- | --------------------------------------------- | ------- |\n| `max-rows`              | Tope global de filas que devuelve un `SELECT` | `1000`  |\n| `query-timeout-seconds` | Timeout por sentencia                         | `120`   |\n| `default-sample-rows`   | Filas que devuelve `get_sample_data`          | `10`    |\n\nNiveles de log vía `LOG_LEVEL` (default `WARN`) y `APP_LOG_LEVEL` (default\n`INFO`). Ten en cuenta que **stdout es el canal JSON-RPC** — los logs van a\nstderr/archivo, nunca a stdout.\n\n### Auditoría SQL\n\nAuditoría SQL opcional por sesión. Si se activa, cada sentencia SQL que llega a\nOracle se añade a un archivo `.txt` — un archivo por sesión.\n\n| Variable            | Significado                                         | Default            |\n| ------------------- | --------------------------------------------------- | ------------------ |\n| `MCP_AUDIT_ENABLED` | Activar el subsistema de auditoría (`true`/`false`) | `false`            |\n| `MCP_AUDIT_DIR`     | Directorio para los archivos de auditoría           | `./mcp-audit-logs` |\n\n#### Activarlo en tu cliente MCP\n\nAñade las dos variables al bloque `env` de tu entrada del servidor MCP — es el\núnico lugar que debes tocar. Ejemplo para Claude Desktop / Cursor\n(`claude_desktop_config.json` o `.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"oracle-db\": {\n      \"command\": \"/ruta/hacia/jdk/bin/java\",\n      \"args\": [\"-jar\", \"/ruta/absoluta/mcp-oracle-db-0.0.1-SNAPSHOT.jar\"],\n      \"env\": {\n        \"ORACLE_DB_URL\": \"jdbc:oracle:thin:@//db.host:1521/ORCLPDB1\",\n        \"ORACLE_DB_USERNAME\": \"mcp_user\",\n        \"ORACLE_DB_PASSWORD\": \"s3cret\",\n        \"MCP_AUDIT_ENABLED\": \"true\",\n        \"MCP_AUDIT_DIR\": \"/var/log/mcp-oracle-db\"\n      }\n    }\n  }\n}\n```\n\nTras guardar, **reinicia el cliente** para que relance el servidor MCP con el\nnuevo entorno. Se crea entonces un `.txt` por sesión en `MCP_AUDIT_DIR`, añadido\nen cada SQL que el servidor lanza contra Oracle.\n\nPara validar rápido sin el cliente, ejecuta el jar directamente:\n\n```bash\n# Linux / macOS\nMCP_AUDIT_ENABLED=true MCP_AUDIT_DIR=./mcp-audit-logs \\\nORACLE_DB_URL=jdbc:oracle:thin:@//host:1521/SVC \\\nORACLE_DB_USERNAME=mcp_user ORACLE_DB_PASSWORD=... \\\njava -jar target/mcp-oracle-db-0.0.1-SNAPSHOT.jar\n```\n\n```powershell\n# Windows (PowerShell) — define las variables en la misma shell y luego lanza\n$env:MCP_AUDIT_ENABLED=\"true\"; $env:MCP_AUDIT_DIR=\"./mcp-audit-logs\"\n$env:ORACLE_DB_URL=\"jdbc:oracle:thin:@//host:1521/SVC\"\n$env:ORACLE_DB_USERNAME=\"mcp_user\"; $env:ORACLE_DB_PASSWORD=\"...\"\njava -jar target/mcp-oracle-db-0.0.1-SNAPSHOT.jar\n```\n\nFormato del nombre: `\u003cserverName\u003e-\u003cdd-MM-yyyy\u003e-\u003csessionId8\u003e-log.txt`.\n\nCada entrada registra la herramienta, parámetros, texto SQL, resultado, filas y\nduración:\n\n```\n===== 2026-06-27T14:30:52.884 =====================================\ntool     : get_sample_data\nparams   : schema=HR, table=EMPLOYEES, rows=10\nkind     : Select\ntype     : READ\nsql      : SELECT * FROM \"HR\".\"EMPLOYEES\" FETCH FIRST 10 ROWS ONLY\noutcome  : OK\nrows     : 10\nduration : 23 ms\n-------------------------------------------------------------------\n```\n\n**Notas:**\n\n- Los archivos de auditoría contienen texto SQL **incluyendo literales y valores\n  de parámetros** — protege el directorio de auditoría.\n- Desactivado por defecto; cero overhead cuando está apagado (sin archivos, sin\n  I/O).\n- Compatible con STDIO — escribe solo al sistema de archivos, nunca a stdout.\n\n## Arquitectura\n\nCapas estrictas. Las dependencias apuntan hacia adentro (tools → services →\npersistence). Un aspecto de auditoría observa cada SQL que llega a\n`OracleDataAccess` sin alterar el texto SQL ni los resultados.\n\n```mermaid\nflowchart TD\n    Client[\"Cliente MCP\u003cbr/\u003e(Claude Desktop, Cursor, Cline, …)\"]\n    subgraph Server[\"mcp-oracle-db (Spring Boot · STDIO)\"]\n        Tools[\"Endpoints @McpTool\u003cbr/\u003e\u003ci\u003etools/*Tools.java\u003c/i\u003e\"]\n        Services[\"Servicios\u003cbr/\u003e\u003ci\u003eMetadata · Query · DML · Plsql ·\u003cbr/\u003ePerformance · IndexAdvisor · Graph · …\u003c/i\u003e\"]\n        Access[\"OracleDataAccess\u003cbr/\u003e\u003ci\u003eJdbcTemplate · named-param · callable\u003c/i\u003e\"]\n        Audit[\"Aspectos de auditoría\u003cbr/\u003e\u003ci\u003eSqlAuditAspect · ToolAuditAspect (MDC)\u003c/i\u003e\"]\n        Tools --\u003e Services --\u003e Access\n        Audit -. observa .-\u003e Access\n    end\n    Oracle[(\"Oracle DB\u003cbr/\u003eusuario de mínimos privilegios\u003cbr/\u003e= la única barrera\")]\n    Client \u003c--\u003e|JSON-RPC sobre STDIO| Tools\n    Access --\u003e Oracle\n    Oracle -. \"ORA-01031 en DDL/DCL\" .-\u003e Access\n```\n\n## Referencia de herramientas\n\n**70 herramientas**, agrupadas por categoría. _Solo lectura_ nunca modifica\ndatos; _escritura_ se ejecuta en la base.\n\n### Introspección de esquema _(solo lectura)_\n\n| Herramienta         | Descripción                                                                                                                                                                                                                                                                                                        |\n| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `list_schemas`      | Lista todos los esquemas (usuarios) de Oracle visibles para la conexión actual.                                                                                                                                                                                                                                    |\n| `list_tables`       | Lista tablas; esquema opcional y patrón LIKE de nombre no sensible a mayúsculas (default `%`).                                                                                                                                                                                                                     |\n| `list_views`        | Lista vistas; esquema opcional y patrón LIKE.                                                                                                                                                                                                                                                                      |\n| `describe_table`    | Columnas de una tabla: nombre, tipo, nulabilidad, valor por defecto y comentario. Llámala antes de un SELECT/INSERT/UPDATE sobre una tabla no verificada.                                                                                                                                                          |\n| `list_indexes`      | Índices de una tabla con sus columnas, unicidad y estado.                                                                                                                                                                                                                                                          |\n| `list_constraints`  | Restricciones de una tabla (PK, FK, unique, check) con columnas y referencias.                                                                                                                                                                                                                                     |\n| `list_sequences`    | Secuencias con rango, incremento, último número, flag de ciclo y cache (de `ALL_SEQUENCES`, no `DBA_SEQUENCES`). Esquema opcional.                                                                                                                                                                                 |\n| `get_sequence_info` | Metadatos de una secuencia (rango, incremento, último número, flags cache/order) de `ALL_SEQUENCES`. Solo lectura: NO consume `NEXTVAL`.                                                                                                                                                                           |\n| `table_exists`      | `true` si una tabla existe (vía `ALL_TABLES`; las vistas no cuentan). Úsala en lugar de `run_query {SELECT 1 FROM ALL_TABLES ...}`.                                                                                                                                                                                |\n| `list_triggers`     | Triggers con tipo, evento disparador, tabla objetivo y estado. Esquema opcional.                                                                                                                                                                                                                                   |\n| `list_objects`      | Objetos de la base; esquema opcional y filtro por tipo de objeto.                                                                                                                                                                                                                                                  |\n| `search_objects`    | Busca objetos por patrón LIKE de nombre no sensible a mayúsculas; filtro de tipo opcional.                                                                                                                                                                                                                         |\n| `get_ddl`           | DDL de un objeto vía `DBMS_METADATA`. Los 3 parámetros son obligatorios (`schema`, `name`, `type`); solo lectura. Tipos: TABLE, VIEW, INDEX, SEQUENCE, PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY, TRIGGER, TYPE, SYNONYM, DB LINK.                                                                                |\n| `describe_plsql`    | Un objeto PL/SQL: sus argumentos y código fuente completo.                                                                                                                                                                                                                                                         |\n| `call_procedure`    | _(escritura)_ Ejecuta un procedimiento, función o subprograma de package PL/SQL con argumentos tipados IN/OUT/INOUT; soporta un `SYS_REFCURSOR` OUT/return y valores de retorno de función. PL/SQL BOOLEAN/RECORD/TABLE/VARRAY/OBJECT se rechazan con guía de envoltura. Requiere `GRANT EXECUTE` sobre el objeto. |\n\n### Introspección extendida _(solo lectura)_\n\n| Herramienta               | Descripción                                                                                    |\n| ------------------------- | ---------------------------------------------------------------------------------------------- |\n| `list_materialized_views` | Vistas materializadas con modo y método de refresco, último refresco y obsolescencia.          |\n| `list_mview_logs`         | Logs de vistas materializadas definidos sobre tablas. Esquema opcional.                        |\n| `list_synonyms`           | Sinónimos privados y públicos con su objetivo resuelto y DB link.                              |\n| `list_partitions`         | Particiones de una tabla particionada (nombre, posición, high value, filas, compresión).       |\n| `list_subpartitions`      | Subparticiones de una tabla con particionamiento compuesto.                                    |\n| `list_ind_partitions`     | Particiones de índices de una tabla (estado, bloques hoja, claves distintas).                  |\n| `list_db_links`           | Database links visibles para el usuario actual.                                                |\n| `list_procedures`         | Procedimientos, funciones, packages y tipos almacenados; filtros opcionales.                   |\n| `list_types`              | Tipos definidos por el usuario con typecode, atributos, métodos y supertipo.                   |\n| `list_dependencies`       | Objetos de los que depende un objeto dado (útil para análisis de impacto).                     |\n| `list_invalid_objects`    | Objetos cuyo estado es Invalid (código roto que hay que recompilar).                           |\n| `list_external_tables`    | Tablas externas con driver de acceso, directorio, reject limit y parámetros.                   |\n| `list_directories`        | Objetos directorio de Oracle y sus rutas en el sistema de archivos.                            |\n| `list_lob_columns`        | Columnas LOB con segmento, caché, flag SECUREFILE y retención.                                 |\n| `list_scheduler_jobs`     | Jobs de `DBMS_SCHEDULER` con estado, conteos de ejecución/fallo, próxima ejecución, intervalo. |\n| `list_scheduler_job_runs` | Detalles recientes de ejecución de jobs `DBMS_SCHEDULER`: estado, duración, código de error.   |\n\n### PL/SQL y estadísticas del optimizador _(solo lectura)_\n\n| Herramienta         | Descripción                                                                                 |\n| ------------------- | ------------------------------------------------------------------------------------------- |\n| `get_plsql_errors`  | Errores de compilación de unidades PL/SQL. Crítico para diagnosticar código roto.           |\n| `get_table_stats`   | Estadísticas del optimizador de una tabla (filas, bloques, longitud media, último analyze). |\n| `get_column_stats`  | Estadísticas del optimizador de columnas (NDV, densidad, nulos, tipo de histograma).        |\n| `get_histogram`     | Endpoints del histograma de una columna (sesgo y cardinalidad).                             |\n| `get_session_privs` | Privilegios de sistema de la conexión actual (directos + vía roles).                        |\n| `get_session_roles` | Roles habilitados para la conexión actual, con flags admin/default.                         |\n\n### Diagnóstico de rendimiento _(solo lectura, vistas V$)_\n\n| Herramienta             | Descripción                                                                             |\n| ----------------------- | --------------------------------------------------------------------------------------- |\n| `list_active_sessions`  | Sesiones actualmente ACTIVE (usuario, máquina, programa, elapsed). Filtros opcionales.  |\n| `list_blocked_sessions` | Sesiones actualmente bloqueadas, con el bloqueante y el evento de espera.               |\n| `list_locks`            | Locks DML/transacción/usuario mantenidos y solicitados, con objeto y modo.              |\n| `get_session_sql_text`  | Texto SQL completo que ejecuta una sesión (sid, serial#).                               |\n| `list_top_sql`          | Top-N SQL ordenado por buffer_gets / disk_reads / elapsed / executions / cpu.           |\n| `get_wait_events`       | Eventos de espera actuales de `V$SESSION_WAIT`. Filtros opcionales de sid y wait-class. |\n| `get_session_longops`   | Operaciones largas con % de progreso y ETA. sid opcional.                               |\n| `get_instance_info`     | Información de instancia: nombre, host, versión, arranque, estado.                      |\n| `get_database_info`     | Información de base: nombre, log mode, open mode, role, flashback.                      |\n| `get_system_stats`      | Estadísticas acumuladas del sistema de `V$SYSSTAT`.                                     |\n| `get_db_time_model`     | Time model de `V$SYS_TIME_MODEL` (DB CPU, DB time, parse time).                         |\n| `get_parameter`         | Parámetros de inicialización de `V$PARAMETER`. Patrón LIKE de nombre opcional.          |\n| `list_datafile_io`      | Datafiles con tamaño, lecturas/escrituras físicas y tiempo medio de IO.                 |\n\n### Asesoría de índices y consultas _(solo lectura)_\n\n| Herramienta              | Descripción                                                                                                                                                           |\n| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `list_unused_indexes`    | Índices con columnas y uso de mejor esfuerzo (`likely_unused` YES/NO/UNKNOWN). Un DBA debe ejecutar `ALTER INDEX ... MONITORING USAGE` para una respuesta definitiva. |\n| `suggest_index`          | Analiza SQL vía `EXPLAIN PLAN`; propone un `CREATE INDEX` como texto (nunca se ejecuta). Aplicarlo manualmente solo tras revisión del DBA.                            |\n| `run_sql_tuning_advisor` | Ejecuta `DBMS_SQLTUNE` y devuelve su reporte TEXT. Requiere el privilegio `ADVISOR` (ver script de setup, sección 8); si no, devuelve una guía.                       |\n\n### Utilidades de datos _(lectura / detección)_\n\n| Herramienta               | Descripción                                                                                                                                                                                                          |\n| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `count_rows`              | Conteo total de filas de una tabla — la herramienta correcta para esto; NO uses `run_query`. Sin predicado (sin superficie SQL oculta). Para un conteo filtrado usa `run_query` con `SELECT COUNT(*) ... WHERE ...`. |\n| `get_next_sequence_value` | `NEXTVAL` de una secuencia. **Con side-effect**: avanza el contador y el valor no se puede reutilizar. Si `cache_size` \u003e 0, verifica que el valor devuelto no exista ya en la tabla destino.                         |\n| `validate_fk_integrity`   | Filas huérfanas que violan FK(s) de una tabla; conteo de huérfanos por FK (0 = OK).                                                                                                                                  |\n| `find_duplicates`         | Filas duplicadas agrupadas por columnas, con conteos. Conteo mínimo opcional.                                                                                                                                        |\n| `find_free_id`            | El menor id positivo libre (1..maxRange) no presente en una tabla.columna; `excludeTable` opcional revisa una 2ª tabla (escenarios FK). Devuelve `null` si el rango está lleno.                                      |\n\n### SQL y datos _(se ejecuta en la base)_\n\n| Herramienta                  | Descripción                                                                                                                                                                                          |\n| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `run_query`                  | Ejecuta un único `SELECT` (acotado por `max-rows`; `offset`/`limit` opcionales para paginar). `CONNECT BY`/`WITH` (CTE) puede ser rechazado por el parser; prefiere `MINUS` o cómputo en el cliente. |\n| `execute_dml`                | Ejecuta un único `INSERT`/`UPDATE`/`DELETE`/`MERGE` y hace auto-commit; devuelve filas afectadas. Una sentencia por llamada (sin bloques PL/SQL, multi-statement ni DDL).                            |\n| `execute_dml_preview`        | Dry-run sin ejecución para `UPDATE`/`DELETE` — conteo + filas de muestra que se verían afectadas.                                                                                                    |\n| `execute_dml_rollback_first` | Ejecuta el DML dentro de una transacción que se revierte de inmediato; devuelve el conteo real sin persistir.                                                                                        |\n| `get_sample_data`            | Previsualiza las primeras N filas de una tabla.                                                                                                                                                      |\n| `explain_plan`               | Devuelve el plan de ejecución de Oracle vía `DBMS_XPLAN`. Necesita una `PLAN_TABLE`.                                                                                                                 |\n\n### Grafo de impacto de esquema _(solo lectura)_\n\n| Herramienta            | Descripción                                                                                                       |\n| ---------------------- | ----------------------------------------------------------------------------------------------------------------- |\n| `get_fk_graph`         | Relaciones de clave foránea de un esquema (o una tabla) como aristas JSON + diagrama Mermaid.                     |\n| `get_dependency_graph` | Grafo de dependencias de objetos (objetos que referencian o son referenciados por un nombre) como JSON + Mermaid. |\n\n### Comentarios de metadatos _(escritura)_\n\n| Herramienta         | Descripción                                                    |\n| ------------------- | -------------------------------------------------------------- |\n| `comment_on_table`  | Añade/reemplaza el comentario de una tabla (esquema propio).   |\n| `comment_on_column` | Añade/reemplaza el comentario de una columna (esquema propio). |\n\n### Sistema\n\n| Herramienta                | Descripción                                                                                                                                                            |\n| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `test_connection`          | Verifica conectividad; reporta versión, nombre, usuario, esquema e instancia.                                                                                          |\n| `oracle_mcp_health_report` | Cinco sondas independientes de readiness (conectividad, versión, rol de catálogo, objetos inválidos, configuración del servidor); agregado `UP` / `DEGRADED` / `DOWN`. |\n\n### Recursos MCP _(direccionables por URI, solo lectura)_\n\n| URI                                            | Devuelve                                                                                         |\n| ---------------------------------------------- | ------------------------------------------------------------------------------------------------ |\n| `oracle://schema/{schema}/table/{table}`       | Descripción a nivel columna (nombre, tipo, nulabilidad, default, comentario).                    |\n| `oracle://schema/{schema}/object/{object}/ddl` | Fuente DDL (tipo autodetectado — tabla, vista, package, procedimiento, etc.).                    |\n| `oracle://schema/{schema}/plsql/{object}`      | Código fuente PL/SQL.                                                                            |\n| `oracle://audit/session/{id}`                  | Log de auditoría SQL de la sesión (`id` = hex de 8 chars; usa `current` para la sesión en vivo). |\n\n### Prompts MCP _(plantillas de guía)_\n\n| Nombre                   | Propósito                                                                                                                              |\n| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |\n| `review-sql-performance` | Revisión estructurada de rendimiento de una sentencia SQL.                                                                             |\n| `explain-schema`         | Exploración guiada de un esquema Oracle (tablas, columnas, relaciones, objetos clave).                                                 |\n| `debug-invalid-plsql`    | Diagnostica PL/SQL roto — objetos inválidos, códigos de error, ubicaciones en el fuente.                                               |\n| `safe-dml-plan`          | Planifica un cambio DML de forma segura (pre-flight, dry-run, post-ejecución).                                                         |\n| `data-quality-audit`     | Audita calidad de datos (completitud, unicidad, integridad referencial, validez).                                                      |\n| `oracle-sql-style`       | Las reglas canónicas del servidor para escribir SQL en Oracle — evita errores de sintaxis comunes (ORA-00923/00936/00904/00911/00933). |\n\n### Completions MCP _(autocompletado de variables de URI / argumentos de prompt)_\n\n13 completions en total — nombres de esquema (6), nombres de tabla (3), nombres de objeto (3) e IDs de sesión de auditoría (1). Limitados por la spec MCP a variables de URI de recursos y argumentos de prompts.\n\n## Modelo de seguridad\n\nSeguridad de capa única: el **usuario de Oracle de mínimos privilegios es la\núnica barrera.** No hay filtro de SQL en la aplicación — `SqlGuard` se eliminó\nde forma deliberada. Cada sentencia que envía una herramienta se ejecuta\nliteral contra Oracle, y el modelo de privilegios de Oracle decide permitir o\ndenegar.\n\nEl servidor se conecta como un usuario dedicado de Oracle con `CREATE SESSION` +\n`SELECT_CATALOG_ROLE` + privilegios `SELECT`/`INSERT`/`UPDATE`/`DELETE` por\nobjeto, `EXECUTE` sobre procedimientos y packages específicos (à la carte), y\n**sin** privilegios DDL/DCL ni cuota de tablespace. Cualquier\n`CREATE`/`ALTER`/`DROP`/`GRANT`/`REVOKE`/`TRUNCATE`/… devuelve un error de\nOracle (típicamente `ORA-01031: insufficient privileges`) que se muestra al\ncliente como un mensaje explicativo.\n\n```\n SQL de IA  ──▶  OracleDataAccess  ──▶  Oracle (usuario mín. priv.)\n                     │                       │\n                     │              Oracle aplica permitir/denegar\n                     │              (ORA-01031 en DDL/DCL)\n                     ▼                       ▼\n            resultado / string de error devuelto al cliente MCP\n```\n\nTodas las consultas internas de metadatos usan vistas `ALL_*` con parámetros\nnombrados (`:param`). Los identificadores se validan y se entrecomillan con\ndobles comillas (ver `SqlIdentifiers`). Una sentencia por llamada a la\nherramienta — los lotes se rechazan.\n\n## Pruebas\n\nLa suite está en capas para que la mayor parte se ejecute en cada commit **sin\nnecesidad de base de datos**, y la ruta con Oracle real es opt-in.\n\n**Nivel 1 — unit + smoke (cada `./mvnw test`, sin DB).** Pruebas sobre\n`SqlIdentifiers`, `IndexAdvisor`, `Graph`, salud de `SystemService`, lector +\nwriter de `AuditLog`, cada tool / resource / prompt / completion, más\n`McpOracleDbApplicationSmokeTest` que arranca el contexto **completo** de Spring\nsobre un datasource H2 en memoria (compat Oracle) y afirma que los 70 endpoints\n`@McpTool` se registran a lo largo de los 11 hosts. Las regresiones de arranque\n(un logback mal configurado, un bean faltante, una auto-config rota) se atrapan\naquí.\n\n**Nivel 2 — harness end-to-end MCP STDIO (opt-in, necesita Oracle).**\n`McpStdioE2ETest` lanza el jar construido como subproceso, realiza el handshake\nreal `initialize` de MCP, lista las herramientas y ejecuta chequeos de solo\nlectura (`describe_table`, `run_query`, `count_rows`) sobre cada tabla que\nconfigures, y luego afirma que Oracle rechaza `CREATE TABLE` (privilegios\ninsuficientes). Está doblemente gateado para que nunca se ejecute por accidente:\n\n1. Copia `src/test/resources/application-e2e.example.yaml` a\n   `application-e2e.yaml` (gitignored) y completa la ruta del jar, las\n   credenciales de Oracle, el esquema y un array `tables: [...]`.\n2. Ejecuta con el perfil `mcp-e2e`:\n\n   ```bash\n   # Linux / macOS\n   ./mvnw test -Pmcp-e2e          # o run-e2e.bat en Windows (compila el jar antes)\n   ```\n\n   ```powershell\n   # Windows (PowerShell)\n   .\\mvnw.cmd test -Pmcp-e2e\n   ```\n\n**Test de integración gateado por entorno.** El test completo de\ncontexto/integración (`McpOracleDbApplicationTests.contextLoads`) solo se\nejecuta cuando `ORACLE_DB_URL` está definida, de modo que `./mvnw test` está\nverde sin base de datos.\n\n```bash\nORACLE_DB_URL=... ORACLE_DB_USERNAME=... ORACLE_DB_PASSWORD=... ./mvnw test\n```\n\n## Resolución de problemas y preguntas frecuentes\n\n**`ORA-01031: insufficient privileges` al ejecutar `CREATE`/`ALTER`/`DROP`/`GRANT`.**\nEs **por diseño**, no un bug. El usuario de mínimos privilegios no tiene\nprivilegios DDL/DCL ni cuota de tablespace, así que Oracle rechaza la\nsentencia. Si de verdad necesitas cambios estructurales, ejecútalos como DBA —\n**no** amplíes los privilegios del usuario MCP (ver\n[Modelo de seguridad](#modelo-de-seguridad)).\n\n**`ORA-12541: TNS:no listener` / `ORA-12514: TNS:listener … service`.** La URL\nJDBC de `ORACLE_DB_URL` es incorrecta o la DB no se alcanza. Revisa host, puerto\ny nombre de servicio. Prefiere la forma EZ-connect\n`jdbc:oracle:thin:@//host:1521/SERVICE` (no necesita `tnsnames.ora`).\n\n**El cliente muestra que el servidor \"falló al iniciar\" / sin salida.** stdout\nes el canal JSON-RPC — cualquier `System.out` espurio corrompe el framing. El\nservidor desactiva el banner de Spring (`spring.main.banner-mode: off`) por\nello; si bifurcas la config, manténlo apagado. Los logs van solo a\nstderr/archivo.\n\n**`explain_plan` devuelve un error de Oracle.** Necesita acceso de escritura a\nuna `PLAN_TABLE`. Otórgalo (ver la línea opcional en\n`db/setup_least_privilege_user.sql`, sección 5) o omite la herramienta.\n\n**Agotamiento del pool / cuelgues tras un reinicio de la DB.** HikariCP se\nconfigura con timeouts de socket de Oracle JDBC (`oracle.jdbc.readTimeout`)\njusto para reciclar conexiones muertas. Si sobrescribes `application.yaml`,\nconserva un read-timeout mayor que `query-timeout-seconds` pero por debajo del\n`request-timeout` de MCP (150s).\n\n**¿Qué esquema introspecta el servidor?** No hay ajuste `schema` — el esquema\npor defecto es `ORACLE_DB_USERNAME`. Pasa cualquier esquema accesible como\nparámetro de la herramienta (p. ej.\n`describe_table(schema=\"HR\", table=\"EMPLOYEES\")`). La visibilidad la acotan los\nprivilegios del script de setup.\n\n**¿Puedo ejecutar varias sentencias SQL en una llamada?** No — una sentencia\npor llamada a la herramienta. Los lotes, bloques PL/SQL y cadenas con `;` se\nrechazan. Esto mantiene el modelo de ejecución predecible y el pool sano.\n\n## Limitaciones y notas\n\n- Solo transporte STDIO (uso local). No se expone servidor HTTP/SSE.\n- `explain_plan` necesita acceso de escritura a una `PLAN_TABLE` (ver el\n  privilegio opcional del script de setup). Sin él, esa herramienta devuelve el\n  error de Oracle.\n- Una sentencia por llamada a la herramienta — los lotes se rechazan.\n- El acceso de lectura lo acota lo que el usuario de mínimos privilegios puede\n  ver en las vistas `ALL_*`.\n- **JSqlParser 4.9 es solo de mejor esfuerzo** — etiqueta el tipo de DML en\n  `DmlService` (`INSERT`/`UPDATE`/`DELETE`/`MERGE`, si no `UNKNOWN`). Ya no filtra\n  nada; Oracle es la autoridad.\n- **Oracle JDBC:** el BOM es `com.oracle.database.jdbc:ojdbc-bom:23.26.2.0.0`.\n  `orai18n` no está en Central bajo ese grupo — se omite; `ojdbc17` por sí solo\n  funciona.\n\n## Licencia\n\n[MIT](LICENSE) © Sadot Hdz. Moreno\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzademy%2Fmcp-oracle-database","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzademy%2Fmcp-oracle-database","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzademy%2Fmcp-oracle-database/lists"}