--- name: zuplo-cli description: "Use when running Zuplo CLI commands to develop or manage a Zuplo API Gateway project, including initializing projects, local development, working with OpenAPI specs, running tests, deploying, managing environment variables, and setting up tunnels." --- # 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 ```