Most tools on a cloud MCP server do something narrow. List the backup vaults. Get the metrics for this resource. Summarise these recommendations. Even the tools that change things usually change one kind of thing in one way. A database query tool is different. Its input is a query, and a query can do almost anything the database login is allowed to do.
Microsoft's release post for Azure MCP Server 3.0 is unusually blunt about this. It describes the MySQL and PostgreSQL query tools as "destructive, non-idempotent, and non-read-only", notes that SQL-verb filtering was removed, and tells users to apply least-privilege database permissions. It also notes that in the server's consolidated mode these tools move from get_azure_databases_details to execute_azure_database_query, a name that finally says what they do. That is a vendor telling you, in writing, that the server is not the safety boundary for database work.
This part explains why database tools need stronger boundaries than resource discovery, and what those boundaries look like.
Why a query is not like a call
Three properties make database tools a separate category.
The input is a programme. A resource tool takes a resource name and returns a description. A query tool takes text that the database will execute. The space of possible actions is the whole query language, limited only by the login's rights.
It is not idempotent. Calling "list vaults" twice returns the same list. Running an UPDATE twice may apply it twice. Running a DELETE after a retry may remove rows that arrived in between. Agents retry; networks time out; an accepted call is not a completed change. Every one of those behaviours is dangerous against a database.
The boundary sits in a different place. For most Azure tools, the boundary is the identity's Azure role assignments. For a query tool, the decisive boundary is the database login and its grants. A Reader role in Azure says nothing about whether the database user can drop a table. Microsoft's post makes the same point: the signed-in database permissions decide what operations are allowed.
Filtering is not a boundary
The natural response is to filter the query: block DROP, DELETE and UPDATE before they reach the database. Microsoft removed SQL-verb filtering from these tools in 3.0, and that is a reasonable signal about how far such filtering can be trusted. SQL has many ways to change data: functions with side effects, stored procedures, SELECT ... INTO, statements chained after a comment, vendor-specific commands. Pattern-matching on verbs catches the obvious cases and misses the rest.
The same applies to instructions in prompts or tool descriptions ("only run SELECT statements"). They make a bad query less likely. They do not make it impossible. The preventing expensive and destructive tool calls article explains why layered controls beat a single gate; for databases, the layer that actually holds is the database's own permission system.
The boundaries that hold
Sedgefield Freight is fictional, and its systems and figures are illustrative. Sedgefield's developers want the assistant to answer questions such as "how many consignments were delayed at the Gqeberha depot last week?" against an operational PostgreSQL database. The platform team's design:
| Boundary | Sedgefield's choice |
|---|---|
| Which database | A disposable copy refreshed nightly from a masked extract, never the production primary |
| Which login | A dedicated role with SELECT on four reporting views only; no table access, no functions with side effects |
| Which data | Views exclude driver and customer contact details; masking happens in the extract, not in the prompt |
| Which limits | statement_timeout set on the role, and views that return bounded result sets, so a runaway query stops at the database |
| Which tools | Only the query tool for this workflow is exposed; administrative database tools are not |
| What is recorded | Every query text, the identity, the row count and the duration, kept with the conversation reference |
None of this depends on the model behaving well. If the agent generates an UPDATE, the database refuses it. If it generates a query that scans everything, the timeout ends it. If a prompt injection in returned data asks it to export the customer table, the customer table is not there.
Prove the boundary by trying to break it
A design table is a claim. Before the tool is enabled, someone should log in as the agent's database role, not as an administrator, and run a short set of statements that must fail or stop:
| Attempt | Expected result | What a pass proves |
|---|---|---|
UPDATE or DELETE against a reporting view | Permission denied | The role has no write grants, even on updatable views |
CREATE TABLE in the default schema | Permission denied | The role cannot create objects; on PostgreSQL versions before 15, every role could create in the public schema by default unless that was revoked |
SELECT from an underlying table | Permission denied | Access is limited to the views |
SELECT pg_sleep(600) | Cancelled at the statement timeout | Limits are enforced by the database |
| Calling a function the views do not use | Permission denied, or the function has no side effects | Side-effecting code is out of reach; PostgreSQL grants EXECUTE on new functions to everyone by default, so this usually needs an explicit revoke |
Two common shortcuts fail this test. Setting default_transaction_read_only on the role looks like a boundary, but a session can switch it off again with a single SET command, so it only protects against accidents. And a role that inherits from a broader group role can carry grants nobody remembers giving; check effective privileges, not just the grants made directly to the agent's role.
Record the results with the date and the database version, and rerun them whenever the grants, the views or the database version change. If one of the attempts succeeds, the tool is not ready, however well the agent has behaved in testing.
When write access is genuinely needed
Some workflows will need an agent to change data: correcting a reference, closing a stuck job, reprocessing a record. Treat these as change workflows, not query workflows.
- Use a narrow interface, not a query tool. A stored procedure or a small API that performs one named action with validated parameters is far safer than free-form SQL. It can be idempotent by design, for example by requiring an operation identifier and refusing duplicates. The design an MCP server as a product article covers this pattern.
- Prepare, then approve. The agent proposes the exact statement or action, with the rows it will affect. A person approves that exact change, not a summary of it.
- Execute under a different identity. The identity that can write is not the identity that explores. It is scoped to the procedure, not the schema.
- Keep the evidence. The proposal, the approval, the executed statement, the affected row count and the result belong in one record. Part 7 describes it.
Never connect an agent's query tool to production with credentials that can write. That is not an agent design; it is an open console.
A checklist before any database tool is enabled
- Is the target a disposable or masked copy? If not, why not, and who approved it?
- Which database login does the tool use, and what are its exact grants?
- Are timeouts and result sizes bounded by the database and its views, not the prompt?
- Is personal information excluded at source, not filtered in the response?
- Are the query texts and results metadata logged with the requesting user?
- Is any write path a named, validated, idempotent action with approval?
- Who owns the login, and when will its grants next be reviewed?
If any answer is "the agent knows not to", the tool is not ready.
Next: Part 5, An MCP upgrade is a production change. All parts are on the series page.
How CloudNala can help
CloudNala helps teams give agents database access safely. We design the masked or disposable data copies, the narrow database roles and views, the limits enforced at the database, and the named write actions that replace free-form queries where change is genuinely needed. We test the design by trying to make the agent do the wrong thing, before your users do.
Work with CloudNala
CloudNala helps organisations move from technology ambition to practical execution across cloud, AI, data, platform engineering and digital services.
Whether you are exploring AI, modernising your cloud environment, building a public-sector digital service, or turning an idea into a working MVP, we can help you shape the roadmap and deliver the next step.
Book an MCP Readiness Review or write to us at consult@cloudnala.co.za