getnao/nao: A Self-Hosted Analytics Agent Built Around a Context Folder
👾 nao is an open source analytics agent. (1) Create context with nao-core cli, (2) deploy nao chat interface for everyone
At a glance
- What is it?
- nao pairs a Python CLI that assembles an agent context from your warehouse and repos with a chat UI you deploy for business users. The design is file-system first, the trade-off is that the context is only as good as what you put in it.
- Who is it for?
- Adopt nao if you have a data team willing to maintain a context folder and a warehouse you can connect over SQL, and if self-hosting with your own LLM keys is a requirement rather than a preference. Do not adopt it if you expect correct answers without curating metadata, rules and tests, or if you need a managed service with a support contract.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem nao targets: analytics agents with no context layer
Most text-to-SQL tools hand a model a schema dump and a question. The model then guesses at join paths, metric definitions and which columns are deprecated. nao takes the opposite position: the README describes it as a framework to build and deploy an analytics agent, and the first half of that sentence is the CLI, not the chat window. The product is aimed at two groups. Data teams build the context, version it and test it. Business users then ask questions in plain English in a deployed UI and get answers with the reasoning and sources shown. The repository topics list bigquery, snowflake, databricks and postgresql, so the intended warehouse surface is broad rather than a single vendor. If your organisation already has a dbt project, a metrics layer or a wiki of definitions, nao is a way to point an agent at that material instead of hoping the model infers it.
How nao turns a folder into an agent context
The mechanism is a project directory. nao init creates a folder named after your project, an architecture for context files, a nao_config.yaml and a RULES.md. nao sync then populates that folder from your context sources, which the command list describes as databases and repos. So the data flow runs in one direction at build time: warehouse and repository in, files on disk out. The agent reads those files at question time. This is why the README calls the context builder file-system like and says you can add data, metadata, docs, tools and MCPs with no limit. The example directory in the repository shows the shape of a finished project: an agent folder, a databases folder, a docs folder, a templates folder, a tests folder, a nao_config.yaml, a RULES.md and a .naoignore for exclusions. A bundled jaffle_shop.duckdb file sits alongside them, which suggests the example runs against a local DuckDB warehouse without any external connection. The .naoignore file matters more than it looks: it is the only documented lever for keeping material out of the context, and anything you leave in is something the agent may quote back to a business user.
Installing nao-core and running a first question
The README gives a five-step quickstart that it describes as one minute. The CLI is a Python package, so the first command installs it. After that, nao init is interactive: it asks for a project name and then offers optional steps for connecting a database, adding a repository to the agent context, adding an LLM key and setting up a Slack connection. The README states you can skip any optional question and configure it later in nao_config.yaml, which is the honest path if you want to inspect the generated files before wiring credentials.
pip install nao-core
nao initOnce the project folder exists, change into it and run the debug command. This is the setup check, and it is the step worth doing before anything else, because a broken database connection or a missing key surfaces here rather than in the middle of a demo.
cd your-project-name
nao debug
nao syncThe sync step writes the context files into the folder. Then the chat command starts the UI and, according to the README, opens it in your browser at http://localhost:5005. Ask a question there and you should see the agent's reasoning and the sources it used, which is the feature the README lists as transparent reasoning.
nao chatIf you would rather not install Python tooling, the Docker path is documented separately. The image is published on DockerHub, and the README gives a run command that uses the example project bundled inside the image, mapping port 5005 and setting BETTER_AUTH_URL to the same address.
docker pull getnao/nao:latest
docker run -d \
--name nao \
-p 5005:5005 \
-e BETTER_AUTH_URL=http://localhost:5005 \
getnao/nao:latestTo run your own project instead of the bundled example, the README adds a volume mount and sets NAO_DEFAULT_PROJECT_PATH to the mount point inside the container. The Dockerfile builds a Node 24 base image with bun, a Vite frontend build and a Python 3.12 stage, so the image carries both the chat application and the Python side.
Testing the agent before users see it, and where that falls short
nao ships an evaluation loop. You create a tests folder containing questions and expected SQL in YAML, then run nao test to measure the agent against those examples. nao test server shows the results in a panel. This is the most defensible part of the design: it treats prompt and context changes as something to regress against, and the README frames the point as unit testing agent performance before deploying to users, with versioned context and tracked performance over time. The limitation is the shape of the test. A question paired with expected SQL only checks whether generated SQL matches. It does not check whether the answer a business user reads is correct, and it does not cover questions nobody thought to write down. The README does not document what happens when the agent produces valid SQL that returns the wrong number, nor how a failing test blocks a deploy. There is no documented CI gate, no stated pass threshold, and no rollback procedure for a context version that turns out to be worse. Treat the test suite as a smoke detector, not a proof of correctness.
Self-hosting, keys and the licence question
The self-hosting story is concrete. The README states you self-host the agent and use your own LLM keys, and the .env.example enumerates the providers: OpenAI, Anthropic, Qwen through DASHSCOPE_API_KEY with a Singapore base URL default, MiniMax, Moonshot, Azure OpenAI and any OpenAI-compatible endpoint via OPENAI_COMPATIBLE_BASE_URL. AWS Bedrock appears with a choice between a bearer token and static IAM credentials. A docker-compose.yml in the repository defines a Postgres 16 service on port 5432 with user, password and database all defaulting to nao, plus a nao service on SERVER_PORT defaulting to 5005. The .env.example notes SQLite as the default DB_URI, with Postgres as the alternative, so a single-user evaluation does not need the database container at all. Authentication is handled by BETTER_AUTH_SECRET, generated with openssl rand -base64 32, and BETTER_AUTH_URL, which the example file says is used for authentication, trusted origins and Slack redirects. Set BETTER_AUTH_URL wrong and the failure will look like a login problem rather than a configuration one. On licensing: the repository's LICENSE file is the authority, and GitHub reports the licence as NOASSERTION, meaning it could not be matched to a standard identifier. The README does not restate the terms. If you plan to run this inside a company, read that file before you deploy, and if the terms are unclear to you, that is a question for your legal team rather than for this article.
Where nao is the wrong tool, and what to compare it against
nao assumes someone will maintain the context. If your warehouse has no documented metric definitions, no owner for the semantics layer and no appetite for writing tests, the agent will produce confident answers from whatever schema it can read, and the transparent reasoning panel will show a plausible chain of thought leading to a wrong number. That is worse than no tool, because the output looks auditable. It is also a poor fit for one-off exploratory analysis by a single analyst who already knows SQL; the setup cost of init, sync and a rules file buys nothing when the audience is one person. For that case, a notebook or a plain SQL client is the right answer. The nearest alternative in the same category is a hosted text-to-SQL assistant that connects to your warehouse and manages the semantic layer for you. The difference in approach is who owns the context: hosted products keep the definitions in their own interface and update them on their schedule, while nao keeps them as files in your repository, which you can diff, review and revert like any other code. That is a real advantage for teams already reviewing changes through pull requests, and a real cost for teams that do not. nao also sits closer to a BI tool than a notebook: the deployed UI is for non-technical users asking questions, not for analysts writing queries.
Maintenance, releases and what upgrading costs
The repository is not archived and the last push was on 2026-09-10. Releases are frequent: v0.3.12 on 2026-09-09, v0.3.11 on 2026-09-04, and a Helm chart release helm-v0.1.1 on 2026-09-03. The version numbering, still at 0.3.x, tells you the project is pre-1.0 and that breaking changes between minor versions are a live possibility; the README documents no upgrade path, no migration guide and no deprecation policy. The practical cost of upgrading sits in two places. First, the context folder: because nao sync regenerates files from your sources, you want to know whether a version bump changes the generated file format before you run it against a context you have hand-edited. Second, the chat application's own database, which the .env.example defaults to SQLite and the compose file switches to Postgres; the package.json exposes db:migrate scripts scoped to the backend workspace, so schema changes are part of an upgrade rather than something that happens silently. The Helm chart and the Docker image give you two deployment routes, and the README points to a separate deployment guide for a full self-hosted setup such as Cloud Run with PostgreSQL. Budget for reading release notes before each bump, because nothing in the README suggests the project guarantees compatibility across them.
Editorial conclusion
Adopt nao if you have a data team willing to maintain a context folder and a warehouse you can connect over SQL, and if self-hosting with your own LLM keys is a requirement rather than a preference. Do not adopt it if you expect correct answers without curating metadata, rules and tests, or if you need a managed service with a support contract. Before committing, run nao init and nao debug on one real schema, check whether the generated context files are something your team will actually review, and confirm the licence terms in the LICENSE file, which GitHub reports as NOASSERTION and which the README does not restate.
Frequently asked questions
How do I install nao and start the chat interface?
Install the Python CLI with pip install nao-core, then run nao init to create a project folder and nao chat to start the UI, which the README says opens at http://localhost:5005. Alternatively, pull getnao/nao:latest from DockerHub and run it with port 5005 mapped.
Does nao work with my data warehouse, or only with specific ones?
The README describes nao as data stack agnostic, working with any data warehouse, stack, type of context and LLM. The repository topics list bigquery, snowflake, databricks and postgresql, and the bundled example uses a local DuckDB file.
Can I test the nao agent before letting business users ask questions?
Yes. Create a tests folder with questions and expected SQL in YAML, then run nao test to measure performance and nao test server to view the results panel. The README presents this as unit testing agent performance before deploying to users.
Which LLM providers can nao use?
The .env.example lists OpenAI, Anthropic, Qwen via DASHSCOPE_API_KEY, MiniMax, Moonshot, Azure OpenAI, AWS Bedrock and any OpenAI-compatible endpoint through OPENAI_COMPATIBLE_BASE_URL. The README states you use your own LLM keys when self-hosting.
What licence does nao use?
GitHub reports the licence as NOASSERTION, meaning it could not be matched to a standard identifier, and the README does not restate the terms. The LICENSE file in the repository is the document to read.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/getnao-nao)