← Back to Skills

Koko Data Access — Quickstart

Platform databases (MongoDB, Redis, Neo4j) run inside the Kubernetes cluster and are not reachable from localhost. The `koko` CLI proxies all operations…

Ruleprovision

About

Platform databases (MongoDB, Redis, Neo4j) run inside the Kubernetes cluster and are not reachable from localhost. The `koko` CLI proxies all operations through the Koko API — authenticated, read-safe, and type-preserving.

Skill Content

This is the raw markdown that gets installed as a Claude Code rule.

# Koko Data Access — Quickstart

Platform databases (MongoDB, Redis, Neo4j) run inside the Kubernetes cluster and are not reachable from localhost. The `koko` CLI proxies all operations through the Koko API — authenticated, read-safe, and type-preserving.

## Setup

```bash
# Install
npm install -g koko-db

# Authenticate (shares your tawa login session — run tawa login first)
tawa login
koko --version   # should be 0.5.0+
```

## The One Rule

**Never use curl, kubectl port-forward, or raw API calls to access databases.**

| Wrong | Right |
|-------|-------|
| `curl http://localhost:3001/api/db/...` | `koko query users -s my-api -e prod` |
| `kubectl port-forward ... && mongosh` | `koko copy users --from prod --to sandbox` |
| Direct MongoDB connection strings | `koko export → koko import` |

The koko CLI handles auth, safety guards, EJSON type preservation, and pagination automatically.

## Service Name

koko resolves your service name automatically from the project directory. You can also pass it explicitly:

```bash
# From inside a service directory (reads catalog-info.yaml or .tawa.yaml)
koko query products -e prod

# Explicit service name
koko query products -s fairshare-cms -e prod
```

## Inspect

```bash
# List databases provisioned for a service
koko databases -s my-api

# Collection stats
koko stats -s my-api -e prod
koko collections -s my-api -e prod

# Sample a few documents (random)
koko sample orders -s my-api -e prod --limit 5
```

## Query

```bash
# Find with filter
koko query users -s my-api -e prod \
  --filter '{"status":"active"}' \
  --limit 20 \
  --sort '{"createdAt":-1}'

# With projection
koko query products -s my-api -e prod \
  --filter '{"active":true}' \
  --projection '{"name":1,"slug":1,"tiers":1}'

# Aggregate
koko query orders -s my-api -e prod \
  --aggregate '[{"$group":{"_id":"$paymentStatus","count":{"$sum":1}}}]'

# JSON output (for piping/scripting)
koko query users -s my-api -e prod --filter '{"email":"[email protected]"}' --json
```

## Export / Import — EJSON Format

`koko export` outputs **EJSON** (MongoDB Extended JSON). ObjectIds are serialized as `{"$oid":"..."}` and Dates as `{"$date":"..."}` — not plain strings. This means the NDJSON file can be re-imported with correct BSON types and no corruption.

```bash
# Export a collection to file
koko export products -s my-api -e prod -o /tmp/products.ndjson

# Export with a filter
koko export orders -s my-api -e prod \
  --filter '{"createdAt":{"$gte":"2026-01-01"}}' \
  -o /tmp/recent-orders.ndjson
```

Import via `koko import` — EJSON is handled natively, no flags needed:

```bash
koko import products -s my-api -e sandbox -i /tmp/products.ndjson --upsert
```

If you must use `mongoimport` (into local MongoDB), add `--legacy` so it recognises `$oid`/`$date` markers:

```bash
mongoimport --db my-api-dev --collection products \
  --file /tmp/products.ndjson --legacy
```

> **Prefer `koko import` over `mongoimport`** — no flags to remember, round-trip is always correct.

## Copy Between Environments

Server-side copy — no download, no EJSON conversion, fastest option:

```bash
# Preview count first
koko copy products -s my-api --from prod --to sandbox --dry-run

# Execute
koko copy products -s my-api --from prod --to sandbox
```

## Sync Prod to Local — Full Workflow

When you need your local MongoDB to exactly match production:

```bash
# Step 1: Export all collections from prod
koko export products -s my-api -e prod -o /tmp/products.ndjson
koko export users    -s my-api -e prod -o /tmp/users.ndjson
koko export orders   -s my-api -e prod -o /tmp/orders.ndjson

# Step 2: Import into local MongoDB (--legacy handles $oid/$date markers)
mongoimport --db my-api-dev --collection products --file /tmp/products.ndjson --legacy --drop
mongoimport --db my-api-dev --collection users    --file /tmp/users.ndjson    --legacy --drop
mongoimport --db my-api-dev --collection orders   --file /tmp/orders.ndjson   --legacy --drop

# OR: sync to sandbox via koko (skip --legacy, it's handled server-side)
koko import products -s my-api -e sandbox -i /tmp/products.ndjson --upsert
koko import users    -s my-api -e sandbox -i /tmp/users.ndjson    --upsert
```

After importing to local, restart your dev server to clear any in-memory caches:

```bash
# If using Next.js
rm -rf .next && npm run dev
```

## Seed Collections

For development seeds committed to the repo:

```bash
# Seeds live in ./seeds/<collection>.ndjson
koko seed -s my-api -e sandbox

# Single collection
koko seed -s my-api -e sandbox --collection products

# Dry-run
koko seed -s my-api -e sandbox --dry-run
```

## Redis

```bash
koko keys      -s my-api -e prod --pattern 'session:*' --limit 100
koko get       -s my-api -e prod 'my-api:some-key'
koko redis-info -s my-api -e prod
```

## Neo4j

```bash
koko cypher "MATCH (n) RETURN labels(n), count(n) LIMIT 10" -s my-api -e prod
koko neo4j-stats -s my-api -e prod --json
```

## Safety Guards

All koko operations are read-only by default:

- MongoDB: `$out` and `$merge` aggregate stages are blocked
- Cypher: `CREATE`, `MERGE`, `DELETE`, `SET`, `REMOVE`, `DROP` are blocked
- Max 1,000 documents per query response
- 30-second query timeout

Write operations (`koko import`, `koko copy`, `koko seed`) require explicit `--upsert` or `--allow-prod` confirmation for production targets.

## EJSON — Why It Matters

MongoDB stores ObjectIds and Dates as special BSON types (not plain strings). When exported as plain JSON, `ObjectId("abc123")` becomes the string `"abc123"` — which looks valid but fails as a MongoDB `_id` on re-import because the type is wrong.

EJSON preserves the type information:

```json
{ "_id": {"$oid": "abc123..."}, "createdAt": {"$date": "2026-01-15T..."} }
```

`koko export` always outputs EJSON. `koko import` always deserializes it. The round-trip is type-safe by default — no manual conversion scripts needed.

Install

Copy the skill content and save it to:

~/.claude/rules/tawa-koko-data-access.md
Download .md

Coming soon via CLI:

tawa chaac install tawa-koko-data-access

Details

Format
Rule
Category
provision
Version
1.0.21331
Tokens
~1,477
Updated
2026-06-24
platformkokoclidatabasemongodbredisneo4jexportimportdevtools