nao CLI
Command-line interface for nao chat.
Installation
Install the core package (lightweight, no database or LLM dependencies):
pip install nao-core
Then add only the providers you need:
# Database backends
pip install 'nao-core[postgres]'
pip install 'nao-core[bigquery]'
pip install 'nao-core[snowflake]'
pip install 'nao-core[duckdb]'
pip install 'nao-core[clickhouse]'
pip install 'nao-core[databricks]'
pip install 'nao-core[mysql]'
pip install 'nao-core[mssql]'
pip install 'nao-core[athena]'
pip install 'nao-core[trino]'
pip install 'nao-core[redshift]'
pip install 'nao-core[fabric]'
pip install 'nao-core[starrocks]'
# LLM providers
pip install 'nao-core[openai]'
pip install 'nao-core[anthropic]'
pip install 'nao-core[mistral]'
pip install 'nao-core[gemini]'
pip install 'nao-core[ollama]'
# Integrations
pip install 'nao-core[notion]'
Combine multiple extras in a single install:
pip install 'nao-core[postgres,openai]'
pip install 'nao-core[snowflake,bigquery,anthropic]'
Or install everything at once (equivalent to the previous default):
pip install 'nao-core[all]'
Convenience groups are also available:
pip install 'nao-core[all-databases]' # all database backends
pip install 'nao-core[all-llms]' # all LLM providers
Usage
nao --help
Usage: nao COMMAND
╭─ Commands ────────────────────────────────────────────────────────────────╮
│ chat Start the nao chat UI. │
│ debug Test connectivity to configured resources. │
│ init Initialize a new nao project. │
│ sync Sync resources to local files. │
│ test Run and explore nao tests. │
│ --help (-h) Display this message and exit. │
│ --version Display application version. │
╰───────────────────────────────────────────────────────────────────────────╯
Initialize a new nao project
nao init
This will create a new nao project in the current directory. It will prompt you for a project name and ask you to configure:
- Database connections (BigQuery, DuckDB, Databricks, Snowflake, PostgreSQL, Redshift, MSSQL, Trino, StarRocks)
- Git repositories to sync
- LLM provider (OpenAI, Anthropic, Mistral, Gemini, OpenRouter, Ollama)
ai_summarytemplate + model (prompted only when you enableai_summaryfor databases)- Slack integration
- Notion integration
The resulting project structure looks like:
<project>/
├── nao_config.yaml
├── .naoignore
├── RULES.md
├── databases/
├── queries/
├── docs/
├── semantics/
├── repos/
├── agent/
│ ├── tools/
│ └── mcps/
└── tests/
Options:
--force/-f: Force re-initialization even if the project already exists--yes/-y/--no-tty: Run non-interactively. Skips all prompts and uses sensible defaults — useful for AI agents and automation scripts. When combined with a pre-writtennao_config.yaml(e.g. written by an agent skill), only scaffolds the folder structure.--name/-n: Project name. When set without an existingnao_config.yaml, this is used as the project name (and folder). In--yesmode without--name, the current directory name is used and the project is initialized in place.
Non-interactive (agent-friendly) mode
For LLM agents and automation, run nao init without any prompts:
# Initialize the current directory as a nao project (uses the directory name)
nao init --yes
# Or create a new sub-folder named "my-project"
nao init --yes --name my-project
# Pre-write nao_config.yaml then scaffold folders without prompting
cat > nao_config.yaml <<'YAML'
project_name: my-project
databases:
- type: duckdb
name: local
path: ":memory:"
YAML
nao init --yes
In non-interactive mode, nao init never asks for input. Configure databases, LLM provider, and integrations by editing nao_config.yaml directly (or by pre-writing it before nao init).
Start the nao chat UI
nao chat
This will start the nao chat UI. It will open the chat interface in your browser at http://localhost:5005.
To let the agent run code in a micro-VM, download the sandbox runtime once with nao chat --sandbox, then enable
Sandboxes in Settings → Experimental. The runtime and the DuckDB engine used by nao test are ~100 MB each, so they
are not shipped in the package: nao fetches them on first use and caches them in ~/.nao/native. Set
NAO_NATIVE_REGISTRY to download them from an npm mirror instead of registry.npmjs.org.
Test connectivity
nao debug
Tests connectivity to all configured databases and LLM providers. Displays a summary table showing connection status and details for each resource.
Sync resources
nao sync
Syncs configured resources to local files:
- Databases - generates markdown docs (
columns.mdwith table schema, description, row count, and partition/clustering/index metadata,query_history.md, andpreview.md) for each table intodatabases/ - Git repositories — clones or pulls repos into
repos/ - Notion pages — exports pages as markdown into
docs/notion/. Databases are exported as markdown tables, whether configured directly or embedded inline in a page. A database embedded in a page is exported through one of its views — Notion exposes no way to tell which view a page renders, so the first one listed is used — applying that view's filters, sorts and visible columns rather than dumping the whole data source. A database configured by URL exports every row and column, unless the URL carries?v=<view_id>, in which case that view applies. When a database cannot be exported, its page fails to sync and the previously synced markdown is left untouched, rather than being rewritten without its table.
After syncing, any Jinja templates (*.j2 files) in the project directory are rendered with the nao context.
Optional ai_summary generation:
- Add
ai_summaryto a database connectiontemplateslist to renderai_summary.md. - AI summaries use profiling statistics for data-quality and distribution observations. The row preview is a tiny, non-representative shape sample.
- Use
prompt("...")inside Jinja templates to generateai_summarycontent. prompt(...)requires anllm.providersentry with anapi_key(except for ollama), plusllm.annotation_model.- Configure
profilingandai_summaryrefreshes independently withrefresh_policy: always,once, orinterval. Interval policies also acceptinterval_days(default:7):
databases:
- type: duckdb
name: analytics
path: analytics.duckdb
templates: [columns, preview, profiling, ai_summary]
profiling:
refresh_policy: once
ai_summary:
refresh_policy: interval
interval_days: 7
Run tests
nao test
Runs test cases defined as YAML files in tests/. Each test has a name, prompt, and expected sql. Results are saved to tests/outputs/.
Options:
--model/-m: Models to test against (default:openai:gpt-4.1). Can be specified multiple times.--threads/-t: Number of parallel threads (default:1)--select/-s: Run only selected tests by name, yaml stem, or subfolder. Comma-separated.--username/-u,--password: Credentials for the nao backend. Fall back toNAO_USERNAME/NAO_PASSWORD.
Examples:
nao test -m openai:gpt-4.1
nao test -m openai:gpt-4.1 -m anthropic:claude-sonnet-4-20250514
nao test --threads 4
Defaults for every run live in the test block of nao_config.yaml, and the --model / --threads flags override them:
test:
models:
- openai:gpt-4.1
- anthropic:claude-sonnet-4-5
threads: 4
comparison:
rtol: 0.00001
atol: 0.00000001
decimals: 2
Explore test results
nao test server
Starts a local web server to explore test results in a browser UI showing pass/fail status, token usage, cost, and detailed data comparisons.
Options:
--port/-p: Port to run the server on (default:8765)--no-open: Don't automatically open the browser
BigQuery service account permissions
When you connect BigQuery during nao init, the service account used by credentials_path/ADC must be able to list datasets and run read-only queries to generate docs. Grant the account:
- Project:
roles/bigquery.jobUser(orroles/bigquery.user) so the CLI can submit queries - Each dataset you sync:
roles/bigquery.dataViewer(or higher) to read tables
The combination above mirrors the typical "BigQuery User" setup and is sufficient for nao's metadata and preview pulls.
Snowflake authentication
Snowflake supports three authentication methods during nao init:
- SSO: Browser-based authentication (recommended for organizations with SSO policies)
- Password: Traditional username/password
- Key-pair: Private key file with optional passphrase
Development
Building the package
cd cli
python build.py --help
Usage: build.py [OPTIONS]
Build and package nao-core CLI.
╭─ Parameters ──────────────────────────────────────────────────────────────────╮
│ --force -f --no-force Force rebuild the server binary │
│ --skip-server -s --no-skip-server Skip server build, only build Python pkg │
│ --bump Bump version (patch, minor, major) │
╰───────────────────────────────────────────────────────────────────────────────╯
This will:
- Build the frontend with Vite
- Compile the backend with Bun into a standalone binary
- Bundle everything into a Python wheel in
dist/
Installing for development
cd cli
pip install -e '.[all]'
Publishing to PyPI
# Build first
python build.py
# Publish
uv publish dist/*
Architecture
nao chat (CLI command)
↓ spawns
nao-chat-server (Bun-compiled binary, port 5005)
+ FastAPI server (port 8005)
↓ serves
Backend API + Frontend Static Files
↓
Browser at http://localhost:5005
Release files for nao-core 0.3.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| nao_core-0.3.4-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| nao_core-0.3.4-py3-none-manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| nao_core-0.3.4-py3-none-manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| nao_core-0.3.4-py3-none-macosx_15_0_x86_64.whl | Python 3 | none | macOS 15.0+ x86-64 | Details |
| nao_core-0.3.4-py3-none-macosx_15_0_arm64.whl | Python 3 | none | macOS 15.0+ ARM64 | Details |
Total release size: 276.5 MB
Release files / nao_core-0.3.4-py3-none-win_amd64.whl
| Download URL | nao_core-0.3.4-py3-none-win_amd64.whl |
|---|---|
| Size | 63.3 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
564f2db359ab58c6010fee9eb39889ef1c40a35b2a56fde85e5940b2cbc9b671
|
|
BLAKE2b-256 checksum How to use checksums |
e2be7af4fcefc422fe2b121c2f4a79d8789bbc16a27f1b28b1a1c8c7a0ae98a3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nao_core-0.3.4-py3-none-manylinux2014_x86_64.whl
| Download URL | nao_core-0.3.4-py3-none-manylinux2014_x86_64.whl |
|---|---|
| Size | 62.4 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
fce5b85e4c2a652c8d22877803d7e58fa73b01eb563af8a31915f92bf218a2ef
|
|
BLAKE2b-256 checksum How to use checksums |
0bd60e55cd9be6aef6c0604443439db0d545627b5ae528834e732a9cdfab3269
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nao_core-0.3.4-py3-none-manylinux2014_aarch64.whl
| Download URL | nao_core-0.3.4-py3-none-manylinux2014_aarch64.whl |
|---|---|
| Size | 61.1 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
f89d1ef6791900492d3c41c13b8cbda1d752cb83175865e8de79b97ac105080a
|
|
BLAKE2b-256 checksum How to use checksums |
3892b08f5d3f7d65227dc4713a2a65fd3844fb464e3c48c4a20687ab15858cbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nao_core-0.3.4-py3-none-macosx_15_0_x86_64.whl
| Download URL | nao_core-0.3.4-py3-none-macosx_15_0_x86_64.whl |
|---|---|
| Size | 46.2 MB |
| Tags | Python 3 macOS 15.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
84200e2ab3562c95b2f5a0f2ed56828569553ac50f13c63945fea17cfc1bd710
|
|
BLAKE2b-256 checksum How to use checksums |
6c32ef9878bf4c5f6d48aaceaf18ac7b9cf7c3adebadfa35eeb6afe72bfdbb79
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nao_core-0.3.4-py3-none-macosx_15_0_arm64.whl
| Download URL | nao_core-0.3.4-py3-none-macosx_15_0_arm64.whl |
|---|---|
| Size | 43.4 MB |
| Tags | Python 3 macOS 15.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2a31553f3723bcf24530a4af9452559c84b3cd4ad8526d27b1fbbc8248e76919
|
|
BLAKE2b-256 checksum How to use checksums |
26de77c6261871ec31afb056422e31513a652e57e660c8a3e9ec59072f0f62ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|