Home · Quick start · Editor · charter.yaml · Sources · Agent · Guides · Evals · Audit · Policies · CLI · MCP · Workspace · Desktop · About · FAQ
DataCharter has an optional natural-language agent that turns a plain-language question into SQL against your sources. It is genuinely optional.
One word, four doors — “agent” on this page means the built-in chat panel (in any of the three modes below). Claude Code connects as that chat’s backend (Mode 3), while external MCP clients — Claude Desktop, Cursor, Cline — connect through the MCP server instead. Every door leads to the same governed tools; nothing reaches your data any other way.
The product is fully usable without any LLM
The engine, the source tree, the SQL editor with catalog autocomplete, the results grid, charts, the profiling panel, the EXPLAIN viewer, exports, and drag-and-drop file querying all work with no model configured and no network access. The agent adds a chat panel on top; nothing else depends on it.
There is no bundled or fine-tuned model. The agent is grounded: it inspects your schema through tools, scopes to your contract, and retries on SQL errors, which is the regime where existing models already do text-to-SQL well.
Mode 1: bring your own endpoint
Point the agent at any OpenAI-compatible /chat/completions endpoint (a hosted
API, a self-hosted server such as vLLM, or a local runtime that speaks the same
protocol). Set the endpoint and key in the environment, then serve:
export OPENAI_BASE_URL=https://api.example.com/v1 # any OpenAI-compatible API
export OPENAI_API_KEY=...
datacharter serve
OPENAI_BASE_URLdefaults tohttps://api.openai.com/v1if unset.DATACHARTER_MODELselects the model (defaultgpt-4o-mini).- The client is a dependency-free
httpxwrapper; there is no vendor SDK.
Mode 2: fully local with --local
Run the agent against a local Ollama instance. No API key, no data leaves your machine:
datacharter serve --local # uses qwen3:8b by default
datacharter serve --local --model ... # choose another Ollama model
Easier still: the Connect an LLM dialog detects runtimes already running on your machine — Ollama, LM Studio, vLLM, llama.cpp — and lists their loaded models under Running on this machine. One click connects; local models need no API key.
--localtargets Ollama athttp://127.0.0.1:11434/v1.- The default model is
qwen3:8b; override with--model. - DataCharter never auto-installs third-party software. If Ollama is not
reachable, it prints an install hint (and the
ollama pullcommand for your chosen model) and serves without the agent. The UI still works; the chat is simply disabled.
Mode 3: your Claude Code subscription
If you have Claude Code installed and are signed in to a Claude Pro or Max plan, the agent can run on that subscription — no API key and no per-token billing. In the chat panel, click Connect Claude Code (shown next to Connect an LLM) and start asking questions.
- Requires the
claudeCLI on yourPATHand an active Claude subscription. - DataCharter drives Claude Code headlessly, one turn per question. Claude reaches
your data only through the same read-only, access-governed tools below —
never your raw files or connections. To be equally plain about what does
leave: your questions and the (PII-masked) tool results are sent to Anthropic
under your Claude subscription — “local” here means local execution and local
governance, not zero egress. Use
--local(Mode 2) if no data may leave your machine. - The connection is fail-closed (if it can’t be proven safe, it’s refused): before enabling it, DataCharter verifies that the tool sandbox exposes nothing beyond those governed tools, and refuses to connect otherwise.
Guides: tell the agent what you’d tell a colleague
Schema alone doesn’t say that revenue means net of refunds or that QA
accounts must be excluded. Put that in guides/*.md (and per-table
context:) and every
agent — the built-in chat, Claude Code, and any MCP client — receives it before
writing a query. See the end-to-end
example workspace
for a working guide.
And you don’t have to write guides from scratch: datacharter suggest mines
your query history for the habits you repeat (“14 of 20 queries on sales
filter refunded = false”) and turns them into one-click guide lines — also
surfaced in the Guides editor in the browser.
How the agent works
The agent runs a short tool loop over a small set of read-only tools:
| Tool | What it does |
|---|---|
list_sources |
List configured sources and their types. |
list_tables |
List queryable tables with their relation names. |
describe_table |
Show columns and types for one relation. |
query |
Run a read-only SQL query and return rows. |
list_metrics |
List certified metrics — name, what each computes, dimensions, time support. |
query_metric |
Run a certified metric by name (optional by dimensions and time grain). |
Certified metrics. Declare a metric once in charter.yaml under
metrics: and the agent gets the definition of
right, not a chance to reinvent it. When a question matches a metric, the agent
calls query_metric instead of writing the aggregate SQL itself — so “revenue”
means the same thing every time, and query_metric runs through the exact same
governed query chokepoint (read-only guard, PII masking, row filters,
policies, canary scan, audit).
- Access is governed and PII-safe. By default the agent sees masked values
(
•••) for any column that is declared PII incharter.yamlor auto-detected as PII when you serve. Override access at the source, table, or column level — from the data explorer’s left panel or via the contract’sagent_accessblock — to unmask a non-sensitive column or hide one that isn’t PII. Agent view — the toggle above any query result — re-renders that result exactly as an agent would receive it: masked columns, row filters, and policies applied. It is the fastest way to check what your contract actually grants. The same governance applies over MCP and to Claude Code. Masking is enforced, not cosmetic: a masked column may be selected (values return as•••) but cannot be used to filter, join, group, or order results, so its values can’t be inferred by predicate. The human SQL editor is unaffected. - Row-level security (optional). Declare
row_filtersincharter.yamlto limit the agent to specific rows per table (e.g.orders: "region = 'US'"); its queries are rewritten to honor the filter, fail-closed. See the charter.yaml reference. - Read-only is enforced in the engine, not just the prompt: a statement
allowlist rejects anything but queries (the only write path is
local.*DDL for snapshots). The agent cannot modify your data. - Charts inline. The agent can emit a Vega-Lite spec that renders directly in the results panel.
- Reproducible answers. Each query the agent runs appears in the transcript as the exact governed SQL, with one click to open it in the editor and run it yourself.
- Streaming. Answers stream to the chat panel over Server-Sent Events
(
/api/agent/ask)./api/agent/availablereports whether an endpoint is configured and which model is in use.
See the quick-start guide to get a workspace running first, then turn the agent on with either mode above.
Next: Guides — teach agents your data’s quirks → · The MCP server →