What you will learn How to attach a database to a workspace, which four kinds are supported, and the one thing you must settle before attaching — not a tool setting, but account permissions.
If tables and SQL are new, start with What a database is.
Until now a person pulled the data and pasted it into the conversation. Attach a database and the agent queries it directly.
The grounding from attaching sources extends from documents to your own data.
| Kind | Connection string |
|---|---|
| PostgreSQL | postgres://… or postgresql://… |
| MySQL | mysql://… |
| MongoDB | mongodb://… · mongodb+srv://… |
| SQLite | a file path — file:… or .sqlite · .sqlite3 · .db |
You do not pick the kind separately. It is inferred from the scheme at the
front of the connection string. Which means a missing scheme means no connection
— writing user:pass@host/db without postgres:// is most first failures.
Same route as "outward" in connecting an MCP server. Add the database MCP address as a connection and pass the connection string as a header.
Put a name in the middle of the header name.
They are then distinguished as primary and analytics. With a single
connection the name is default.
Never paste a connection string into a conversation. It contains a password. Put it in the connection settings only — the same principle as managing credentials.
Sorted into the three classes from tools are permissions:
| Class | Tools | Nature |
|---|---|---|
| Connection | db_connect · db_disconnect · db_list_connections | state |
| Read | db_list_tables · db_describe_table · db_select | changes nothing |
| Raw query | db_query | runs the SQL it is handed, as given |
| Irreversible | db_insert · db_update · db_delete | writes and deletes |
db_query row againdb_query is not read-only. It executes the SQL string it receives. Turn off
db_insert, db_update and db_delete and you still have not blocked writes if
db_query is on.
db_delete does require a where clause, which prevents whole-table deletions —
but deleted rows do not come back.
A read-only account is more reliable than turning tools off.
The difference is who enforces it. Tool settings can be changed by someone inside the workspace; account permissions are enforced by the database. Least privilege here is a question about the database account, not the tool list.
A connection opened by db_connect closes 30 minutes after it was last used.
Mid-way through a long job you will see exactly this:
Just call db_connect again. For unattended work such as a schedule, put
"reconnect if the connection has dropped" into the instruction.
The last line matters most. It creates a path where a sentence from outside
becomes a query — the structure from when what it reads becomes a
command. If an email body from a customer can reach
db_query, a read-only account is a condition, not a choice.
Deciding by instruction and blocking by permission are different things. Instructions can drift or be invented, and they can be overridden by outside input. Blocking is the account's job.
db_list_tables lists them and db_describe_table shows the columns. But only
what the account can see is visible — which is why narrowing the account is
narrowing the scope.
1. Why is turning off every write tool not enough?
Because db_query executes the SQL it is handed. It is not read-only, so it
alone permits writes.
2. Why is a read-only account more reliable than a tool setting?
Different enforcers. Tool settings can be changed inside the workspace; account permissions are enforced by the database itself.
3. Why is an inbound path in the same workspace dangerous?
A sentence from outside can turn into a query. It is the same structure as prompt injection, so in that configuration a read-only account is a condition rather than a choice.
Next, try the attached tools by hand → The playground
"Break last month's returns down by region and lay it out in a table" -> list tables -> inspect columns -> query -> tableX-DB-Connection-String: postgres://reader:••••@db.example.com:5432/shopX-DB-Primary-Connection-String: postgres://reader:••••@db1/appX-DB-Analytics-Connection-String: mysql://reader:••••@db2/analytics✗ Attaching the account the application uses✓ Creating a new account with SELECT only, and attaching that✓ Attaching a replica or an analytics database instead of productionConnection not found: … It may have expired or been disconnected.□ Is the account read-only?□ Is this production, or a replica?□ Is db_query enabled? -> if so, writes can only be blocked by the account, not by tool settings□ Do insert, update and delete have human approval?□ Does this workspace also have an inbound path (widget, channel, email)?