# AI agents (https://docs.clouzark.com/ai-agents) ## MCP server [#mcp-server] The CLI runs as an MCP server over stdio. It uses the CLI's login and the projects linked in its working directory. ```bash npm i -g clouzark && clouzark login claude mcp add clouzark -- clouzark mcp # Claude Code claude mcp add clouzark -- clouzark mcp --read-only # reading tools only ``` For other clients (Cursor, Windsurf, VS Code), add a server with command `clouzark` and args `["mcp"]`: ```json title="mcp.json" { "mcpServers": { "clouzark": { "command": "npx", "args": ["-y", "clouzark", "mcp"] } } } ``` `--project ` and `--db ` set the default projects. With `--read-only`, only reading tools are exposed and SQL runs in a read-only transaction. | Tools | | |---|---| | Reading | `whoami`, `list_projects`, `list_deployments`, `get_deployment`, `list_env`, `list_domains`, `list_databases`, `get_api_keys`, `execute_sql`, `list_migrations`, `generate_types` | | Changing | `create_project`, `deploy`, `redeploy`, `promote_deployment`, `rollback`, `set_env`, `remove_env`, `add_domain`, `remove_domain`, `create_database`, `apply_migration` | `apply_migration` also writes the migration file into `clouzark/migrations/`, so the change stays in the repo. ## Repo instructions [#repo-instructions] ```bash clouzark init ``` Writes a Clouzark section into `AGENTS.md`, describing the linked projects and how to deploy and migrate. If the repo has a `CLAUDE.md`, it imports `AGENTS.md`. Running `init` again refreshes only that section. ## llms.txt [#llmstxt] These docs are available as plain text for agents: - [docs.clouzark.com/llms.txt](/llms.txt) — an index of every page - [docs.clouzark.com/llms-full.txt](/llms-full.txt) — every page in one file - Any page as Markdown: add `.md` to its URL, for example `docs.clouzark.com/quickstart.md` - [clouzark.com/llms.txt](https://clouzark.com/llms.txt) — a one-page summary of the CLI, MCP tools, and APIs # Command reference (https://docs.clouzark.com/cli/commands) Run `clouzark --help` for the same information in your terminal. List commands accept `--json`. ## Account [#account] | Command | Does | |---|---| | `login [--token ] [--api-url ] [--no-browser]` | Log in through the browser, or with an access token | | `logout` | Revoke this machine's token and forget it | | `whoami` | Show the user, team, and API | | `init [--no-agents]` | Link hosting and database, and write a Clouzark section into `AGENTS.md` | | `link [-p ] [-y]` / `unlink` | Link this directory to a hosting project | | `mcp [--read-only] [-p ] [--db ]` | Run as an MCP server for coding agents ([AI agents](/ai-agents)) | ## Web hosting [#web-hosting] | Command | Does | |---|---| | `projects ls` | List the team's hosting projects | | `projects create [repo] [-n ] [--root ] [--framework ] [--production-branch ] [--no-link] [--no-wait]` | Import a GitHub repo as a project (this repo's origin by default), link it, and follow the first production build | | `deploy [--prod] [-b ] [--no-wait]` | Build a branch's latest pushed commit and stream the log | | `deploy --upload [--prod]` | Build this directory as it is now | | `deployments ls [-n ]` | Recent deployments | | `logs [deploymentId] [-f]` | Show or follow a build log (the latest deployment by default) | | `promote ` | Make a deployment the live production deployment | | `rollback` | Roll production back to the previous live deployment | | `redeploy [deploymentId] [--no-wait]` | Rebuild with the current environment variables | | `cancel ` | Cancel a queued deployment | | `env ls` | List variable names and targets | | `env add [value] [-t all\|production\|preview]` | Add or update a variable (prompts for the value if omitted) | | `env rm [-t ...]` | Remove a variable | | `env pull [file] [-e production\|preview] [-y]` | Write resolved values to a file (`.env.local` by default) | | `domains ls` | List custom domains | | `domains add ` | Add a domain and print the DNS records to create | | `domains verify ` | Check DNS and issue the certificate | | `domains rm ` | Remove a domain | ## Database [#database] | Command | Does | |---|---| | `db ls` | List database projects | | `db create [--no-link]` | Create a database (and link it) | | `db delete [-y]` | Permanently delete a database | | `db link [--db ]` | Link this directory to a database | | `db query [sql] [-f file] [--json]` | Run SQL from an argument, a file, or stdin | | `db url [--json]` | Print the connection string | | `db keys [--json]` | Print the REST URL, anon key, and service key | | `db dump [-f file] [--data-only\|--full]` | Dump with your local `pg_dump` (schema only by default) | | `migration new ` | Create `clouzark/migrations/_.sql` | | `migration ls` | Compare local migrations with the applied ones | | `db push [--dry-run] [-y]` | Apply pending migrations | | `gen types typescript [-o file]` | Generate TypeScript types for the `public` schema | # CLI (https://docs.clouzark.com/cli) ```bash npm i -g clouzark ``` Node.js 20 or later. Without installing, prefix commands with `npx`: `npx clouzark deploy`. ## Log in [#log-in] ```bash clouzark login ``` The CLI shows a one-time code and opens [clouzark.com/cli/authorize](https://clouzark.com/cli/authorize). Approve it and pick a team; the CLI receives a token for that team that lasts 90 days. The token appears in the team's **Access Tokens** settings, where it can be revoked. Run `clouzark login` again to switch teams. ```bash clouzark whoami # user, team, and role clouzark logout # revoke this machine's token ``` The CLI has exactly your role in the team: a viewer can read but not deploy. ## Link a directory [#link-a-directory] Commands act on the project linked to the current directory, saved in `.clouzark/project.json` (git-ignored). Link once per repo: ```bash clouzark init # link hosting and database, and write AGENTS.md clouzark link # link only the hosting project clouzark db link # link only the database clouzark unlink ``` To act on another project, pass `-p, --project ` (hosting) or `--db ` (database). A ref is a project's slug or id. ## Configuration [#configuration] | | | |---|---| | `~/.config/clouzark/config.json` | API URL and token (file mode 600; honors `XDG_CONFIG_HOME`) | | `CLOUZARK_TOKEN` | Token to use instead of the stored one | | `CLOUZARK_API_URL` | API to use (default `https://api.clouzark.com`) | | `CLOUZARK_PROJECT` | Hosting project to use instead of the linked one | | `CLOUZARK_DB` | Database to use instead of the linked one | ## CI [#ci] Create a token under the team's **Settings → Access Tokens** and save it as a secret in your CI. For example, to apply migrations on every push to `main`: ```yaml title=".github/workflows/migrate.yml" - run: npx clouzark db push --yes --db my-app-db env: CLOUZARK_TOKEN: ${{ secrets.CLOUZARK_TOKEN }} ``` # Auth (https://docs.clouzark.com/database/auth) Each database has its own user accounts, stored in the `auth.users` table. These are your app's users, not Clouzark team members. Base URL: `https://api.clouzark.com/auth/`, called with the anon key in the `apikey` header. ## Sign up and sign in [#sign-up-and-sign-in] ```ts const base = 'https://api.clouzark.com/auth/my-app-db'; const headers = { apikey: ANON_KEY, 'Content-Type': 'application/json' }; const { user, token } = await fetch(`${base}/signup`, { method: 'POST', headers, body: JSON.stringify({ email, password }), }).then((r) => r.json()); ``` `POST /login` takes the same body and returns `{ user, token }`. Send the token as `Authorization: Bearer ` to the REST, GraphQL, Storage, and Realtime APIs to act as that user; `auth.uid()` then returns their id in row-level security policies. ## Endpoints [#endpoints] | Request | Does | |---|---| | `POST /signup` `{ email, password }` | Create a user and sign them in | | `POST /login` `{ email, password }` | Sign in | | `POST /logout` | Sign out | | `GET /me` | The signed-in user | | `PUT /user` `{ password }` | Change the signed-in user's password | | `POST /magiclink` | Email a sign-in link | | `POST /recover` | Email a password reset link | | `GET /factors`, `POST /factors`, `POST /factors//verify`, `DELETE /factors/` | Multi-factor authentication | Email templates, providers, and rate limits are set in the dashboard under the database's **Authentication** settings. # Migrations (https://docs.clouzark.com/database/migrations) Migrations are SQL files in `clouzark/migrations/`, named `_.sql`. They're applied in order, and Clouzark records which ones ran inside the database itself (`clouzark_migrations.schema_migrations`). ## Create and apply [#create-and-apply] ```bash clouzark migration new add_orders # write the SQL in clouzark/migrations/20261028093000_add_orders.sql clouzark db push --dry-run # list what would run clouzark db push # apply pending migrations clouzark migration ls # compare local files with what's applied ``` ```sql title="clouzark/migrations/20261028093000_add_orders.sql" create table orders ( id bigint generated always as identity primary key, user_id uuid not null, total_cents integer not null, created_at timestamptz not null default now() ); alter table orders enable row level security; create policy "own orders" on orders for select using (user_id = auth.uid()); ``` ## Rules [#rules] - **Each migration runs in one transaction**, together with its record. Don't add `BEGIN` or `COMMIT`, and don't use statements that can't run in a transaction, such as `CREATE INDEX CONCURRENTLY`. - **Never edit an applied migration.** Clouzark stores a checksum and refuses a changed file. Add a new migration instead. - Commit the migration files, so every environment and teammate applies the same history. After changing the schema, [regenerate your types](/database/typescript-types). # Overview (https://docs.clouzark.com/database/overview) Each database project is its own Postgres database. Use it with any Postgres client, or call its APIs from your app without writing a backend. ## Create one [#create-one] ```bash clouzark db create my-app-db # creates the database and links this directory to it clouzark db ls clouzark db link # link an existing database instead ``` ## Connect [#connect] ```bash clouzark db url # postgres:// connection string clouzark db keys # REST URL, anon key, and service key ``` Use the connection string from server code, ORMs, and migration tools. Use the keys with the [REST API](/database/rest-api), [Auth](/database/auth), [Storage](/database/storage), and [Realtime](/database/realtime). | Key | Where it's safe | Row-level security | |---|---|---| | Anon key | Browsers and mobile apps | Applies | | Service key | Server-side only | Bypassed | Never ship the service key or the connection string to a browser. ## Run SQL [#run-sql] ```bash clouzark db query "select count(*) from orders" clouzark db query -f report.sql --json cat seed.sql | clouzark db query ``` `db query` runs as the database owner, so it bypasses row-level security. The dashboard also has an SQL editor, a table editor, and CSV import and export. ## Back up [#back-up] ```bash clouzark db dump -f schema.sql # schema only clouzark db dump --full -f backup.sql # schema and data clouzark db dump --data-only -f data.sql ``` `db dump` runs your local `pg_dump`, so Postgres client tools must be installed. # Realtime (https://docs.clouzark.com/database/realtime) Channels let clients send each other messages (Broadcast) and share who's online (Presence). Subscriptions use Server-Sent Events. Base URL: `https://api.clouzark.com/realtime//channels/` Channel names use letters, digits, and `_ - : .`. Channels starting with `private:` refuse the anon key, so only signed-in users (or the service key) can join them. ## Subscribe [#subscribe] `EventSource` can't send headers, so pass credentials as query parameters (`apikey`, and `access_token` for a user token): ```ts const url = `https://api.clouzark.com/realtime/my-app-db/channels/room-1?apikey=${ANON_KEY}`; const events = new EventSource(url); let connectionToken = ''; events.addEventListener('system', (e) => { connectionToken = JSON.parse(e.data).connectionToken; }); events.addEventListener('broadcast', (e) => console.log(JSON.parse(e.data))); events.addEventListener('presence', (e) => console.log(JSON.parse(e.data))); ``` ## Broadcast [#broadcast] ```ts await fetch(`https://api.clouzark.com/realtime/my-app-db/channels/room-1/broadcast`, { method: 'POST', headers: { apikey: ANON_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ event: 'cursor', payload: { x: 10, y: 20 }, connectionToken }), }); ``` Pass the `connectionToken` from your subscription to skip echoing the message back to yourself, or `self: true` to receive it too. ## Presence [#presence] | Request | Does | |---|---| | `GET .../presence` | Who's on the channel | | `POST .../presence` `{ connectionToken, key?, state }` | Share this connection's state | | `DELETE .../presence` `{ connectionToken }` | Stop sharing | Subscribers get `presence` events whenever someone joins, leaves, or updates their state. # REST and GraphQL (https://docs.clouzark.com/database/rest-api) Every table in the `public` schema gets REST endpoints at: ``` https://api.clouzark.com/rest/ ``` Find the URL and keys with `clouzark db keys`. ## Authentication [#authentication] Send one of: - `apikey: ` — browsers and mobile apps. [Row-level security](#row-level-security) applies. - `apikey: ` — server-side only. Bypasses row-level security. - `Authorization: Bearer ` — acts as a signed-in user from [Auth](/database/auth). ## Endpoints [#endpoints] | Request | Returns | |---|---| | `GET /rest/` | `{ tables }` | | `GET /rest//?page=1` | `{ columns, rows, total, pageSize }`, 50 rows per page | | `GET /rest//
/` | `{ row }` | | `POST /rest//
` with a JSON row | `{ row }` (201) | | `PATCH /rest//
/` with the changed columns | `{ row }` | | `DELETE /rest//
/` | 204 | Errors come back as `{ "error": "..." }`. ```ts const base = 'https://api.clouzark.com/rest/my-app-db'; const headers = { apikey: process.env.NEXT_PUBLIC_CLOUZARK_ANON_KEY!, 'Content-Type': 'application/json' }; const { rows } = await fetch(`${base}/orders?page=1`, { headers }).then((r) => r.json()); const { row } = await fetch(`${base}/orders`, { method: 'POST', headers, body: JSON.stringify({ total_cents: 4200 }), }).then((r) => r.json()); ``` ## Row-level security [#row-level-security] With the anon key or a user token, Postgres row-level security decides what each request can see and change. Enable it on every table your app exposes, and write policies with `auth.uid()`, which returns the signed-in user's id (or null): ```sql alter table orders enable row level security; create policy "read own orders" on orders for select using (user_id = auth.uid()); create policy "create own orders" on orders for insert with check (user_id = auth.uid()); ``` ## GraphQL [#graphql] The same data is available over GraphQL, with the same keys and policies: ``` POST https://api.clouzark.com/graphql/ { "query": "...", "variables": { } } ``` # Storage (https://docs.clouzark.com/database/storage) Create buckets in the dashboard under the database's **Storage** page. Public buckets serve files to anyone; private buckets need a key, a user token, or a signed URL. Storage policies control which users can read and write. Base URL: `https://api.clouzark.com/storage/` | Request | Does | |---|---| | `POST /object//` | Upload (raw body). Add `x-upsert: true` to overwrite | | `PUT /object//` | Upload or replace | | `GET /object//` | Download | | `DELETE /object//` | Delete | | `GET /list/?prefix=&limit=100&offset=0` | `{ objects }` | | `GET /public//` | Download from a public bucket, no key needed | | `POST /sign//` `{ expiresIn }` | `{ signedUrl, expiresAt }`, a temporary link to a private file | ```ts await fetch(`https://api.clouzark.com/storage/my-app-db/object/avatars/${userId}.png`, { method: 'PUT', headers: { apikey: ANON_KEY, Authorization: `Bearer ${token}`, 'Content-Type': 'image/png' }, body: file, }); ``` # TypeScript types (https://docs.clouzark.com/database/typescript-types) ```bash clouzark gen types typescript -o src/database.types.ts ``` The output describes the `public` schema and includes helpers: ```ts import type { Tables, TablesInsert, TablesUpdate, Enums } from './database.types'; type Order = Tables<'orders'>; // a row type NewOrder = TablesInsert<'orders'>; // generated and defaulted columns are optional type OrderPatch = TablesUpdate<'orders'>; // every column optional ``` The full schema is also exported as the `Database` type. Run the command again after every migration. # Deployments (https://docs.clouzark.com/hosting/deployments) ## From GitHub [#from-github] Every push to a connected repository creates a deployment: - A push to the **production branch** (set per project, `main` by default) deploys to production. - A push to any other branch, or a pull request, deploys a **preview** with its own URL. Each deployment also keeps its own immutable URL, so you can always open exactly what a given build served. To deploy without pushing, run: ```bash clouzark deploy # the current branch's latest pushed commit clouzark deploy --branch staging clouzark deploy --prod # the production branch, to production ``` `clouzark deploy` builds what's on GitHub, not your local files. It warns when you have uncommitted changes or unpushed commits that won't be included. ## From your machine [#from-your-machine] `--upload` builds the directory as it is now, uncommitted changes included: ```bash clouzark deploy --upload # preview, named after the current branch clouzark deploy --upload --prod # production ``` - In a git repo, the CLI sends the files git sees (tracked and untracked, minus `.gitignore`). Outside a git repo it skips `node_modules`, build output, and similar folders, and `--upload` is the default. - `.env` files are never sent. Set variables with [`clouzark env add`](/hosting/environment-variables). - The upload limit is 100 MB. ## Frameworks [#frameworks] Clouzark detects the framework from the repository: | Framework | How it runs | |---|---| | Next.js | `next build`, then `next start` | | React (Vite and similar) | Built, then served as a single-page app from the output directory (`dist` by default) | | Node | `npm run start`; the app should listen on the `PORT` and `HOST` environment variables | | Static HTML | Served as-is | The build command, output directory, install command, and root directory (for monorepos) can be changed in the project's settings. ## Monorepos [#monorepos] One repository can hold several projects. Import the repo once per app and give each project its own **root directory**, such as `apps/web` and `docs`: ```bash clouzark projects create acme/monorepo --name acme-web --root apps/web clouzark projects create acme/monorepo --name acme-docs --root docs ``` A push then builds every project that uses the repo, except projects whose root directory had no changes. To always build on every push, turn off **Skip deployments when nothing in the root directory changed** in the project's settings. Deploys started from the dashboard or with `clouzark deploy` always build. ## Build logs [#build-logs] ```bash clouzark deployments ls # recent deployments clouzark logs # the latest deployment's log clouzark logs -f # follow a build until it finishes ``` A deployment moves through `queued`, `building`, `deploying`, and then `live`, `failed`, or `canceled`. ## Promote and roll back [#promote-and-roll-back] ```bash clouzark promote # make a deployment the live production deployment clouzark rollback # go back to the previous production deployment clouzark redeploy # rebuild the latest deployment with current env vars clouzark cancel # cancel a deployment that's still queued ``` Promotion and rollback switch traffic without rebuilding, so they only work with deployments that are still `live`. # Custom domains (https://docs.clouzark.com/hosting/domains) Every project gets a default URL. To add your own domain: ```bash clouzark domains add www.example.com ``` The CLI prints the DNS records to create at your DNS provider: a `CNAME` for subdomains, or an `A` record for an apex domain. Once the records are in place: ```bash clouzark domains verify www.example.com ``` Clouzark checks the DNS and issues a TLS certificate automatically. ```bash clouzark domains ls clouzark domains rm www.example.com ``` In the dashboard, under the project's **Domains** tab, you can also point a domain at a specific branch or make it redirect to another domain. # Environment variables (https://docs.clouzark.com/hosting/environment-variables) Environment variables are encrypted at rest and injected into both the build and the running app. Each variable targets **production**, **preview**, or **all** environments. ## In the dashboard [#in-the-dashboard] Open the project's **Settings → Environment Variables**. To add many at once, paste the contents of a `.env` file into a key field: each line becomes its own row. You can also import a `.env` file. ## With the CLI [#with-the-cli] ```bash clouzark env ls clouzark env add DATABASE_URL "postgres://..." -t production clouzark env add API_KEY # prompts for the value clouzark env rm API_KEY -t preview clouzark env pull # writes .env.local with the preview values clouzark env pull .env.production -e production ``` `-t` (`--target`) takes `all`, `production`, or `preview`. Changes apply to the next deployment. Run `clouzark redeploy` to rebuild the latest deployment with the new values. Never commit `.env` files. `clouzark deploy --upload` skips them on purpose. # Introduction (https://docs.clouzark.com) Clouzark has two services, managed from one dashboard, CLI, and API: - **Web hosting.** Connect a GitHub repo and every push builds and deploys: the production branch goes to production, other branches and pull requests get preview URLs. Next.js, React (Vite), Node servers, and static sites are detected automatically. - **Databases.** Managed Postgres with an SQL editor, migrations, generated TypeScript types, and APIs your app can call directly: REST, GraphQL, end-user auth, file storage, and realtime. A team (organization) owns both kinds of project. Members get one of three roles: | Role | Can | |---|---| | Viewer | Read projects, deployments, logs, and data | | Member | Everything a viewer can, plus deploy, run SQL, and apply migrations | | Owner | Everything, including environment variables, domains, members, and deleting databases | # Management API (https://docs.clouzark.com/management-api) The CLI and MCP server are built on this API; anything they do, you can do with plain HTTP. ``` https://api.clouzark.com/v1 ``` ## Authentication [#authentication] Send a team access token, created under the team's **Settings → Access Tokens** (or by `clouzark login`): ```bash curl https://api.clouzark.com/v1/me -H "Authorization: Bearer cz_pat_..." ``` A token acts with its creator's current role in the team. Requests and responses are JSON, errors are `{ "error": "..." }`, and each token can make 120 requests a minute. Wherever a path has `:ref`, pass a project's slug or id. ## Account [#account] | Request | | |---|---| | `GET /me` | User, team, role, and token expiry | | `DELETE /tokens/current` | Revoke the calling token | ## Hosting projects [#hosting-projects] | Request | | |---|---| | `GET /projects` | List projects | | `GET /projects/:ref` | One project | | `POST /projects` `{ repo, name?, root_directory?, framework?, production_branch?, install_command?, build_command?, output_directory? }` | Import a GitHub repo (`owner/name`) and queue its first production build; returns `{ project, deployment_id }` | | `GET /projects/:ref/deployments?limit=20` | Recent deployments | | `POST /projects/:ref/deployments` `{ branch? }` | Build a branch's latest pushed commit (the production branch by default) | | `POST /projects/:ref/deployments/upload?environment=preview` | Build an uploaded `.tar.gz` of the project (`Content-Type: application/gzip`) | | `POST /projects/:ref/rollback` | Roll production back | | `GET /deployments/:id?log_offset=0` | Deployment status, plus build log from `log_offset` | | `POST /deployments/:id/promote` | Promote to production | | `POST /deployments/:id/redeploy` | Rebuild | | `POST /deployments/:id/cancel` | Cancel a queued deployment | A deployment's `status` is one of `queued`, `building`, `deploying`, `live`, `failed`, `canceled`, or `stopped`; `done` is true once it stops changing. To follow a build, poll `GET /deployments/:id` and pass the previous `log_length` as `log_offset`. ### Environment variables [#environment-variables] | Request | | |---|---| | `GET /projects/:ref/env` | Names and targets | | `GET /projects/:ref/env/values?environment=preview` | Resolved values for one environment | | `POST /projects/:ref/env` `{ key, value, target }` | Add or update | | `DELETE /projects/:ref/env/:key?target=all` | Remove | ### Domains [#domains] | Request | | |---|---| | `GET /projects/:ref/domains` | Domains, with the DNS records each needs | | `POST /projects/:ref/domains` `{ hostname }` | Add | | `POST /projects/:ref/domains/:hostname/verify` | Check DNS | | `DELETE /projects/:ref/domains/:hostname` | Remove | ## Database projects [#database-projects] | Request | | |---|---| | `GET /database-projects` | List databases | | `GET /database-projects/:ref` | One database | | `POST /database-projects` `{ name }` | Create | | `DELETE /database-projects/:ref` | Delete permanently | | `POST /database-projects/:ref/query` `{ sql, read_only? }` | Run SQL; returns `{ command, row_count, fields, rows, duration_ms }` | | `GET /database-projects/:ref/migrations` | Applied migrations | | `POST /database-projects/:ref/migrations` `{ version, name, sql }` | Apply a migration. `version` is `YYYYMMDDHHMMSS`; re-sending the same SQL is a no-op, different SQL for an applied version is a 409 | | `GET /database-projects/:ref/types/typescript` | `{ types }` | | `GET /database-projects/:ref/keys` | `{ rest_url, anon_key, service_key }` | | `GET /database-projects/:ref/credentials` | Host, port, database, username, password, and connection string | # Quickstart (https://docs.clouzark.com/quickstart) ### Create a project [#create-a-project] Sign in at [clouzark.com](https://clouzark.com) with GitHub, then create a project from one of your repositories. The first build starts right away. You can also create it from the terminal once the CLI is installed and logged in (the next two steps): run `clouzark projects create` inside a clone of the repo. ### Install the CLI [#install-the-cli] Clouzark's CLI needs Node.js 20 or later. ```bash npm i -g clouzark ``` Or run any command without installing, with `npx clouzark `. ### Log in [#log-in] ```bash clouzark login ``` The CLI shows a code and opens the browser. Approve it, pick the team, and the CLI is logged in for 90 days. In CI, use a token instead; see [Configuration](/cli#configuration). ### Link your repo [#link-your-repo] From the repo's directory: ```bash clouzark init ``` `init` links the directory to its hosting project and database (saved in `.clouzark/project.json`, which is git-ignored) and writes instructions for coding agents into `AGENTS.md`. To link only the hosting project, run `clouzark link`. ### Deploy [#deploy] ```bash clouzark deploy # preview of the current branch clouzark deploy --prod # production branch to production ``` The CLI streams the build log and prints the URL when the deployment is live. Pushing to GitHub deploys the same way, without the CLI.