AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Mcp Oracle Database

mcp-zademy-mcp-oracle-database · by zademy

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.

No reviews yet
0 installs
29 views
0.0% view→install

Install

$ agentstack add mcp-zademy-mcp-oracle-database

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-zademy-mcp-oracle-database)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mcp Oracle Database? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

[English](README.md) | [Español](README.es.md)

mcp-oracle-db

An MCP server for Oracle Database, built with Spring Boot and Spring AI.

[](https://opensource.org/licenses/MIT) [](https://openjdk.org/) [](https://spring.io/projects/spring-boot) [](https://spring.io/projects/spring-ai) [](https://www.oracle.com/database/) [](https://modelcontextprotocol.io) [](https://github.com/zademy/mcp-oracle-database/commits/main) [](https://deepwiki.com/zademy/mcp-oracle-database) [](https://github.com/zademy/mcp-oracle-database/stargazers)

Let any MCP-compatible client (Claude Desktop, Cursor, Cline, Continue, VS Code, Windsurf, …) introspect an Oracle schema and run SQL — safely.


Why mcp-oracle-db?

  • Safe by design — the only security barrier is a **least-privilege Oracle

user**. There is no application-layer SQL gate; Oracle itself rejects every CREATE/ALTER/DROP/GRANT/… with ORA-01031.

  • 70 tools across schema introspection, performance diagnostics, index/query

advisory, data helpers, DML, explain plan, schema graphs, PL/SQL and system.

  • No web port — STDIO transport only. No HTTP/SSE server is ever exposed.
  • Virtual threads — Java 26 virtual threads, a natural fit for blocking JDBC.
  • No secrets in the repo — credentials come from environment variables.

Who is it for? DBAs, backend developers and AI-assisted workflows that need a local, read-heavy Oracle companion: explore a schema, diagnose performance, preview DML, and let an LLM run ad-hoc SQL without ever risking structural changes.

What it does

Executed

  • Schema reads — metadata, DDL source, PL/SQL source, sequences, constraints,

partitions, performance diagnostics via V$ views.

  • DML — INSERT, UPDATE, DELETE, MERGE on existing tables.
  • PL/SQL invocation — call_procedure (requires GRANT EXECUTE on the target).
  • Metadata comments — COMMENT ON ....

Rejected by Oracle (the least-privilege user has no DDL/DCL privileges)

  • All structural DDL — all CREATE ... forms, ALTER, DROP, TRUNCATE,

RENAME.

  • All DCL — GRANT, REVOKE, PURGE, FLASHBACK, LOCK TABLE, AUDIT,

NOAUDIT, ANALYZE.

Table of contents

  • [Why mcp-oracle-db?](#why-mcp-oracle-db)
  • [What it does](#what-it-does)
  • [Requirements](#requirements)
  • [Quickstart](#quickstart)
  • [1. Create the least-privilege Oracle user](#1-create-the-least-privilege-oracle-user)
  • [2. Configure credentials](#2-configure-credentials-environment-variables)
  • [3. Build](#3-build)
  • [4. Connect your MCP client](#4-connect-your-mcp-client-stdio)
  • [Quick first session](#quick-first-session)
  • [MCP client configuration](#mcp-client-configuration)
  • [Configuration reference](#configuration-reference)
  • [SQL audit log](#sql-audit-log)
  • [Architecture](#architecture)
  • [Tools reference](#tools-reference)
  • [Security model](#security-model)
  • [Testing](#testing)
  • [Troubleshooting and FAQ](#troubleshooting-and-faq)
  • [Limitations and notes](#limitations-and-notes)
  • [Contributing and agent workflow](#contributing-and-agent-workflow)
  • [License](#license)

Requirements

  • JDK 26
  • Apache Maven 3.9+ (the included mvnw wrapper is enough)
  • Oracle Database 12c+ (tested against 19c / 23ai drivers)
  • An MCP client that speaks STDIO (Claude Desktop, Cursor, Cline, Continue,

VS Code, Windsurf, …)

Quickstart

1. Create the least-privilege Oracle user

Run db/setup_least_privilege_user.sql as a DBA. Edit the & placeholders first.

# Linux / macOS
sqlplus system/@//:1521/ @db/setup_least_privilege_user.sql
:: Windows (cmd / PowerShell)
sqlplus system/@//:1521/ @db\setup_least_privilege_user.sql

It creates a user with CREATE SESSION, SELECT_CATALOG_ROLE, and per-object SELECT/INSERT/UPDATE/DELETE grants on the target schema's tables (plus SELECT on views and sequences). It deliberately grants no DDL and no tablespace quota.

2. Configure credentials (environment variables)

| Variable | Meaning | Example | | -------------------- | ---------------------------------------------- | ------------------------------------------- | | ORACLE_DB_URL | Thin JDBC URL | jdbc:oracle:thin:@//db.host:1521/ORCLPDB1 | | ORACLE_DB_USERNAME | Least-privilege user from step 1 | mcp_user | | ORACLE_DB_PASSWORD | That user's password | s3cret | | ORACLE_POOL_SIZE | HikariCP max pool size (optional, default 7) | 7 |

> Which schema does the server use? There is no schema setting. In > Oracle the schema equals the connected user, so the default schema is the > ORACLE_DB_USERNAME you configure. Because the server introspects through the > ALL_* views, it can see any schema where that user has grants — pass the > desired schema name as a tool parameter (e.g. list_tables(schema="HR")). > Which schemas are visible is controlled entirely by the grants in > db/setup_least_privilege_user.sql.

3. Build

# Linux / macOS
./mvnw clean package -DskipTests
# Windows (PowerShell)
.\mvnw.cmd clean package -DskipTests

This produces target/mcp-oracle-db-0.0.1-SNAPSHOT.jar (Spring Boot executable jar).

4. Connect your MCP client (STDIO)

The JSON shape below is the de-facto standard used by Claude Desktop, Cursor, Cline, Windsurf and Continue. See [MCP client configuration](#mcp-client-configuration) for the exact config-file path per client.

{
  "mcpServers": {
    "oracle-db": {
      "command": "/path/to/jdk/bin/java",
      "args": ["-jar", "/absolute/path/mcp-oracle-db-0.0.1-SNAPSHOT.jar"],
      "env": {
        "ORACLE_DB_URL": "jdbc:oracle:thin:@//db.host:1521/ORCLPDB1",
        "ORACLE_DB_USERNAME": "mcp_user",
        "ORACLE_DB_PASSWORD": "s3cret"
      }
    }
  }
}

Restart the client after saving. Verify with the test_connection tool, which reports the database version, name, current user, current schema and instance.

Quick first session

Once the client shows the server connected, try these in order:

  1. test_connection — confirm reachability and the connected user/schema.
  2. list_tables(schema="HR") — see the tables you can access.
  3. describe_table(schema="HR", table="EMPLOYEES") — columns, types, nullability.
  4. get_sample_data(schema="HR", table="EMPLOYEES") — first N rows, no risk.
  5. run_query(sql="SELECT department_id, COUNT(*) FROM \"HR\".\"EMPLOYEES\" GROUP BY department_id")

— ad-hoc SQL, capped by max-rows.

MCP client configuration

All STDIO clients share the same server block shown in [step 4](#4-connect-your-mcp-client-stdio). They differ only in where that block is read from:

| Client | Config file | Key / notes | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | | Claude Desktop | macOS ~/Library/Application Support/Claude/claude_desktop_config.json · Windows %APPDATA%\Claude\claude_desktop_config.json | "mcpServers" | | Cursor | .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) | "mcpServers" | | Cline (VS Code) | …/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json | "mcpServers", set "disabled": false | | Windsurf | ~/.codeium/windsurf/mcp_config.json (Windows: %USERPROFILE%\.codeium\windsurf\mcp_config.json) | "mcpServers" | | Continue | ~/.continue/config.yaml (or .continue/config.json in the repo) | "mcpServers" | | VS Code (MCP, 1.102+) | .vscode/mcp.json in the workspace | uses "servers" with "type": "stdio" |

> Paths can change between client versions — when in doubt, check the client's own > docs. What matters is that the command / args / env block is identical for > all of them.

VS Code note — its schema uses servers instead of mcpServers, and each entry needs "type": "stdio":

{
  "servers": {
    "oracle-db": {
      "type": "stdio",
      "command": "/path/to/jdk/bin/java",
      "args": ["-jar", "/absolute/path/mcp-oracle-db-0.0.1-SNAPSHOT.jar"],
      "env": {
        "ORACLE_DB_URL": "jdbc:oracle:thin:@//db.host:1521/ORCLPDB1",
        "ORACLE_DB_USERNAME": "mcp_user",
        "ORACLE_DB_PASSWORD": "s3cret"
      }
    }
  }
}

Configuration reference

Optional tuning lives in application.yaml under oracle.mcp:

| Property | Meaning | Default | | ----------------------- | ------------------------------------- | ------- | | max-rows | Global cap on rows a SELECT returns | 1000 | | query-timeout-seconds | Per-statement timeout | 120 | | default-sample-rows | Rows returned by get_sample_data | 10 |

Logging levels via LOG_LEVEL (default WARN) and APP_LOG_LEVEL (default INFO). Keep in mind that stdout is the JSON-RPC channel — logs go to stderr/file, never stdout.

SQL audit log

Opt-in per-session SQL audit. When enabled, every SQL statement that reaches Oracle is appended to a .txt file — one file per session.

| Variable | Meaning | Default | | ------------------- | ------------------------------------------- | ------------------ | | MCP_AUDIT_ENABLED | Enable the audit subsystem (true/false) | false | | MCP_AUDIT_DIR | Directory for audit log files | ./mcp-audit-logs |

Enabling in your MCP client

Add the two variables to the env block of your MCP server entry — this is the only place you need to touch. Example for Claude Desktop / Cursor (claude_desktop_config.json or .cursor/mcp.json):

{
  "mcpServers": {
    "oracle-db": {
      "command": "/path/to/jdk/bin/java",
      "args": ["-jar", "/absolute/path/mcp-oracle-db-0.0.1-SNAPSHOT.jar"],
      "env": {
        "ORACLE_DB_URL": "jdbc:oracle:thin:@//db.host:1521/ORCLPDB1",
        "ORACLE_DB_USERNAME": "mcp_user",
        "ORACLE_DB_PASSWORD": "s3cret",
        "MCP_AUDIT_ENABLED": "true",
        "MCP_AUDIT_DIR": "/var/log/mcp-oracle-db"
      }
    }
  }
}

After saving, restart the client so it relaunches the MCP server with the new environment. One .txt per session is then created in MCP_AUDIT_DIR and appended on every SQL the server launches against Oracle.

To validate quickly without the client, run the jar directly:

# Linux / macOS
MCP_AUDIT_ENABLED=true MCP_AUDIT_DIR=./mcp-audit-logs \
ORACLE_DB_URL=jdbc:oracle:thin:@//host:1521/SVC \
ORACLE_DB_USERNAME=mcp_user ORACLE_DB_PASSWORD=... \
java -jar target/mcp-oracle-db-0.0.1-SNAPSHOT.jar
# Windows (PowerShell) — set env vars in the same shell, then launch
$env:MCP_AUDIT_ENABLED="true"; $env:MCP_AUDIT_DIR="./mcp-audit-logs"
$env:ORACLE_DB_URL="jdbc:oracle:thin:@//host:1521/SVC"
$env:ORACLE_DB_USERNAME="mcp_user"; $env:ORACLE_DB_PASSWORD="..."
java -jar target/mcp-oracle-db-0.0.1-SNAPSHOT.jar

Filename format: ---log.txt.

Each entry records the tool name, parameters, SQL text, outcome, row count and duration:

===== 2026-06-27T14:30:52.884 =====================================
tool     : get_sample_data
params   : schema=HR, table=EMPLOYEES, rows=10
kind     : Select
type     : READ
sql      : SELECT * FROM "HR"."EMPLOYEES" FETCH FIRST 10 ROWS ONLY
outcome  : OK
rows     : 10
duration : 23 ms
-------------------------------------------------------------------

Notes:

  • Audit files contain SQL text including literals and parameter values

protect the audit directory.

  • Disabled by default; zero overhead when off (no files, no I/O).
  • STDIO-safe — writes to the filesystem only, never to stdout.

Architecture

Strict layering. Dependencies point inward (tools → services → persistence). An audit aspect observes every SQL reaching OracleDataAccess without altering SQL text or results.

flowchart TD
    Client["MCP client(Claude Desktop, Cursor, Cline, …)"]
    subgraph Server["mcp-oracle-db (Spring Boot · STDIO)"]
        Tools["@McpTool endpointstools/*Tools.java"]
        Services["ServicesMetadata · Query · DML · Plsql ·Performance · IndexAdvisor · Graph · …"]
        Access["OracleDataAccessJdbcTemplate · named-param · callable"]
        Audit["Audit aspectsSqlAuditAspect · ToolAuditAspect (MDC)"]
        Tools --> Services --> Access
        Audit -. observes .-> Access
    end
    Oracle[("Oracle DBleast-privilege user= the only barrier")]
    Client |JSON-RPC over STDIO| Tools
    Access --> Oracle
    Oracle -. "ORA-01031 on DDL/DCL" .-> Access

Tools reference

70 tools, grouped by category. Read-only never modifies data; write executes on the database.

Schema introspection (read-only)

| Tool | Description | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | list_schemas | List all Oracle schemas (users) visible to the current connection. | | list_tables | List tables; optional schema and case-insensitive LIKE name pattern (defaults to %). | | list_views | List views; optional schema and LIKE name pattern. | | describe_table | Columns of a table: name, data type, nullability, default value and comment. Call before writing SELECT/INSERT/UPDATE against an unverified table. | | list_indexes | Indexes on a table with their columns, uniqueness and status.

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.