access-control
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies,…
Writes, builds, and deploys an app the user asks for in the chat, with no repository and no image yet. Use when the user asks to create, generate, write, vibe-code, prototype, or scaffold an app, API, site, bot, game, or service and run it on Control Plane, or to change an app
Claude Code
$ npx -y skills add controlplane-com/ai-plugin --skill create-app --agent claude-code
Codex
$ npx skills add controlplane-com/ai-plugin --skill create-app -a codex -y
Cursor
$ npx skills add controlplane-com/ai-plugin --skill create-app -a cursor -y
Gemini CLI
$ npx skills add controlplane-com/ai-plugin --skill create-app -a gemini-cli -y
GitHub Copilot
$ npx skills add controlplane-com/ai-plugin --skill create-app -a github-copilot -y
OpenCode
$ npx skills add controlplane-com/ai-plugin --skill create-app -a opencode -y
Windsurf
$ npx skills add controlplane-com/ai-plugin --skill create-app -a windsurf -y
name: create-app description: "Writes, builds, and deploys an app the user asks for in the chat, with no repository and no image yet. Use when the user asks to create, generate, write, vibe-code, prototype, or scaffold an app, API, site, bot, game, or service and run it on Control Plane, or to change an app made this way."
You write the app's files, Control Plane builds them into an image, and `mcp__cpln__deploy_app` runs the image as a workload and waits for it. The first decision is where the files live.
| Your environment | Files live | Build | |---|---|---| | You run in a shell on the user's machine (a coding agent such as Claude Code, Codex, or Cursor), and the `cpln` CLI is installed and logged in | **Local:** a folder `./NAME` on the user's machine, theirs to keep and version | `cpln image build --remote --dir ./NAME --name NAME:v1 --org ORG`, then `deploy_app` with `image: //image/NAME:v1` | | A chat app (ChatGPT, Claude web and desktop), even one with a code sandbox, or no working CLI | **Stored:** on Control Plane through `mcp__cpln__write_app_files`, kept across sessions | `deploy_app` with the same `name` builds the stored files |
In a shell on the user's machine with a working CLI, local is the default; stored is fine when the user asks for it. The CLI only builds: `ORG` is the org the tools use, and the deploy, every read, and every secret go through the tools. A chat app's sandbox is not the user's machine: never look for, install, or run `cpln` there, and give the user a CLI command only when they ask for one or a step has no tool, such as building a folder they already have. Say which way you are taking.
Other starting points: an existing image or a git repository goes straight to `deploy_app` (`image` or `repoUrl`); a folder the user already has is built with the CLI. A database or Redis the app needs comes from `mcp__cpln__add_database`, whose result lists the env values to pass to `deploy_app`; other infrastructure comes from the Template Catalog (`template-catalog` skill). An app the user asks for, for example a blog, a wiki, or a shop, is one you write; install a template instead only when they name one. Never build a database from source or inline an app into a base image.
A stateless app, one that keeps nothing (for example a game, a calculator, or a landing page), has nothing to decide: build it on the `deploy_app` defaults with no storage, and say so. An app that keeps anything (content, records, files, or sign-ins; for example a portfolio, a blog, a wiki, a shop, or a ledger) gets what a production app of its kind has, even where the user did not spell it out: content the owner adds or changes after launch (menu items, products, posts, and their photos) is managed from the app itself and kept on its file storage, never built into the image, and the owner adds what they already have from the app once it runs.
Call `mcp__cpln__plan_app` first. It returns how Control Plane keeps files, records, secrets, and replicas, and the tools that do each. Plan as a senior engineer would for a real business: put to the user in one message the decisions that shape the build and that the request does not settle (for example how the owner and staff sign in), each with the option you recommend as production and industry practice, why, and the alternatives, and build nothing until they answer; a user who says "your call" gets your recommendations. Never ask for content the owner will add from the app, or to confirm what they already said or what `plan_app` settles. Build what they chose, production ready from the first deploy: what it keeps survives restarts and deploys, and a deploy never takes it offline. Choose what fits this user, not the most elaborate build. Give prices only when the user asks.
1. **Name.** Short kebab-case, at most 40 characters (`todo-app`). The same name is the app files name, the image NAME, and the workload name, for the app's whole life; a different name is a different app. 2. **Write a deployable app.** Bind `0.0.0.0`, listen on the port from the `PORT` env var with a default of 8080, and serve `GET /healthz` with 200. Read configuration from env, and secrets through `cpln://secret/NAME.KEY` references; no credentials or `.env` values in files, which the tool refuses. Mail (contact forms, bookings, password resets) needs a provider key the user pastes in the Console after `create_secret` with values "user", never in the chat. Add a `Dockerfile` on `linux/amd64` bases (`node:20-slim`, `python:3.12-slim`, `golang:1.23`); auto-detection works for common stacks, but a Dockerfile gives a readable build log. Leave out `node_modules`, build output, and lockfiles you did not generate. Never put the user's name, email, or other personal details on a public page they did not ask for: use clear placeholders and ask. 3. **Files the user has** (a logo, photos, fonts, a PDF, a dataset) never go inline and cannot be forwarded from the chat. Content the owner adds or changes after launch (menu items, products, posts, and their photos) never goes through an upload link, not even as a first batch: once the app runs, the owner adds it from the app, including the files they already have, and the app keeps it on its file storage (`plan_app`). An upload link is only for files that stay as they are until the next build. In the same turn you write the code, call `mcp__cpln__create_app_files_upload_link` with a `label` the user understands on each entry: `files` for each file the code uses in one specific place (the logo, the hero image), and `folders` for a set the code does not tell apart (photos the user says will not change), which takes up to 100 files (`max`, up to 200) the user never matches to paths; add `caption` ("Where it was taken") when the code needs each one named. Have the code read a folder's files from a data file (`src/photos.json`), since
Run containerized workloads across AWS, GCP, Azure, OCI, and your own hardware under one API.
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies,…
Audit trail and compliance on Control Plane. Use when the user asks about audit logs, who changed what, change tracking, audit…
Workload autoscaling and Capacity AI on Control Plane. Use when the user asks about scaling up/down, min/max replicas,…
CDN caching and request rate limiting for Control Plane workloads. Use when the user asks about CDN, Cloudflare, CloudFront, edge…
Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI…
Custom domains for Control Plane workloads. Use when the user asks to put a domain or subdomain in front of a workload, pick…
Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…
Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…
Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…