Scope
A UI-free service in lib/core/mcp/ that the MCP tools call. It reuses the existing database services and does not duplicate execution logic.
listConnections(): id, name, type, environment, database of connections with MCP access enabled. No host, user, password, SSH data or connection strings.
listTables(conn, {schema}), describeTable(conn, table): columns, types, nullability, PK / FK, indexes (reuse postgres_metadata, TableSchemaMeta, MySQL / SQLite catalog queries).
sampleRows(conn, table, {n = 20}): quoted identifiers, never string-built SQL from model input.
runQuery(conn, sql), explainQuery(conn, sql).
Read-only guarantees
Tests
- Classifier table: allowed / refused statements, including comments, strings,
WITH ... DELETE, multiple statements, EXPLAIN ANALYZE DELETE.
- A refused statement never reaches the driver (fake delegate).
listConnections output never contains secrets (scan of JSON for password / host / connection string).
Part of #1133.
Scope
A UI-free service in
lib/core/mcp/that the MCP tools call. It reuses the existing database services and does not duplicate execution logic.listConnections(): id, name, type, environment, database of connections with MCP access enabled. No host, user, password, SSH data or connection strings.listTables(conn, {schema}),describeTable(conn, table): columns, types, nullability, PK / FK, indexes (reusepostgres_metadata,TableSchemaMeta, MySQL / SQLite catalog queries).sampleRows(conn, table, {n = 20}): quoted identifiers, never string-built SQL from model input.runQuery(conn, sql),explainQuery(conn, sql).Read-only guarantees
isMutatingSqlStatement/DestructiveSqlDetector.PgSessionMode.readOnly, MySQLSET SESSION TRANSACTION READ ONLYon a dedicated pooled session, SQLitePRAGMA query_only=ON(or a read-only open).sql_limit.dart); result saystruncated: true.database_error_mapper.Tests
WITH ... DELETE, multiple statements,EXPLAIN ANALYZE DELETE.listConnectionsoutput never contains secrets (scan of JSON for password / host / connection string).Part of #1133.