Also, read the launch post: why we built this.
Columna is an honest metrics engine. It sits between your questions and your warehouse and refuses to return a confident wrong number: where a metric is ambiguous, non-reconciling, or out-of-domain, it says so instead of guessing. Every answer is one of four moods — serve, disclose, clarify, or refuse — returned as structured data on one contract, identical on every surface (Python, MCP, and a natural-language agent).
pip install columna
columna-server demo --playpip install columna is the canonical install — the metapackage that pulls in columna-core (the
engine) and columna-server (the MCP server + agent). You can still install the two directly
(pip install columna-core columna-server) if you want only one.
demo --play runs four real asks end to end and pretty-prints the actual wire JSON for all four
moods in one flow:
- clarify —
SELECT avg(aov) AT {cal.month}: the inline reduction leaves the input anchor foraovunderdetermined; the server names the candidate input anchors as substitutable alternatives instead of inventing one. - refuse —
SELECT level.last AT {customer}: inventory is keyed by store and day — it has no customers, so the ask addresses outside the contracted space and the server refuses with the reason (never a guess). - disclose —
SELECT level.sum AT {store*cal.month}: summing a stock across calendar months adds quantities that don't reconcile along the blocked day→month axis; the server returns the numbers with a material caveat naming the blocked lineage and the remedy (.last), never a silent wrong total. - serve —
SELECT aov AT {cal.month}: average order value by calendar month, one population and well posed; the server returns the numbers.
That transcript is the product. (No path arguments needed — the demo Manifold and a small warehouse
ship in the package. For a richer run over the full benchmark warehouse, see
packages/columna-server/README.md.)
columna-server demo (no --play) serves the same demo over MCP stdio — five read-only tools, no
path args. To wire it into Claude Desktop, add to claude_desktop_config.json:
(Claude Desktop launches the server from an arbitrary working directory, so demo — which needs no
path — is the reliable choice.) See
packages/columna-server/demos/mcp_claude_desktop.md
for the full config and a real clarify → refuse → disclose → serve transcript.
Or talk to it in natural language — Columna's own agent is a true MCP client over the server:
pip install "columna-server[agent]"
ANTHROPIC_API_KEY=... columna-server agent # chat REPL over the packaged demoThe agent turns your question into a proposed Frame-QL query and lets the four moods drive the
conversation — it never touches the engine in-process, never auto-picks a clarify, and every number
comes verbatim from the wire. See
packages/columna-server/demos/agent_transcript.md.
git clone https://github.com/datumwise/columna && cd columna
pip install -e packages/columna-core -e "packages/columna-server[test]"
pytest packages/columna-core -q # warehouse proofs skipped unless COLUMNA_BENCH_WAREHOUSE is set
pytest packages/columna-server -q # MCP stdio acceptance + the packaged demo + the agentThe repo is a uv workspace: packages/columna-core (the engine + wire contract) and
packages/columna-server (the MCP server + NL agent). See CLAUDE.md for the project
state, specs/ for the design record, and research/ for the theory behind
the four moods.
{ "mcpServers": { "columna": { "command": "columna-server", "args": ["demo"] } } }