Skip to main content
ClaudeWave
igorolv avatar
igorolv

jdbc-mcp-server

View on GitHub

Read-only JDBC MCP server for PostgreSQL, Oracle, and SQL Server: safe SQL access for AI agents (Claude Code, Cursor, Copilot) with schema discovery, query validation, execution plans, benchmarking, and index/statistics tools

MCP ServersOfficial Registry0 stars1 forksJavaApache-2.0Updated today
ClaudeWave Trust Score
95/100
Verified
Passed
  • Open-source license (Apache-2.0)
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
  • Documented (README)
Last scanned: 9/16/2026
Install in Claude Code / Claude Desktop
Method: Manual
Claude Code CLI
git clone https://github.com/igorolv/jdbc-mcp-server
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Clone https://github.com/igorolv/jdbc-mcp-server and follow its README for install instructions.
Use cases

MCP Servers overview

# JDBC MCP Server

[![CI](https://github.com/igorolv/jdbc-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/igorolv/jdbc-mcp-server/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/igorolv/jdbc-mcp-server?include_prereleases)](https://github.com/igorolv/jdbc-mcp-server/releases/latest)
[![License](https://img.shields.io/github/license/igorolv/jdbc-mcp-server)](LICENSE)
[![Java 21](https://img.shields.io/badge/Java-21%2B-blue?logo=openjdk)](https://adoptium.net/)
[![MCP](https://img.shields.io/badge/MCP-server-8A2BE2)](https://modelcontextprotocol.io/)
[![Glama score](https://glama.ai/mcp/servers/igorolv/jdbc-mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/igorolv/jdbc-mcp-server)
[![Listed on mcpservers.org](https://mcpservers.org/badge.svg)](https://mcpservers.org/servers/igorolv/jdbc-mcp-server)

A local MCP server for read-only access to PostgreSQL, Oracle, and Microsoft SQL Server databases.
It lets AI agents such as Claude Code, Cursor, VS Code Copilot, and others write SQL queries,
inspect execution plans, and explore database structure: tables, columns, indexes, foreign keys,
views, functions, and sequences.

PostgreSQL, Oracle, and Microsoft SQL Server JDBC drivers are bundled into the fat jar, so no
extra driver installation is required.

The server exposes 49 MCP tools and can optionally expose catalog-qualified MCP resources for table
and column metadata. Tools may update the local SQLite catalog, but they never write to the inspected
PostgreSQL, Oracle, or SQL Server database.

One server process can serve several databases: name them in
[`connections.json`](#databases-and-credentials) and pass `connection` to any tool. The tool manifest
stays a single set regardless of how many databases are configured, and pools are opened only for the
databases actually used.

## Quickstart

**1. Get the jar** — download `jdbc-mcp-server.jar` from the
[latest release](https://github.com/igorolv/jdbc-mcp-server/releases/latest) (JDK 21+ required;
all JDBC drivers are bundled), or build it yourself:

```bash
./gradlew bootJar   # → build/libs/jdbc-mcp-server.jar
```

**2. Describe your databases** in `~/.jdbc-mcp-server/connections.json`:

```json
{
  "connections": {
    "myapp": {
      "url": "jdbc:postgresql://db.example.com:5432/myapp",
      "username": "ai_readonly",
      "password": "secret",
      "description": "Application database — customers, orders, shipments"
    }
  }
}
```

Use a [read-only database user](#maximum-protection-use-a-read-only-database-user); five minutes
there outweighs every other protection in this server.

**3. Register the server** with your MCP client — with no database settings in the client config:

```json
{
  "command": "java",
  "args": ["-jar", "<absolute-path>/jdbc-mcp-server.jar"],
  "env": {}
}
```

For Claude Code that is one command:

```bash
claude mcp add --scope user jdbc java -jar /path/to/jdbc-mcp-server.jar
```

**4. Ask the agent for `listConnections`.** It answers with the databases this server serves; every
other tool takes that name as its first argument:

```json
{"connection": "myapp", "sql": "SELECT count(*) FROM orders"}
```

Full details: [Databases and Credentials](#databases-and-credentials),
[Connecting an AI Client](#connecting-an-ai-client),
[Serving Several Databases from One Server](#serving-several-databases-from-one-server).

## Databases and Credentials

Every database this server serves is described in one JSON file. Nothing about a database — URL,
credentials, schema, timeouts, limits — comes from the environment.

### The connections file

Default path `~/.jdbc-mcp-server/connections.json` (`<data-dir>/connections.json`), overridden with
`JDBC_MCP_CONNECTIONS_FILE`. When the file is missing or defines no connection the server still
starts (so an MCP client can list its tools), logs a warning, and `listConnections` returns an empty
list; every other tool then reports that no connection is available. A file that is present but
malformed is a startup error.

```json
{
  "connections": {
    "orders": {
      "url": "jdbc:postgresql://db.example.com:5432/orders",
      "username": "ai_readonly",
      "password": "secret",
      "defaultSchema": "public",
      "description": "Order service — customers, orders, shipments",
      "structureSnapshotSchemas": ["public", "nsi"]
    },
    "billing": {
      "url": "jdbc:oracle:thin:@//oracle.example.com:1521/BILLING",
      "username": "AI_READONLY",
      "password": "${BILLING_DB_PASSWORD}",
      "description": "Legacy billing (Oracle)"
    }
  }
}
```

The object key is the connection name. It is also the name of the connection's local catalog
directory (`<data-dir>/<name>/`) and appears in MCP resource URIs, so it must match
`[A-Za-z0-9._-]+(@[A-Za-z0-9._-]+)?`, be at most 64 characters, and not be `.` or `..`.

The optional `@` is there to name the two axes separately: `<service>@<stand>`, as in `ssj@dev`,
`nsi@dev`, `ssj@tst`. A dash cannot do that job, because dashes already occur inside service names
(`ssj-ws`, `ssj-ek-export`, `ais-ui`), so `ssj-ws-dev` is ambiguous to a human and to a model alike.
`@` never occurs in a service name and reads as "what, where" the way `user@host` does. It is
percent-encoded to `%40` in resource URIs; nothing else about the name changes — the directory on
disk is the name as written.

`url` is the only required field; the engine is detected from its prefix (`jdbc:postgresql:`,
`jdbc:oracle:`, `jdbc:sqlserver:`). `description` is free text returned by `listConnections`, so an
agent can pick a database by meaning rather than by name — worth filling in.

Any string value may reference an environment variable as `${VAR}`. A referenced variable that is
not set fails startup with a message naming the variable and the field; it never becomes an empty
password. Read the next section before reaching for it.

### Why credentials live in a file, not in environment variables

The point of this server is that the agent reaches the database *only* through it: every statement
goes through the read-only guard, every result is capped by `maxRows`, and nothing but
`SELECT` / `WITH` / `EXPLAIN` gets through.

Credentials in environment variables undermine exactly that. They are set on the server process by
the MCP client, which means they also sit in the client's own configuration — a file agents read and
edit as a matter of routine — and in the environment of whatever shell launched it. An agent that
has seen a URL, a user and a password does not need the tools any more: `psql`, `sqlplus`, `sqlcmd`
or three lines of Python connect straight to the database, with no guard, no row cap and no trace in
this server's log.

So the server accepts no database credentials from the environment at all — there are no `JDBC_URL`
/ `JDBC_USERNAME` / `JDBC_PASSWORD` variables. They live in `connections.json`, which only the server
reads.

Be clear about what that does and does not buy:

- It removes the easy path. Credentials stop being part of the material an agent routinely handles:
  MCP client configs, shell environment, `env` dumps in logs and bug reports.
- **It is not a sandbox.** An agent with shell access running as you can read the file; `chmod 600`
  keeps out other users, not a process running as your user.
- The guarantee that survives everything is a
  [read-only database user](#maximum-protection-use-a-read-only-database-user). The file narrows the
  attack surface; the database's own permissions close it.

For the same reason, prefer a literal password in the file over a `${VAR}` reference whose variable
would be set in the MCP client's `env` block — that puts the secret straight back where the agent
looks. `${VAR}` earns its place when the value is injected from outside the agent's reach (a systemd
unit, a wrapper script, a secret manager), or when the file itself is shared or committed and the
secret must not be.

### Connection fields

Everything except `url` is optional; a field left out falls back to the built-in default:

| Field | Default | Meaning |
|---|---|---|
| `url` | required | JDBC URL; also selects the engine |
| `username`, `password` | none | Database credentials |
| `description` | none | Free text returned by `listConnections` |
| `defaultSchema` | the session schema | Schema used when a metadata tool call omits one |
| `queryTimeoutSeconds` | `30` | Per-query timeout; `0` disables |
| `maxRows` | `1000` | Row cap for one response; `truncated: true` when hit |
| `fetchSize` | `500` | JDBC `fetchSize` hint |
| `readonlyGuard` | `strict` | `off` disables the client-side SELECT-only check |
| `poolMaximumSize` | `40` | Hikari maximum pool size |
| `poolMinimumIdle` | `0` | Hikari minimum idle; `0` keeps the pool lazy |
| `poolConnectionTimeoutMs` | `10000` | Hikari connection checkout timeout |
| `poolValidationTimeoutMs` | `5000` | Hikari validation timeout |
| `poolIdleTimeoutMs` | `60000` | Idle connections above `poolMinimumIdle` are closed after this |
| `structureSnapshotSchemas` | the default schema | Schemas captured by `rebuildCatalog` |
| `structureSnapshotOracleColumnQueryTimeoutSeconds` | `300` | Oracle-only timeout for the bulk column query during `rebuildCatalog`; `0` disables |
| `usageCatalogEnabled` | `true` | When `false`, usage tools report the disabled state |
| `usageCatalogPaths` | none | Extra directories, JSON files or zip archives with QueryUsage records |
| `usageNativeSchemas` | the default schema | Schemas scanned for native usage |
| `usageNativeIncludeViews`, `usageNativeIncludeRoutines`, `usageNativeIncludeTriggers` | `true` | What native usage scanning covers |
| `usageNativeMaxObjects` | `10000` | Maximum native usage records per index build |

The `JDBC_MCP_TOOLS_*` group flags stay in the environment — they shape the tool manifest, which is
shared by all connections. See [Configuration](#configuration) for the handful of variables the
server itself reads.

### URL 
ai-agentsclaude-codedatabaseexecution-planjavajdbcllm-toolsmcpmcp-servermodel-context-protocolmssqloracle-databasepostgresqlquery-optimizationschema-discoveryspring-aispring-bootsqlsql-server

What people ask about jdbc-mcp-server

What is igorolv/jdbc-mcp-server?

+

igorolv/jdbc-mcp-server is mcp servers for the Claude AI ecosystem. Read-only JDBC MCP server for PostgreSQL, Oracle, and SQL Server: safe SQL access for AI agents (Claude Code, Cursor, Copilot) with schema discovery, query validation, execution plans, benchmarking, and index/statistics tools It has 0 GitHub stars and its last recorded update is dated 2026-09-15.

How do I install jdbc-mcp-server?

+

You can install jdbc-mcp-server by cloning the repository (https://github.com/igorolv/jdbc-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is igorolv/jdbc-mcp-server safe to use?

+

Our security agent has analyzed igorolv/jdbc-mcp-server and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains igorolv/jdbc-mcp-server?

+

igorolv/jdbc-mcp-server is maintained by igorolv. The last recorded GitHub activity is dated 2026-09-15, with 1 open issues.

Are there alternatives to jdbc-mcp-server?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy jdbc-mcp-server to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: igorolv/jdbc-mcp-server
[![Featured on ClaudeWave](https://claudewave.com/api/badge/igorolv-jdbc-mcp-server)](https://claudewave.com/repo/igorolv-jdbc-mcp-server)
<a href="https://claudewave.com/repo/igorolv-jdbc-mcp-server"><img src="https://claudewave.com/api/badge/igorolv-jdbc-mcp-server" alt="Featured on ClaudeWave: igorolv/jdbc-mcp-server" width="320" height="64" /></a>

More MCP Servers

jdbc-mcp-server alternatives