Oracle Read-Only MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Oracle Read-Only MCP Serverlist tables in schema HR"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Oracle Read-Only MCP Server
Local Python MCP server for Oracle database access using python-oracledb in thin mode only.
This server is designed to:
run locally on demand through an MCP client
support multiple named Oracle environments such as
DEV1andUAT3connect to Oracle without OCI / Oracle Instant Client
support read-only SQL queries and schema inspection
support both
tnsnames.oraalias mode and direct host/port/service-name mode
Quick Start
Copy
oracle-mcp.example.jsonctooracle-mcp.jsoncand fill in your real environment entries such asDEV1orUAT3.Start the server with
make run-serveror your MCP client.In the LLM workflow:
call
list_environments()call
check_database("DEV1")then run queries like
run_query("DEV1", "select * from ...")
default_schema is optional. Use it only if your read-only login user is different from the application schema you normally query.
Related MCP server: mcp-oracle-dba
Features
run_query(environment, sql)environment-specific execution using a moniker parameter
execute a single read-only
SELECTorWITH ... SELECTqueryreturns columns, rows, row count, and truncation status
list_environments()list configured environment monikers and connection mode
check_database(environment)verify whether the selected environment is available
performs a real Oracle connection and
select 1 from dual
preview_query(sql)validates SQL with the same read-only guard as
run_queryreturns normalized SQL without executing it
list_tables(environment, schema?, name_pattern?)list accessible tables
list_views(environment, schema?, name_pattern?)list accessible views
search_objects(environment, name_pattern, schema?, object_types?)search tables, views, synonyms, or other allowed object types by SQL
LIKEpattern
describe_table(environment, table_name, schema?)full table/view structure including type, precision/scale, defaults, and comments when available
list_columns(environment, table_name, schema?)lightweight column listing for quick schema inspection
get_primary_key(environment, table_name, schema?)list primary key columns and position order
list_foreign_keys(environment, table_name, schema?)list outbound foreign key relationships and referenced columns
get_table_sample(environment, table_name, schema?, limit?)return a capped sample of rows from a table or view
list_schemas(environment)list visible Oracle schemas/users
Security Model
This server rejects non-read-only SQL in application code, but the real security boundary should be the Oracle account itself.
Use a database user that only has read access.
The SQL guard allows only a single statement starting with SELECT or WITH and rejects DML, DDL, PL/SQL, and multi-statement input.
Application-level protection:
only read-oriented MCP tools are exposed
run_query()andpreview_query()validate SQL before executionmulti-statement input is rejected
common write and DDL keywords are rejected outside string literals
SELECT ... FOR UPDATEis also blocked by the guard
Database-level protection:
the Oracle user should only have
CREATE SESSIONandSELECTprivileges as neededdo not use
SYSTEM,SYS, or any account with write privileges in normal usethe Oracle account should not have
EXECUTEon dangerous packages such asDBMS_SQL,UTL_FILE, orDBMS_LOB
The MCP server reduces risk, but a read-only Oracle account is what actually guarantees that writes cannot happen.
Requirements
Python 3.10+
Oracle database reachable over the network
No OCI / Oracle Instant Client required
Install
python -m venv .venv
. .venv/bin/activate
pip install -e .[dev]Configuration
This server now uses a single JSONC configuration file with named environments.
Use:
oracle-mcp.example.jsoncas the templateoracle-mcp.jsoncas your real local config file
The real oracle-mcp.jsonc is ignored by git because it contains plain-text credentials.
Default config path:
oracle-mcp.jsoncin the project root
Override config path with:
ORACLE_MCP_CONFIG_PATH
Example:
{
"defaults": {
"fetch_max_rows": 500,
"connect_timeout": 15,
"protocol": "tcp"
},
"environments": {
"DEV1": {
"mode": "tns",
"tnsnames_path": "C:\\oracle\\network\\admin\\tnsnames.ora",
"dsn_alias": "DEV1",
"username": "readonly_user",
"password": "plain_text_password",
"default_schema": "APP" // optional
},
"UAT3": {
"mode": "direct",
"host": "uat3-db.internal",
"port": 1521,
"service_name": "UAT3",
"username": "readonly_user",
"password": "plain_text_password"
}
}
}TNS environments still use the file path to tnsnames.ora, and the server uses the file's parent directory as Oracle's config_dir for alias resolution.
Schema resolution order for metadata/sample tools is:
explicit
schemaargument passed to the tooldefault_schemafrom the selected environment, if presentthe Oracle username for that environment
Run
oracle-mcp-serverOr during development:
python -m oracle_mcp_server.serverIf your config file is not in the project root:
ORACLE_MCP_CONFIG_PATH=C:\path\to\oracle-mcp.jsonc python -m oracle_mcp_server.serverOr use the included Makefile helpers:
make install
make test
make test-integration
make run-serverMakefile Commands
make installcreate
.venvinstall the project and dev dependencies
make testrun the default test suite
integration tests remain skipped
make test-integrationrun the live Oracle integration tests
requires a suitable Oracle test environment
make run-serverstart the MCP server from the project virtualenv
OpenCode MCP Configuration
OpenCode uses local MCP server definitions under the mcp key in opencode.json or opencode.jsonc.
Example OpenCode config:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"oracle_readonly": {
"type": "local",
"command": ["/absolute/path/to/oracle-mcp/.venv/bin/oracle-mcp-server"],
"cwd": "/absolute/path/to/oracle-mcp",
"enabled": true,
"environment": {
"ORACLE_MCP_CONFIG_PATH": "C:\\path\\to\\oracle-mcp.jsonc"
}
}
}
}Once configured in OpenCode, the MCP tools are available under the oracle_readonly server namespace.
Typical workflow with the LLM:
list_environments()check_database("DEV1")run_query("DEV1", "select * from ...")
Generic MCP Client Configuration
Example for a generic client that launches a local stdio server:
{
"mcpServers": {
"oracle-readonly": {
"command": "/absolute/path/to/.venv/bin/oracle-mcp-server",
"env": {
"ORACLE_MCP_CONFIG_PATH": "C:\\path\\to\\oracle-mcp.jsonc"
}
}
}
}Tests
pytestOr with make:
make test
make test-integrationDefault test runs exclude live Oracle integration tests.
Run the live integration suite only when you have a suitable Oracle environment available:
pytest --run-integration -m integrationIntegration tests use these environment variables, with Docker-friendly defaults matching the sample Oracle XE setup:
ORACLE_TEST_HOST=127.0.0.1
ORACLE_TEST_PORT=1521
ORACLE_TEST_SERVICE_NAME=XE
ORACLE_TEST_USERNAME=system
ORACLE_TEST_PASSWORD=oracle
ORACLE_TEST_DEFAULT_SCHEMA=SYS
ORACLE_TEST_DSN_ALIAS=XETEST
ORACLE_TEST_CONNECT_TIMEOUT=15
ORACLE_TEST_PROTOCOL=tcpThis lets you keep the tests in the repo but skip them in normal development or CI unless explicitly requested.
Test coverage currently includes:
JSONC config validation with named environments
unknown environment rejection
SQL guard behavior for read-only validation
connection kwargs for direct and TNS modes
tnsnames.oraparent-directory resolution, ensuring the server passes the containing directory asconfig_direnvironment-specific DB availability checks
opt-in live integration tests for direct-mode queries, metadata tools, sampling, health checks, and TNS alias resolution
There is also a live smoke-tested tests/fixtures/tnsnames.ora example used during development to validate real TNS alias resolution against Oracle XE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pos123/oracle-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server