From jamf-cli-skills
Sets up Jamf CLI for Jamf Pro, Protect, and Platform administration: verifies install, loads command reference, and selects a profile.
How this skill is triggered — by the user, by Claude, or both
Slash command
/jamf-cli-skills:jamf-cliThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Work through these steps in order. Do not skip ahead.
Work through these steps in order. Do not skip ahead.
Run via Bash:
which jamf-cli 2>/dev/null && jamf-cli version 2>/dev/null
If the command returns nothing (not installed):
Tell the user jamf-cli is not installed and use AskUserQuestion to offer:
brew tap Jamf-Concepts/tap
brew trust Jamf-Concepts/tap
brew install jamf-cli
After install, verify with jamf-cli version, then re-run /jamf-cli to continue setup.https://jamf-concepts.github.io/jamf-cli/ for all install options.Do NOT continue to Step 1 until jamf-cli is installed and which jamf-cli returns a path.
Fetch the full command reference using WebFetch:
URL: https://jamf-concepts.github.io/jamf-cli/llms-full.txt
Prompt: "Return the full content verbatim — this is a structured CLI reference that will be used as the command map for the rest of the session."
Treat the fetched content as the authoritative source for all available commands, subcommands, flags, and resource names for the remainder of the session.
Run via Bash:
jamf-cli config list 2>/dev/null
Parse the profile names from the output. Use AskUserQuestion with:
If no profiles exist, skip the question and go directly to the creation instructions below.
Existing profile selected: remember it as the active profile for this session. Confirm: "Using profile <name>. Ready for Jamf tasks."
"Create new profile" selected: tell the user to run one of the following (type ! <command> to run it here):
jamf-cli pro setup — Jamf Pro or Platform APIjamf-cli protect setup — Jamf ProtectThen ask them to re-run /jamf-cli to pick the new profile.
Always use jamf-cli via the Bash tool for all Jamf operations.
Command pattern: jamf-cli -p <active-profile> <subcommand> [flags]
jamf-cli -p <profile> <resource> --help--output json; omit for human-readable table outputdelete, apply replacing existing): confirm with the userThere is no --id flag. IDs are always positional arguments placed directly after the subcommand:
jamf-cli -p <profile> pro <resource> get <id>
jamf-cli -p <profile> pro <resource> update <id>
jamf-cli -p <profile> pro <resource> delete <id>
--name is not universal. Only resources with name-based lookup support it — check --help for the resource before assuming it exists. Never attempt --name and fall back if it fails; check first.
Standard lookup pattern when you have a name but need an ID:
# 1. List to find the ID
jamf-cli -p <profile> pro <resource> list -o json | jq '.results[] | select(.name == "My Resource") | .id'
# 2. Use the ID positionally
jamf-cli -p <profile> pro <resource> get <id>
Do not attempt to guess an ID or try --name on a resource that does not advertise it in --help.
Never guess the shape of a request body. Before constructing any JSON or YAML input for a mutating operation (create, update, apply, patch), load the authoritative OpenAPI spec for that resource.
Specs live in three locations depending on the command namespace:
| Command namespace | Spec location | Naming convention | Example |
|---|---|---|---|
pro <resource> (modern API) | specs/<ResourceName>.yaml | PascalCase singular | Category.yaml, MobileDevice.yaml |
pro <resource> (Classic API) | specs/classic/resources.yaml | single manifest | specs/classic/resources.yaml |
pro blueprints, pro compliance-benchmarks, pro platform-devices, pro platform-device-groups, pro ddm-reports (Platform API) | specs/platform/<resource>-api.json | kebab-case + -api.json | blueprints-api.json, device-groups-api.json |
Steps:
Determine which namespace the command belongs to (shown in --help under "Platform:" vs other groups). Pick the correct spec location from the table above.
Fetch the raw spec via WebFetch using the appropriate URL:
https://raw.githubusercontent.com/Jamf-Concepts/jamf-cli/main/specs/<ResourceName>.yamlhttps://raw.githubusercontent.com/Jamf-Concepts/jamf-cli/main/specs/classic/resources.yamlhttps://raw.githubusercontent.com/Jamf-Concepts/jamf-cli/main/specs/platform/<resource>-api.jsonExtract the request schema (requestBody → content → application/json → schema). Use that schema — and only that schema — to construct the body.
If you cannot confidently map the resource to a spec file, tell the user and ask them to confirm before proceeding. Do not fall back to guessing.
Prefer apply over create/update whenever it is available for the resource.
apply is a name-based upsert: it creates the resource if it does not exist, or replaces it if it does. It is idempotent and the correct default for configuration management.create and update are lower-level primitives. create will fail if the resource already exists; update requires knowing the ID and that the resource already exists.{id} in their path) have no apply — use get and update directly.Check --help to confirm whether apply is available before reaching for create/update.
Before writing any JSON body for create, update, or patch, run:
jamf-cli -p <profile> pro <resource> create --scaffold
This prints the exact JSON template the server expects. Use it together with the spec (see request body policy above) to construct a valid payload. Never write a body from memory.
Some resources are singletons — a single settings object with no collection. These use get and update with no ID or name argument:
jamf-cli -p <profile> pro <resource> get
jamf-cli -p <profile> pro <resource> update
Passing an ID or --name to a singleton command will fail. Singletons are identifiable in --help by the absence of a positional <id> argument and the absence of a list subcommand.
Classic API resources (commands under pro that map to /JSSResource/ paths) use XML request and response bodies — not JSON. When constructing a --from-file payload or piping input, the content must be valid XML. Check specs/classic/resources.yaml for the expected structure.
.idThe field name holding the object ID in a list response differs by resource. Do not assume .id. After running list -o json, inspect the actual response shape before writing a jq filter:
jamf-cli -p <profile> pro <resource> list -o json | jq '.' | head -40
Common patterns: .id, .computerAppleId, .udid. Always derive the field name from the actual output.
npx claudepluginhub jamf-concepts/jamf-cli --plugin jamf-cli-skillsAnswers natural language questions about a Jamf Pro instance by composing jamf-cli CLI commands. Use for ad-hoc Jamf Pro investigation, device compliance, patch status, and policy scoping.
Automates Jumpcloud operations via Composio's Jumpcloud toolkit through Rube MCP. Always searches tools first for current schemas before executing workflows.
References Auth0 CLI commands for managing apps, APIs, users, roles, organizations, actions, logs, custom domains, universal login, and Terraform exports. Helps with authentication, RBAC, branding, debugging, and scripting via --json output.