App Store Connect CLI for Agents
Give the agent asc, not App Store Connect in a browser.
Rudrank’s 5.0.0 release is the public example of a task-shaped Apple CLI:
JSON stdout, no prompts, --confirm on writes.
← AI Agents · Tech · CLI for agents · CLI vs MCP · MCP new · GrokBot limits · Gym hack
Source
Rudrank Riyam (@rudrank, building ASC CLI and rork.com) — x.com/rudrank/status/2096595527085555965 (6 Sep 2026). “App Store Connect CLI 5.0.0 is out.” ~3.2k bookmarks / ~169k views at capture. A whole AI week of shipping. Many of the new commands are labeled experimental; he calls that out as he goes.
Canonical repo:
github.com/rorkai/App-Store-Connect-CLI
(~6.8k stars). Docs:
asccli.sh.
Agent skill pack:
rorkai/app-store-connect-cli-skills
(23 skills; install with asc install-skills).
5.0 migration:
migrate-to-5-0.mdx
.
This page is a study file for an agent that has to ship Apple
work. It is not Apple’s CLI, not a paste of every flag, and not
a substitute for asc --help. Unofficial. Independent.
One-sentence TL;DR
Install asc, authenticate with an App Store Connect API
key, talk JSON, never invent a prompt, treat --confirm as
Require Approval, and do not pin CI to experimental 5.0 commands until
you’ve watched them be right.
Why this belongs next to /cli
Matt Van Horn’s rule: a CLI is Google Maps for agents. Thin API wrappers fail. Good agent CLIs are task-shaped, documented for models, JSON-first, sticky, and gated. ASC CLI is that thesis pointed at Apple:
- No interactive prompts. Destructive work needs
--confirm. - TTY-aware output. Table in a terminal, minified JSON in pipes/CI. Explicit
--output jsonalways wins. - Stdout vs stderr. Structured results on stdout; Xcode diagnostics and errors on stderr. Agents can parse one without drowning in the other.
- Stability labels. Unlabeled = contract.
[experimental]= useful, still moving. Deprecated = leave it alone. - Help is the source of truth. The repo’s own
AGENTS.mdsays: never memorize command shapes. Inspect live help first.
Reply worth keeping from the thread: @gem7318 — “The JSON test output is the one I’ll wire in tonight, my agents have been picking failures out of xcodebuild logs like raccoons.” That is the whole product.
Agent contract (read this first)
Copy these into the Apple-app bot’s description / skill. They are
distilled from the official repo AGENTS.md plus 5.0.0
behavior. If this page and live asc --help disagree, help
wins.
- Discover, don’t recall.
asc --helpthenasc <command> --helpbefore you invent flags. Useasc searchwhen you only have a job name. - Long-form flags.
--app,--output,--confirm. Not short aliases in scripts. - JSON for agents.
Always pass
--output json(add--prettyonly when a human is reading). Do not scrape tables. - Read-only first.
list,view,status,doctor,--dry-run, plan commands. Writes wait. -
--confirmis the human gate. Same job as Grok Bot Require Approval / Stripe Link CLI. If the command needs it and you don’t have explicit authority, stop. Uncertain sends are never auto-retried (review replies especially). - Experimental ≠ CI. Use 5.0 experimental commands in a sitting. Do not pin a nightly workflow to them until the label comes off.
- Keys stay out of git.
.p8files, web-session JSON (live cookies), signing passwords,ASC_WEB_SESSION. Secret store only. Failed web-session import leaves the existing cache unchanged — don’t “fix” it by overwriting. - Team key vs individual key.
Team keys need
--issuer-id. Individual keys use--key-type individualand omit issuer. Don’t mix them. - Web session ≠ API key.
A lot of 5.0 surface (
asc web …) rides an Apple web login, not the public API. Treat cookies like a password. Export / import is for moving a session to CI, not for sharing across people. - 5.0.0 is a break. Expired 4.x compatibility aliases are gone. Unknown flag = exit 2, not a warning. Read the migration guide before upgrading scripts.
Install and prove the binary
# Homebrew (recommended)
brew install asc
# Or the install script
curl -fsSL https://asccli.sh/install | bash
asc version
asc --help
Self-contained Go binary. You do not need a Go toolchain to run a
release. If Homebrew is behind GitHub, use the install script.
Windows: signed binaries from
releases
until WinGet lists Rorkai.ASC.
Then install the skill pack so Cursor / Claude Code / Codex actually know the verbs:
git --version
asc install-skills
That checks out a pinned commit of the 23-skill pack and
copies it into the global agent-skills directory. It does not run
npx or repo scripts. Rollback if any file fails.
Authenticate
Create an API key at appstoreconnect.apple.com/access/integrations/api . Team key:
asc auth login \
--name "MyApp" \
--key-id "ABC123" \
--issuer-id "DEF456" \
--private-key /path/to/AuthKey.p8 \
--network Individual key (no issuer):
asc auth login \
--name "MyIndividualKey" \
--key-id "ABC123" \
--key-type individual \
--private-key /path/to/AuthKey.p8 Headless / CI / no keychain (same idea as install the CLI on the bot VM):
asc auth login \
--bypass-keychain \
--name "MyCIKey" \
--key-id "ABC123" \
--issuer-id "DEF456" \
--private-key /path/to/AuthKey.p8
asc auth status --validate
asc auth doctor First real command, always JSON:
asc apps list --output json --pretty ASC_BYPASS_KEYCHAIN=1 on any live test so you don’t trip
a keychain prompt. Repo tests require it. So should we.
Command map (where to look)
Full taxonomy is generated into docs/COMMANDS.md . Families an agent actually hits:
| Family | Job | Agent note |
|---|---|---|
auth / doctor | Keys, profiles, health | Start every session here if a call fails weirdly |
apps / versions / metadata | App records, listings, ASO | IDs not names; resolve with the id-resolver skill |
builds / testflight / publish | Upload, beta, App Store submit | publish appstore --submit --confirm is the high-level ship |
xcode | Local build / test / signing plan / device install | 5.0 experimental gold for coding agents |
signing / notarization | Profiles, sync, resign, staple | Plan then apply. Isolated keychain. Don’t rebase team claims casually |
screenshots | Plan, capture matrix, upload | Matrix is local-only; upload is a separate step |
web | Things Apple only exposes when signed in | Review threads, tax, finance ZIPs, API keys, Xcode Cloud settings |
review / validate / status | Readiness and App Review | Draft replies; never auto-send the first time |
xcode-cloud | Trigger / duplicate / aliases | Duplicate starts disabled. SCM linking still happens in Apple’s UI |
ads / storekit | Apple Ads, retention messaging | Separate credentials from the ASC API key |
workflow | Repo-local graphs | validate then --dry-run then run |
5.0.0: what the coding agent can now do
Rudrank’s thread, grouped. Commands marked experimental in the tweet stay marked here. Copy the command, then re-check help — flags move.
1. The machine itself
asc xcode doctor --sdk iphonesimulator --output table Experimental. Verifies selected Xcode, tool resolution, SDK. Run this before burning ten minutes on a wrong simulator.
asc xcode test --project App.xcodeproj --scheme App \
--destination 'platform=iOS Simulator,name=iPhone 17 Pro' \
--output json
Experimental. Structured results an agent can read. Test plans,
filters, .xcresult bundles. Split compile from run with
--action build-for-testing then
--action test-without-building. Repeat
--destination for multiple simulators. Diagnostics →
stderr; results → stdout.
asc xcode install --ipa ./App.ipa --device-id DEVICE_ID Experimental. Development / ad-hoc IPA onto a connected iPhone. Checks the embedded profile, targets that device, verifies version + build.
2. Signing: plan, then apply
asc xcode signing plan --project App.xcodeproj --settings-file .asc/xcode-signing.json
asc xcode signing apply --plan .asc/xcode/signing/plan.json --confirm Experimental. JSON describes the target. Inspect the plan. Apply re-checks the project; a stale, blocked, or tampered plan is refused. Same spirit as seoloop Access → Judgment → Reversal: don’t mutate Xcode settings from vibes.
asc signing sync pull --repo REPO_URL --bundle-id com.example.app \
--profile-type IOS_APP_STORE --password-file ./secret --output-dir ./signing
asc signing sync rotate-password --repo REPO_URL \
--password-file ./old-secret --new-password-file ./new-secret --confirm
Pull one target (or --targets-file for app + extensions).
Rotate re-encrypts and publishes one Git commit.
asc signing resign --ipa ./App.ipa --output ./Resigned.ipa \
--identity ./App.p12 --identity-password-file ./secret \
--profiles-manifest ./profiles.json
Experimental. Exact profile mapping for every nested target. Isolated
temporary keychain. --rebase-team-claims is explicit —
changing a KVS claim changes its data namespace. Review that like a
production migration, not a flag you toss on.
3. Mac notarization (local)
asc notarization staple --file ./MyApp.dmg --confirm
asc notarization validate --file ./MyApp.dmg Experimental. App bundles, DMGs, signed flat installer packages.
4. Screenshot matrix
asc screenshots matrix --plan .asc/screenshots-matrix.json --max-concurrency 4 Experimental. Devices × locales × light/dark × content variants. Offline HTML review + JSON manifest including failed cells. Bounded concurrency and retries. Simulators must already be booted. Capture stays local; uploading is a different command. Don’t let an agent conflate “we have PNGs” with “they’re on the listing.”
5. Move a web session to CI
asc web auth export --output-path ./session.json
asc web auth import --file ./session.json --validate
asc web auth import --from-env --validate # ASC_WEB_SESSION secret
Experimental. --validate checks the session with Apple
before import. The bundle is live cookies. Invalid bundles do not
clobber the existing cache. This is how you stop agents from clicking
through 2FA on every job — and how you accidentally leak an Apple
login if the JSON hits git.
6. API keys, Services IDs, Push, iCloud
asc web api-keys create-individual --user-id USER_UUID --output-dir ./keys --confirm
asc web api-keys revoke --key-id KEY_ID --type individual --confirm
asc web service-ids create --identifier com.example.service --name "My Service" --confirm
asc web website-push-ids create --name "My Website" --identifier https://web.example.com --confirm
asc web icloud-containers list --output table
Individual key creation generates the keypair locally and writes the
.p8 with restricted permissions. Revoke re-reads to
verify. Services IDs and Website Push IDs are experimental CRUD.
iCloud containers are read-only (add --hidden
for the hidden collection). Sign in with Apple domain config remains
a separate workflow.
7. App Review: read, draft, then maybe send
asc web review threads --app APP_ID --drafts --plain-text
asc web review drafts create --app APP_ID --thread-id THREAD_ID --body-file ./reply.txt --confirm
asc web review reply --thread-id THREAD_ID --message "We updated the demo account." --confirm Threads include unsent drafts and binary / metadata / informational threads, not just the current submission. Drafts have update + delete. Reply is experimental, verified with a fresh read, never auto-retried on an uncertain send, and does not upload attachments. This is the gym hack fence: drafting is cheap, sending is a letter to Apple Review.
8. Xcode Cloud
asc xcode-cloud workflows duplicate --id WORKFLOW_ID --name "Nightly"
asc web xcode-cloud settings version-aliases create \
--product-id PRODUCT_ID --type xcode_version --name Stable --build latest:stable --confirm
asc web xcode-cloud settings next-build-number set --product-id PRODUCT_ID --value 102 --confirm
asc web xcode-cloud scm connection-status --scm-provider-id PROVIDER_ID Duplicate is experimental and starts disabled for review. TestFlight post-actions and env vars need a separate pass. Next build number must increase; asc reads it back and only succeeds when the number is confirmed. SCM status is read-only — linking still happens in Apple’s UI.
9. Tax, finance, medical, custom distribution
asc web apps tax-category view --app APP_ID
asc web apps tax-category set --app APP_ID --category CATEGORY_ID --confirm
asc web iap tax-category reset --iap IAP_ID --confirm
asc web finance transaction-tax download --date 2026-07 --output-path ./transaction-tax.zip
asc web apps medical-device region set --app APP_ID --region GBR --input ./medical-gbr.json --confirm
asc web apps distribution users create --app APP_ID --recipient-apple-id account@example.com --confirm List Apple’s tax catalog before you set anything. IAP reset drops the override so the purchase inherits the parent app. Transaction Tax Report is experimental and only for periods that offer it; ZIP gets restricted permissions. Medical-device regional answers require the app-level answer already yes. Custom distribution users require the app already on CUSTOM distribution.
10. History, transfers, restore, sandbox
asc web apps history --app APP_ID
asc web apps transfer status --app APP_ID
asc web removed-apps restore --app APP_ID --access limited --confirm
asc web sandbox delete --id TESTER_ID --confirm
History is recorded status changes, dates, actors; add
--version-id to narrow. Transfer status is experimental
and read-only — initiate / accept / cancel / decline stay manual Apple
workflows. Restore now requires an explicit access setting. Sandbox
delete refuses family members or incomplete data and re-reads the list
to confirm the tester is gone.
Stable verbs the agent should already know
5.0 is the new surface. The everyday ship loop was already there. Don’t skip it for shiny experimental flags.
# Resolve IDs
asc apps list --output json
# TestFlight
asc testflight feedback list --app "123456789" --paginate
asc testflight crashes list --app "123456789" --sort -createdDate --limit 10
# Upload
asc builds upload --app "123456789" --ipa "/path/to/MyApp.ipa"
# Readiness then ship
asc validate --app "123456789" --version "1.2.3" --output json
asc publish appstore --app "123456789" --ipa "./MyApp.ipa" --version "1.2.3" --submit --confirm
asc status --app "123456789" --watch
# Metadata (dry-run first)
asc metadata apply --app "123456789" --version "1.2.3" --dir "./metadata" --dry-run asc validate --strict turns leftover
TODO / Lorem ipsum in listings into a
blocker. Experimental --deep needs a web session and
checks things the public API doesn’t (privacy publication, agreements).
Unavailable Apple web endpoints come back unverified, not
a fake fail — don’t treat unverified as green.
Allow / deny for the Apple bot
| Job | Default | Why |
|---|---|---|
doctor, apps list, status, history, threads (read) | Allow | No mutation. JSON in, report out. |
xcode test / xcode doctor | Allow on a Mac with Xcode | Local. This is why 5.0 exists for coding agents. |
signing plan, screenshot matrix, validate, release stage --dry-run | Allow, then human reads the artifact | Plan is not apply. |
| review drafts | Allow with a written reply file | Unsent. Still a letter-shaped artifact — look at it. |
signing apply, resign, publish --submit, review reply, tax set, restore, sandbox delete, API key revoke | Require Approval + --confirm | Apple-facing writes. Gym-hack class of mistake. |
web session export/import, .p8 create | Human-only path into the secret store | Cookies and private keys. Not a chat attachment. |
| app transfer initiate/accept, SCM linking, Sign in with Apple domains | Skip — still Apple UI | CLI is honest about non-goals. Don’t fake them in a browser agent. |
Skill pack (install, don’t retype)
asc install-skills is the on-ramp. Highest-value skills
for a coding agent, in sitting order:
- asc-cli-usage — verbs, flags, pagination, JSON, auth. Load this always.
- asc-id-resolver — names → IDs. Most failed commands are a name where an ID belongs.
- asc-xcode-build — archive / export / build numbers before upload.
- asc-signing-setup — bundle IDs, profiles, encrypted sync.
- asc-testflight-orchestration + asc-build-lifecycle — groups, testers, processing waits.
- asc-submission-health then asc-release-flow — diagnose, then ship. Producer ≠ submitter.
- asc-metadata-sync / asc-whats-new-writer / asc-localize-metadata — listing work with dry-run.
- asc-shots-pipeline — capture → frame → upload. Matrix from 5.0 feeds this.
- asc-crash-triage — TestFlight crashes + feedback as JSON, not a screenshot of Organizer.
- asc-workflow —
.asc/workflow.jsongraphs once the sitting is boring.
Later / only if you actually sell: Apple Ads, PPP pricing, RevenueCat
sync, notarization, Wall of Apps. Don’t install a 23-skill firehose
into a bot that doesn’t ship iOS this month — but do install
asc-cli-usage if the binary is on the machine.
Week-one sitting (don’t boil the account)
Same ladder as the field manual:
teach → skill → routine. Do not cron publish --submit.
Day 1 — binary + read-only
- Install
asc.asc version.asc install-skills. - Auth with a limited API key.
asc auth doctor. asc apps list --output json. Save the app IDs. Never hunt names again.- Optional:
asc telemetry disableif you don’t want command-level usage events (payload is sanitized; still your call).ASC_TELEMETRY_DISABLED=1orDO_NOT_TRACK=1also work.
Day 2 — local Xcode, still no Apple write
asc xcode doctor --output jsonon the Mac that builds.asc xcode test … --output jsonon one scheme. Confirm the agent can name failing tests without grepping logs.- If you have an IPA and a phone:
asc xcode installonce, by hand.
Day 3 — review desk, drafts only
asc web review threads --drafts --plain-text(needs web session).- Draft a reply to a file. Create the draft. Do not
replyon day one.
Day 4+ — fenced writes
Signing apply, metadata apply (after dry-run), TestFlight add-groups,
then — last — publish --submit --confirm. Separate the
bot that produces the plan from the bot (or human) that confirms.
Channel model: one Apple-app channel per bundle, not one bot per
command family.
How this maps here
| Our note | ASC equivalent |
|---|---|
| /cli — CLI as maps, not MCP dump | This binary. Task verbs, JSON, help, --confirm. |
| /cli2 — pulse scripts over fat MCP | Don’t wrap 200 ASC endpoints as MCP tools. Shell to asc. |
| /mcpnew — keep CLI, thin MCP | Optional MCP that calls the same CLI. Skills pack already covers the agent UX. |
| /grokbotlimits — CLIs on the bot VM | Install asc next to Cursor/Codex/Grok Build. Coordination stays on the Grok Bot meter; compile/test don’t. |
| /link-cli — human gate | --confirm + Require Approval. Same shape, Apple instead of dollars. |
| /gymhack — write APIs without a fence | Auto-sending App Review replies or auto-resigning IPAs is the gym class. |
| Field manual quota furnace | Don’t poll asc status --watch every 5 minutes from a metered bot. Watch on the VM. |
Honest: this site is not an iOS shop. The keep is the interface. If we ever ship a TestFlight build (GFAVIP wearable, a client app, a Rork-style experiment), this is the runbook the agent reads first instead of opening App Store Connect.
What we keep vs skip
- Keep: JSON test output, doctor-before-build, plan-then-apply signing, draft-then-send review, pinned skill pack,
--confirmas policy, 5.0 migration before upgrading CI. - Verify: whether our Macs even have the named simulators; whether a web session stays valid long enough for CI; whether Homebrew is on 5.0.0 yet (
asc version). - Skip: memorizing the thread as the flag bible; Always Allow on
publish --submit; stuffing live cookies in the repo; treating experimental screenshot matrix as an upload; faking app transfers in a browser agent; wrapping the whole CLI as 200 MCP tools.
Related on this site
- CLI for agents — why a CLI beats raw API / fat MCP
- CLI not MCP for GTM pulse — owned scripts, thin MCP
- MCP new (2026) — keep CLI, inventory MCP
- Stripe Link CLI — another agent-native CLI with a human gate
- Bunny list script — tiny owned CLI over an API
- GrokBot limits — put the CLI on the shared VM
- Gym hack — unfenced write APIs
- Knowledge base — rulings so the agent doesn’t re-argue flags
Primary: @rudrank — ASC CLI 5.0.0 · GitHub · asccli.sh
Field notes · September 2026 · JSON stdout · --confirm is the gate ·
@rudrank
Comments
Approved comments appear below. Log in once with GFAVIP — it applies across the whole site. GFAVIP login
View comments archive