Clerk CLI
The
binary is a pre-authenticated gateway to Clerk's Backend API and Platform API, plus project-level tooling (auth, linking, env pulls, instance config). When the user asks anything that touches a Clerk resource, reach for
first instead of hand-rolling
.
This skill targets clerk
. If
disagrees with the latest available CLI, refresh it with
or a package runner such as
. The binary is always the source of truth, so run
to verify anything this skill claims.
Execution environment (prefer the host, understand the sandbox warning)
Most AI coding agents default to running shell commands in a sandbox where the
user's home directory, OS keychain, browser launch, localhost callback
binding, or network access may be blocked. The Clerk CLI depends on all of
those host capabilities:
- OS credential store: stores the OAuth token in the
system keychain. A sandbox without keychain access reports "not logged in"
even when the host is authenticated.
- Home-directory Clerk state: saved config, cached metadata, and fallback
credentials live under the user's Clerk config/data directories.
- Linked project metadata: resolved from the repo's git remote plus Clerk
config. Sandboxes with stripped repo state or blocked home-dir reads can
misreport "not linked".
- Local files: publishable and secret keys materialized by
.
- Outbound network access to Clerk: every Backend and Platform API call.
- Browser + localhost OAuth callback: needs both.
In agent mode, the CLI now does a best-effort warn-once check at the
host-sensitive library boundaries. When it detects that host-only Clerk state
or system capabilities are unavailable, it emits:
text
Host-only Clerk state or system capabilities may be unavailable in agent mode. This may be a sandboxed run.
Re-run this command on the host shell before trusting auth, link, env, or API failures.
Treat that warning as authoritative. The command may continue, but any auth,
link, env, config, API, browser, or OAuth callback failure from that
invocation is untrusted until you rerun the same command on the host.
Prefer these commands on the user's host shell, not in a sandbox:
If a command was accidentally run in a sandbox and it reports
,
,
, missing env, keychain/file permission errors,
or network failures,
do not treat the result as authoritative. Rerun it on
the host before acting on it or reporting it to the user.
Invoking the CLI
Before running any
command, figure out which binary to invoke and bind that choice for the rest of the session:
sh
# 1. Prefer a globally installed binary when it matches the skill's target version.
command -v clerk >/dev/null 2>&1 && clerk --version
If that prints
or any version you trust, use bare
for the rest of the session.
Otherwise fall back to a package runner, in this order (matches the CLI's own
logic, which prefers the runner that matches the project's lockfile):
| Project package manager | Invocation |
|---|
| bun () | |
| npm () | |
| pnpm () | |
| yarn >= 2 () | |
Yarn Classic (v1) has no
; treat those projects as "no preferred runner" and fall back to the first runner from the list above that's on PATH.
The published npm package is
, not
. Never teach
as the primary path. If the global CLI is stale or behaves differently from this skill, either upgrade the global install or fall back to the
runner form above.
Prerequisites (run at session start)
Before running any other Clerk command in a session, verify the CLI is authenticated, linked, and healthy:
sh
clerk --version # confirm the binary is on PATH
clerk doctor --json # structured health check; exit 1 if anything failed
Always run first. It catches the common setup failures (not logged in, project not linked, missing keys, stale CLI version) up front, so later commands don't fail with confusing errors. In agent mode it also includes a
check that warns when Clerk's host-side config / credential directories are not writable, which is the canonical signal that the current invocation is likely sandboxed.
Each result has
,
(
/
/
),
, optional
, optional
(how to fix it), and optional
(label for auto-fixable issues). Parse that and act on it, or surface it to the user. If
warns, rerun the command on the host before trusting any auth/link/env/API failures from the same sandboxed run. Rerun
whenever a later command starts misbehaving.
If
reports a newer CLI than this skill covers, trust
first and refresh this skill bundle from its source.
The mental model
| Layer | What it does | Commands |
|---|
| Session / project | Auth, link a repo to a Clerk app, pull env keys | , , , , , |
| Instance config | Manage the configuration (social providers, session lifetimes, etc.) for a specific instance | , , , |
| Backend API (default) | Runtime data: users, orgs, sessions, invitations, JWT templates, webhooks | |
| Platform API () | Account-level: applications, instances, billing | clerk api --platform <path>
|
A project is "linked" to an application via
. Once linked, most commands auto-resolve the target app and dev instance from the repo's git remote. To target something else, pass
and/or
--instance dev|prod|<instance_id>
. See
references/auth.md for the full resolution order.
Discover endpoints - don't memorize them
The CLI ships with the Clerk OpenAPI catalog. Always discover endpoints dynamically instead of guessing paths:
sh
clerk api ls # list every Backend API endpoint
clerk api ls users # filter by keyword (matches path, summary, tag, operationId)
clerk api ls --platform apps # list Platform API endpoints
Use this before
. If you don't see the endpoint you expected, it probably isn't exposed.
The command (the workhorse)
makes authenticated HTTP calls. It auto-resolves keys, auto-detects method from body presence, supports stdin, and can preview mutations with
.
sh
# GET requests
clerk api /users # list users
clerk api /users/user_abc123 # fetch one
clerk api /users?limit=5&order_by=-created_at # query params work inline
# Mutating requests
clerk api /users -d '{"email_address":["a@b.co"]}' # POST (auto-detected from body)
clerk api /users/user_abc123 -X PATCH -d '{"first_name":"A"}'
clerk api /users/user_abc123 -X DELETE
# Body from file or stdin
clerk api /users --file payload.json
cat payload.json | clerk api /users
# Always preview mutations first
clerk api /users/user_abc123 -X DELETE --dry-run
clerk api /users/user_abc123 -X DELETE --yes # skip confirmation once you've verified
# Target a specific app/instance
clerk api /users --app app_abc123 --instance prod
# Include response headers when debugging
clerk api /users --include
# Platform API (account-level, not tenant data)
clerk api /v1/platform/applications --platform
For instance config, prefer the dedicated
commands over raw Platform API
paths. They handle dry-run, diffing, and confirmation more cleanly than the raw endpoint form.
Always a mutation before running it for real. Then re-run without
(add
if you're sure). In agent mode, interactive confirmation is bypassed, so
is the only safety net for destructive calls.
JSON bodies must be valid JSON. The CLI validates and rejects malformed payloads.
Endpoint paths may be given with or without prefix - both work for Backend API calls. The CLI normalizes.
See references/recipes.md for concrete patterns: listing/filtering users, creating orgs, impersonation sessions, etc.
Inspecting large outputs (do not flood your context)
,
,
, and most
GETs return payloads that can be many kilobytes or megabytes. Production tenants commonly have thousands of users; an instance config can be hundreds of fields deep. Reading those responses into the conversation costs context window for no benefit. Save the response to a file first, then query just what you need with
:
sh
# 1. Persist the response. Use --limit 250 to maximize page size for users list.
clerk users list --json --limit 250 > /tmp/users.json
clerk apps list --json > /tmp/apps.json
clerk api /users/user_abc123 > /tmp/user.json
# 2. Inspect only what you need.
jq '.data | length' /tmp/users.json # current page size
jq '.hasMore' /tmp/users.json # are more pages available?
jq '.data[0] | keys' /tmp/users.json # discover the user shape once
jq '.data[] | {id, email_addresses}' /tmp/users.json # project to a few fields
jq '[.data[] | select(.banned)] | length' /tmp/users.json # aggregate without reading rows
If is not available, fall back to Python or Node - both can stream the file without printing it whole:
sh
python3 -c 'import json; d=json.load(open("/tmp/users.json")); print(len(d["data"]), d["hasMore"])'
node -e 'const d=require("/tmp/users.json"); console.log(d.data.length, d.hasMore)'
/
the file only when you genuinely need to see the raw structure for one-off debugging. When walking pages, write each page to its own file (e.g.
) so individual pages stay independently inspectable.
Core commands at a glance
| Command | Purpose | Key flags |
|---|
| Scaffold Clerk into a project. only supports bootstrap for Next.js, React Router, Astro, Nuxt, TanStack Start, React, Vue, and JavaScript. | , , (with ), , , , |
| OAuth browser login (stores token). Agent mode: no-op if already logged in. With no stored session it still opens a browser and binds a localhost callback, so it is not unattended; prefer for headless flows. Aliases: , , . Top-level shortcut: . | - |
| Clear stored credentials. Aliases: , . Top-level shortcut: . | - |
| Print the logged-in email. | - |
| / | Link this repo to a Clerk app, or remove the link. requires in agent mode. | (see ) |
| Write publishable + secret keys to the framework's env file (merge, not clobber). Resolves → framework-preferred file → ; override with . | (see ) |
clerk config {pull,schema}
| Fetch instance config JSON, or its JSON Schema. | (see ) |
| Partial update (PATCH) of instance config. Pass to actually delete sub-resources touched by the patch rather than resetting them to defaults. | , , , , , , |
| Full replacement (PUT) of instance config. Pass to actually delete removed sub-resources rather than resetting them to defaults. | , , , , , , |
| List or create Clerk applications. Defaults to JSON in agent mode. | (see ) |
| (no subcommand) | Interactive picker for actions in human mode; in agent mode prints the action list and exits . Always pass an explicit subcommand from agents. | , , |
| List users via curated BAPI flags. JSON output (default when piped or in agent mode) is so callers can paginate without . defaults to 100 (max 250). | , , , , , , , , , , , , |
| Create a user from curated flags or a raw BAPI body. Confirmation prompt unless . | , , , , , , , , , , , |
clerk users open [user-id]
| Open a user's dashboard page. Agent mode requires and prints a JSON descriptor instead of launching a browser. | (see ) |
| Open the linked app's dashboard in a browser. Agent mode: prints a JSON descriptor instead of opening. | (see ) |
| Human-mode production deploy wizard. Agent mode: emits a read-only JSON handoff and tells the agent whether to ask the human to run the wizard, wait for provisioning, finish OAuth, or do nothing. | , , |
| Read-only deploy verification. Triggers a DNS check, reports aggregate domain and OAuth readiness, and exits only when complete. Agent mode does one quick check by default; pass to keep waiting. | , , |
| Health check (CLI version, login, link, env, config, completion; plus host-execution probe in agent mode). | , , , |
| Authenticated HTTP to Backend/Platform API. | , , , , , , , , , |
| Discover endpoints from the bundled OpenAPI catalog. | (see ) |
| Print a shell completion script (, , , ). | - |
| Update the CLI to the latest version. | , , |
| Reinstall the bundled skill from the CLI. In this standalone bundle, update the skill source directly instead. | (see ) |
is the source of truth for flags. This table is a hint, not a spec. Before running an unfamiliar command or flag combination, run
once per session. Every command also defines
in source, which
renders as a copy-pasteable Examples block, so you rarely need to guess syntax.
Agent-mode behavior (important)
The CLI auto-detects agent mode when stdout is not a TTY, or when
/
is set. In agent mode:
- Interactive prompts are disabled. Commands that would normally show pickers ( without , without , without a subcommand) either auto-resolve or exit with a usage error. with no args prints usage guidance and exits 0; pass an endpoint (or ) explicitly. Always pass explicit flags (, ) in scripted calls.
- Host-sensitive operations emit a sandbox warning once per invocation. Home-directory Clerk state, keychain access, networked Clerk calls, browser launch, and localhost OAuth callback setup can trigger the warning shown above. If it appears, rerun the same command on the host before trusting the result.
- If your harness does not clearly present as agent mode, force it. Use or when you want the CLI's non-interactive behavior and sandbox warning path to apply deterministically.
- supports deterministic agent flows. In agent mode, links directly. Without , the CLI will try silent key-based autolink first; if it cannot determine the app unambiguously, it exits and tells you to pass .
- never selects or creates a real Clerk app for you in agent mode unless authenticated or given a target. Pass (or pre-link the project) to authenticate and link a real app, or pass to use auto-generated temporary development keys when bootstrapping a new project on a keyless-capable framework. Without either, agent mode prints manual setup guidance and exits cleanly.
- requires in agent mode. This preserves the same safety bar as other destructive commands while still letting an agent complete the unlink non-interactively.
- Mutations still require unless you accept per-call confirmation is impossible.
- is ignored. Parse output's field and act on it yourself.
- and default to JSON when piped.
- defaults to JSON when piped, like . and emit JSON in agent mode. Bare (no subcommand) is a usage error in agent mode - pass , , or explicitly. requires the positional in agent mode and prints a JSON descriptor instead of launching a browser.
- has an agent handoff plus a verification gate. In agent mode, bare is read-only and emits a JSON handoff. It never drives the interactive wizard. Do not tell Claude or another agent to run , because the wizard needs interactive stdin prompts. Ask the human to run in a new terminal window when needed, then run
clerk deploy status --mode agent
to verify completion. See references/agent-mode.md.
--input-json <json|@file|->
expands JSON into flags on any command (e.g. clerk init --input-json '{"framework":"next","yes":true}'
). Piped stdin is also accepted: echo '{"yes":true}' | clerk init
. Place after the leaf subcommand. Full rules in references/agent-mode.md.
Full matrix and sandbox details in references/agent-mode.md.
Output format and errors
- JSON output: on and . For , the response body is the raw API JSON, so pipe into freely.
- Exit codes: success, runtime error, usage/validation error. returns if any check failed.
- Error format: User-facing errors print a single line to stderr and set a non-zero exit code. Use for stack traces when debugging.
Safety rules for autonomous use
- Discover before acting: before .
- Preview mutations: on every , ,
api -X POST/PATCH/PUT/DELETE
.
- Target explicitly in production: pass rather than relying on defaults, and confirm with the user before any production mutation.
- Never commit secrets: writes to (which should be gitignored). Don't paste secret keys into code or chat.
- Use to diagnose before assuming the CLI is broken.
References
- references/auth.md - auth flow, key resolution order, host-vs-sandbox behavior, / targeting, Backend vs Platform API.
- references/recipes.md - copy-pasteable recipes for common Clerk tasks.
- references/agent-mode.md - agent-mode behavior matrix, sandbox warning semantics, exit codes, error format.