The generated config does exactly this for Oracle, and it is the right pattern: the model reaches for the read-only entry for everything except the rare write, which has to be asked for by name. Two flags look alike in the output of `database_info` and are not the same thing: `mcp_server_readonly_mode` is this server's setting, `read_only` is the database's own. Check the first one when you want to know what the agent can do.
A Quarkus-based set of MCP servers packaged so each one is a single JAR or a single container. The JDBC server is the centre of it: point it at a connection string and any database with a JDBC driver becomes queryable.
- `read_query` runs SELECTs, `list_tables` lists what is there, `describe_table` returns a table's structure, and `database_info` reports on the database — including whether read-only mode is on
- `write_query` for INSERT, UPDATE and DELETE and `create_table` for schema changes, both blocked when read-only mode is active
- Read-only mode as a launch flag — `--jdbc.readonly=true` — rather than a permission you have to arrange in the database
- Drivers for Oracle, PostgreSQL, MySQL, H2, SQLite, SQL Server and MariaDB, each with its connection-string shape documented
- Three more servers alongside it: a filesystem server that exposes a directory you name, a containers server, and a JVM insights server
JDK 17 — the repository ships `./setup-jdk17.sh`, which detects your architecture and OS, downloads a build, and writes an environment file you source. Then `./build-no-tests.sh` produces the JARs. From there either run the JAR directly with `java -jar`, or build the Docker image with `./docker-mcp.sh build` and run each server as a container. `./docker-mcp.sh config` generates a ready-made Claude Desktop configuration for all four servers. Database credentials go on the launch command as `--jdbc.url`, `--jdbc.user` and `--jdbc.password`.
One command — docker run -i --rm --network host mcp-servers:latest jdbc --jdbc.url=jdbc:oracle:thin:@localhost:1521:xe --jdbc.user=ORACLEUSR --jdbc.password=ORACLEUSR --jdbc.readonly=false
