Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
saya is a database-aware AI agent for the terminal. Ask questions in plain language or run SQL directly. For agent queries, saya discovers the schema, shows you the SQL, then runs it read-only with bounded results against PostgreSQL, MySQL, SQLite, DuckDB, or Snowflake.
Install
Prebuilt binaries for macOS (Apple Silicon + Intel), Linux, and Windows are on
every release, with
SHA256SUMS to verify them.
Building from crates.io needs one flag for SQLite's maths functions, which the released binaries already carry:
LIBSQLITE3_FLAGS=-DSQLITE_ENABLE_MATH_FUNCTIONS
Quick start
# the profile references it; never commit it
config init writes to your user config directory, which saya trusts. Pass
--project to write a .saya/ pair for a repository instead — that layer is
untrusted, so security-critical settings in it are ignored unless you pass
--trust-project-config. config doctor names what is missing and exits
non-zero when the setup cannot run a query, so a script can tell.
The starter config points at a local Ollama; edit [ai]
in config.toml for OpenAI, Anthropic, Gemini, or any OpenAI-compatible
gateway.
One-shot, no TUI:
Work with your data
- Ask in plain language. saya inspects your schema, proposes SQL, and
shows the statement in the transcript. Choose
ask,read-only, orneverwith--approval-modeto control approval prompts;bypassis an explicit session-wide option. - Run SQL directly. Use
saya queryfor a single read-only statement, or usesayato open the interactive terminal UI. The UI streams answers, offers/command search and@tableschema completion, and supports exporting results. (TUI demo, export demo) - Connect more than one database. Work with PostgreSQL, MySQL, SQLite, DuckDB, and Snowflake; add profiles to a session so saya can inspect and query each connection. (cross-database demo)
- Keep useful context. Optional memory carries typed facts about tables, columns, relationships, and metrics into later questions. Facts are bound to the schema, and inferred facts wait for your confirmation. Off by default. → Memory
- Use local or hosted models. Supported providers include Ollama, OpenAI, OpenAI-compatible endpoints, Anthropic, and Gemini.
- Automate from scripts. Piped input and non-interactive commands support text, JSON, or NDJSON output with documented exit codes.
- 🏃 Long-running runs —
saya run "<goal>"asks the model for a plan, shows it to you once with its scopes and budgets, and executes it step by step, pausing (never silently stopping) when a declared budget trips so a resume picks up at the first incomplete step. Scopes are declared up front with--allow, and today the one writable surface any run can reach is its own run directory. Approval is one ask, not one per tool call — and the trade is stated where you make it: if users rubber-stamp plans, the security story leans on the sandbox, the bounds, and the sentinel tests. → commands - 🖥️ Host commands (unsandboxed) — the
run_commandlane composes wherever a workspace root binds: PATH-resolved programs run as your user with your whole filesystem and network.run_commandclaims no containment — the contained lane's guarantees arerun_program's, not this one's. Under bypass, a hostile workspace file is effectively arbitrary code execution as the user.--deny <program>(repeatable) refuses named programs at every session door before every grant, prompt, and bypass; the deny list bounds the direct ask only — a deniedcurldoes not stop an allowedmakefrom invoking curl. → commands
Safety
Database queries use two read-only layers. Every SQL statement is parsed and
rejected if it writes, and the database session itself is opened read-only —
Postgres default_transaction_read_only, MySQL transaction_read_only, SQLite
PRAGMA query_only, a read-only DuckDB open. Results are bounded by a row cap
and byte budgets, and marked when truncated.
Long-running runs require explicit --allow scopes before they start. Host
commands require approval under ask; bypass is a deliberate session-wide
approval and does not weaken SQL's read-only policy.
Secrets live in your environment or on disk as references, never inline in committed config. Resolved secrets, provider headers, and raw result rows are structurally excluded from saved sessions.
Neither layer can prove that an arbitrary database function is side-effect free, and Snowflake has no session read-only switch — so connect with a least-privilege, read-only database role. → SECURITY.md
Documentation
Start with saya --help for current flags and commands, or /help inside the
TUI. These guides cover setup and common tasks:
| Guide | Covers |
|---|---|
| Installation | binaries, Homebrew, cargo, building from source |
| Configuration | config layers, environment variables, state paths |
| Connections | every database type, TLS modes, secret references |
| Providers | every supported provider and its settings |
| Commands | the CLI surface and output formats |
| Querying databases | worked examples, cross-database queries |
| Memory | what saya remembers, and the trust model behind it |
| Security policy | security boundaries and vulnerability reporting |
Development
The demo GIFs are generated with vhs
from the docs/*.tape scripts; the live ones need SAYA_API_KEY and a
reachable database.
See CONTRIBUTING.md. Apache-2.0 licensed.