Skip to content

The desktop app, or a server?

Kozou comes in two forms, and they are easy to confuse. This page is the decision.

The desktop app is the one you look at. It is the only place where several databases’ compiled semantics sit in one interactive view, next to what the AI actually receives. A server is the one other things reach — a database your machine cannot open a socket to, a client that only accepts a network URL, a second person, an agent that should execute rather than only read.

Neither replaces the other, and plenty of people want both.

A Kozou server is what the rest of this site documents: kozou dev during development, or the scaffolded container stack. It compiles your schema, serves the MCP endpoint, and hosts the reference Admin UI. It runs where you put it — including next to the database, which matters below. Install it with npm or the compose scaffold.

kozou Desktop is a desktop app that renders those same compiled semantics as a visual map across multiple databases, and can start a local MCP hub — one loopback server per connection profile — for AI clients on the same machine. It is read-only by default; browsing rows and editing rows are separate per-profile opt-ins. It is also experimental: pre-releases are run from source, and no binaries are distributed. If you want something to install and run today, that is the server path.

If this is trueUse
You want to look at the schema yourself, across several databases at oncekozou Desktop
You want to draft COMMENT ON statements against what is already therekozou Desktop
The database is somewhere your machine cannot open a socket to — inside a VPC, behind an IP allowlistA server, next to the database
Your MCP client only accepts a URL it can reach over the networkA server that client can reach
A second person needs the same schema contextA server
Callers must be told apartA server with auth
An agent should execute the functions you exposed, not just read about themA server with execution opted in

The first is the only reason to reach for the desktop app that a server cannot answer at all. The rest are the reasons a server becomes necessary — and note that three of them (1, 2 and 5) apply even when you are the only person involved. Needing a server is not the same as having a team.

The desktop app is the only one of the two that draws an interactive map, and the only one that puts more than one database in a single view. It also places the describe output an AI client reads beside the human view, and can draft COMMENT ON statements for you to apply yourself, running none of them.

A server has no equivalent. Its Admin UI is a CRUD reference, not a map, and kozou docs writes a static Mermaid ER diagram into a Markdown file, one project at a time. (That diagram is the fuller rendering in one respect: it carries columns and crow’s-foot cardinality, where the desktop map shows relationships and their documented meaning.)

This is the one factor on this page with no server answer, which is why it is first.

The desktop app connects to your database directly — outbound, that connection is its only network peer. So a database your machine cannot open a socket to is a database the desktop app cannot read, and no setting changes that. (A bastion counts only if you cannot forward a port through it; once you can, the app takes that URL like any other.)

A server can be put where the database is: inside the VPC, on the allowlisted host, behind the same boundary. What crosses the boundary is then the MCP endpoint, not your database credentials.

2. What shape of connection does your client need?

Section titled “2. What shape of connection does your client need?”

Two different cases hide under “my client can’t connect”:

  • The client starts a local command, or takes a loopback URL (Claude Code, Claude Desktop, Cursor are set up this way). Both options have a path here: the desktop app produces a config entry pointing at its hub, and the server has its own stdio and HTTP paths. Rarely the deciding factor.
  • The client only accepts a URL it can reach over the network. A hub bound to your own machine’s loopback is not such a URL. That case needs a server you host where the client can reach it — with auth on the MCP endpoint, not the unauthenticated default.

The desktop hub is addressed to AI clients on the same machine. The app passes 127.0.0.1 as the host and there is no setting for it, and the hub runs in the no-auth mode — a per-profile random capability path and a DNS-rebinding guard raise the local bar, but there is no authentication, so there is no one to grant and no one to revoke. It is not under-configured for sharing; sharing is not its shape.

A server is the shape that holds more than one caller, and auth is how it tells them apart.

With auth configured, a server distinguishes its callers — and what that buys depends on which surface they arrive at:

  • REST verifies the JWT and runs each request under SET LOCAL ROLE, so your RLS policies decide what that caller may read and write. See Authentication and authorization.
  • MCP gates by the token’s scopes at tool granularity: one scope for the describe tools, another for call. The describe tools themselves read one shared schema cache, so two callers who both hold the describe scope get the same description.

The desktop app has no equivalent to either: it constructs its MCP server without the OAuth options at all. One profile is one stored connection, and every client on that machine that can reach the hub gets the same view.

5. Should an agent be able to run something?

Section titled “5. Should an agent be able to run something?”

A server can expose a call tool that executes the functions you chose to expose — opt-in, off by default. Without OAuth it runs under one fixed service role you configure; with OAuth it runs under the verified token’s role instead, and the configured role is ignored. See RPC actions.

The desktop app’s hub constructs its MCP server without the execution capability, so call is neither advertised in tools/list nor dispatchable there. Its hub is describe-only by construction rather than by configuration.

Four things people reach for that do not decide it

Section titled “Four things people reach for that do not decide it”
  • REST. kozou dev binds @kozou/api to 127.0.0.1 — the port is configurable, the host is not — and the scaffolded compose stack publishes no REST port at all. What that leaves is a loopback service, not a private one: anything sharing that loopback reaches it, including your own curl and your own app on that machine, with no authentication until you configure auth. So REST is already there for local use, and serving it anywhere else is something you run yourself with startApiServer — either way, a separate decision from this page’s. See the REST API.
  • kozou docs. It is a one-shot CLI command that introspects and writes a file. It needs the CLI, not a running server.
  • The Admin UI, and staying up when you close your laptop. Real reasons to run a server, but weak ones: they are conveniences, and neither makes the other option impossible.
  • “Which one is newer.” They are versioned independently and neither supersedes the other.

This is not an exhaustive list of what the server path gives you — type generation (@kozou/codegen) has no desktop counterpart either. It is the list of things people reach for when deciding between these two, that should not carry the decision.

The desktop app is where you look at the semantics — several databases at once, and what the AI sees beside it. A server is where everything else reaches them: the database you cannot open a socket to, the client that cannot come to your loopback, the people who are not you, and the agent that should act rather than read.