MCPDBWizard

Writing  · 

What people actually mean by a read-only MCP server

“Read-only” is the first thing anyone asks for, and it is the right instinct.

Making a server read-only is three layers and worth doing, but does not, on its own, lead to a ‘safe’ MCP server.

This is why we created MCP DB Wizard. In MCP DB Wizard the administrator not only defines every statement the server can run, but can also add notes to them to explain when an agent should and should not use them.

What do people actually want when they say ‘read only MCP server’?

When you start to think about it you realise that ‘read only MCP server’ is actually a shorthand for a set of desired behaviours. It breaks down into:

The agent can’t make unauthorized changes to the database.

There may well be changes people would be happy to allow, but without an obvious mechanism for deciding which ones, the choice on offer looks like ‘dangerous mcp server’ or ‘read only mcp server’, and people instinctively go for the latter.

The agent can’t cause harm to the database.

I’ve worded this carefully! I can ‘cause harm’ without changing anything, simply by issuing a swarm of daft resource hogging queries, or a SELECT ... FOR UPDATE that sits there holding row locks. Do this at scale and you can bring the database to its knees while still being a ‘read only mcp server’.

The read only mcp server will provide correct answers.

This is what people want, but there is no guarantee that it’s what they’ll get. ‘Read Only’ != ‘Correct’.

MCP DB Wizard meets the first two, and improves the third. Here’s how…

Instead of giving SQL access and letting the agent wander the data dictionary an administrator decides which Objects and SQL statements are turned into tools and matching descriptions.

For complex queries and updates you provide a SQL statement you know works, and an explanation of when to use it.

For PL/SQL procedures and functions you decide on a case-by-case basis whether access is OK, as well as providing an explanation of use. PL/SQL access is important, as you can build all the sanity checking you want into a procedure, and the agent has no way to bypass it — as long as you did not also expose the underlying table, which would let it go straight round the checks. Exposing the routine instead of the table is the whole point.

For tables we allow CRUD operations, but reads are limited to lookups on the primary key, and on the unique keys, indexes and foreign keys you selected. There is no free-form query.

And for the second need, curation is not enough on its own — an approved statement can still be an expensive one, and an unselective index lookup returns every matching row. The control that actually protects the database is a timeout: DAO_QUERY_TIMEOUT_SECONDS lets Oracle raise ORA-01013 on a runaway call, so the query stops and the pooled connection goes back. There is a per-caller rate limit as well, which bounds how often calls start rather than how long one runs. Both matter, and they are different things.

How do I get MCP DB Wizard?

It’s available from our GitHub repo as a Docker image, and the quickstart will get you a running server against your own schema.