Guide
Flags
--domains=<list>: Comma-separated domains to load, orall(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 of | Call | Needs |
|---|---|---|
| app → group → subscription → price points | pricing__get_subscription_price — one country or, with the territory omitted, all ~175 grouped by price | monetization:subscription-pricing |
| the same chain plus the write | pricing__set_subscription_price | monetization:subscription-pricing |
| setting a price country by country | pricing__equalize_price — one anchor price, every other market derived by Apple; for an app, an IAP or a subscription | monetization:subscription-pricing |
| open a submission, add the version, hand it over — three calls in that order | release__submit — refuses what the pre-flight blocks | distribution:submission |
| comparing store text across forty languages by eye | metadata_ai__audit_localizations | distribution:version |
| pasting a translation into each locale by hand | metadata_ai__apply_localizations — from a CSV or JSON file | distribution:version |
| version + build + review detail + localizations + screenshots, to answer "can this be submitted" | preflight__check_version | distribution:version |
| two versions × every locale, compared by hand | listing__diff_metadata — only the fields that differ, plus locales added or dropped | distribution:version |
| version → 50 localizations → screenshot sets → screenshots | listing__get_screenshots | distribution:version |
| reserving a screenshot slot, then moving the bytes yourself | listing__upload_screenshot | distribution:version |
| request → report → instance → segment → a signed URL | analytics__get_report — returns rows, not a link | analytics |
| fetching reviews and grouping them by hand | reviews_ai__triage, reviews_ai__daily_briefing, reviews_ai__draft_response | marketing:customer-review |
| listing apps, then a versions call each, then reading App Store states | asc__account_status — which app is live, which is in flight, and whether the next move is yours or Apple's | core, 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
environmentargument (Production/Sandbox). A transaction ID exists in exactly one environment; the default comes from your setup choice, and you override per call. --read-onlyhides the two mutating tools (request_test_notification,extend_renewal_date); the seven read tools stay.
Prompts
Three workflows are offered as MCP prompts.
| Prompt | What it runs | Offered when |
|---|---|---|
release-readiness | preflight__check_version, then listing__diff_metadata, ending in GO or NO-GO | distribution:version |
review-triage | briefing → triage → a drafted reply per review, none of them sent | marketing:customer-review |
price-check | worldwide prices in one call, then what looks unintended | monetization: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.