4:00pm
The screen is stuck
The browser shows an old status. The agent needs the real shape of the data, not a guessed column name.
Tool choice · Agent database operations
At 4pm, the agent says it only needs to connect to the local database, inspect a column, and finish the screen. It often does. The question usually arrives later: which fixture did it change, and why does CI no longer match the laptop?

#42 received a refund event, but the UI is still stuck on “processing.” The agent looks at orders, then proposes marking a few rows paid. You only wanted the screen to work, but e2e, a teammate, and tomorrow morning’s CI all use the same fixture.If the database will genuinely live for five minutes in front of you, opening a client and letting the agent help with a line or two of SQL is perfectly reasonable. Once “confirm the bug” becomes “change data that everyone relies on,” however, the job has changed. You need more than a connection: the next person needs to understand it, and the next machine needs to reproduce it.
4:00pm
The browser shows an old status. The agent needs the real shape of the data, not a guessed column name.
4:06pm
This is no longer a read. The wrong predicate can make the next test begin with already-contaminated data.
9:12am, tomorrow
The chat does not contain the whole predicate, and someone has to reconstruct what happened yesterday.
Best for: throwaway experiments, synthetic data, and a trusted developer who will inspect every statement.
Best for: low-risk, interactive tool exploration in an agent host whose authorization and logging model already meets the need.
Best for: realistic data, shared fixtures, migrations, CI, incident runbooks, or any result another person must rerun.
At first
You only want to see the screen work
A direct client gets the agent an answer quickly.
Five minutes later
You are changing a shared fixture
Use dbcli and leave a command the next person can run.
Letting an agent operate a client
The agent can browse, compose SQL, and send writes from a GUI, driver, or shell. Its context lives in this conversation and this session; when you are beside it, that can be very efficient.
But when it says “I also fixed three rows,” the meaningful facts are spread across chat, tool output, and browsing history: which columns it inspected, what the WHERE predicate was, and whether anyone reviewed the write before it ran.
Using dbcli
Schema, protection rules, a previewed write, the actual execution, and recovery after a failure use one CLI surface. The agent can still move quickly, but what it gives you is more than “done”: it is a command sequence that belongs in a PR, test script, or runbook.
This is not about turning every local experiment into a ceremony. It is about taking shared data, repeatable operations, and handoffs out of a one-off conversation.
These three steps do not make the agent do less. They put the judgement that was hidden inside a client session somewhere anyone can inspect. The first pass may take a few more seconds; the next morning can save half an hour of guessing.
It may have imagined paid_at when the table uses payment_at. First see what it must not read, then give it the columns that really exist. It is a mundane step, but it prevents a plausible-looking fix from being built on the wrong assumption.
dbcli blacklist list
dbcli schema orders --format jsonPrint the UPDATE first. In a few seconds, you can see whether the predicate selects only #42, and whether it touches a refund amount or test account. This is a good moment for a human to intervene: the SQL has not run, but the risk is finally concrete.
dbcli update orders --where "id=42" --set '{"status":"paid"}' --dry-runPut the reviewed command in the test script or PR description instead of reconstructing it from memory. When a supported command fails, --recovery leaves a machine-readable next step tied to its audit record. It is not magic rollback; it lets an investigation start from concrete evidence.
dbcli query "SELECT status FROM orders WHERE id=42" --format json --recoveryMCP is not inherently unsafe, and it does not have to compete with dbcli. If an agent host has already put least-privilege access, data masking, approval, and useful audit logs around a particular database server, MCP can be excellent for interactive discovery: “show me the tables” or “let me inspect a small sample.”
The difference is where responsibility sits. MCP’s boundary and record depend on how that host, server, and tool are implemented; a direct client’s boundary is commonly the connection and the operator’s habits.
dbcli focuses on a command contract that the project can agree on, inspect, and run again in CI. Once exploration becomes a write, a shared fixture, or a handoff, that contract is usually more valuable than the fact that the agent is already connected.