Skip to main content

Guide

Flags​

  • --domains=<list>: Comma-separated domains to load, or all (combined server only)
  • --read-only: Expose only tools that cannot modify anything
  • --confirm: Ask before every write, not just the strong risk levels
  • --no-confirm: Never ask; the client's own tool approval is the only gate
  • --dry-run: Writes never reach Apple; each mutating call returns what would have been sent, with its risk level
  • --include-deprecated: Also load the 123 operations Apple has deprecated. In profile mode this adds the retired operations of the domains that profile covers — 102 of the 123 are Game Center

Confirmation before risky writes is on by default. Changing a price, handing out Admin, deleting a certificate — Heimdall asks you to confirm through your client's prompt (MCP elicitation), showing what would change. So even if it misreads "drop the price a bit" as 0.99, nothing changes until you approve it.

One call instead of a chain​

A handful of hand-written tools collapse a multi-step flow into one call. The raw tools stay exactly as they are; these sit on top, and each is turned on by the sub-profile that owns it. Worked through in Examples.

Instead ofCallNeeds
app → group → subscription → price pointspricing__get_subscription_price — one country or, with the territory omitted, all ~175 grouped by pricemonetization:subscription-pricing
the same chain plus the writepricing__set_subscription_pricemonetization:subscription-pricing
setting a price country by countrypricing__equalize_price — one anchor price, every other market derived by Apple; for an app, an IAP or a subscriptionmonetization:subscription-pricing
open a submission, add the version, hand it over — three calls in that orderrelease__submit — refuses what the pre-flight blocksdistribution:submission
comparing store text across forty languages by eyemetadata_ai__audit_localizationsdistribution:version
pasting a translation into each locale by handmetadata_ai__apply_localizations — from a CSV or JSON filedistribution:version
version + build + review detail + localizations + screenshots, to answer "can this be submitted"preflight__check_versiondistribution:version
two versions × every locale, compared by handlisting__diff_metadata — only the fields that differ, plus locales added or droppeddistribution:version
version → 50 localizations → screenshot sets → screenshotslisting__get_screenshotsdistribution:version
reserving a screenshot slot, then moving the bytes yourselflisting__upload_screenshotdistribution:version
request → report → instance → segment → a signed URLanalytics__get_report — returns rows, not a linkanalytics
fetching reviews and grouping them by handreviews_ai__triage, reviews_ai__daily_briefing, reviews_ai__draft_responsemarketing:customer-review
listing apps, then a versions call each, then reading App Store statesasc__account_status — which app is live, which is in flight, and whether the next move is yours or Apple'score, so every profile

pricing__equalize_price is a REVENUE-level write covering about 175 countries. Run it under --dry-run first: it returns the full derived table before anything is sent.

Naming an app​

The 46 tools rooted at /v1/apps/{id} take a name, a bundle ID or the numeric Apple ID, and resolve it before the call. "List Acme's versions" needs no ID lookup first. Only there, and only when the value is not already numeric — anywhere else an id is an id.

StoreKit 2 — customer transactions​

The App Store Server API answers questions about individual customers rather than your listing: purchase history, entitlement, refunds, subscription status. It's enabled when a Bundle ID is configured (setup or ASC_BUNDLE_ID) and comes with monetization:storekit.

  • Each StoreKit tool accepts an optional environment argument (Production / Sandbox). A transaction ID exists in exactly one environment; the default comes from your setup choice, and you override per call.
  • --read-only hides the two mutating tools (request_test_notification, extend_renewal_date); the seven read tools stay.

Prompts​

Three workflows are offered as MCP prompts.

PromptWhat it runsOffered when
release-readinesspreflight__check_version, then listing__diff_metadata, ending in GO or NO-GOdistribution:version
review-triagebriefing → triage → a drafted reply per review, none of them sentmarketing:customer-review
price-checkworldwide prices in one call, then what looks unintendedmonetization:subscription-pricing

A prompt only appears when every tool it names is loaded; a narrowed profile or --read-only removes it the same way it removed the tools. Each one stops at the write: the submission, the reply and the price change are yours to make.