Skip to content

CLI

The muhkoo CLI drives the platform from your terminal — create apps, provision their backend (tables, agents, functions), deploy hosted clients, and manage domains, keys, and releases. It’s built on @muhkoo/connect, so it speaks the same APIs your app does.

npm install -g @muhkoo/cli

Requires Node.js 20+. Verify with muhkoo --version.

Two ways to authenticate; both store the resulting session token in ~/.muhkoo/config.json.

Terminal window
muhkoo login --web

Opens auth.muhkoo.dev in your browser, where you sign in however you like — password, passkey, or Google. The CLI captures the session over a one-time localhost redirect, so your credentials never touch the terminal. Best when you use passkeys or Google sign-in.

Every command can also override the stored session with --token <sessionToken> or the MUHKOO_DEV_TOKEN environment variable — handy in CI, where you paste a token from the portal instead of logging in.

A provision spec is a JSON file describing your backend. The CLI applies it idempotently — re-running updates tables, agents, and functions in place.

app.json
{
"slug": "team-standup",
"allowedOrigins": "*",
"email": "you@example.com", // only needed to bootstrap a new developer
"crossOriginIsolation": true, // optional — serve the app cross-origin-isolated (SharedArrayBuffer / threaded wasm). See Hosting.
"tables": [
{
"table": "tasks",
"columns": [
{ "name": "title", "type": "text", "nullable": false },
{ "name": "done", "type": "boolean", "nullable": false, "default": false }
]
}
],
"agents": [ { "handle": "@helper", "model": "", "systemPrompt": "", "enableChannel": "general" } ],
"functions": [ { "name": "hello", "code": "export default { async fetch() { return new Response('hi'); } }" } ]
}
Terminal window
muhkoo provision --spec app.json

This creates the app (issuing test + live key pairs), provisions the tables, and creates any agents and functions. It writes .muhkoo-app.json — the app id and keys — so later commands run with no extra flags.

Terminal window
muhkoo provision --spec app.json --dry-run # preview the API calls, change nothing
muhkoo provision --spec app.json --enable # enable agents/functions on their channels

A function’s code runs server-side and may need a secret (an API token, a signing key). Don’t commit it. Keep a committed app.template.json with placeholders, and generate the real app.json at provision time by substituting values from your environment — so the secret lives in CI/your shell, never in git:

app.template.json
{
"slug": "team-standup",
"functions": [
{ "name": "notify", "code": "export default { async fetch() { /* uses __SLACK_TOKEN__ */ } }" }
]
}
Terminal window
# Substitute, provision, then discard the generated spec.
sed "s/__SLACK_TOKEN__/$SLACK_TOKEN/" app.template.json > app.json
muhkoo provision --spec app.json

Because provision is idempotent, re-running it after editing the template updates tables, agents, and functions in place — it’s safe to run on every change.

Build your client, then ship its dist/ to Muhkoo hosting. Uploads are content-addressed — only changed files transfer — and a release is an atomic pointer flip (instant, and rollback-able).

Terminal window
muhkoo deploy
# → Deploying 18 files from dist/ → https://api.muhkoo.dev
# 12 uploaded, 6 unchanged (18 unique files)
# ✓ Deployed. live at: https://team-standup.apps.muhkoo.dev

deploy reads the app id and a secret key from .muhkoo-app.json. In CI, pass them explicitly:

Terminal window
muhkoo deploy --app "$MUHKOO_APP_ID" --key "$MUHKOO_DEPLOY_KEY"

Every app has a test and a production environment, and the deploy lands in whichever the secret key belongs to. muhkoo deploy uses the test key from .muhkoo-app.json by default; pass a live secret key to ship production:

Terminal window
muhkoo deploy # → test (<slug>.test.apps.muhkoo.dev)
muhkoo deploy --key "$MUHKOO_LIVE_SK" # → production (<slug>.apps.muhkoo.dev)

Iterate against test, then promote test → production — in place, as an atomic pointer flip — with muhkoo promote (or from the portal):

Terminal window
muhkoo promote # copy the test release + functions onto prod

promote is owner-only (it uses your developer session, not an app key) and reads the app id from .muhkoo-app.json. Production data and per-env app config (CORS + redirect URIs) are never touched. See Environments & deploy.

deploy is built for CI: it authenticates with an app secret key (no interactive login) and only transfers changed files. Build your client, then run muhkoo deploy with the app id and a deploy key from your CI secrets — a live key to ship production, a test key for a preview environment:

.github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci && npm run build
- run: npx @muhkoo/cli deploy
env:
MUHKOO_APP_ID: ${{ secrets.MUHKOO_APP_ID }}
MUHKOO_DEPLOY_KEY: ${{ secrets.MUHKOO_LIVE_SK }} # an app secret key

To provision the backend in CI instead (or as well), authenticate with a session token from the portal via MUHKOO_DEV_TOKEN, and run muhkoo provision --spec app.json.

--base selects the API base for any command — prod (default), staging, local, or a literal URL. muhkoo login remembers your choice.

Terminal window
muhkoo apps ls --base staging
muhkoo deploy --base local # http://localhost:8787
muhkoo whoami --base https://api.example.com
Terminal window
muhkoo apps ls # your apps
muhkoo apps get <appId> # details + key metadata + hosting URL
muhkoo apps create --slug my-app --email you@x # create (bootstraps billing on first app)
muhkoo apps slug my-app # is a slug available?
muhkoo keys rotate <appId> # rotate all four keys (revokes the old set)
muhkoo deploy # publish dist/ to the test env
muhkoo promote # promote test → production, in place
muhkoo hosting status <appId> # releases + current pointer
muhkoo hosting rollback <appId> --release <id> # instant rollback
muhkoo hosting unpublish <appId> # remove the live pointer
muhkoo domains add <appId> app.example.com # attach a custom domain (returns DNS records)
muhkoo domains ls <appId>
muhkoo tables ls <appId>
muhkoo agents ls <appId> · agents enable <appId> <agentId> --channel general
muhkoo functions ls <appId> · functions code <appId> <functionId>
muhkoo logs <appId> # inspect the server-log Space

Add --json to most read commands for machine-readable output. Run muhkoo <command> --help for the full option list on any command.

muhkoo eject shows the system prompt and tools config a @Muhkoo*-decorated agent description compiles to — what the agent will actually be told and allowed to do — before you provision it.

Terminal window
muhkoo eject src/agent/agentApp.ts

Most flags have an environment-variable equivalent, so CI never needs interactive input:

VariableEquivalent flagPurpose
MUHKOO_DEV_TOKEN--tokenDeveloper session token — for provision and account/app management in CI
MUHKOO_DEPLOY_KEY--keyApp secret key (mk_*_sk_*) — authorizes deploy
MUHKOO_APP_ID--appThe app id, when not running from a provisioned app dir
MUHKOO_API_BASE--baseAPI base: prod (default), staging, local, or a literal URL

A provisioned app directory carries its own .muhkoo-app.json (app id + keys), so locally these are usually unnecessary — they exist mainly for CI and scripting.

AreaCommands
Accountlogin · logout · whoami
Appsapps ls|get|create|slug|rm · keys rotate
Backendprovision · tables · agents · functions
Hostingdeploy · hosting status|rollback|rm-release|unpublish · domains ls|add|rm
Toolslogs · eject