Model or dataset
bagofwords1/bagofwords avatar
bagofwords1/bagofwords

bagofwords1/bagofwords: an agentic analytics platform that deploys with one docker run

Chat with your data - with memory, rules, and observability built in. Deploy in 2 minutes

455 stars82 forksPythonNOASSERTION

At a glance

What is it?
Bag of Words (BOW) is an open-source agentic analytics platform that gives each agent its own data, tools, credentials, instructions and permissions, then carries that same context into chat, reports, automations and MCP clients. The quick start is a single docker run, but the caching break-even math and the NOASSERTION licence are the two things to check before you commit.
Who is it for?
Adopt BOW if you already have a warehouse or database and want a governed layer where the same agent context is reused in chat, scheduled reports, webhooks and MCP clients, rather than rebuilding prompts per surface. Do not adopt it if you only need a single text-to-SQL endpoint, because the agent pane, evals, channels and cache are the parts you would pay for in operational surface without using.
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 last received commits 1 day ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem BOW solves: agent context that survives past the chat window

Most text-to-SQL demos stop at a question and an answer. The hard part in production is that the same agent needs to behave identically when it is asked in Slack, triggered by a webhook, run on a schedule, or called from an MCP client. Bag of Words builds what its README calls a governed analysis context for each agent, then reuses that context across every surface. Each agent gets its own data, tools, credentials, instructions, permissions and starters, so the scoping is per agent rather than per deployment.

The audience is a data or platform team that already has a warehouse and wants LLM agents pointed at it without giving every agent the same broad credentials. The README lists RBAC, approvals, audit logs, service accounts, SSO, model policies and row-level security support under governance, which is the part a single-purpose text-to-SQL tool typically leaves out. If your problem is one analyst asking one database a question, this is more machinery than the task needs.

How BOW works: agents, a governed context layer, and an optional cache in front of the warehouse

The README describes BOW as sitting between your models, enterprise data, tools and channels. It connects databases, warehouses, BI systems, files, business apps, MCP servers and custom APIs, and the same analysis context is available in chat, automations, channels and external MCP clients. Agents plan their work, use tools, and reflect on the result, per the README's description of the chat flow.

The mechanism worth understanding is query acceleration. Admins choose what to cache, either whole tables or specific queries, and BOW refreshes the copy on a schedule. The README is unusually direct about the cost: a refresh is a full run of your SQL, so a copy refreshed more often than it is queried costs more than it saves. It puts the break-even at about 1.8 agent questions per refresh on BigQuery and 1.0 on Snowflake. One copy is shared by every agent that activates it, and row-level security can filter it per person against profile attributes, groups or roles.

Around that core sit evals. You define eval sets for expected behavior, and when an eval fails, a self-improving loop can draft instruction changes and re-run the tests up to a configured limit. Passing candidates can wait for approval or be promoted automatically. The README also mentions LLM-as-judge scores for accuracy, instruction coverage and context use, which feed failures back into the eval loop. Note that the README does not document rollback for an automatically promoted instruction change, so treat the approval gate as the control you actually have.

Installing BOW and asking your first question

The README's quick start is one command. It runs the container with the default SQLite database on port 3000, which is the fastest way to see whether the interface fits how your team works.

bash
docker run -p 3000:3000 bagofwords/bagofwords

After the container starts, the web app is on port 3000. The README does not specify a default login in the excerpt available, so check the installation docs at docs.bagofwords.com/install for the first-run credentials before assuming you can sign in.

To point BOW at PostgreSQL instead, pass the connection string through BOW_DATABASE_URL. The README gives this exact form.

bash
docker run -p 3000:3000 \
  -e BOW_DATABASE_URL=postgresql://user:password@localhost:5432/dbname \
  bagofwords/bagofwords

The repository also ships docker-compose.yaml for a production deployment behind Caddy with SSL. Its header comment lists the environment variables you need in a .env file: DOMAIN, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, BOW_ENCRYPTION_KEY and the optional BOW_LICENSE_KEY. The encryption key is a Fernet key, and the file gives the generator command.

bash
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

The compose file expects a 44-character key ending in =. For a development setup without SSL, the same header points at docker-compose.dev.yaml instead. The README states that Docker Compose and Kubernetes deployments are recommended for servers, and the repository has both a k8s/ directory and a deploy/ directory to match.

Where BOW is the wrong tool, and what the documentation does not settle

The caching feature is the clearest case where BOW can cost more than it saves. The README itself says a copy refreshed more often than it is queried is a net loss, and gives break-even figures of about 1.8 agent questions per refresh on BigQuery and 1.0 on Snowflake. If your agents ask a handful of questions a day against a large table, enabling a frequent refresh schedule works against you. The honest move is to leave the cache off until you can measure question volume against refresh frequency.

There is also a scope mismatch. BOW is built around a fleet of agents with distinct credentials, permissions and channels. A team that wants a thin text-to-SQL helper inside an existing application would be adopting an agent management pane, an eval system, a channel layer and a cache to get one query endpoint. That is not a defect, but it is the wrong shape for the job.

On the operational side, the README excerpt does not document rollback for self-improving instruction changes, and it does not document a migration or upgrade procedure between releases. The release cadence is fast: v0.0.560 landed on 2026-09-14, v0.0.559 the same day, and v0.0.556 on 2026-09-08. The compose file sets pull_policy to always for the app image, which means a restart can pick up a newer image than the one you validated. Pin an image tag if that matters to you. The repository also carries a VERSION file and a CHANGELOG.md, so the changelog is the place to check before upgrading.

BOW compared with a plain text-to-SQL pipeline

The realistic alternative for many teams is a hand-rolled pipeline: a schema description, a prompt, a SQL execution step and a chart library, wired together in a notebook or a small service. That approach is transparent and cheap to run, and you control every line.

The difference in approach is where the state lives. A hand-rolled pipeline keeps context in code and prompt files, so adding a second surface (a Slack bot, a scheduled report) means duplicating the prompt and the credentials. BOW keeps that context in the platform and reuses it across chat, automations, channels and MCP clients, which is the README's central claim. The trade is that you now run a Postgres instance, an app container, and optionally a cache, and you inherit the release cadence above.

If your alternative is a hosted analytics assistant, the difference is deployment. BOW is self-hosted, and its Dockerfile shows what that involves: an Ubuntu 24.04 backend builder, a Rust stage for a qvd2parquet tool, Playwright chromium installed in the image, and pre-cached tiktoken encodings for airgapped environments. That is a real image, not a thin wrapper, and it is the reason the airgapped path works at all.

Licence and upgrade cost

The repository's licence is reported as NOASSERTION, which means the licence could not be automatically classified from the LICENSE file. The compose file references an optional BOW_LICENSE_KEY described as an enterprise licence key, which suggests there is a commercial tier alongside the open-source code. What the LICENSE file grants cannot be determined from the repository metadata, and this is not legal advice: read the LICENSE file in the repository and decide whether its terms fit your deployment before you build on it.

Upgrade cost is driven by the release cadence. Three releases in the week of 2026-09-14 is a fast-moving project, and the compose file's pull_policy of always means an unpinned deployment follows that cadence whether you intend to or not. The practical controls are the VERSION file, CHANGELOG.md and a pinned image tag in your own compose file.

Editorial conclusion

Adopt BOW if you already have a warehouse or database and want a governed layer where the same agent context is reused in chat, scheduled reports, webhooks and MCP clients, rather than rebuilding prompts per surface. Do not adopt it if you only need a single text-to-SQL endpoint, because the agent pane, evals, channels and cache are the parts you would pay for in operational surface without using. Before rolling it out, verify two things in your own environment: what the auto-updating cache actually costs on your warehouse, since the README puts the break-even at about 1.8 agent questions per refresh on BigQuery and 1.0 on Snowflake, and what the NOASSERTION licence in the repository permits for your deployment.

Frequently asked questions

What is bagofwords1/bagofwords?

It is an open-source agentic analytics platform that connects an LLM to your data and gives each agent its own data, tools, credentials, instructions and permissions. The README describes the same agent context being reused in chat, reports, dashboards, automations, team channels and MCP clients.

How do I use Bag of Words to deploy it?

The README's quick start runs the container with SQLite on port 3000 using docker run -p 3000:3000 bagofwords/bagofwords. For servers, the README recommends Docker Compose or Kubernetes and points at the installation docs.

What is the limitation of the Bag of Words query cache?

A refresh is a full run of your SQL, so the README states that a copy refreshed more often than it is queried costs more than it saves. It puts the break-even at about 1.8 agent questions per refresh on BigQuery and 1.0 on Snowflake.

What is a bag of words in Python?

That question is about the classic NLP bag-of-words representation, not this repository. Bag of Words here is bagofwords1/bagofwords, a Python-based agentic analytics platform whose quick start is a docker run command.

Official sources

  1. bagofwords1/bagofwords on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Community notes

Community notes