Skip to content
Deployment
Skill

/query-spec

Filters, selects, and sorts Control Plane resources with the query spec language. Use when the user asks about targetQuery, memberQuery, cpln query commands, tag-based selection, property filtering, or dynamic location selection.

From plugin
ai-plugin
1132 skills2 agents2 commands1 MCP

Claude Code

$ npx -y skills add controlplane-com/ai-plugin --skill query-spec --agent claude-code

SKILL.md

query-spec.SKILL.md
name: query-spec
description: "Filters, selects, and sorts Control Plane resources with the query spec language. Use when the user asks about targetQuery, memberQuery, cpln query commands, tag-based selection, property filtering, or dynamic location selection."

Query Spec — Filtering & Selecting Resources

Control Plane has one query language used in two ways: **ad-hoc filtering** of a resource list (CLI / API), and **dynamic targeting** embedded inside three resource fields.

| Where | Field / command | Purpose | |:---|:---|:---| | Policy | `targetQuery` | Target resources by tag/property instead of listing `targetLinks` (see **access-control**) | | Group | `memberQuery` | Assign members dynamically — **users only** | | GVC | `spec.staticPlacement.locationQuery` | Select locations dynamically instead of listing `locationLinks` | | CLI | `cpln KIND query` | Ad-hoc filtering — every resource kind | | API | `POST /org/ORG/KIND/-query` | Ad-hoc filtering — every resource kind |

**Not an MCP list parameter.** `list_resources` has no filter argument (list a kind, then filter the table yourself); `query_audit_events` filters by kind/name/subject/context/time; `query_metrics` takes PromQL. The query spec appears only inside the three resource fields above, set when you create or update that resource.

Structure

kind: workload          # resource kind being selected
fetch: items            # "items" (objects, default) or "links" (references)
spec:
  match: all            # "all" (default), "any", or "none"
  terms:
    - op: "="
      tag: environment
      value: production
    - op: exists
      tag: monitored
  sort:
    by: name
    order: asc

Terms

Each term targets exactly **one** of three fields (mutually exclusive — the schema rejects a term that sets more than one):

| Field | Targets | Example | |:---|:---|:---| | `tag` | Resource tags (key/value labels) | `tag: environment`, `value: production` | | `property` | Built-in properties (`name`, `description`, `status.phase`, …) | `property: name`, `value: my-app` | | `rel` | Relationships to other resources | `rel: gvc`, `value: my-gvc` |

Operators

| Operator | Needs `value` | Meaning | |:---|:---:|:---| | `=` | yes | Equal (default when `op` is omitted) | | `!=` | yes | Not equal | | `>` `>=` `<` `<=` | yes | Numeric / date comparison | | `~` | yes | Pattern match (schema op name `match`) | | `=~` | yes | Regex match (schema op name `regex`) | | `contains` | yes | Substring match | | `exists` | no | Tag/property is present (any value) | | `!exists` | no | Tag/property is absent |

`value` accepts a string, number, boolean, or ISO date. **Boolean values are auto-converted to strings on `tag` terms only** — store `monitored=true` and you must query `value: "true"`, not `value: true`, or it silently matches nothing.

Match modes

| Mode | Behavior | |:---|:---| | `all` | Every term must match (default) | | `any` | At least one term matches | | `none` | No term may match |

Sorting

sort:
  by: name            # required
  order: asc          # "asc" (default) or "desc"

Sort is **API- and manifest-only** — the `cpln KIND query` CLI has no sort flag, so a sort directive passed there is ignored.

Common fields (most kinds): `id`, `name`, `version`, `description`, `created`, `lastModified`. Kind-specific: `location` adds `origin`/`provider`/`region`; `cloudaccount` adds `provider`; `user` adds `idp`/`email`; `policy` and `group` add `origin`.

CLI

**Ad-hoc filtering** — every kind supports `query`:

cpln workload query --tag environment=production
cpln workload query --match all --tag environment=production --tag region=europe
cpln workload query --rel gvc=my-gvc
cpln policy query --prop name=my-policy
cpln workload query --tag monitored                       # existence (no value)
cpln workload query --match any --rel gvc=one --rel gvc=two

| Flag | Alias | Notes | |:---|:---|:---| | `--match` | | `all` / `any` / `none` (default `all`); single value | | `--tag` | | `KEY=VALUE`, or `KEY` for existence; repeatable | | `--property` | `--prop` | `KEY=VALUE`; repeatable | | `--rel` | | `KEY=VALUE`; repeatable |

Results cap at 50 by default — raise with `--max 0` for all records.

**Authoring dynamic targeting** — `gvc`, `policy`, and `group` create/update commands embed a query via `--query-match`, `--query-tag`, `--query-property`, `--query-rel` (group also `--query-kind user`):

cpln policy create --name img-policy --query-kind image --query-property repository=my-app ...

API

POST https://api.cpln.io/org/ORG/workload/-query
{ "spec": { "match": "all",
  "terms": [
    { "op": "=", "tag": "region", "value": "emea" },
    { "rel": "gvc", "op": "=", "value": "mygvc" }
  ],
  "sort": { "by": "name", "order": "asc" } } }

Dynamic targeting examples

**Policy `targetQuery`** — applies to matching resources, including ones created later:

kind: policy
targetKind: image
targetQuery:
  spec:
    terms:
      - { property: repository, value: my-app }
bindings:
  - permissions: [pull, view]
    principalLinks: [//group/developers]

**Group `memberQuery`** — dynamic membership by user tag (users only; service accounts must be added via `memberLinks`):

kind: group
memberQuery:
  kind: user
  spec:
    terms:
      - { tag: "firebase/sign_in_provider", value: "microsoft.com" }

Defaults & gotchas

  • Omitted `op` defaults to `=`; omitted `match` defaults to `all`; omitted `fetch` defaults to `items`; omitted sort `order` defaults to `asc`.
  • Boolean tag values become strings — query `"true"`, not `true`.
  • `targetQuery` is retroactive: tag a new resource and matching policies cover it automatically — a scope to watch when granting permissions.
  • `memberQuery` ignores service accounts.
Read more
@controlplane-com
Ships withai-plugin

Run containerized workloads across AWS, GCP, Azure, OCI, and your own hardware under one API.

1132 skills2 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
11
Star history of controlplane-com/ai-plugin on GitHub, a chart by star-history.com

Other skills on ai-plugin.

cpln

cpln

Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI…

create-app

create-app

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…

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify10d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel13d16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

pinme2mo3.8k
@glitternetwork@glitternetworkInstall Skill

Questions about query-spec.

Which coding agents can use query-spec?
query-spec installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.