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 json always 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.md says: 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.

  1. Discover, don’t recall. asc --help then asc <command> --help before you invent flags. Use asc search when you only have a job name.
  2. Long-form flags. --app, --output, --confirm. Not short aliases in scripts.
  3. JSON for agents. Always pass --output json (add --pretty only when a human is reading). Do not scrape tables.
  4. Read-only first. list, view, status, doctor, --dry-run, plan commands. Writes wait.
  5. --confirm is 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).
  6. Experimental ≠ CI. Use 5.0 experimental commands in a sitting. Do not pin a nightly workflow to them until the label comes off.
  7. Keys stay out of git. .p8 files, 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.
  8. Team key vs individual key. Team keys need --issuer-id. Individual keys use --key-type individual and omit issuer. Don’t mix them.
  9. 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.
  10. 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:

  1. asc-cli-usage — verbs, flags, pagination, JSON, auth. Load this always.
  2. asc-id-resolver — names → IDs. Most failed commands are a name where an ID belongs.
  3. asc-xcode-build — archive / export / build numbers before upload.
  4. asc-signing-setup — bundle IDs, profiles, encrypted sync.
  5. asc-testflight-orchestration + asc-build-lifecycle — groups, testers, processing waits.
  6. asc-submission-health then asc-release-flow — diagnose, then ship. Producer ≠ submitter.
  7. asc-metadata-sync / asc-whats-new-writer / asc-localize-metadata — listing work with dry-run.
  8. asc-shots-pipeline — capture → frame → upload. Matrix from 5.0 feeds this.
  9. asc-crash-triage — TestFlight crashes + feedback as JSON, not a screenshot of Organizer.
  10. asc-workflow.asc/workflow.json graphs 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

  1. Install asc. asc version. asc install-skills.
  2. Auth with a limited API key. asc auth doctor.
  3. asc apps list --output json. Save the app IDs. Never hunt names again.
  4. Optional: asc telemetry disable if you don’t want command-level usage events (payload is sanitized; still your call). ASC_TELEMETRY_DISABLED=1 or DO_NOT_TRACK=1 also work.

Day 2 — local Xcode, still no Apple write

  1. asc xcode doctor --output json on the Mac that builds.
  2. asc xcode test … --output json on one scheme. Confirm the agent can name failing tests without grepping logs.
  3. If you have an IPA and a phone: asc xcode install once, by hand.

Day 3 — review desk, drafts only

  1. asc web review threads --drafts --plain-text (needs web session).
  2. Draft a reply to a file. Create the draft. Do not reply on 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, --confirm as 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

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