Guide · 04
Connections and passwords
Saved profiles, where passwords live, adding databases from the chat, and moving between them.
A profile is a saved connection: where the database is, who to log in as, and the rules for it (access mode, visible schemas, row cap). Profiles live in ~/.config/nexql-mcp/config.toml. Passwords never do.
Adding a database
Pick whichever fits. All four keep the password out of the chat and out of plain-text files.
From the chat (easiest once NexQL is running)
Ask your assistant, for example:
“Also connect our billing database: host db.internal, database billing, user billing_reader.”
It calls add_database with those details. nexql-mcp opens a one-time page on your computer at 127.0.0.1. You check the host and user, type the password, and press Test and connect. The connection is tested, the password goes to your OS keyring, and a read-only profile is saved and available straight away, with no restart.
The page only answers on your own machine, uses a secret link, accepts five attempts and expires after ten minutes. Set NEXQL_MCP_OPEN_BROWSER=0 if you’d rather open the link yourself.
In a terminal
Leave out the password and nexql-mcp asks for it without showing what you type:
npx -y nexql-mcp@latest profile add billing --host db.internal --dbname billing --user billing_reader --access-mode read
In a browser wizard
npx -y nexql-mcp@latest setup
Opens a local page for adding profiles and wiring them into your apps. nexql-mcp tui is the same in the terminal.
In Claude Desktop
The install form asks for a database URL. That one connection is passed in as DATABASE_URL. To add more, ask in the chat as above.
Where passwords live
nexql-mcp looks for a profile’s password in this order:
password_command: a command that prints it, such asop read op://vault/pg/passwordfor 1Password.password_file: a file that holds only the password.- Your OS keyring (macOS Keychain, Windows Credential Manager, Secret Service on Linux). This is where
add_database,profile addand the setup wizard put it.
For a one-off connection without a profile, PGPASSWORD in the environment works too.
On Linux without a running keyring, nexql-mcp falls back to an encrypted file under its config folder. An old config with a plain password = "…" line is moved into the keyring automatically the first time it loads. To change a stored password:
npx -y nexql-mcp@latest profile set-password billing
Which database it connects to
When nexql-mcp starts, the first of these that’s present wins:
- A URL on the command line:
nexql-mcp postgres://dev@localhost:5432/appdb --profile name--host,--port,--dbname,--userflagsDATABASE_URL(orPOSTGRES_URL)PGHOST,PGPORT,PGUSER,PGDATABASE- The
default_profilein a project’s.nexql/config.toml - The
default_profilein your own config
nexql-mcp doctor prints which one it used and whether it can connect.
Moving between databases
list_connectionsshows your saved profiles;get_current_contextshows which one is active.switch_connectionmoves the session to another profile or database.- Most query tools also take
connectionIdanddatabasefor a single call, without switching. search_all_databasesfinds which database holds a table, andresolve_targetpicks a connection from a hint like “staging”.
So you can ask “Compare last month’s orders in shop with paid invoices in billing” and the assistant reads each part from the right place.
Sharing with a team
Commit a .nexql/config.toml to your project to pick a profile and tighten its rules for everyone. It holds no secrets:
default_profile = "staging"
access_mode = "read"
schemas = ["public", "billing"]
deny_tables = ["auth.*"]
max_rows = 200
Each person keeps the actual connection, and their own password, in their personal config. export_profile writes a shareable version of a profile with credentials stripped, and import_profile brings one in.
Use a role that can only read
The safest setup is a database role that can’t change anything, whatever the access mode says. On PostgreSQL 14 and later:
CREATE ROLE nexql_readonly WITH LOGIN PASSWORD 'replace-with-a-secret';
GRANT pg_read_all_data TO nexql_readonly;