Skip to content

Connecting a Database

A database source lets agents query your relational data — either as plain-English questions turned into read-only SQL, or as indexed rows that appear in ordinary search results. Both are read-only: nothing here ever writes to your database.

Setup spans two pages, deliberately:

  • Connections — add the source, test it, rotate its credential.
  • Settings → Database sources — tune what gets indexed and who may see which rows. Also where you remove a source.

1. Add the source

On Connections, add a database source and fill in:

FieldNotes
KindWhich driver, from those compiled into your deployment. An empty list means the build has no database drivers.
Connection stringe.g. postgres://user:password@host:5432/database. Stored as an encrypted secret under a derived id — the console never reads it back.
Connection secretAlternative to typing a string: point at a secret you already uploaded.
SchemaDefaults to public.
Workspace idOptional. Inherits from the source name if left blank. This is the workspace its rows and schema land in.

The dialog tests before saving, running the same three checks a reload runs, in the same order. A typo in the host or password fails here rather than three steps later as a puzzling sync error.

Use a database account with read-only grants on only the tables you intend to expose. The engine never issues writes, but the credential should not be able to either.

2. Apply a reload

A saved source is not a running source

It shows Needs a reload and its Test and Sync buttons stay disabled. Open Settings → Database sources, then Dry runApply reload. The badge on Connections links straight there.

Once live, Test pings it and Sync now runs the first sync.

3. Decide what gets indexed

Two levels, and the distinction matters for both cost and privacy.

Schema only (the default)

Without row indexing, the engine indexes structure: table names, column names, types, and relationships. That is enough for database_query to write correct SQL against your schema — the tool profiles table statistics and generates queries; it does not need your rows pre-embedded.

This is the cheap option. No row content is embedded, so no per-row token cost, and no row content is stored in the index.

Indexed rows

Turn on Index row content (per source, and per table) when you want rows themselves to appear in semantic search results — a support ticket surfacing next to the code that handles it.

Per table you then choose:

  • Embed columns — which columns become the searchable text. Leave blank for all. Naming just the meaningful text columns is both cheaper and more accurate than embedding every numeric id in the row.
  • Ontology class — the class assigned to rows from this table, when the source is bound to a vocabulary.

Rows need a single-column primary key

Row indexing pages through the table with a keyset pager, which needs one column to page on. A table with no primary key, or a composite one, reports that it cannot be indexed and says which case it is. Schema indexing still works for those tables.

Nothing syncs on a schedule yet, so run Sync now after adding a source and after changing a row policy.

4. Restrict who sees which rows

If more than one person queries this source, set a row policy per table. This is the database equivalent of folder access rules.

FieldMeaning
Owner columnThe column holding the value that identifies a row's owner — a Salesforce user id, an account manager's id.
Group columnThe column holding a group identifier, for rows shared with a team.

With a policy set, the rows an actor reaches through database_query, and the rows that appear in their search results, are limited to those matching their owner or group values.

There are two ways to give an actor its owner values:

  1. Per actor. In the Directory, enter that person's owner-column values for the source, one per line.
  2. By convention. Turn on "An actor id is an owner value" for the source, and an actor reaches rows whose owner column holds their own actor id — nothing to configure per person.

Option 2 is much less work, but only correct when your owner column and your actor ids are the same namespace. Leave it off when the owner column holds values from an unrelated namespace, such as a numeric internal key: an actor id that happened to equal one would otherwise reach rows nobody intended.

Changing a row policy needs a re-sync

A row's labels are derived from the values in its own owner and group columns at sync time. Nothing can re-stamp them in place — refreshing them means re-reading the table. After changing a policy, run Sync now, or already-indexed rows keep their old labels and search will not be filtered the way you just configured. The console warns you about exactly this after such a save.

Querying it

Agents reach the source through the database_query tool, which needs the dbsource:<name>:read scope on the key — one scope per source, so a key can be limited to one database.

The tool accepts either SQL or a plain-English question. Generated SQL is read-only and grounded on auto-profiled table statistics.

Rotating the credential

Use Rotate credential on Connections. It works even on a source that has not been reloaded yet — which is exactly when a mistyped string most wants replacing — and takes effect at the next reload. Until then the source keeps using the previous string.

Removing a source

Remove it in Settings → Database sources. That stops syncing, but rows already indexed stay searchable until you purge them. Stopping a sync and deleting data are deliberately separate actions, so removing a source by mistake does not destroy an index.

Released under the Private Beta License.