Build with Kaiten.
Kaiten is open source under Apache 2.0: the engine, the Go, TypeScript and Python SDKs, and the CLI. One control plane, four ways in: REST, GraphQL, OpenFeature over OFREP, and MCP. REST, OFREP and the MCP tools share one OpenAPI document generated from the Go handlers, so they cannot drift from the server. GraphQL answers reads only.
OPEN SOURCE
The engine, three SDKs and a CLI.
All of it under Apache 2.0: read it, run it, fork it, and embed the clients in a closed-source product.
Kaiten
The engine: the control plane API — REST, OFREP and a read-only GraphQL endpoint — with the console, the event pipeline and the MCP server.
github.com/kaitencloud/kaitenGo SDK
Reports usage and reads entitlements from your Go services.
github.com/kaitencloud/sdk-goTypeScript SDK
@kaitencloud/client in the browser and @kaitencloud/server on Node, generated from the published OpenAPI contract.
github.com/kaitencloud/sdk-jsPython SDK
The kaitencloud package: the Kaiten API from your Python services.
github.com/kaitencloud/sdk-pythonCLI
The kaiten command: every resource from a terminal, plus kaiten doctor, which checks your configuration and that the API answers.
github.com/kaitencloud/cli
QUICKSTART
One command, and the whole stack is up.
Postgres, the API, the event pipeline, the console, seeded data and generated clients. No account with any provider — not even ours.
Bring the stack up
git clone https://github.com/kaitencloud/kaiten.git
cd kaiten
cp .env.example .env
task dev
# Console http://localhost:3000
# API http://localhost:6060
# Platform API http://localhost:6001 (its own listener, no public route)
# Traces http://localhost:16686git clone https://github.com/kaitencloud/kaiten.git
cd kaiten
cp .env.example .env
task dev
# Console http://localhost:3000
# API http://localhost:6060
# Platform API http://localhost:6001 (its own listener, no public route)
# Traces http://localhost:16686Create a customer, an entitlement, a license
curl -X POST http://localhost:6060/api/customers \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Corp", "slug": "acme-corp" }'
curl -X POST http://localhost:6060/api/entitlements \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Seats", "slug": "seats", "description": "Seats per workspace",
"type": "NUMBER", "aggregationMethod": "SUM" }'
curl -X POST http://localhost:6060/api/licenses \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Scale", "slug": "scale", "type": "PAID",
"description": "Our main paid plan", "isDefault": false }'curl -X POST http://localhost:6060/api/customers \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Corp", "slug": "acme-corp" }'
curl -X POST http://localhost:6060/api/entitlements \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Seats", "slug": "seats", "description": "Seats per workspace",
"type": "NUMBER", "aggregationMethod": "SUM" }'
curl -X POST http://localhost:6060/api/licenses \
-H "Authorization: Bearer $KAITEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Scale", "slug": "scale", "type": "PAID",
"description": "Our main paid plan", "isDefault": false }'Evaluate a flag through OpenFeature
import (
"github.com/open-feature/go-sdk-contrib/providers/ofrep"
"github.com/open-feature/go-sdk/openfeature"
)
provider := ofrep.NewProvider("http://localhost:6060/api",
ofrep.WithBearerToken("ksh_your_access_token"))
openfeature.SetProvider(provider)
client := openfeature.NewClient("my-service")
// A broken targeting rule does not silently answer false:
// evaluation moves on to the next rule or the default, and
// the failure comes back in the flag metadata under
// kaiten.brokenTargetingRules.
enabled, _ := client.BooleanValue(ctx,
"advanced-analytics", false, openfeature.EvaluationContext{})import (
"github.com/open-feature/go-sdk-contrib/providers/ofrep"
"github.com/open-feature/go-sdk/openfeature"
)
provider := ofrep.NewProvider("http://localhost:6060/api",
ofrep.WithBearerToken("ksh_your_access_token"))
openfeature.SetProvider(provider)
client := openfeature.NewClient("my-service")
// A broken targeting rule does not silently answer false:
// evaluation moves on to the next rule or the default, and
// the failure comes back in the flag metadata under
// kaiten.brokenTargetingRules.
enabled, _ := client.BooleanValue(ctx,
"advanced-analytics", false, openfeature.EvaluationContext{})DEPLOY
Running it for real is in the docs and in the repository.
Docker Compose brings the whole stack up on your machine with one command, and two Helm charts run it on Kubernetes. The documentation walks through self-hosting, configuration and sign-in; the repository holds the charts, the Compose file and its README.
Rather not run it yourself? Kaiten Cloud runs the same engine for you, in private beta. Compare the tiers
SDKS
Clients generated from the contract.
Three SDKs, each in its own public repository and on its package registry, all under Apache 2.0. The TypeScript packages are generated from the committed OpenAPI snapshot, which is synced from the published spec — so a client is never newer than the contract it claims to implement.
| SDK | Package | What it is |
|---|---|---|
| TypeScript | The browser client — catalog, licensing snapshot, flag evaluation, usage reporting — and its counterpart for Node runtimes holding a secret key. | |
| Go | Typed clients for Go services that report usage and read entitlements server-side. | |
| Python | The Kaiten API for Python services that report usage and read entitlements server-side. |
Flags need no Kaiten package: OpenFeature publishes OFREP providers for TypeScript (@openfeature/ofrep-provider on the server, @openfeature/ofrep-web-provider in the browser), Go, Python, Java, .NET and Ruby, and any of them evaluates Kaiten flags. That is the point of speaking a standard protocol.
CLI
Every resource, scriptable.
The CLI covers customers, instances and their usage, licenses, entitlements and entitlement groups, feature flags, components, releases, deployment zones, and service accounts and their tokens — plus kaiten doctor, which checks your configuration and that the API answers.
Install it with go install github.com/kaitencloud/cli/cmd/kaiten@latest, or take a pre-built binary for Linux, macOS or Windows from the releases page of github.com/kaitencloud/cli.
# Report consumption from your own service
kaiten instances usage report acme-production seats --value 187
# Read it back, with the window and the ceiling
kaiten instances usage get acme-production seats --output json
# What did this instance do?
kaiten instances audit-trails acme-production
# Is the configuration right, and does the API answer?
kaiten doctor# Report consumption from your own service
kaiten instances usage report acme-production seats --value 187
# Read it back, with the window and the ceiling
kaiten instances usage get acme-production seats --output json
# What did this instance do?
kaiten instances audit-trails acme-production
# Is the configuration right, and does the API answer?
kaiten doctor