--- name: zuplo-cli description: Zuplo CLI helper for developing and managing Zuplo API Gateway projects. Use when the user wants to run zuplo CLI commands, deploy, manage environment variables, set up tunnels, run tests, initialize projects, work with OpenAPI specs, or do local development with the Zuplo platform. --- # Zuplo CLI This skill helps developers use the Zuplo CLI to develop and manage their Zuplo API Gateway projects. ## How to look up Zuplo documentation Use these sources in priority order: 1. **Local docs (preferred):** Read from `node_modules/zuplo/docs/cli/` — version-matched, always available offline. Check both the project root and parent directories for monorepos. 2. **MCP server tools:** Use `search-zuplo-docs` and `ask-question-about-zuplo` if the Zuplo MCP server is connected. 3. **Fetch docs via URL:** Fetch `https://zuplo.com/docs/cli/overview` or discover all pages at `https://zuplo.com/docs/llms.txt`. ## When to Use This Skill Use this skill when the user: - Wants to deploy their Zuplo project - Needs to start local development - Wants to run API tests - Needs to manage environment variables - Wants to create, list, or manage tunnels - Needs to initialize or link a project - Wants to work with OpenAPI specs (merge, convert, overlay) - Asks about Zuplo CLI commands or options - Needs to manage mTLS certificates - Wants to create a new Zuplo project ## Prerequisites The Zuplo CLI requires Node.js 20+ (Node.js 22 recommended). The `zuplo` package is included as a dependency in Zuplo projects — there is no need to install it globally. Run CLI commands using your package manager's exec command: ```bash npx zuplo # npm pnpx zuplo # pnpm ``` > **Note:** All `zuplo` commands shown below should be run via `npx zuplo`, `pnpx zuplo`, or equivalent. The `zuplo` prefix is shown without `npx` for brevity. ## Authentication Two methods: ### OAuth (interactive) Uses device flow authentication — opens a browser for login and returns a refresh token for session persistence. ```bash zuplo login ``` ### API Key (CI/CD and automation) Pass via `--api-key` flag or `ZUPLO_API_KEY` environment variable: ```bash export ZUPLO_API_KEY=zpka_d67b7e241bb948758f415b79aa8exxxx_2efbxxxx ``` API keys are scoped to an account. Get them from portal.zuplo.com > Settings > API Keys. ## Zuplo Project Structure A Zuplo project has this layout: ``` my-api/ ├── config/ │ ├── routes.oas.json # Route definitions (OpenAPI 3.1 format with x-zuplo-route extensions) │ └── policies.json # Policy configuration (named policy instances) ├── modules/ │ └── my-handler.ts # Custom handlers and policies (TypeScript) ├── docs/ # Developer portal (optional, Zudoku-based) │ └── zudoku.config.ts ├── tests/ # API test files (run with `zuplo test`) ├── zuplo.jsonc # Project config: version, compatibilityDate, projectType ├── package.json ├── .env # Local environment variables (do NOT commit) └── .env.zuplo # Generated by `zuplo link` (do NOT commit) ``` ### Key files - **`config/routes.oas.json`** - OpenAPI 3.1 spec defining routes. Uses `x-zuplo-route` extension to attach handlers and policies. Multiple OpenAPI files are supported (processed alphabetically). - **`config/policies.json`** - Defines named policy instances (type, handler module, options). Routes reference policies by name. - **`zuplo.jsonc`** - Project-level config. `projectType` can be `managed-edge`, `managed-dedicated`, or `self-hosted`. `compatibilityDate` locks runtime behavior. - **`modules/`** - Custom TypeScript code referenced from config via `$import(./modules/...)` syntax. - **`.env`** - Local environment variables (not synced with remote). Format: `KEY=VALUE` per line. - **`.env.zuplo`** - Auto-generated by `zuplo link`. Contains account/project/environment info for connecting to Zuplo services locally. ### The `$import()` syntax JSON config files use `$import()` to reference code modules: - `$import(@zuplo/runtime)` - Built-in Zuplo modules - `$import(./modules/my-handler)` - Custom modules in `modules/` directory ## CLI Commands Reference ### Local Development #### `zuplo dev` Start the local development server. Runs the API gateway, route designer (editor), and docs server. ```bash zuplo dev # Default: API on :9000, editor on :9100, docs on :9200 zuplo dev --port 8080 # Custom API port zuplo dev --no-start-editor # Skip the editor zuplo dev --no-start-docs # Skip the docs server zuplo dev --debug-port 9229 # Enable Chrome DevTools inspector ``` **Ports:** - API server: 9000 (default) - Route designer/editor: 9100 (default) - Docs server: 9200 (default) To use Zuplo services (API keys, rate limiting) locally, first run `zuplo link` to connect to a remote environment. #### `zuplo editor` Start just the OpenAPI Designer (route editor) standalone. ```bash zuplo editor # Default port 9100 zuplo editor --port 8080 # Custom port ``` #### `zuplo docs` Start just the docs server standalone. ```bash zuplo docs # Default port 9200 zuplo docs --port 3000 # Custom port zuplo docs --server-url https://my-api.zuplo.dev # Point to remote API zuplo docs --server-url http://localhost:9000 # Point to local API ``` ### Project Management #### `zuplo link` Link a local directory to an existing Zuplo project. Creates `.env.zuplo` with account/project/environment info. ```bash zuplo link # Interactive zuplo link --account my-acct --project my-proj --environment my-env # Explicit ``` Use `--no-fetch-environments` to auto-detect environment from the git branch instead of fetching from Zuplo. #### `zuplo list` List all deployed Zuplo APIs/environments. ```bash zuplo list zuplo list --account my-acct --project my-proj ``` #### `zuplo project create` Create a new project in your account. ```bash zuplo project create --name my-api-project zuplo project create --name my-proj --account my-acct ``` ### Deployment #### `zuplo deploy` Deploy the current directory. Uses the current git branch to select the environment by default — the default branch (typically `main`) maps to the production environment. In CI/CD, leave `--environment` unset so the branch being built selects the environment automatically. Only pass `--environment` when there is no git branch to detect (e.g. not in a git repo) or when you deliberately want to deploy to a specific named environment (e.g. deploying a tag to `staging`). ```bash zuplo deploy # Uses git branch to select the environment zuplo deploy --account my-acct --project my-proj # Explicit account/project (branch selects environment) zuplo deploy --environment staging # Explicitly target a named environment ``` The default branch that maps to the production environment can be changed in the Zuplo portal. **Polling timeout:** Default polls every 1s for 150s. Override with environment variables: ```bash POLL_INTERVAL=5000 MAX_POLL_RETRIES=300 zuplo deploy ``` Even if the CLI times out, the deployment continues. Check status in the Zuplo portal. #### `zuplo delete` Delete a deployed environment by URL. ```bash zuplo delete --url https://my-api-dev-123abc.zuplo.app zuplo delete --url https://my-api-dev-123abc.zuplo.app --wait # Wait for completion ``` ### Testing #### `zuplo test` Run API tests from the `tests/` directory against a deployment endpoint. ```bash zuplo test --endpoint https://your-api-123abc.zuplo.app # Run all tests zuplo test --endpoint https://your-api.zuplo.app --filter 'auth' # Filter by name zuplo test --endpoint https://your-api.zuplo.app --filter '/api\/v1/' # Filter by regex MY_VAR=example zuplo test --endpoint https://your-api.zuplo.app # With env vars ``` ### Environment Variables #### `zuplo variable create` ```bash zuplo variable create \ --name API_KEY \ --value my-secret-key \ --is-secret true \ --branch main zuplo variable create \ --name BASE_URL \ --value https://api.example.com \ --is-secret false \ --branch production \ --account my-acct \ --project my-proj ``` #### `zuplo variable update` ```bash zuplo variable update --name API_KEY --value new-secret-key --branch main ``` ### Tunnels Tunnels provide secure connectivity from Zuplo's edge to private/on-premises backends without exposing them to the internet. The tunnel agent runs inside your network and makes an outbound connection to Zuplo. #### `zuplo tunnel create` ```bash zuplo tunnel create --tunnel-name my-tunnel zuplo tunnel create --tunnel-name prod-tunnel --account my-acct ``` #### `zuplo tunnel list` ```bash zuplo tunnel list zuplo tunnel list --account my-acct ``` #### `zuplo tunnel describe` ```bash zuplo tunnel describe --tunnel-id tnl_xxxxx ``` #### `zuplo tunnel delete` ```bash zuplo tunnel delete # Interactive selection zuplo tunnel delete --account my-acct ``` #### `zuplo tunnel rotate-token` Rotate the authentication token for a tunnel. ```bash zuplo tunnel rotate-token --tunnel-id tnl_xxxxx ``` #### `zuplo tunnel services describe` View the services configuration for a tunnel. ```bash zuplo tunnel services describe --tunnel-id tnl_xxxxx ``` #### `zuplo tunnel services update` Update services config from a JSON file. ```bash zuplo tunnel services update --tunnel-id tnl_xxxxx --configuration-file ./services.json ``` ### OpenAPI Tools #### `zuplo openapi merge` Merge an external OpenAPI file into the Zuplo project (into `routes.oas.json` by default). ```bash zuplo openapi merge --source openapi.yaml # From local file zuplo openapi merge -s https://api.example.com/openapi.json # From URL zuplo openapi merge --source openapi.yaml --destination ./config/api.oas.json # Custom dest zuplo openapi merge --source openapi.yaml --merge-mode operation-id # Match by operationId zuplo openapi merge --source openapi.yaml --prepend-path /v1 # Prepend path prefix zuplo openapi merge --source openapi.yaml --watch # Watch for changes ``` Merge modes: `path-method` (default) or `operation-id`. #### `zuplo openapi convert` Convert OpenAPI files between JSON and YAML. ```bash zuplo openapi convert --input openapi.yaml --json # YAML to JSON zuplo openapi convert -i openapi.json --yaml -o api-spec.yaml # JSON to YAML with custom output zuplo openapi convert --input openapi.yaml --json --watch # Watch mode ``` #### `zuplo openapi overlay` Apply an OpenAPI Overlay to an OpenAPI document. ```bash zuplo openapi overlay --input openapi.json --overlay changes.json --output result.json zuplo openapi overlay -i api.yaml -l overlay.yaml -o result.yaml --yaml zuplo openapi overlay --input openapi.json --overlay changes.json --output result.json --watch ``` ### mTLS Certificates #### `zuplo mtls-certificate create` ```bash zuplo mtls-certificate create \ --name my_cert \ --cert ./cert.pem \ --key ./key.pem \ --environment-type production # Multiple environment types: zuplo mtls-certificate create \ --name dev_cert \ --cert ./cert.pem \ --key ./key.pem \ --environment-type development \ --environment-type preview ``` #### `zuplo mtls-certificate list` ```bash zuplo mtls-certificate list zuplo mtls-certificate list --account my-acct --project my-proj ``` Additional mTLS commands: `mtls-certificate describe`, `mtls-certificate update`, `mtls-certificate delete`, `mtls-certificate disable`. ### Source Management #### `zuplo source upgrade` Update project structure to latest conventions. ```bash zuplo source upgrade ``` ### Scaffolding a New Project (without CLI installed) ```bash npx create-zuplo-api@latest # Interactive npx create-zuplo-api@latest my-api # Named project npx create-zuplo-api@latest my-api --example my-ex # From example template npx create-zuplo-api@latest my-api --eslint --prettier # With tooling ``` ## Global Options All commands support: - `--help` - Print help message - `--api-key ` - API key for authentication (or use `ZUPLO_API_KEY` env var) ### Debug Logging Enable verbose output for troubleshooting: ```bash zuplo deploy --log-level debug # Debug-level output zuplo dev --log-level verbose # Most verbose output ``` ## Network Connectivity The CLI requires access to: - `dev.zuplo.com` - Zuplo public API - `storage.zuploedge.com` - Project asset uploads during deploy Local development additionally needs: - `*.zuploedge.com` - Various services (API keys, rate limiting, etc.) ## Analytics Opt-Out ```bash export ZUPLO_DO_NOT_TRACK=1 ``` ## Common Workflows ### New project setup ```bash npx create-zuplo-api@latest my-api cd my-api npx zuplo login npx zuplo init npx zuplo dev ``` ### Deploy from CI/CD Set `ZUPLO_API_KEY` and run `zuplo deploy`. **Do NOT pass `--environment` in normal CI/CD** — the CLI reads the current git branch and maps it to the matching Zuplo environment automatically (the default branch, typically `main`, maps to the production environment). Since CI checks out the branch being built, the correct environment is selected for you. ```bash export ZUPLO_API_KEY=zpka_xxxxx npx zuplo deploy --account my-account --project my-project ``` The default branch (the one that deploys to the production environment) can be changed in the Zuplo portal. Only pass `--environment` when the branch-based mapping doesn't apply, for example: - The build isn't running inside a git repo (no branch to detect). - You deploy from tags instead of branches and want to target a specific named environment — e.g. deploy a tag to `staging` first, then promote to `production`: ```bash export ZUPLO_API_KEY=zpka_xxxxx npx zuplo deploy --account my-account --project my-project --environment staging ``` ### Connect local dev to remote services ```bash npx zuplo link # Select account, project, environment npx zuplo dev # Now has access to API keys, rate limiting, etc. ``` ### Import an existing OpenAPI spec ```bash npx zuplo openapi merge --source ./my-api-spec.yaml npx zuplo dev ```