SQL Queries and Database Tools

Declare a database in a .nornai sidecar. A .norn flow imports that sidecar alongside any .nornsql file whose named operations use the database.

Declare the Database

db/database.nornai
database appDb
    adapter postgres
    connectionString {{$env.APP_DB_URL}}
    access read
end database

adapter and connectionString are required. Built-in adapters are postgres, sqlserver, and sqlserver-windows. The connection string can be written directly in the block, or reference a selected .nornenv secret or process environment variable. The database account's permissions remain the final authority.

For Windows integrated authentication, use adapter sqlserver-windows with an integrated-auth connection string. This adapter runs only on Windows.

.nornenv
[env:dev]
secret APP_DB_URL = ENC[NORN_AGE_V1:kid=team-main:...]

access read is the default for AI tools. It accepts one SELECT without INTO or FOR UPDATE; PostgreSQL also executes it in a read-only transaction. access full permits write statements. Use a restricted database login for reliable read-only access, especially with SQL Server or custom adapters. This access setting applies to AI tools; deterministic run sql operations use the permissions of the database account.

Named SQL Operations

db/customers.nornsql
connection appDb

query ListUsersByStatus(status)
select Id, Email, Status
from Users
where Status = :status
end query

command UpdateUserStatus(id, status)
update Users
set Status = :status
where Id = :id
end command

Use query for rows and command for writes or other non-row work. SQL parameters use named :paramName placeholders. Each .nornsql file names one database alias.

customer-tests.norn
import "./db/database.nornai"
import "./db/customers.nornsql"

test sequence VerifyCustomerState
    var activeUsers = run sql ListUsersByStatus("Active")
    assert activeUsers[0].Email exists

    var updateResult = run sql UpdateUserStatus(42, "Disabled")
    assert updateResult.affectedRows == 1
end sequence

The flow must import the database sidecar directly. Query results are arrays of row objects; command results include metadata such as affectedRows. The same syntax works in VS Code and the local CLI.

Existing SQL projects must move each sql.connections entry from norn.config.json into a .nornai database block and import that sidecar directly from every flow that uses it. For a custom adapter, replace its old sql.adapters command and adapter ID with the script path in the block's adapter line. Project timeout and MCP settings can still use norn.config.json.

Give an Agent Database Access

db/database.nornai
model Workbench
    provider openai
    name gpt-5.6-luna
    apiKey {{$env.OPENAI_API_KEY}}
end model

database appDb
    adapter postgres
    connectionString {{$env.APP_DB_URL}}
    access read
end database

agent Inspector
    model Workbench
    database appDb
    system "Inspect the database before answering."
end agent

An agent receives query_database and inspect_database only after a database appDb grant in its own block. The inspection tool lists schemas, tables, columns, and types. These tools are recorded for replay, but pure replay does not reconnect to the database. The Agent Graph shows database and knowledge declarations as nodes connected to agents that grant them, without showing the connection string.

Custom Adapters

Set adapter to a path relative to the .nornai file. Norn runs JavaScript adapters with Node and sends the SQL adapter protocol payload on standard input. Built-in adapters use the names postgres, sqlserver, or sqlserver-windows.

db/database.nornai
database appDb
    adapter ./adapters/custom-db.js
    connectionString {{$env.APP_DB_URL}}
end database

VS Code Support

.nornai database blocks have syntax highlighting, folding, diagnostics, and simple completion. .nornsql files retain SQL highlighting and operation completion. The connection alias is checked in the importing .norn file, where its direct sidecar imports are known. The starter catalogue includes a runnable fake SQL adapter and a real database starter.