Quickstart
The fastest way to understand Kozou is to watch it fix a wrong answer.
This walkthrough runs a small seeded demo: an online-store database where the obvious revenue query an AI agent writes is off by 4.8× — and the same agent, given Kozou’s context, gets it right. You will see the gap, see what closes it, connect an agent over MCP, and only then scaffold a project of your own.
Plan for about 10 minutes. You need Docker,
git, and (for the last step) Node.js 20+.
What you’ll see
Section titled “What you’ll see”The demo schema has six paid-looking orders. Ask an agent for total revenue and, working from the raw DDL alone, it confidently returns the wrong number:
| Query an agent writes from… | Result | Why |
| --- | --- | --- |
| the obvious column — sum(amount_total) over paid orders | 575.00 ❌ | amount_total is a deprecated stale cache |
| recompute from products.list_price | 580.00 ❌ | values old orders at today’s catalog price |
| sum line items at the captured unit_price | 560.00 ❌ | the careful answer — and still wrong |
| Kozou’s context — sum(net_revenue) from vw_recognized_revenue | 120.00 ✅ | the view encapsulates every recognition rule |
Every wrong answer shares one error no choice of column fixes: a $400 internal
test order and two soft-deleted rows are counted as revenue. None of that
lives in the DDL — it lives in COMMENT ON text, which Kozou hands to the agent.
1. Run the demo
Section titled “1. Run the demo”Clone the repository and start the demo stack:
git clone --depth 1 https://github.com/kozou-dev/kozou.gitcd kozou/examples/quickstartcp .env.example .envdocker compose updocker compose up brings up PostgreSQL — initialized from the demo
schema.sql —
and kozou dev, which serves the bundled Admin UI and an MCP server, both
pointed at the database. When the logs settle you have:
- Admin UI —
http://localhost:3333 - MCP endpoint (HTTP) —
http://localhost:3334/mcp
Open the Admin UI and click into orders: the rows, the deprecated
amount_total column, the status and is_test flags, and the three reporting
views are all there — generated from the schema, with no UI code written.
2. See why the obvious query is wrong — and what fixes it
Section titled “2. See why the obvious query is wrong — and what fixes it”Open a psql shell against the demo database and reproduce the numbers
yourself:
docker compose exec postgres psql -U kozou -d kozou-- Correct: the view encapsulates every recognition ruleSELECT sum(net_revenue) FROM vw_recognized_revenue; -- 120.00
-- Wrong: the "obvious" column, over paid ordersSELECT sum(amount_total) FROM orders WHERE status = 'paid'; -- 575.00Nothing in \d orders tells an agent that amount_total is abandoned, that
test orders are mixed in, or that two rows are soft-deleted. That knowledge
lives in COMMENT ON text — and the same describe_table("public.orders") call
an agent makes over MCP returns it as structured, agent-facing fields (abridged):
{ "name": "amount_total", "aiDescription": "Do NOT use this for reporting — it is a stale cache the application stopped maintaining and includes test orders. Compute revenue from vw_recognized_revenue instead."},{ "name": "is_test", "aiDescription": "ALWAYS exclude is_test = true from revenue, order counts, and dashboards — these are not real customer orders."}…plus, on the table itself, a policy and a pointer to the authoritative view:
{ "qualifiedName": "public.orders", "aiDescription": "An order is recognized revenue only when status = 'paid' AND is_test = false AND deleted_at IS NULL … The vw_recognized_revenue view already applies every one of these rules — start there for any revenue question."}With that context the agent stops re-deriving business rules and uses the view that encapsulates them. Same model, same question — a correct answer instead of a plausible wrong one. (Kozou can also tell the agent what a given role may touch — see the demo’s README.)
3. Connect an AI agent over MCP
Section titled “3. Connect an AI agent over MCP”Point your own agent at the running demo so you can ask it the revenue question
yourself. The stack already serves the MCP endpoint over HTTP at
http://localhost:3334/mcp; an agent can also launch Kozou itself over stdio.
The full per-client setup (Claude Code, Claude Desktop, Cursor) — including how
to confirm it connected and how to troubleshoot — is in
Connect an AI agent over MCP. The short version for
Claude Code against the running demo:
claude mcp add --transport http kozou http://localhost:3334/mcpclaude mcp list # expect: kozou … ✓ ConnectedTry it. Once the kozou tools appear, ask your agent:
Using the kozou tools, what is our total recognized revenue? Explain which rows and columns you excluded and why.
A Kozou-informed agent calls describe_table / get_concept_context, finds
vw_recognized_revenue, and answers 120.00 — naming the test order and
soft-deleted rows it left out. Ask the same question without the tools and you
get one of the plausible wrong numbers above. That contrast is the whole point.
4. Now scaffold your own project
Section titled “4. Now scaffold your own project”Once you’ve seen the payoff, start your own project. create-kozou writes a
fresh project from the bundled templates — your own schema, not the demo’s:
npx -p kozou create-kozou my-projectcd my-project
create-kozouships as a secondary bin of thekozoupackage rather than a standalone npm package, sonpxneeds-p kozouto find it on a clean machine.
This writes a project directory:
my-project/├── docker-compose.yml # PostgreSQL + a `kozou` service (REST served in-process)├── kozou.config.yaml # database URL, adapter, and UI-hints path├── ui-hints.yaml # optional per-column label / widget overrides├── .env.example # template for the env vars the stack reads└── migrations/ # your schema; 0001_init.sql ships a worked exampleThe starter migrations/0001_init.sql is not empty — it ships a worked
example of the COMMENT conventions (an orders table and a source-of-truth
view, using @ai / @widget / @policy / @example), commented out and ready
to read. Replace it with your own CREATE TABLE / CREATE VIEW /
COMMENT ON … statements, then cp .env.example .env && docker compose up to
bring up your stack exactly as the demo did.
Annotate with COMMENT
Section titled “Annotate with COMMENT”Kozou reads ordinary PostgreSQL COMMENT text. A few prefix tags are extracted
as structured hints — @ai, @widget, @policy, and @example. The single
comment that drives the demo above looks like this:
COMMENT ON COLUMN orders.amount_total IS 'Denormalized order total in cents.
@ai: Do NOT use this for reporting — it is a stale cache the application stopped maintaining. Compute revenue from vw_recognized_revenue.';Two things happen from one comment:
@ai: …reaches the MCP context. It surfaces through tools such asdescribe_tableandget_concept_context, so an agent writing a query sees your guidance. The@ailine stays in the human-readable body too, so the comment still reads naturally.@widget: enum-select(on a column comment) changes the Admin UI input — a plain text field becomes a dropdown. Even without it, Kozou infersenum-selectfor a column whoseCHECKconstraint is a value list likestatus IN ('draft','published','archived'); the tag is the explicit override.
For the full set of conventions, see COMMENT conventions.
Troubleshooting
Section titled “Troubleshooting”- Port already in use — another process is bound to 3333 or 3334 (or 5432
for PostgreSQL). Stop it, or remap the ports via
server.ui/server.mcp.httpinkozou.config.yaml(and the matching mappings indocker-compose.yml). - Database not reachable — confirm the database container is healthy
(
docker compose ps). On a slow first start the other services may come up before PostgreSQL is ready to accept connections; they retry. - The agent doesn’t list the
kozoutools — work through When the tools don’t appear. The fastest check is to run the server by hand and read the error. - Admin UI form POSTs are rejected — the Admin UI is served over plain HTTP,
so SvelteKit needs an
ORIGIN. The scaffold setsORIGIN=${KOZOU_ORIGIN:-http://localhost:3333}; keep it in sync if you remap the Admin UI port.
What’s next
Section titled “What’s next”- Connect an AI agent over MCP — per-client setup for Claude Code, Claude Desktop, and Cursor, both transports, and troubleshooting.
- COMMENT conventions — every tag (
@ai,@widget,@policy,@example) and how each is parsed. - Emitted surfaces — what the Admin UI, the REST layer, and MCP each expose, and why.
- Installation — global install, the runtime image, and using the workspace packages as libraries.
The REST layer is served in-process by @kozou/api, the default backend since
v1.0. PostgREST is the opt-out, enabled with kozou dev --adapter postgrest.