Yaoti

Yaoti

Menu

Is a "Skeleton key” the right MCP tool for a DBA?

1 June 2026 by Yaoti

Our MCP Servers ship (SQLcl) or optionally offer (OCI) a run_sql tool. It’s great! We built it, we use it, and it works exactly as intended — give the agent a way to execute SQL (generated or otherwise) against your Oracle database.

Be careful WHO gets the keys to your house!

But “works as intended” and “right tool for every job” aren’t the same thing. And if you’re thinking about putting an AI assistant in front of a junior DBA, or automating routine database maintenance tasks, reaching for run_sql as your only option is leaving a lot on the table.

I want to dig deeper on this – maybe a more bespoke MCP Tools is called for.

The tool isn’t the problem. The context is.

run_sql is great for exploration and ad-hoc analysis. A developer investigating a schema, a DBA debugging a slow query, someone doing one-off data work — that’s exactly what it’s for. The flexibility is the point.

The risk shows up when you take that same flexibility and drop it into a workflow that’s supposed to be repeatable, reliable, and bounded. Maintenance tasks. Automated pipelines. An assistant helping a less-experienced person do the right thing consistently.

In those contexts, you don’t actually want the agent improvising SQL. You want it doing the right thing the same way every time. AI Skills can help with this, so can agent memory, or various other context engineering techniques.

And beyond this, we’ve also always said: use the database to protect the database. Oracle has row-level security, VPD, SQL Firewall, Data Vault, invoker rights, DBMS_ASSERT — all of it enforces your rules at the layer that can’t be prompted around. Relying on ‘the front end’ to secure your back end, is not a good choice.

What about Deep Data Security? Read the official blog, and yes, we ARE building in support for this, stay tuned!

But defense in depth means you’re also thinking about what the agent is even able to ask for. That’s where the need for a custom MCP tool might come into play.

What a purpose-built tool gives you

I’ve been building a perf_ops wrapper over the past few days — a PL/SQL package that handles five common DBA operations:

  • gathering optimizer statistics,
  • rebuilding indexes,
  • refreshing materialized views,
  • taking AWR snapshots, and
  • canceling runaway SQL.

It’s exposed as a single MCP tool, and here’s what that buys us:

Consistent, typed output

run_sql returns whatever the query returns. Column names, data types, row order — all shaped by however the NL2SQL came out that particular time. If anything downstream needs to consume that output reliably, you’re in trouble the first time the agent phrases things differently.

A custom tool returns a defined JSON envelope. Every single time. "status":"SUCCESS","operation":"GATHER_STATS","num_rows":1908,.... The structure is guaranteed because the PL/SQL produces it, not the agent.

The agent can’t do what isn’t in the tool

Say hello to “Jeff,’ our new-hire college fresher Jr. DBA. We trusted him enough to hire him, but not enough to give him access to the SYS account on any meaningful system. Now say you want “Jeff’ to have an AI Assistant. Maybe…maybe you don’t that combo of Jr DBA + AI Agent to have any sort of autonomy in a database. Codex perhaps will provide AI assistance for Jeff when it comes to routine maintenance — gathering stats, rebuilding bloated indexes, taking an AWR snapshot before or after a perf tuning exercise.

With run_sql, the agent figures out the SQL on the fly. Most of the time it’ll be fine. But NL2SQL isn’t perfect, and for operational tasks “most of the time” isn’t the bar you want. A slightly wrong DBMS_STATS call with bad parameters, an index rebuild that wasn’t ONLINE, a CANCEL SQL with a mangled literal — these aren’t catastrophic but they’re annoying and avoidable.

With perf_ops, the agent doesn’t generate SQL for these operations at all. It passes a JSON payload to a tool, and the PL/SQL does the work correctly — with DBMS_ASSERT validation, proper error handling, and a clean result back. The junior DBA assistant is good at exactly the operations you’ve defined. Not because you’ve restricted it with a prompt (prompts are suggestions, not enforcement), but because the other operations simply don’t exist in the interface.

One tool, multiple operations

Every tool in your MCP Server costs context. The agent has to reason about what each one does, when to reach for it, whether it’s the right fit. Proliferating thin single-operation tools multiplies that overhead.

perf_ops dispatches five operations through a single JSON input. The agent doesn’t choose between gather_table_stats, rebuild_index, take_awr_snapshot, and so on. It knows there’s a perf_ops tool and passes the right operation key. Cleaner reasoning, fewer tokens, more reliable behavior. One well-designed tool beats five thin wrappers every time.

What this looks like

The Custom Tool I’ve defined for my OCI Database Tools MCP Server is invoked with this simple SQL –

SQL

SELECT DBMS_LOB.SUBSTR(
 perf_ops.perform_operation(:json_payload),
 4000,
 1)
 FROM DUAL;

One bind variable, always a VARCHAR2. The package unpacks it via JSON_VALUE, validates identifiers through DBMS_ASSERT, dispatches to the right private function, and returns typed JSON.

Calling it from the agent looks like this:

JSON


 "operation":"GATHER_STATS",
 "owner":"JEFF",
 "object_name":"TRANSACTIONS"

So once this is deployed to our MCP Server, I can simply ask my agent to refresh and summarize stats on an object in my schema, no SQL/PLSQL generation required!

And the agents still excel at what agents were built for – summarizing, putting large amounts of data into context!

💡🥃 Idea for a new drinking game, take a shot every time someone says the words ‘tokens’ or ‘context.’

The database still protects the database!

None of this replaces proper database security. The invoker rights on perf_ops mean the calling user needs the actual privileges to do the work — you don’t get GATHER_STATS for free just because you called the tool. SQL Firewall, VPD, Data Vault — all of that is still in play underneath.

What custom tools add is a layer of intentionality on top of that foundation. You’ve decided what operations make sense for this assistant, built them correctly once, and now the agent just calls them. The database enforces the rest.

That’s not a skeleton key. That’s a purpose-built set of tools for a specific job. And for a Jr. DBA AI assistant, that’s exactly what you want.

How I built it

When defining new MCP Server Toolsets, one of your options in our OCI offering is to define a ‘custom’ tool.

Here’s what mine looks like, from the console definition and how the tool looks to my Agent:

I have security on this tool locked down to my Operators/Admins group members.

The PL/SQL code

PLSQL