# Database manager

Browse and edit the VPS PostgreSQL and MySQL from the dashboard or over MCP, through a private tunnel, with guards and auditing.

Source: https://ardumaker.com/en/docs/gestor-de-bases-de-datos/

- Category: Servers and infrastructure
- Status: Available
- Requirements: An active VPS with PostgreSQL or MySQL/MariaDB installed; Being a company member with access to that VPS
- MCP tools (Read only): `listar_motores_db_vps`, `probar_conexion_db_vps`, `listar_bases_db_vps`, `listar_tablas_db_vps`, `describir_tabla_db_vps`, `leer_filas_db_vps`, `contar_filas_db_vps`, `consultar_sql_db_vps`, `explicar_sql_db_vps`, `historial_operaciones_db_vps`
- MCP tools (Write or modify): `guardar_credencial_db_vps`, `insertar_fila_db_vps`
- MCP tools (Destructive): `actualizar_fila_db_vps`, `borrar_fila_db_vps`, `ejecutar_ddl_db_vps`

## What can you do with it?

The database manager is ArduMaker's window into the PostgreSQL and MySQL engines running inside the VPS. It works the same from the dashboard, the interactive console and MCP: a single implementation per engine.

- See engines, databases (size and encoding), tables and views with estimated row counts.
- Describe a table: columns with normalized type, nullability, primary key, foreign keys and indexes.
- Read rows with filters and ordering without writing SQL, with keyset paging.
- Insert, edit or delete one row by its complete primary key.
- Read-only SQL console and `EXPLAIN`.
- Run DDL (`CREATE`, `ALTER`, `DROP`, `TRUNCATE`) with confirmation by name when it destroys data.
- Export tables to CSV or Excel and import CSV or Excel (up to 32 MB) in two steps.
- See the history of destructive operations: who, when, which statement and from where.

## When should you use it?

- Check production data without opening the engine to the internet or installing a client.
- Give an AI agent controlled database access, with row-by-row writes and auditing.
- Load a spreadsheet into a table checking first how it will go in.

## How does it work in ArduMaker?

The backend reaches the engine through a private SSH tunnel to the VPS, with an ephemeral key that only allows forwarding to the engine port. The database port is not published for this: [PostgreSQL](https://ardumaker.com/en/docs/postgresql) and [MySQL](https://ardumaker.com/en/docs/mysql) keep listening only inside the VPS.

1. Permissions: the company, the agent's MCP scope on that VPS and the VPS allowed or excluded member lists.
2. Tunnel and connection: the tunnel is opened or reused and validated with `SELECT 1`.
3. Credential: the stored one for that engine (if the customer changed the password by hand and saved it) or the platform's admin credential.
4. Operation: the SQL is built by each engine's layer from allowlists; values always travel as driver parameters, never glued into the text.
5. Audit: whatever writes or destroys is logged with its origin (interface or agent).

## What actually changes?

Reading changes nothing. Writing rows, running DDL and importing change customer data inside the engine; creating tables from the form too, and it is audited as a write. On the VPS, the tunnel uses its own user with a restricted key that does not open a shell.

| Operation | Rule |
| --- | --- |
| SQL console | A single read statement; up to 1000 rows per page |
| Update or delete rows | One row at a time, by complete primary key; no bulk update |
| Destructive DDL | Answers 428 with `confirmacion_esperada`; repeat passing that exact name |
| Import | Step 1 `dry_run` analyzes without touching; step 2 requires the table name as confirmation |
| `EXPLAIN ANALYZE` | Really runs the query; PostgreSQL only |

## Differences between engines

- In PostgreSQL a table can carry a schema (`schema.table`); in MySQL the schema is the database.
- `EXPLAIN` returns each engine's own format; they are not comparable.
- The row count of `listar_tablas_db_vps` is the engine's estimate; the exact count is `contar_filas_db_vps`, more expensive on large tables.

## Diagram

**From the dashboard or the agent to the engine**

```text
Dashboard or MCP agent (same service and permissions)
  ↓
ArduMaker backend (permissions, guards and audit)
  ↓
Private SSH tunnel (ephemeral key, engine port only)
  ↓
Engine on the VPS (PostgreSQL `127.0.0.1:5432` or MySQL `127.0.0.1:3306`)
```

## Expected result

`probar_conexion_db_vps` confirms the backend reaches the engine and logs in. From there, `listar_bases_db_vps`, `listar_tablas_db_vps` and `describir_tabla_db_vps` show the structure and `leer_filas_db_vps` the data. Every write returns the row as it ended up, with defaults and auto-increments resolved.

## Errors and troubleshooting

| Error | Cause |
| --- | --- |
| `vps_apagado` | The VPS is not `active` |
| `credenciales_invalidas` | The engine rejects the user or password (someone changed it by hand): save it with `guardar_credencial_db_vps` |
| `credenciales_requeridas` | No stored credential nor a usable admin one |
| `motor_no_responde` | The tunnel is open but the engine refuses the connection or `SELECT 1` fails |
| `tunel_no_disponible` / `clave_tunel_rechazada` | The tunnel could not be prepared; the key is regenerated and retried once automatically |
| `pool_agotado` | The limit of simultaneous connections for that database was reached |
| `consulta_fallida` | The engine rejected the operation (syntax, constraint, permissions); the message comes sanitized |
| `acceso_denegado` | Not in the company, excluded from the VPS or the agent does not have that VPS in scope |

> **PELIGRO:** In MySQL every DDL does an implicit `COMMIT` and cannot be undone: the answer says whether it was transactional (`transaccional`).

## MCP access

The full manager is available over MCP; reference at [/mcp/docs](https://ardumaker.com/en/mcp/docs) and [/mcp/bases-de-datos](https://ardumaker.com/en/mcp/bases-de-datos). Every tool takes `engine` (`postgres` or `mysql`) and, except the engine ones, the `base`.

| Kind | Tools |
| --- | --- |
| Read | `listar_motores_db_vps`, `probar_conexion_db_vps`, `listar_bases_db_vps`, `listar_tablas_db_vps`, `describir_tabla_db_vps`, `leer_filas_db_vps`, `contar_filas_db_vps`, `consultar_sql_db_vps`, `explicar_sql_db_vps`, `historial_operaciones_db_vps` |
| Modify | `insertar_fila_db_vps`, `guardar_credencial_db_vps` |
| Destructive | `actualizar_fila_db_vps`, `borrar_fila_db_vps`, `ejecutar_ddl_db_vps` |

- `consultar_sql_db_vps` rejects writes on purpose and a second statement separated by `;`. Values go in `params`.
- Destructive `ejecutar_ddl_db_vps` requires repeating with `confirmacion` equal to `confirmacion_esperada`; confirming a wrong name is rejected.
- `guardar_credencial_db_vps` stores the engine password encrypted and no tool returns it.
- Exporting and importing files only exist in the dashboard.

## Related features

- [PostgreSQL](https://ardumaker.com/en/docs/postgresql/)
- [MySQL](https://ardumaker.com/en/docs/mysql/)
- [Agent audit](https://ardumaker.com/en/docs/auditoria-de-agentes/)
- [MCP server](https://ardumaker.com/en/docs/servidor-mcp/)
- [SSH tunnels](https://ardumaker.com/en/docs/tuneles-ssh/)
