Skip to main content
The Oracle Database MCP Toolkit supports multiple deployment modes: stdio for local development, HTTP for remote access, and Docker for containerized environments. Each mode supports optional authentication and TLS encryption.

Prerequisites

  • JDK 17+
  • Maven 3.9+ (for building from source)
  • Database access (for database tools)
  • MCP client (Claude Desktop, Cline, etc.)

Building from Source

Build the JAR file:
mvn clean package
Output: target/oracle-db-mcp-toolkit-1.0.0.jar

Transport Modes

The toolkit supports two transport modes:
  • stdio (default): Client spawns JVM process, communicates via stdin/stdout
  • http: Server runs as HTTP service, clients connect via URL

stdio Mode (Default)

Best for local development and single-user scenarios.

Basic Configuration

{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "java",
      "args": [
        "-Ddb.url=jdbc:oracle:thin:@your-host:1521/your-service",
        "-Ddb.user=your_user",
        "-Ddb.password=your_password",
        "-jar",
        "/path/to/oracle-db-mcp-toolkit-1.0.0.jar"
      ]
    }
  }
}

With Tool Selection

Enable specific tools only:
{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "java",
      "args": [
        "-Ddb.url=jdbc:oracle:thin:@host:1521/service",
        "-Ddb.user=user",
        "-Ddb.password=pass",
        "-Dtools=get-jdbc-stats,get-jdbc-queries,similarity_search",
        "-jar",
        "/path/to/oracle-db-mcp-toolkit-1.0.0.jar"
      ]
    }
  }
}

With YAML Configuration

{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "java",
      "args": [
        "-DconfigFile=/absolute/path/to/config.yaml",
        "-jar",
        "/path/to/oracle-db-mcp-toolkit-1.0.0.jar"
      ]
    }
  }
}

With Extra JDBC JARs

For wallets, token auth, or centralized config:
{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "java",
      "args": [
        "-Ddb.url=jdbc:oracle:thin:@host:1521/service",
        "-Ddb.user=user",
        "-Ddb.password=pass",
        "-Dojdbc.ext.dir=/path/to/extra-jars",
        "-jar",
        "/path/to/oracle-db-mcp-toolkit-1.0.0.jar"
      ]
    }
  }
}

Log Analysis Only (No Database)

Run without database connection:
{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "java",
      "args": [
        "-Dtools=get-jdbc-stats,get-jdbc-queries,get-jdbc-errors",
        "-jar",
        "/path/to/oracle-db-mcp-toolkit-1.0.0.jar"
      ]
    }
  }
}

HTTP Mode

Best for remote access, multi-user environments, and production deployments.

Basic HTTP Server

Start the server:
java \
  -Dtransport=http \
  -Ddb.url=jdbc:oracle:thin:@host:1521/service \
  -Ddb.user=user \
  -Ddb.password=pass \
  -jar oracle-db-mcp-toolkit-1.0.0.jar
Endpoint: http://localhost:8080/mcp (default)

HTTPS with TLS

Enable HTTPS at your own risk. When enabling HTTPS, pay extra attention to the MCP tools you enable, as they may create new security risks for your database server.
Generate or obtain a PKCS12 certificate:
# Self-signed certificate (development only)
keytool -genkeypair -keyalg RSA -keysize 2048 \
  -storetype PKCS12 -keystore certificate.p12 \
  -validity 365 -storepass changeit \
  -dname "CN=localhost,OU=Dev,O=Example,L=City,ST=State,C=US"
Start with HTTPS:
java \
  -Dtransport=http \
  -Dhttps.port=45450 \
  -DcertificatePath=/path/to/certificate.p12 \
  -DcertificatePassword=changeit \
  -Ddb.url=jdbc:oracle:thin:@host:1521/service \
  -Ddb.user=user \
  -Ddb.password=pass \
  -Dtools=get-jdbc-stats,similarity_search \
  -jar oracle-db-mcp-toolkit-1.0.0.jar
Endpoint: https://localhost:45450/mcp Supported Certificate Formats:
  • PKCS12 (.p12, .pfx) only

Client Configuration for HTTP

Cline (Streamable HTTP)

{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "type": "streamableHttp",
      "url": "https://localhost:45450/mcp"
    }
  }
}

Claude Desktop (via mcp-remote)

{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://localhost:45450/mcp"
      ]
    }
  }
}

Authentication

HTTP mode supports multiple authentication methods.

Development Token (Testing Only)

For development and testing use only. Not secure for production.
Enable authentication without OAuth2:
java \
  -Dtransport=http \
  -Dhttps.port=45450 \
  -DcertificatePath=/path/to/certificate.p12 \
  -DcertificatePassword=changeit \
  -DenableAuthentication=true \
  -Ddb.url=jdbc:oracle:thin:@host:1521/service \
  -Ddb.user=user \
  -Ddb.password=pass \
  -jar oracle-db-mcp-toolkit-1.0.0.jar
Token Generation:
  1. From environment variable (if set):
    export ORACLE_DB_TOOLKIT_AUTH_TOKEN=Secret_DeV_T0ken
    
    The token will be: Secret_DeV_T0ken
  2. Auto-generated UUID (if env var not set):
    INFO: Authorization token generated (for testing and development use only): 0dd11948-37a3-470f-911e-4cd8b3d6f69c
    
Using the Token: Include in the Authorization header:
curl -H "Authorization: Bearer 0dd11948-37a3-470f-911e-4cd8b3d6f69c" \
  https://localhost:45450/mcp

OAuth2 Configuration

For production deployments with OAuth2 introspection.

Prerequisites

  • OAuth2 server (e.g., Keycloak, Auth0, Okta)
  • OAuth2 server must provide /.well-known/oauth-authorization-server
  • Introspection endpoint that returns {"active": true/false}

System Properties

PropertyDescriptionRequired
enableAuthenticationEnable authenticationYes
authServerOAuth2 server URLYes
introspectionEndpointToken introspection endpointYes
clientIdOAuth2 client IDYes
clientSecretOAuth2 client secretYes
allowedHostsCORS allowed origins (default: *)No
redirectOAuthToOpenIDRedirect to OpenID config (default: false)No

Example: Keycloak OAuth2

java \
  -Dtransport=http \
  -Dhttps.port=45450 \
  -DcertificatePath=/path/to/certificate.p12 \
  -DcertificatePassword=changeit \
  -DenableAuthentication=true \
  -DauthServer=http://localhost:8080/realms/mcp \
  -DintrospectionEndpoint=http://localhost:8080/realms/mcp/protocol/openid-connect/token/introspect \
  -DclientId=oracle-db-toolkit \
  -DclientSecret=Xj9mPqR2vL5kN8tY3hB7wF4uD6cA1eZ0 \
  -DallowedHosts=http://localhost:6274 \
  -Ddb.url=jdbc:oracle:thin:@host:1521/service \
  -Ddb.user=user \
  -Ddb.password=pass \
  -jar oracle-db-mcp-toolkit-1.0.0.jar
Key Settings:
  • authServer: Your Keycloak realm URL
  • introspectionEndpoint: Token introspection endpoint
  • clientId: Registered client ID
  • clientSecret: Client secret from Keycloak
  • allowedHosts: Allowed CORS origins (e.g., MCP Inspector)

OpenID Configuration Redirect

Some OAuth2 servers only provide /.well-known/openid-configuration instead of /.well-known/oauth-authorization-server. Use the redirect workaround:
java \
  -Dtransport=http \
  -DenableAuthentication=true \
  -DauthServer=http://localhost:8080/realms/mcp \
  -DredirectOAuthToOpenID=true \
  -DintrospectionEndpoint=http://localhost:8080/realms/mcp/protocol/openid-connect/token/introspect \
  -DclientId=oracle-db-toolkit \
  -DclientSecret=secret \
  -jar oracle-db-mcp-toolkit-1.0.0.jar
This creates an endpoint at /.well-known/oauth-authorization-server that redirects to the OAuth server’s /.well-known/openid-configuration.

OAuth2 Flow

  1. Client requests /.well-known/oauth-protected-resource from MCP server
  2. MCP server returns OAuth2 configuration
  3. Client obtains access token from OAuth2 server
  4. Client sends requests with Authorization: Bearer <token>
  5. MCP server validates token via introspection endpoint
  6. If {"active": true}, request is processed
MCP Specification: Authorization in MCP

Testing with MCP Inspector

Use MCP Inspector to test OAuth2:
# Run MCP Inspector
npx @modelcontextprotocol/inspector

# Configure allowedHosts
java \
  -Dtransport=http \
  -DenableAuthentication=true \
  -DallowedHosts=http://localhost:6274 \
  ...

Docker Deployment

Containerized deployment using Podman or Docker.

Build Docker Image

Using the provided Dockerfile:
podman build -t oracle-db-mcp-toolkit:1.0.0 .
Or with Docker:
docker build -t oracle-db-mcp-toolkit:1.0.0 .

Run HTTP Server in Container

podman run --rm \
  -p 45450:45450 \
  -p 45451:45451 \
  -v /path/to/certificate.p12:/app/certif.p12:ro,z \
  -e JAVA_TOOL_OPTIONS="\
    -Dtransport=http \
    -Dhttps.port=45451 \
    -DcertificatePath=/app/certif.p12 \
    -DcertificatePassword=changeit \
    -Dtools=get-jdbc-stats,similarity_search \
    -Ddb.url=jdbc:oracle:thin:@host:1521/service \
    -Ddb.user=user \
    -Ddb.password=pass" \
  oracle-db-mcp-toolkit:1.0.0
Endpoint: https://<host-ip>:45451/mcp

With Extra JDBC JARs

Mount external JARs for wallets or token auth:
podman run --rm \
  -p 45450:45450 \
  -p 45451:45451 \
  -v /path/to/ext:/ext:ro \
  -v /path/to/certificate.p12:/app/certif.p12:ro,z \
  -e JAVA_TOOL_OPTIONS="\
    -Dtransport=http \
    -Dhttps.port=45451 \
    -DcertificatePath=/app/certif.p12 \
    -DcertificatePassword=changeit \
    -Ddb.url=jdbc:oracle:thin:@host:1521/service \
    -Ddb.user=user \
    -Ddb.password=pass \
    -Dojdbc.ext.dir=/ext" \
  oracle-db-mcp-toolkit:1.0.0

stdio Mode in Container

Run with stdio transport (spawned by client):
{
  "mcpServers": {
    "oracle-db-mcp-toolkit": {
      "command": "podman",
      "args": [
        "run",
        "--rm",
        "-i",
        "-v", "/path/to/ext:/ext:ro",
        "-e",
        "JAVA_TOOL_OPTIONS=-Dtools=similarity_search -Ddb.url=jdbc:oracle:thin:@host:1521/service -Ddb.user=user -Ddb.password=pass -Dojdbc.ext.dir=/ext",
        "oracle-db-mcp-toolkit:1.0.0"
      ]
    }
  }
}

System Properties Reference

PropertyRequiredDescriptionExample
db.urlNo*JDBC URLjdbc:oracle:thin:@host:1521/service
db.userNo*Database usernameADMIN
db.passwordNo*Database passwordpass
toolsNoComma-separated tool list (default: all)get-jdbc-stats,similarity_search
configFileNoPath to YAML config/opt/mcp/config.yaml
transportNoTransport mode (default: stdio)http
https.portNoHTTPS port45450
certificatePathNoPath to PKCS12 certificate/path/to/cert.p12
certificatePasswordNoCertificate passwordchangeit
ojdbc.ext.dirNoDirectory for extra JARs/opt/oracle/ext-jars
enableAuthenticationNoEnable HTTP auth (default: false)true
authServerNoOAuth2 server URLhttp://localhost:8080/realms/mcp
introspectionEndpointNoOAuth2 introspection endpointhttp://...
clientIdNoOAuth2 client IDoracle-db-toolkit
clientSecretNoOAuth2 client secretsecret
allowedHostsNoCORS allowed origins (default: *)http://localhost:6274
redirectOAuthToOpenIDNoRedirect to OpenID config (default: false)true
* Conditional:
  • db.url, db.user, db.password required only if database tools are enabled
  • Not required for log analysis tools only
  • Not required if using token-based auth via ojdbc.ext.dir

Security Best Practices

Database Credentials

  • Use environment variables instead of hardcoding in config
  • Rotate credentials regularly
  • Use read-only accounts when possible
  • Enable token-based auth for production (via ojdbc.ext.dir)

Network Security

  • Always use HTTPS in production (not HTTP)
  • Use valid certificates (not self-signed) in production
  • Configure firewalls to restrict access
  • Use OAuth2 for authentication
  • Set allowedHosts to restrict CORS

Tool Security

  • Limit enabled tools using -Dtools
  • Review custom YAML tools for SQL injection risks
  • Use parameterized queries only (YAML tools do this automatically)
  • Audit logs regularly

Container Security

  • Run as non-root user (Dockerfile should handle this)
  • Use read-only mounts for certificates and JARs (:ro flag)
  • Don’t expose unnecessary ports
  • Scan images for vulnerabilities
  • Use secrets management for passwords (e.g., Kubernetes secrets)

Troubleshooting

Connection Refused

Symptom: Cannot connect to database Solutions:
  • Verify JDBC URL format
  • Check database hostname, port, service name
  • Ensure network connectivity
  • Check firewall rules
  • Verify credentials

Certificate Errors

Symptom: SSL/TLS handshake failures Solutions:
  • Ensure certificate is PKCS12 format (.p12 or .pfx)
  • Verify certificate password
  • Check certificate validity dates
  • For development, trust self-signed cert in client

Authentication Failed

Symptom: 401 Unauthorized Solutions:
  • Verify enableAuthentication=true
  • Check token in Authorization: Bearer <token> header
  • For OAuth2, verify introspection endpoint is reachable
  • Check client ID and secret
  • Verify token is active (not expired)

Port Already in Use

Symptom: “Address already in use” error Solutions:
  • Change port with -Dhttps.port=<different-port>
  • Stop other services using the port
  • Check for zombie processes

Tool Not Found

Symptom: “Tool X is not available” Solutions:
  • Check -Dtools list includes the tool
  • Verify tool name spelling
  • For custom YAML tools, check configFile path
  • Ensure YAML syntax is valid

Next Steps

Custom Tools

Define YAML-based SQL tools

Built-in Tools

Explore available tools

Build docs developers (and LLMs) love