Skip to content

Releases: akoskomuves/appstoreconnect-mcp

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 15:59
267425f

Minor Changes

  • f7d559e: Add IAP + subscription review assets — 22 tools across a new review-assets domain, closing a real correctness gap: Apple requires an App Store review screenshot on an in-app purchase / subscription before it can be submitted, and there was no tool to attach one.

    Four resources, each with the v0.13 three-step asset-upload flow (composite asc_upload_* + raw reserve/commit/delete + reads):

    • IAP promotional images (inAppPurchaseImages, to-many) — list / get / upload / post / patch / delete
    • IAP review screenshot (inAppPurchaseAppStoreReviewScreenshots, to-one) — get / upload / post / patch / delete
    • Subscription promotional images (subscriptionImages, to-many) — full set
    • Subscription review screenshot (subscriptionAppStoreReviewScreenshots, to-one) — full set

    Apple-contract details captured: the reserve relationship key differs per resource (IAP image uses inAppPurchase, IAP review screenshot uses inAppPurchaseV2 — same inAppPurchases target), the uploaded wire key (Swift isUploaded), and the to-one review-screenshot cardinality (the upload/reserve tools pre-flight and refuse a second one with a delete-first remedy). Reserve/commit wire shapes pinned by unit tests; read paths live-smoked against the real API.

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 15:28
277d5c1

Minor Changes

  • 0ee436f: Add subscription win-back offers — the third subscription offer type alongside introductory and promotional offers.

    Win-back offers target lapsed subscribers and are surfaced automatically by Apple to eligible churned customers. Six new tools in a new win-back-offers domain:

    • asc_list_subscription_win_back_offers / asc_get_subscription_win_back_offer / asc_list_subscription_win_back_offer_prices (reads)
    • asc_post_subscription_win_back_offer — create with eligibility rules, schedule, priority, and per-territory prices in one atomic POST (pre-flights offerId uniqueness)
    • asc_patch_subscription_win_back_offer — update the mutable attributes (eligibility, startDate/endDate, priority, promotionIntent)
    • asc_delete_subscription_win_back_offer

    Immutability mirrors Apple's contract: referenceName, offerId, duration, offerMode, periodCount, targetSubscriptionPlanType, and the prices are fixed after creation (delete + re-create to change them). Wire shapes for create/patch are pinned by unit tests.

v1.0.2

Choose a tag to compare

@github-actions github-actions released this 08 Jul 15:31
4850003

Patch Changes

  • e91d8b3: Fix LocaleSchema regex to accept BCP-47 script subtags like zh-Hans and zh-Hant.

    The previous regex /^[a-z]{2,3}(-[A-Z]{2})?$/ only allowed a 2-letter region
    suffix (e.g. en-US), which incorrectly rejected 4-letter script subtags
    (Hans, Hant). This caused input validation errors for Traditional and
    Simplified Chinese locales (zh-Hant, zh-Hans) even though the tool's own
    error message listed them as valid examples.

    The new regex /^[a-z]{2,3}(-[A-Z][a-z]{3})?(-[A-Z]{2})?$/ covers all three
    forms Apple uses: language-only (ja), language + script (zh-Hant), and
    language + region (en-US).

v1.0.1

Choose a tag to compare

@github-actions github-actions released this 17 Jun 15:01
d5e4927

Patch Changes

  • 557ff93: Add mcpName to package.json and a server.json manifest for publishing to the official MCP Registry (registry.modelcontextprotocol.io). No functional change to the server — this is metadata for registry namespace verification (io.github.akoskomuves/appstoreconnect-mcp).

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 16:27
ee8aa9a

Major Changes

  • ef99375: v1.0 — EU DMA / alternative distribution, completing the roadmap. Every planned surface from v0.1 to v1.0 has now shipped: ~230 tools across 40 domains covering monetization, TestFlight, the full product page, release lifecycle, territory/rollout/export compliance, webhooks, revenue + analytics reporting, customer feedback, A/B testing, runtime health, accessibility, pre-orders, real-FX PPP, and alternative distribution.

    19 new tools in 1 sub-domainsrc/domains/alternative-distribution.ts. Entitlement-gated: every endpoint 403s unless the account holds Apple's EU alternative-distribution / marketplace entitlement; the error formatter explains this rather than presenting it as a bug.

    • Web-distribution domains (3): list / register / delete (⚠️ delete stops installs from that domain). No PATCH exists — delete + re-create.
    • Signing keys (4): list, per-app to-one get, register (takes the PUBLIC PEM only — the tool description forbids pasting private keys), delete (⚠️ artifacts stop validating).
    • Packages (5): relationships-only create per App Store Version, to-one get, versions list (state COMPLETED/REPLACED with pre-signed time-limited download URLs printed verbatim — same hygiene as analytics segments: download promptly, never with the ASC bearer), variants + deltas lists.
    • Marketplace search details (4): to-one get, create / patch / delete of the catalogUrl MarketplaceKit queries.
    • Marketplace webhooks (4): list / create / patch / delete with a write-only HMAC secret (v0.17 semantics).

    Apple-contract gotchas pinned by tests: catalogURLcatalogUrl + endpointURLendpointUrl (URL-strip family), relationships-only package create, optional-app-relationship omission on key create, write-only marketplace secret.

    1.0 stability statement: 486 unit tests; every release v0.12–v1.0 live-smoked against a real App Store Connect account; all 73 sparse fieldsets validated against Apple's official OpenAPI spec (scripts/audit-fieldsets.py); security posture — Apple-only egress (pre-signed URLs fetched bearer-free), write-only secrets, public-key-only intake, customer-facing writes (review responses, experiment starts, accessibility publishes, territory pulls, pricing) explicitly flagged for human approval in their descriptions.

    Live smoke (2026-06-12, unentitled account — the expected boundary): team-level lists (domains, keys, marketplace webhooks) return clean empty 200s; the per-app key to-one returns 200 + data:null when absent (the v0.19 pattern — tool now reports it plainly); calling marketplaceSearchDetail on a NON-marketplace app surfaces an Apple-side 500 UNEXPECTED_ERROR (documented in the tool description: it means "not a marketplace app", not an outage). Writes not exercisable without the entitlement — body shapes pinned by unit tests.

v0.21.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 16:20
6c7c0ae

Minor Changes

  • 379eb20: v0.22 — Per-territory pre-orders + real-FX PPP. Two of the three remaining v1.0+ items.

    Pre-orders (1 new tool)asc_patch_territory_availability: PATCH /v1/territoryAvailabilities/{id} with available / releaseDate / preOrderEnabled, completing the v0.15 availability surface (list → patch → end-pre-order). The ID is the Apple-opaque base64 composite from asc_list_territory_availabilities (the v0.15 discovery) — bare ISO codes rejected. ⚠️ available=false pulls the app from sale in that territory; the description requires confirmed intent.

    Real-FX (PPP engine upgrade, no new tool)fxRates on ppp_compute_proposal AND ppp_apply_proposal (and threaded through every offer-apply path):

    • Semantics: USD value of ONE unit of each currency (e.g. {"BHD": 2.65, "KWD": 3.25}); USD implied 1.
    • Rescues the currency-mismatch territories the engine previously skipped (USD-billed Gulf storefronts where Apple Music prices in BHD/KWD/OMR) with a dimension-correct conversion: factor = (indexLocal × usd(idx)) / (anchorLocal × usd(anchor)), target converted into the billing currency. Implemented as the pure, unit-tested fxAdjustedTarget in the PPP engine.
    • fx-adjusted rows are flagged (* on FACTOR + summary count); reason stays exactly change/unchanged so apply filters are unaffected.
    • The skip message now says how to rescue ("pass fxRates") or what's missing ("fxRates missing a needed currency").
    • Security stance: rates are USER-SUPPLIED only. This server's egress remains Apple-API-only — no third-party FX feed is ever fetched.

    Tests: FX math (mismatch rescue, all-same-currency reduction, non-USD billing conversion, missing/invalid-rate refusals) + territory-availability patch body.

    Live smoke (2026-06-12, WikiCatch): territory-availability read verified (175 territories, opaque composite IDs feeding the new PATCH tool); real-FX rescue verified against the real bundled index (BHR: 1.49 BHD × 2.65 USD/BHD vs the USD anchor → factor 0.359, dimension-correct target). The PATCH write itself was NOT drilled — it is store-affecting on a shipped app; its body shape is pinned by unit tests.

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 16:10
375b49c

Minor Changes

  • 251cc79: v0.21 — Runtime health + accessibility: diagnostic signatures, perf/power metrics, accessibility declarations. Two of the three remaining v1.0+ "niche read surfaces" turn out richer than planned — accessibility declarations are full CRUD with a customer-facing publish gate.

    8 new tools across 2 sub-domains.

    Diagnostics + perf/power (4 tools, all read-only)src/domains/diagnostics.ts.

    • asc_list_diagnostic_signatures — per-build problem hotspots (DISK_WRITES / HANGS / LAUNCHES), impact-weighted, heaviest-first digest.
    • asc_get_diagnostic_logs — the anonymized call stacks behind one signature. NOT JSON:API: application/vnd.apple.diagnostic-logs+json via an Accept override on requestText.
    • asc_get_app_perf_power_metrics / asc_get_build_perf_power_metrics — Xcode-metrics percentile curves (8 metric types × device classes), app-rolling or single-build. NOT JSON:API: application/vnd.apple.xcode-metrics+json. maxChars-capped raw JSON.
    • All three populate only with enough opted-in usage — empty/404 on small apps is the documented normal case.

    Accessibility declarations (4 tools)src/domains/accessibility-declarations.ts. The "Accessibility Nutrition Label" on the product page, per (app, deviceFamily).

    • asc_list_accessibility_declarations — deviceFamily/state filters; digest renders the nine support flags as a Y/N/— matrix (— = not declared ≠ declared-unsupported).
    • asc_post_accessibility_declaration — DRAFT create (deviceFamily required + any subset of nine flags; omitted flags OMITTED on the wire, not false).
    • asc_patch_accessibility_declaration — flag edits + ⚠️ publish=true is CUSTOMER-FACING (label goes live; previous PUBLISHED becomes REPLACED). Description instructs explicit human approval.
    • asc_delete_accessibility_declaration — DRAFTs only.

    Apple-contract gotchas pinned by tests:

    1. The largest is-prefix strip family yet (10 members): nine isSupports*supports* + isPublishpublish.
    2. Omitted ≠ false on support flags — undeclared flags are dropped from the body.
    3. Two non-JSON:API content types requiring Accept overrides (vnd.apple.diagnostic-logs+json, vnd.apple.xcode-metrics+json).
    4. Static fieldset literal kept audit-compatible with scripts/audit-fieldsets.py (validated against Apple's official OpenAPI spec — 71 fieldset usages clean).

    Live smoke (2026-06-12, WikiCatch): CLEAN — zero corrections (second clean round in a row). Both non-JSON:API content types verified live (real xcode-metrics documents returned through the Accept overrides; empty productData is the small-app expected shape), diagnostic-signatures empty-list read clean, and the accessibility drill (DRAFT create with two flags → third-flag patch → delete, publish never sent) confirmed all ten strip-family wire keys against the live API with the flag-matrix digest rendering correctly.

    Schemas (5 new): DiagnosticSignatureIdSchema, DiagnosticTypeSchema, PerfMetricTypeSchema, AccessibilityDeclarationIdSchema, AccessibilityDeclarationStateSchema.

    Digests (2 new): digestDiagnosticSignatures (heaviest-first), digestAccessibilityDeclarations (flag matrix).

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 16:08
a9bdda5

Minor Changes

  • 396ca2d: v0.20 — App Store Version Experiments V2 (product-page A/B tests). The highest-leverage ASO item from the v1.0+ bucket, pulled forward: test alternate screenshots, previews, and app icons against the live product page with a controlled traffic split.

    12 new tools in 1 sub-domainsrc/domains/version-experiments.ts. V2 surface only (app-attached, rolls across versions); the deprecated version-attached v1 experiments are not exposed.

    Experiment lifecycle (5 tools)

    • asc_list_version_experiments — GET /v1/apps/{id}/appStoreVersionExperimentsV2 (the URL-version QUIRK: a /v1 path listing V2 resources; CRUD lives at /v2/appStoreVersionExperiments). Digest shows the 9-state lifecycle, traffic %, review-required flag, start/end dates.
    • asc_get_version_experiment — with treatments + latestControlVersion included.
    • asc_post_version_experiment — ALL THREE attrs required (name, platform, trafficProportion 1–99). Created in PREPARE_FOR_SUBMISSION; publicly invisible until submitted AND started.
    • asc_patch_version_experiment — name / trafficProportion / started=true (⚠️ customer-facing: begins serving treatments to real traffic; requires APPROVED; the description instructs explicit human approval first). Wire-key gotcha pinned: Swift isStarted → wire started.
    • asc_delete_version_experiment.

    Treatments + localizations (7 tools)

    • Treatment CRUD-minus-get (asc_list/post/patch/delete_experiment_treatment[s]) — name + optional appIconName (alternate-icon testing; the icon must ship in the binary). Create emits the appStoreVersionExperimentV2 relationship, never the deprecated v1 sibling (pinned by test).
    • Treatment localization list/create/delete — per-locale containers for variant assets. Variant screenshots/previews reuse the existing v0.13 asset tools (asc_post_app_screenshot_set etc. already accept parentType appStoreVersionExperimentTreatmentLocalizations) — no new upload machinery.
    • Submission rides the existing v0.11 V2 review-submission flow.

    Apple-contract gotchas pinned by tests: the isStartedstarted strip, all-required experiment create attrs, V2-only treatment relationship, /v1-list-vs-/v2-CRUD path split.

    Live smoke (2026-06-12, WikiCatch): CLEAN — full create → get → patch → treatment → localization → lists → delete drill verified every tool path with zero spec corrections (first fully-clean round since v0.14). started=true and review submission deliberately NOT exercised (customer-facing). The read list also rendered a real historical experiment correctly (a STOPPED screenshots test from April), confirming digest output against genuine data.

    Schemas (5 new): VersionExperimentIdSchema, ExperimentTreatmentIdSchema, TreatmentLocalizationIdSchema, TrafficProportionSchema, ExperimentStateSchema (9-value enum).

    Digests (3 new): digestVersionExperiments, digestExperimentTreatments (PROMOTED column = winner pushed live), digestTreatmentLocalizations.

v0.18.1

Choose a tag to compare

@github-actions github-actions released this 12 Jun 15:32
6330241

Patch Changes

  • 3683434: Fix: asc_list_app_infos (and asc_get_app_info's digest) 400ed on every call — Apple REMOVED the kidsAgeBand attribute from the AppInfo contract after v0.12 shipped, and the hard-coded sparse fieldset still requested it ("'kidsAgeBand' is not a valid field name"). The field is dropped from the fieldset, digest column, and schema/tool descriptions. Live-verified: the old fieldset reproduces the 400, the fixed one returns data. Reported from real usage during a release workflow on 2026-06-12.

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 12 Jun 12:02
7b00b3a

Minor Changes

  • b959be2: v0.19 — Customer reviews + review summarizations. The last planned roadmap row before v1.0+: read what customers say, reply publicly (with guardrails), and pull Apple's AI-aggregated review summary.

    6 new tools in 1 sub-domainsrc/domains/customer-reviews.ts.

    • asc_list_customer_reviews — app-wide (/v1/apps/{id}/customerReviews) or version-scoped (/v1/appStoreVersions/{id}/customerReviews); pass exactly one of appId / appStoreVersionId. Filters: rating (STRINGS "1".."5" per the wire contract), territory, and hasPublishedResponse (wire exists[publishedResponse]) — false is the unanswered queue. Sorts: ±createdDate, ±rating. Digest shows star bars, title/body previews, and the developer-response state via include=response.
    • asc_get_customer_review — full review body + response included.
    • asc_get_customer_review_response — the review's single developer reply (state PUBLISHED / PENDING_PUBLISH).
    • asc_post_customer_review_response⚠️ PUBLIC-FACING WRITE: publishes the reply on the App Store under the review; one response per review (re-posting REPLACES). The tool description instructs models to draft → show the human → post only on explicit approval. responseBody capped at 5,970 chars per Apple's UI limit.
    • asc_delete_customer_review_response — removes the public reply; the review itself is untouched.
    • asc_list_customer_review_summarizations — Apple's AI-aggregated summary per (platform, territory, locale), the same text shown on the product page. filter[platform] REQUIRED by Apple; empty lists are common (feature rollout + review-volume gated).

    Apple-contract gotchas pinned by tests:

    1. Exists-param strip variant: Swift isExistsPublishedResponse → wire exists[publishedResponse] — a new member of the is-prefix strip family, on a query param rather than an attribute.
    2. filter[rating] values are strings, not numbers.
    3. CustomerReviewResponseV1CreateRequest: responseBody attribute REQUIRED + review relationship.
    4. include=response baked into the list (v0.16 lesson — relationship objects don't materialize without include).
    5. No sentiment filter exists on Apple's side — rating is the documented proxy.

    Live-smoke spec corrections caught on 2026-06-12 (real WikiCatch reviews via scripts/smoke-reviews.ts, strictly read-only — the respond tool is public-facing and was NOT drilled):

    1. A review with no developer response returns 200 + data: null on /v1/customerReviews/{id}/response — not a 404. The tool detects it and reports "no response yet" instead of dumping {"data": null}.
    2. Verified live: app-wide list (2 real reviews with star bars + previews), the exists[publishedResponse]=false unanswered queue, rating filters, single-review get with include, version-scoped list, and a clean empty-list summarizations read (Apple hasn't generated one for this app). Respond/delete paths covered by body-builder tests only — intentionally not exercised against the live store.

    Schemas (5 new): CustomerReviewIdSchema, CustomerReviewResponseIdSchema, ReviewRatingFilterSchema, ReviewSortSchema, SummarizationPlatformSchema.

    Digests (2 new): digestCustomerReviews (star bars + response state), digestCustomerReviewSummarizations (full summary text blocks).

Patch Changes

  • ebf09b0: Document the ASC_VENDOR_NUMBER env var (introduced in v0.18 as the vendor-number fallback for asc_get_sales_report / asc_get_finance_report): README gets an "Optional: vendor number" config section (where to find it in App Store Connect, role requirements for the report endpoints), and appstoreconnect-mcp --help lists it alongside the other optional env vars.