Skip to main content

MCP Explained: How AI Assistants Connect to Databases

Calculating read time…

The Model Context Protocol (MCP) is an open standard, introduced by Anthropic in November 2024, that gives AI assistants like Codex a single, standardized way to discover and call external tools — including databases — instead of relying on one custom integration per tool. 🔌

Why this matters in a corporate setting: as of mid-2026, roughly 78% of enterprise AI teams already run MCP-backed agents in production, and about 28% of Fortune 500 companies operate their own MCP servers — Bloomberg alone used MCP to close what its engineering team calls the "productionization gap" across more than 9,500 engineers, turning one-off GenAI demos into governed, deployable systems. If you're learning to connect an AI coding assistant to a production database today, you are learning the exact connective layer enterprises are standardizing on right now. 🏢

Diagram showing Codex CLI connecting through an MCP Client to the SQLcl MCP Server, which connects to Oracle Database

🔀 Quick Comparison: The Three Ways to Reach Oracle via MCP

Method Runs Where Best For
SQLcl MCP Server (this post) Locally, on your machine (stdio) Individual developer productivity, local workflows
OCI Database Tools MCP Server Cloud-managed, serverless (OCI) Centrally managed enterprise access
ORDS MCP Endpoint Remote HTTPS streaming Teams already running ORDS with OAuth2/JWT

🧩 Section 1: What MCP Actually Is (And Why It Exists)

💡 Real Example: Figma's MCP Server
Figma runs an official MCP server that lets AI coding tools pull live design specifications directly onto the canvas — developers using Codex, Claude, or Cursor can ask for a component's exact spacing and colors without a designer manually exporting values. This works today, across multiple AI vendors, because Figma implemented MCP once instead of building a separate plugin for every AI tool.

Before MCP, if your company wanted three different AI assistants (say, Codex, Claude, and an internal chatbot) to talk to five different systems (Oracle, Salesforce, GitHub, Slack, an internal API), you needed 3 × 5 = 15 separate integrations. This is called the NxM problem — the number of integrations grows multiplicatively with every new AI tool or system you add.

MCP flattens this into N + M: each AI tool implements the MCP client side once, and each system implements the MCP server side once. Any MCP client can now talk to any MCP server, regardless of who built either side.

Host — the application you actually use (Codex CLI, Claude, ChatGPT desktop). Runs the MCP Client internally.

Client — the piece inside the Host that speaks MCP: sends requests, receives responses, over JSON-RPC 2.0.

Server — a small, focused program that exposes one system's capabilities (e.g. SQLcl exposing Oracle Database).

Transport — how Client and Server actually talk: stdio (local process, what we'll use today) or Streamable HTTP (remote server over the network).

MCP servers expose three kinds of primitives: Tools (functions the model can call, like run-sql), Resources (data the model can read, like a schema listing), and Prompts (reusable templates). For a database server, Tools are what you'll interact with the most.

🎯 Use this when: You're explaining to a non-technical stakeholder why "just building one integration" isn't actually simpler than adopting MCP once you have more than one AI tool or more than one backend system.

🗄️ Section 2: Why AI Assistants Need MCP To Reach Databases

An AI assistant like Codex, on its own, cannot query your Oracle database. It has no network access to it, no credentials, and — critically — no built-in understanding of your specific schema. Historically, teams solved this by either (a) writing custom scripts the AI could shell out to, or (b) pasting query results manually into the chat. Both approaches don't scale and don't leave an audit trail.

MCP solves this properly: the database vendor (Oracle, in this case) ships an official MCP server that already knows how to authenticate safely, run SQL, and return structured results. Codex just needs to know the server exists and how to launch it — Codex never sees your raw database password, and every AI-issued query is logged on the database side.

💡 Harder Example: Why "Just Give the AI the Connection String" Fails
A team once let an AI assistant hold a live Oracle connection string with a SYSDBA-level account "to save setup time." Within days, an ambiguous prompt caused the model to run a broad UPDATE across a shared table during a routine "clean up test data" request. The MCP model prevents exactly this: SQLcl's MCP server never accepts credentials at runtime, only pre-saved, named connections tied to a specific, limited-privilege schema — so the blast radius is bounded before the AI ever sends a single query.

🎯 Use this when: A colleague asks "why can't I just paste my DB password into the AI prompt?" — this is your answer, backed by a real failure mode.

🛠️ Section 3: Meet the Players — Codex, MCP, and Oracle SQLcl

Three pieces come together for today's walkthrough:

1. OpenAI Codex CLI — the MCP Host. Reads its MCP server list from ~/.codex/config.toml (global) or a project-scoped .codex/config.toml, and shares this configuration with the Codex desktop app and IDE extension.

2. The MCP Protocol — the shared language. Codex's built-in MCP client speaks JSON-RPC 2.0 to any server it's configured to launch.

3. Oracle SQLcl MCP Server — Oracle's official, free MCP server, built into SQLcl (Oracle's modern command-line tool, version 25.2+, requiring Java 17+). Launching sql -mcp starts it in stdio mode, exposing five tools: list-connections, connect, disconnect, run-sql, and run-sqlcl.

🎯 Use this when: Deciding which MCP server to standardize on for Oracle — SQLcl is the right default for individual developer machines; see the comparison table above for cloud-managed alternatives.

🚀 Section 4: Step-by-Step — Connect Codex to Oracle Database via MCP (True Beginner Edition)

Before you start: Oracle strongly recommends never pointing this at a production database directly. Use a sanitized copy, a test database, or a dedicated least-privilege schema.

💡 The Big Picture Before We Touch a Terminal

Think of it like hiring a personal assistant (Codex) who is brilliant at language but has never met your database. So you also hire a specialist translator (SQLcl) who already speaks fluent "Oracle." You introduce them once — "Codex, meet SQLcl, SQLcl already knows how to reach the database" — and from then on, you just talk to your assistant in plain English, and it relays your requests through the translator.

That's the whole chain: You (English) → Codex (AI Assistant) → MCP (the introduction/handshake) → SQLcl (the translator) → Oracle Database. Every step below just builds one link in that chain, one at a time, and tests it before moving to the next.

🧾 What You'll Need Before Starting (Checklist)

☐ A computer with a terminal / command line app (Terminal on Mac, PowerShell or WSL on Windows)

☐ Access to an Oracle database — a test/sandbox one, not production (ask your DBA, or use Oracle's free "Always Free" Autonomous Database if you don't have one)

☐ Admin/install rights on your machine, to install Java and SQLcl

☐ OpenAI Codex CLI already installed (if not, Step 1 below covers it)

☐ About 30–45 minutes, uninterrupted, for your very first setup

  1. Open a terminal and confirm Codex CLI is installed.
    A "terminal" is just a text window where you type commands instead of clicking buttons — on a Mac, open the Terminal app (search for it with Spotlight, Cmd+Space); on Windows, open PowerShell (search "PowerShell" in the Start menu).

    Check whether Codex is already installed:
    codex --version
    What you should see: a version number like codex-cli 0.42.0. If instead you see command not found, install it with:
    npm install -g @openai/codex
    ⚠️ If npm also isn't found: you need Node.js installed first. Download it from nodejs.org (choose the "LTS" version), install it, close and reopen your terminal, then try again.
  2. Install and verify Java 17 or newer.
    SQLcl (Oracle's command-line tool) is itself built on Java, so Java has to be present on your machine — think of it as the engine SQLcl runs on top of, invisible to you once it's working.

    Check if you already have a suitable version:
    java -version
    What you should see: a line mentioning 17, 21, or higher, e.g. openjdk version "21.0.3". If you see command not found, or a version below 17, install a current JDK — search "Oracle JDK download" or "OpenJDK 21 download," pick the installer for your operating system, and run it like any normal app installer.
    After installing, close your terminal completely and open a new one before re-checking — this matters, because the terminal only picks up new software after a fresh restart.
    ⚠️ Common first-timer trap: installing Java but still seeing "command not found" — this almost always means you're still in the old terminal window from before the install. Open a brand new terminal window and try again.
  3. Install SQLcl and make sure your terminal can find it.
    SQLcl is a free download from Oracle — it's a single tool you unzip, not something with a complicated installer. Two common ways to get it:

    • Standalone: download the zip from Oracle's SQLcl page and unzip it somewhere permanent, like ~/tools/sqlcl

    • Via VS Code: if you already use the "Oracle SQL Developer" extension in VS Code, SQLcl is bundled inside its extension folder


    Either way, you need your terminal to know where the sql program lives. This is called adding it to your PATH — think of PATH as a list of folders your terminal automatically searches whenever you type a command name.

    On Mac/Linux, add this line to the end of your ~/.zshrc (or ~/.bashrc) file, replacing the path with wherever you unzipped SQLcl:

    export PATH="$PATH:/Users/yourname/tools/sqlcl/bin"
    Then reload it: source ~/.zshrc

    On Windows, search "Environment Variables" in the Start menu → "Edit the system environment variables" → "Environment Variables" button → under "Path," click "Edit" → "New" → paste the folder path to SQLcl's bin folder → OK everything, then open a brand new PowerShell window.

    Now verify it worked:
    sql -V
    What you should see: something like SQLcl: Release 25.2. That number needs to read 25.2 or higher.
  4. Get your database connection details.
    You need four things, usually from your DBA or your test-environment provisioning email: the host (server address), the port (almost always 1521), the service name, and a username/password. If you're using Oracle's free Autonomous Database, these details are in your cloud console's connection panel instead.
    ⚠️ Do not use your personal, full-access DBA account here, even temporarily "to test." Move straight to Step 5 and get a limited account instead — it takes a few extra minutes and prevents a very bad day later.
  5. Ask for (or create) a least-privilege database user.
    This is the single most important safety step in this whole guide. You want a database user that can only see and touch the exact tables the AI needs — nothing more. If you're the DBA yourself, on a test database, a simple example looks like:
    CREATE USER mcp_reader IDENTIFIED BY "StrongPassword123!";
    GRANT CREATE SESSION TO mcp_reader;
    GRANT SELECT ON hr.employees TO mcp_reader;
    -- add more SELECT grants only for the specific tables you need
    What this does: creates a brand-new login (mcp_reader) that can only start a session and read one specific table — even if the AI is instructed (accidentally or maliciously) to delete data, this user has no permission to do so.
  6. Open SQLcl by itself and connect once, interactively.
    Before wiring anything to Codex, let's prove the basic connection works on its own. Simply type:
    sql /nolog
    What you should see: a SQL> prompt — this is SQLcl waiting for your commands, similar to opening a blank chat window. Now connect using your details from Step 4:
    connect mcp_reader/StrongPassword123!@//your-host:1521/your_service_name
    What you should see: Connected. If instead you see an error like ORA-12154 or ORA-01017, your host/port/service or password is wrong — double-check with whoever gave you the details, this is very common on a first attempt and not something you did "wrong."
  7. Save this connection permanently, with the password stored.
    Once connected, save it so you never have to retype the password again — and so the MCP server (which never accepts typed passwords) has something to use later:
    conn -save mcp_readonly -savepwd mcp_reader/StrongPassword123!@//your-host:1521/your_service_name
    Breaking this command down piece by piece:

    • conn — short for "connect"

    • -save mcp_readonly — gives this connection a nickname, mcp_readonly, that you (and later, the AI) will refer to it by

    • -savepwd — tells SQLcl to remember the password too, encrypted, so nobody has to type it again — this flag is mandatory for MCP; without it, the AI has no way to authenticate later

    • mcp_reader/StrongPassword123!@//your-host:1521/your_service_name — the connection string itself: username/password@//host:port/service_name

    What you should see: Connection saved. This is stored safely under a hidden folder called ~/.dbtools on your machine — not inside any file you'll accidentally share or commit to Git.
    ⚠️ Forgot -savepwd? Just re-run the same command with it added — it's safe to save the same connection name again, it simply overwrites the old one.
    Type exit to leave SQLcl.
  8. Test the MCP server manually, by itself, before involving Codex at all.
    This step exists purely to isolate problems — if something breaks later inside Codex, you'll already know SQLcl and your connection are fine on their own.
    sql -mcp
    What this does: instead of giving you an interactive SQL> prompt, this starts SQLcl in a special "listening" mode — it sits quietly, waiting for structured requests (not typed SQL) to arrive over what's called stdio (standard input/output — just a fancy way of saying "the same channel you'd normally type into"). You should see:
    ---------- MCP SERVER STARTUP ----------
    MCP Server started successfully
    Press Ctrl+C to stop the server
    ----------------------------------------
    Nothing else will happen — that's correct! It's just waiting. There's no SQL> prompt because this mode isn't meant for you to type into directly; it's meant for a program like Codex to talk to. Press Ctrl+C now to stop it and return to your normal terminal.
  9. Open Codex's configuration file for the first time.
    Codex reads its list of MCP servers from a plain text file called config.toml (TOML is just a simple settings-file format, similar in spirit to a .ini file). It normally lives at:

    • Mac/Linux: ~/.codex/config.toml

    • Windows: C:\Users\yourname\.codex\config.toml

    If the file or folder doesn't exist yet, create it — for example on Mac/Linux:
    mkdir -p ~/.codex
    touch ~/.codex/config.toml
    open ~/.codex/config.toml
    On Windows, you can open it with Notepad, VS Code, or any plain text editor.
  10. Add the Oracle MCP server entry.
    Paste this into config.toml (add it at the end of the file if there's already content there):
    [mcp_servers.oracle-db]
    command = "sql"
    args = ["-mcp"]
    What each line means, in plain English:

    • [mcp_servers.oracle-db] — "here's a new MCP server, and I'm calling it oracle-db" (you can name it anything)

    • command = "sql" — "when you need this server, run the program called sql" (the same one we tested in Step 3)

    • args = ["-mcp"] — "and pass it the -mcp flag," exactly like we typed manually in Step 8

    Save the file and close the editor.
    ⚠️ Don't want to edit the file by hand? You can skip this step entirely and instead run this one command, which writes the same thing for you automatically:
    codex mcp add oracle-db -- sql -mcp
  11. Start Codex and confirm it sees your new server.
    In your terminal, from any folder, simply type:
    codex
    This opens an interactive Codex session — you'll see a prompt where you can start typing to the AI. Now type this exact slash command:
    /mcp
    What you should see: a small list showing oracle-db with a status like "connected" or a green indicator. If you don't see it at all, double-check Step 10's file path and contents, and make sure you saved the file.
    ⚠️ Working in a specific project folder instead? If you placed a config.toml inside a project's own .codex/ folder rather than your home folder, Codex will silently ignore it unless that project is marked "trusted." For your very first attempt, stick with the global ~/.codex/config.toml to avoid this trap entirely.
  12. Have your very first conversation with the database.
    Still inside the Codex session, type in plain English:
    List my saved Oracle connections, then connect to mcp_readonly
    and show me what tables I have access to.
    What happens next, step by step:

    1. Codex recognizes it needs the list-connections tool and shows you exactly what it's about to do, then asks something like "Allow this tool call?" — type y or click "Approve." This approval step is a deliberate safety feature, not a bug — Codex will never silently touch a real system without asking first.

    2. It shows you the list, sees mcp_readonly in it, and asks to call connect next — approve again.

    3. Once connected, it calls run-sql to list your tables and shows you a clean, readable answer in English — not raw database output.

    If any step gets rejected or errors out, Codex will tell you which tool call failed and usually why — read that message carefully before retrying.
  13. Check that everything you just did was logged.
    Open a fresh SQLcl session (or reuse Step 6's connection) and run:
    SELECT * FROM DBTOOLS$MCP_LOG ORDER BY log_time DESC;
    What you should see: one row per query the AI ran a moment ago, each timestamped and tagged with the model's name. Seeing your own recent activity appear here is your confirmation that the entire chain — Codex → MCP → SQLcl → Oracle — worked end to end, and that it's auditable, not a black box.
🎯 Use this when: This is your very first MCP setup, ever — every step above is written to be done once, slowly, with a working checkpoint before moving to the next. Once it works the first time, Steps 8–13 are the only ones you'll repeat for future databases.

🏛️ Section 5: Enterprise Rollout at Scale

A single developer wiring up SQLcl on their laptop is very different from rolling MCP-based database access out across an engineering org. Based on how leading enterprises (like Bloomberg's 9,500+ engineer deployment) approach this, four things separate a pilot from a governed production rollout:

Governance & Identity — treat every MCP server as something requiring its own service identity, not a shared personal login. Forrester projects 60% of Fortune 100 companies will have a dedicated head of AI governance in 2026 specifically to own this.

Ownership — assign a named owner per MCP server (who patches it, who reviews its permission scope, who's paged if it's compromised).

Templates & CI Enforcement — provide a pre-approved, version-controlled config.toml template with an already-vetted least-privilege connection, so individual developers aren't improvising their own database permissions.

Metrics — track query volume through DBTOOLS$MCP_LOG and V$SESSION (filtering on PROGRAM='SQLcl-MCP') centrally, feeding a dashboard your security team actually reviews, not just a table nobody queries.

🎯 Use this when: Writing the internal proposal to move MCP-based database access from "a few developers doing this locally" to an approved, org-wide standard.

⚠️ Section 6: Common Mistakes (And Why They Happen)

Connecting with a high-privilege account "just to get it working."
Why it happens: least-privilege setup takes an extra 10 minutes, and under deadline pressure that feels skippable. Why it's dangerous: the AI now operates with every permission that account has, and a single ambiguous instruction can trigger a destructive query across data it was never meant to touch.

Skipping the manual sql -mcp test before wiring it into Codex.
Why it happens: it feels redundant when you're in a hurry to see the AI working. Why it's dangerous: if Java, SQLcl version, or the saved connection is misconfigured, you'll get a confusing "server not connecting" error inside Codex with no clear indication of which of the three layers actually failed.

Leaving the project untrusted in Codex and wondering why MCP servers never load.
Why it happens: project-scoped .codex/config.toml files silently don't load for untrusted projects — there's no loud error, the server just never appears. Why it matters: teams have lost hours debugging a "broken" server that was actually just never being read.

Never reviewing DBTOOLS$MCP_LOG.
Why it happens: the log table is created silently and easy to forget about once things "seem to be working." Why it's dangerous: it's your only clean audit trail if something goes wrong later — treating it as optional defeats the entire security model Oracle built into the server.


❓ Section 7: FAQ

Does Codex ever see my Oracle database password?

No. SQLcl's MCP server does not accept credentials at call-time. You pre-save a named connection with conn -save -savepwd, and Codex only ever references that connection by name.

Can the AI run destructive queries like DELETE or DROP?

Only if the database user you connected as has that privilege. This is exactly why Section 4, Step 2 (least-privilege user) matters — the AI's capability is bounded entirely by the database account's actual grants, not by anything the AI "chooses" to restrict itself.

What's the difference between SQLcl MCP, OCI Database Tools MCP, and ORDS MCP?

SQLcl runs locally on your machine over stdio (what this post covers). OCI Database Tools MCP is a cloud-managed, serverless option for centrally administered access. The ORDS MCP endpoint is a remote HTTPS streaming option for teams already running Oracle REST Data Services with OAuth2/JWT.

Why does Codex say the MCP server isn't connecting?

The most common causes: SQLcl isn't on your system PATH, Java 17+ isn't installed or isn't the active version, the saved connection wasn't stored with -savepwd, or — for project-scoped configs — the project isn't marked as trusted in Codex.

Is it safe to point this directly at a production database?

Oracle explicitly recommends against it. Use a sanitized replica, a dedicated test database, or a tightly scoped, limited-privilege schema — and always review DBTOOLS$MCP_LOG regularly.


🔗 Section 8: References & Further Reading

All product names (Oracle, Oracle SQLcl, Codex, OpenAI, Anthropic, MCP) are trademarks of their respective owners. This post synthesizes and explains publicly available documentation in original wording — it does not reproduce source text verbatim.


📝 Section 9: Summary

🧩 MCP solves the NxM integration problem — one standard connection instead of a custom bridge for every AI-tool-to-system pairing

🗄️ AI assistants can't safely reach a database without it — MCP servers handle authentication and query execution so the AI never touches raw credentials

🛠️ Codex, MCP, and SQLcl each play a distinct role — Host, protocol, and database-specific server, wired together through one config file

🚀 The 8-step setup is repeatable and auditable — save a least-privilege connection, test manually, register in Codex, verify, and always check the audit log

🏛️ Enterprise rollout needs governance, not just installation — named ownership, templates, and centralized metrics separate a pilot from production

⚠️ Most real-world mistakes come from skipped steps under time pressure — least-privilege setup and the audit log are the two most commonly skipped, and the most costly to skip

Happy Building — and query responsibly! 🔥

Comments