io.github.SardorbekR/appstore-connect·Commerce

appstore-connect

MCP server for Apple's App Store Connect API. Manage apps, TestFlight, and more.

Stars
22
Version
2.0.3
License
MIT
Review
Passed
Language
TypeScript
Last commit
2h ago
Forks
5
Open issues
0
Registry update
Oct 16, 2026
aiapp-store-connectappleautomationclaudeiosmacosmcpmcp-servertestflighttvosvisionos

Connect

npm
Terminal
$claude mcp add appstore-connect \  -- npx -y [email protected]

Environment variables

Nothing to configure — it works as is.

Security review

Review passed

Reviewed 34m ago.

metadata
scanned
packages
1 checked

No findings.

Tools

This server runs on your machine, so its tool list is not fetched before install — the README below describes what it offers.

App Store Connect MCP Server

npm version License: MIT Node.js Version

A Model Context Protocol (MCP) server for Apple's App Store Connect API. Manage your iOS, macOS, tvOS, and visionOS apps directly from Claude, Cursor, or any MCP-compatible client.

Features

  • Any API Operation - Call any of the 1,303 App Store Connect API operations through asc_api_request, validated against Apple's OpenAPI spec, with asc_api_search and asc_api_describe to find and inspect them
  • Submission & Release - Edit version metadata (copyright, version string, release type), attach builds, App Review details, review submissions, phased and manual release, export compliance
  • App Info - Categories, age rating declaration, app info localizations, custom EULA
  • App Store Localizations - Full CRUD for version descriptions, keywords, and what's new
  • App Management - List and inspect apps across all platforms
  • Version Control - Create and manage app store versions
  • TestFlight - Groups, build access, testers and invitations, What to Test notes, beta app localizations, beta review submissions
  • Screenshots & Previews - Upload, reorder, and delete screenshots and app previews; review screenshots for subscriptions and in-app purchases
  • Customer Reviews - Read reviews and publish or remove responses
  • Bundle ID Management - Full CRUD for bundle identifiers
  • Device Management - List and inspect registered devices
  • User Management - List and inspect team users
  • Build Management - List and inspect app builds
  • Category & Pricing - Browse categories, check pricing and availability
  • Pricing & PPP - Set per-territory pricing with Purchase Power Parity support
  • Subscriptions - Groups, subscriptions, localizations, pricing & PPP, availability, promotional, introductory and win-back offers, offer codes
  • In-App Purchases - Create and manage one-time purchases (lifetime/non-consumable, consumable, non-renewing): metadata, localization, pricing & PPP, availability, offer codes, review screenshots, and review submission
  • Custom Product Pages - Pages, versions, and per-locale promotional text
  • Analytics Reports - Request and download app analytics reports (engagement, commerce, usage, performance)
  • Sales & Finance - Download sales, trends, and financial reports
  • Performance & Diagnostics - App/build power & performance metrics and diagnostic logs
  • Toolsets & Read-Only Mode - Expose only the tool groups you need, or block every write with ASC_READ_ONLY=1
  • Secure by Default - ES256 JWT auth with automatic token refresh, credential redaction in logs

Table of Contents

Quick Start

  1. Get an App Store Connect API key (see Prerequisites).
  2. Add the server to your MCP client with npx -y asc-mcp@latest and your credentials (see MCP Client Configuration).
  3. Restart the client. New releases are picked up on each restart.

Installation

npx (recommended)

npx -y asc-mcp@latest

Your MCP client runs this command itself (see MCP Client Configuration). npx fetches the newest release whenever the client starts, so you stay up to date.

Global install

npm install -g asc-mcp

Then use "command": "asc-mcp" in your client config. A global install does not update by itself: run npm install -g asc-mcp@latest to update.

Updating

  • npx: restart your MCP client. A running client keeps the version it started with.
  • Global install: npm install -g asc-mcp@latest, then restart the client.
  • Pin a version for stability with [email protected] (or any version) instead of asc-mcp@latest.

Once a day the server asks npm for the latest version in the background, without delaying startup. If yours is older, the next time the server starts it tells your assistant, which mentions it to you once. It sends nothing but that request, and installs nothing. Set ASC_DISABLE_UPDATE_CHECK=1 to turn it off.

From Source

git clone https://github.com/SardorbekR/appstore-connect-mcp.git
cd appstore-connect-mcp
npm install
npm run build

Configuration

Prerequisites: Get Your Apple API Credentials

  1. Sign in to App Store Connect
  2. Go to Users and Access → Integrations → App Store Connect API
  3. Click Generate API Key (or use existing)
  4. Select appropriate role (Admin or App Manager recommended)
  5. Download the .p8 file - you can only download it once!
  6. Note your Key ID (shown in the keys list)
  7. Note your Issuer ID (shown at the top of the page)

Environment Variables

VariableRequiredDescription
APP_STORE_CONNECT_KEY_IDYesYour API Key ID (e.g., ABC123DEFG)
APP_STORE_CONNECT_ISSUER_IDYesYour Issuer ID (UUID format)
APP_STORE_CONNECT_P8_PATHYes*Path to your .p8 private key file
APP_STORE_CONNECT_P8_CONTENTYes*Raw content of .p8 key (alternative to path)

*One of P8_PATH or P8_CONTENT is required.

Optional settings:

VariableDefaultDescription
ASC_TOOLSETSallComma-separated tool groups to expose: apps, versions, media, testflight, pricing, subscriptions, iap, reviews, product-pages, provisioning, users, analytics, api. Fewer tools means less context in clients with small tool budgets. The api group reaches every operation, including ones outside the other groups.
ASC_READ_ONLYoff1 exposes only read tools and makes the client refuse every non-GET request
ASC_MAX_RESPONSE_CHARS80000Size cap for asc_api_request results; larger results end at a page boundary with a cursor to continue
ASC_DISABLE_UPDATE_CHECKoff1 skips the once-a-day check for a newer asc-mcp release

MCP Client Configuration

Claude Desktop

Add to your Claude Desktop config file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "app-store-connect": {
      "command": "npx",
      "args": ["-y", "asc-mcp@latest"],
      "env": {
        "APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
      }
    }
  }
}
Cursor

Add to your Cursor MCP settings (Settings → MCP Servers):

{
  "mcpServers": {
    "app-store-connect": {
      "command": "npx",
      "args": ["-y", "asc-mcp@latest"],
      "env": {
        "APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
      }
    }
  }
}
VS Code with Continue

Add to your Continue configuration:

{
  "mcpServers": {
    "app-store-connect": {
      "command": "npx",
      "args": ["-y", "asc-mcp@latest"],
      "env": {
        "APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_CONNECT_P8_PATH": "/absolute/path/to/AuthKey.p8"
      }
    }
  }
}
Using P8 Content Instead of Path

For CI/CD or containerized environments, you can pass the key content directly:

{
  "mcpServers": {
    "app-store-connect": {
      "command": "npx",
      "args": ["-y", "asc-mcp@latest"],
      "env": {
        "APP_STORE_CONNECT_KEY_ID": "YOUR_KEY_ID",
        "APP_STORE_CONNECT_ISSUER_ID": "YOUR_ISSUER_ID",
        "APP_STORE_CONNECT_P8_CONTENT": "-----BEGIN PRIVATE KEY-----\nMIGT...your key here...AB12\n-----END PRIVATE KEY-----"
      }
    }
  }
}

Available Tools

Apps

ToolDescriptionParameters
list_appsList all apps in your accountlimit? (number, 1-200)
get_appGet details of a specific appappId (string, required)

Versions

ToolDescriptionParameters
list_app_versionsList all versions for an appappId, platform?, versionState?, limit?
get_app_versionGet version detailsversionId
create_app_versionCreate a new app versionappId, platform, versionString, releaseType?

Version Localizations

ToolDescriptionParameters
list_version_localizationsList localizations for a versionversionId, limit?
get_version_localizationGet localization detailslocalizationId
create_version_localizationAdd a new localeversionId, locale, description?, keywords?, whatsNew?
update_version_localizationUpdate localizationlocalizationId, description?, keywords?, whatsNew?, promotionalText?
delete_version_localizationRemove a localelocalizationId

App Info Localizations

ToolDescriptionParameters
list_app_infosList app info recordsappId, limit?
list_app_info_localizationsList name/subtitle localizationsappInfoId, limit?
update_app_info_localizationUpdate app name, subtitlelocalizationId, name?, subtitle?, privacyPolicyUrl?

Beta Testing (TestFlight)

ToolDescriptionParameters
list_beta_groupsList beta groups for an appappId, limit?
list_beta_testersList testers in a groupbetaGroupId, limit?
add_beta_testerAdd a tester to a groupbetaGroupId, email, firstName?, lastName?
remove_beta_testerRemove a tester from a groupbetaGroupId, betaTesterId

Screenshots

ToolDescriptionParameters
list_screenshot_setsList screenshot setslocalizationId, limit?
list_screenshotsList screenshots in a setscreenshotSetId, limit?
upload_screenshotUpload a new screenshotscreenshotSetId, fileName, fileSize, filePath

Bundle IDs

ToolDescriptionParameters
list_bundle_idsList all bundle IDslimit?, platform?
get_bundle_idGet bundle ID detailsbundleIdId
create_bundle_idRegister a new bundle IDidentifier, name, platform
update_bundle_idUpdate bundle ID namebundleIdId, name
delete_bundle_idDelete a bundle IDbundleIdId

Devices

ToolDescriptionParameters
list_devicesList registered deviceslimit?, platform?, status?
get_deviceGet device detailsdeviceId

Users

ToolDescriptionParameters
list_usersList team userslimit?, roles?
get_userGet user detailsuserId

Builds

ToolDescriptionParameters
list_buildsList builds for an appappId, limit?
get_buildGet build detailsbuildId

Categories & Pricing

ToolDescriptionParameters
list_app_categoriesList app categorieslimit?, platform?
get_app_price_scheduleGet app pricing infoappId
get_app_availabilityGet app territory availabilityappId

Pricing (PPP)

ToolDescriptionParameters
list_territoriesList all territories with currencieslimit?
list_app_price_pointsList available price tiers for an appappId, territory?, limit?
get_price_point_equalizationsGet PPP equivalent prices across countriespricePointId, territories?, limit?
set_app_pricesSet per-territory manual pricing (replaces entire schedule)appId, baseTerritory, manualPrices

In-App Purchases (Lifetime / Non-Consumable)

One-time purchases via Apple's In-App Purchases v2 API. create_in_app_purchase defaults to NON_CONSUMABLE — a "lifetime" unlock. To ship one: create → add a localization → set a price → set availability → submit for review.

Note: App Review usually requires a review screenshot on the in-app purchase. Uploading IAP review screenshots is not yet covered by these tools — add one in App Store Connect if submit_in_app_purchase_for_review is rejected for a missing screenshot.

ToolDescriptionParameters
list_in_app_purchasesList an app's in-app purchases, optionally by typeappId, inAppPurchaseType?, limit?
get_in_app_purchaseGet a single in-app purchase's details and stateinAppPurchaseId
create_in_app_purchaseCreate an IAP (defaults to NON_CONSUMABLE / lifetime)appId, name, productId, inAppPurchaseType?, familySharable?, reviewNote?
update_in_app_purchaseUpdate name, Family Sharing, or review note (productId/type immutable)inAppPurchaseId, name?, familySharable?, reviewNote?
delete_in_app_purchaseDelete an in-app purchaseinAppPurchaseId
list_in_app_purchase_localizationsList localized names/descriptionsinAppPurchaseId, limit?
create_in_app_purchase_localizationAdd a localized display name (+ description)inAppPurchaseId, locale, name, description?
update_in_app_purchase_localizationUpdate a localizationlocalizationId, name?, description?
delete_in_app_purchase_localizationDelete a localizationlocalizationId
list_in_app_purchase_price_pointsList price points (customer price & proceeds)inAppPurchaseId, territory?, limit?, offset?
get_in_app_purchase_price_point_equalizationsApple's PPP-equivalent price points for a base price pointpricePointId, territories?, limit?
set_in_app_purchase_priceSet pricing (replaces schedule; one base territory to auto-equalize, or full PPP list)inAppPurchaseId, baseTerritory, manualPrices
list_in_app_purchase_pricesRead current per-territory prices (manual; optional automatic)inAppPurchaseId, territory?, includeAutomatic?, limit?
get_in_app_purchase_availabilityGet territory availabilityinAppPurchaseId
set_in_app_purchase_availabilitySet territory availabilityinAppPurchaseId, availableInNewTerritories, territories?
submit_in_app_purchase_for_reviewSubmit the IAP to App Review (independent of an app version)inAppPurchaseId

Analytics Reports

ToolDescriptionParameters
create_analytics_report_requestRequest an analytics report (ongoing or one-time snapshot)appId, accessType
list_analytics_report_requestsList analytics report requests for an appappId
get_analytics_report_requestGet an analytics report requestrequestId
delete_analytics_report_requestDelete an analytics report requestrequestId
list_analytics_reportsList reports available within a requestrequestId
list_analytics_report_instancesList instances (by date) of a reportreportId
list_analytics_report_segmentsList downloadable segments of a report instanceinstanceId
download_analytics_report_segmentDownload a report segmenturl

Sales & Finance

ToolDescriptionParameters
get_sales_reportDownload a sales/trends reportvendorNumber, reportType, reportSubType, frequency, reportDate
get_finance_reportDownload a financial reportvendorNumber, regionCode, reportDate, reportType

Performance & Diagnostics

ToolDescriptionParameters
get_app_perf_metricsGet an app's power & performance metricsappId, metricType
get_build_perf_metricsGet a build's performance metricsbuildId, metricType
list_diagnostic_signaturesList diagnostic signatures for a buildbuildId
list_diagnostic_logsList diagnostic logs for a signaturesignatureId

Any API Operation (generic)

ToolDescriptionParameters
asc_api_requestCall any App Store Connect API operation (1303 operations from Apple's OpenAPI 4.5.1).method?, path?, query?, body?, paginate?, maxItems?, cursor?, allowUnknown?
asc_api_searchSearch the App Store Connect API operation index by keywords (matches paths, operation IDs, resource types), e.g. 'phased release', 'customer reviews', 'offer codes'.query, method?, limit?
asc_api_describeDescribe one App Store Connect API operation: query parameters with allowed values, body attributes (types, enums, required), relationships, and a minimal body template.method, path

Subscriptions

ToolDescriptionParameters
list_subscription_groupsList all subscription groups for an app.appId, limit?
get_subscription_groupGet details of a specific subscription group by its ID.subscriptionGroupId
create_subscription_groupCreate a new subscription group for an app.appId, referenceName
update_subscription_groupUpdate the reference name of a subscription group.subscriptionGroupId, referenceName
list_subscription_group_localizationsList the localizations for a subscription group.subscriptionGroupId, limit?
get_subscription_group_localizationGet a single subscription group localization by its ID.localizationId
create_subscription_group_localizationCreate a localization for a subscription group.subscriptionGroupId, name, locale, customAppName?, customAppDescription?
update_subscription_group_localizationUpdate an existing subscription group localization.localizationId, name?, customAppName?, customAppDescription?
list_subscriptionsList all auto-renewable subscriptions within a subscription group.subscriptionGroupId, limit?
get_subscriptionGet details of a specific auto-renewable subscription by its ID.subscriptionId
create_subscriptionCreate a new auto-renewable subscription within a subscription group.subscriptionGroupId, name, productId, subscriptionPeriod, familySharable?, reviewNote?, groupLevel?
update_subscriptionUpdate the metadata of an existing auto-renewable subscription.subscriptionId, name?, familySharable?, subscriptionPeriod?, reviewNote?, groupLevel?
delete_subscriptionDelete an auto-renewable subscription.subscriptionId
list_subscription_localizationsList all localizations (translated names and descriptions) for a subscription.subscriptionId, limit?
create_subscription_localizationCreate a localized name and description for a subscription in a specific locale.subscriptionId, name, locale, description?
update_subscription_localizationUpdate the localized name or description for a subscription localization.localizationId, name?, description?
delete_subscription_localizationDelete a localization for a subscription.localizationId
list_subscription_price_pointsList available price points for a subscription, showing customer price and developer proceeds.subscriptionId, territory?, limit?, offset?
list_subscription_pricesList the current prices set for a subscription, including price tier and territory details.subscriptionId, territory?, limit?
get_subscription_availabilityGet the territory availability configuration for a subscription — shows which territories it is available in and whether it is automatically available in new territories.subscriptionId
set_subscription_availabilitySet the territory availability for a subscription.subscriptionId, availableInNewTerritories, territories?
create_subscription_priceSet the price for a subscription in a specific territory.subscriptionId, subscriptionPricePointId, startDate?, preserveCurrentPrice?
list_promotional_offersList all promotional offers configured for a subscription.subscriptionId, limit?
create_promotional_offerCreate a promotional offer for a subscription.subscriptionId, name, offerCode, duration, offerMode, periodCount?, prices?
update_promotional_offerUpdate an existing promotional offer's attributes or prices.promotionalOfferId, name?, offerCode?, duration?, offerMode?, periodCount?, prices?
delete_promotional_offerDelete a promotional offer from a subscription.promotionalOfferId
list_promotional_offer_pricesList the prices set for a promotional offer, with resolved price tier and territory details.promotionalOfferId, limit?

Version Admin & App Review Details

ToolDescriptionParameters
update_app_versionUpdate an App Store version's version string, copyright, release type, or scheduled release date.versionId, versionString?, copyright?, releaseType?, earliestReleaseDate?
delete_app_versionDelete an App Store version.versionId
get_app_version_buildGet the build attached to an App Store version (null when none is attached).versionId
set_app_version_buildAttach a build to an App Store version.versionId, buildId
get_review_detailGet the App Review details for a version: contact, demo account, and review notes.versionId
create_review_detailCreate App Review details for a version that has none. contactFirstName and contactPhone are required.versionId, contactFirstName, contactPhone, contactLastName?, contactEmail?, demoAccountName?, demoAccountPassword?, demoAccountRequired?, notes?
update_review_detailUpdate App Review details (contact, demo account, notes).reviewDetailId, contactFirstName?, contactLastName?, contactPhone?, contactEmail?, demoAccountName?, demoAccountPassword?, demoAccountRequired?, notes?

Release & Export Compliance

ToolDescriptionParameters
get_phased_releaseGet the phased release (gradual rollout) of an App Store version.versionId
create_phased_releaseCreate a phased release for an App Store version.versionId, phasedReleaseState?
update_phased_releaseChange a phased release to ACTIVE, PAUSED, or COMPLETE.phasedReleaseId, phasedReleaseState, confirmReleaseToAll?
delete_phased_releaseDelete a phased release for an App Store version.phasedReleaseId
release_app_versionRelease an App Store version that is approved and waiting for developer release (PENDING_DEVELOPER_RELEASE).versionId
list_encryption_declarationsList export compliance (encryption) declarations for an app.appId, limit?
get_encryption_declarationGet one export compliance (encryption) declaration by ID.declarationId
create_encryption_declarationCreate an export compliance (encryption) declaration for an app.appId, appDescription, containsProprietaryCryptography, containsThirdPartyCryptography, availableOnFrenchStore
assign_builds_to_encryption_declarationLink builds to an encryption declaration.declarationId, buildIds
update_buildUpdate a build's usesNonExemptEncryption flag, its encryption declaration, or expire it.buildId, expired?, confirmExpire?, usesNonExemptEncryption?, appEncryptionDeclarationId?

App Review Submissions

ToolDescriptionParameters
list_review_submissionsList review submissions for an app, optionally filtered by state or platform.appId, state?, platform?, limit?
get_review_submissionGet a review submission with the items it contains.submissionId
create_review_submissionCreate a review submission for one platform of an app.appId, platform
add_review_submission_itemAdd one item to a review submission.submissionId, itemType, itemId
remove_review_submission_itemRemove an item from a review submission.itemId
submit_review_submissionSubmit a review submission to App Review.submissionId, expectedItemIds
cancel_review_submissionCancel a review submission that is in progress.submissionId

App Info: Categories, Age Rating, EULA

ToolDescriptionParameters
get_app_info_categoriesGet the primary and secondary App Store categories and subcategories of an app info record.appInfoId
set_app_categoriesSet one or more App Store categories or subcategories on an app info record.appInfoId, primaryCategoryId?, primarySubcategoryOneId?, primarySubcategoryTwoId?, secondaryCategoryId?, secondarySubcategoryOneId?, secondarySubcategoryTwoId?
list_app_subcategoriesList the subcategories of an App Store category, for example the subcategories of GAMES.categoryId, limit?
get_age_rating_declarationGet the age rating questionnaire answers for an app info record.appInfoId
update_age_rating_declarationUpdate age rating questionnaire answers.declarationId, attributes
create_app_info_localizationCreate an app info localization (name, subtitle, privacy links) for a locale.appInfoId, locale, name, subtitle?, privacyPolicyUrl?, privacyChoicesUrl?, privacyPolicyText?
delete_app_info_localizationDelete an app info localization.localizationId
get_eulaGet the custom end user license agreement for an app.appId
create_eulaCreate a custom end user license agreement for an app, applied to the given territories (e.g.appId, agreementText, territories
update_eulaUpdate an app's custom EULA text and/or territories.eulaId, agreementText?, territories?
delete_eulaDelete an app's custom end user license agreement.eulaId

Media: Screenshot Sets, App Previews, Review Screenshots

ToolDescriptionParameters
create_screenshot_setCreate a screenshot set for one device display size in an App Store version localization.localizationId, screenshotDisplayType
delete_screenshot_setDelete a screenshot set and every screenshot in it.screenshotSetId
delete_screenshotDelete one screenshot from its screenshot set.screenshotId
reorder_screenshotsSet the display order of the screenshots in a set. screenshotIds must list every current screenshot in the set exactly once, in the new order; get the IDs with list_screenshots.screenshotSetId, screenshotIds
list_preview_setsList the app preview sets (one per device type) in an App Store version localization.localizationId, limit?
create_preview_setCreate an app preview set for one device type in an App Store version localization.localizationId, previewType
delete_preview_setDelete an app preview set and every app preview in it.previewSetId
list_previewsList the app previews (videos) in an app preview set.previewSetId, limit?
upload_app_previewUpload a .mov, .m4v, or .mp4 video as an app preview.previewSetId, filePath, fileName?, previewFrameTimeCode?, waitForProcessing?
delete_app_previewDelete one app preview from its preview set.previewId
reorder_previewsSet the display order of the app previews in a preview set. previewIds must list every current preview in the set exactly once, in the new order; get the IDs with list_previews.previewSetId, previewIds
upload_subscription_review_screenshotUpload the App Review screenshot for a subscription from a local file.subscriptionId, filePath, fileName?
upload_iap_review_screenshotUpload the App Review screenshot for an in-app purchase from a local file.inAppPurchaseId, filePath, fileName?

TestFlight Groups

ToolDescriptionParameters
get_beta_groupGet a beta group's settings, including its public TestFlight link.betaGroupId
create_beta_groupCreate a beta group for an app.appId, name, isInternalGroup?, hasAccessToAllBuilds?, publicLinkEnabled?, publicLinkLimitEnabled?, publicLinkLimit?, feedbackEnabled?
update_beta_groupUpdate a beta group's settings.betaGroupId, name?, publicLinkEnabled?, publicLinkLimitEnabled?, publicLinkLimit?, feedbackEnabled?, iosBuildsAvailableForAppleSiliconMac?, iosBuildsAvailableForAppleVision?
delete_beta_groupDelete a beta group.betaGroupId
list_beta_group_buildsList the builds available to a beta group.betaGroupId, limit?
add_builds_to_beta_groupMake one or more builds available to a beta group.betaGroupId, buildIds
remove_builds_from_beta_groupRemove one or more builds from a beta group.betaGroupId, buildIds
add_testers_to_beta_groupAdd existing beta testers to a beta group by tester ID.betaGroupId, betaTesterIds
delete_beta_testerDelete a beta tester from the account.betaTesterId
invite_beta_testerSend an existing beta tester an invitation to test an app.appId, betaTesterId

TestFlight Builds & Beta Review

ToolDescriptionParameters
list_beta_build_localizationsList the TestFlight 'What to Test' notes for a build, one per locale.buildId, limit?
create_beta_build_localizationAdd 'What to Test' notes for a build in one locale.buildId, locale, whatsNew?
update_beta_build_localizationReplace the 'What to Test' notes of a build localization.localizationId, whatsNew
delete_beta_build_localizationDelete the 'What to Test' notes of a build for one locale.localizationId
list_beta_app_localizationsList the TestFlight app details (description, feedback email, URLs) for an app, one per locale.appId, limit?
create_beta_app_localizationAdd TestFlight app details for an app in one locale.appId, locale, description?, feedbackEmail?, marketingUrl?, privacyPolicyUrl?, tvOsPrivacyPolicy?
update_beta_app_localizationUpdate the TestFlight app details for one locale.localizationId, description?, feedbackEmail?, marketingUrl?, privacyPolicyUrl?, tvOsPrivacyPolicy?
delete_beta_app_localizationDelete the TestFlight app details for one locale.localizationId
get_beta_app_review_detailGet the TestFlight beta App Review details for an app: contact, demo account, and notes.appId
update_beta_app_review_detailUpdate the TestFlight beta App Review details (contact, demo account, notes).reviewDetailId, contactFirstName?, contactLastName?, contactPhone?, contactEmail?, demoAccountName?, demoAccountPassword?, demoAccountRequired?, notes?
submit_build_for_beta_reviewSubmit a build to TestFlight beta App Review so it can be shared with external testers.buildId
list_beta_review_submissionsList the TestFlight beta App Review submissions for a build, optionally filtered by review state.buildId, betaReviewState?, limit?
get_build_beta_detailGet the TestFlight settings and processing states for a build (auto-notify, internal and external state).buildId
update_build_beta_detailTurn automatic tester notifications on or off for a build.buildBetaDetailId, autoNotifyEnabled
list_pre_release_versionsList the TestFlight pre-release versions (version string and platform) of an app.appId, limit?

Customer Reviews

ToolDescriptionParameters
list_customer_reviewsList customer reviews for an app, each with its developer response when one exists.appId, rating?, territory?, sort?, hasResponse?, limit?
get_customer_reviewGet one customer review by ID, including its developer response when one exists.reviewId
get_review_responseGet the developer response to a customer review (null when there is none).reviewId
create_review_responsePublish a developer response to a customer review.reviewId, responseBody
delete_review_responseDelete a developer response to a customer review.responseId

Subscription Offers (Introductory & Win-Back)

ToolDescriptionParameters
list_introductory_offersList introductory offers for a subscription, with territory and price point IDs.subscriptionId, territoryId?, limit?
create_introductory_offerCreate an introductory offer for a subscription in one territory.subscriptionId, duration, offerMode, numberOfPeriods, startDate?, endDate?, targetSubscriptionPlanType?, territoryId?, pricePointId?
update_introductory_offerChange the end date of an introductory offer.introductoryOfferId, endDate
delete_introductory_offerDelete an introductory offer by ID.introductoryOfferId
list_win_back_offersList win-back offers for a subscription.subscriptionId, limit?
create_win_back_offerCreate a win-back offer for lapsed subscribers, with one price entry per territory.subscriptionId, referenceName, offerId, duration, offerMode, periodCount, customerEligibilityPaidSubscriptionDurationInMonths, customerEligibilityTimeSinceLastSubscribedInMonths, startDate, priority, prices, customerEligibilityWaitBetweenOffersInMonths?, endDate?, promotionIntent?, targetSubscriptionPlanType?
update_win_back_offerUpdate a win-back offer's eligibility, dates, priority, or promotion intent.winBackOfferId, customerEligibilityPaidSubscriptionDurationInMonths?, customerEligibilityTimeSinceLastSubscribedInMonths?, customerEligibilityWaitBetweenOffersInMonths?, startDate?, endDate?, priority?, promotionIntent?
delete_win_back_offerDelete a win-back offer by ID.winBackOfferId
list_win_back_offer_pricesList the per-territory prices of a win-back offer, with territory and price point IDs.winBackOfferId, territoryId?, limit?

Subscription Offer Codes

ToolDescriptionParameters
list_subscription_offer_codesList the offer codes for a subscription, optionally filtered by territory codes such as USA.subscriptionId, territories?, limit?
get_subscription_offer_codeGet one subscription offer code by ID, including its code counts and state.offerCodeId
create_subscription_offer_codeCreate a subscription offer code.subscriptionId, name, customerEligibilities, offerEligibility, duration, offerMode, numberOfPeriods, autoRenewEnabled?, targetSubscriptionPlanType?, prices?
update_subscription_offer_codeActivate or deactivate a subscription offer code.offerCodeId, active
create_subscription_one_time_codesGenerate a batch of one-time use redemption codes for a subscription offer code.offerCodeId, numberOfCodes, expirationDate, environment?
list_subscription_one_time_code_batchesList the one-time use code batches generated for a subscription offer code.offerCodeId, limit?
get_subscription_one_time_code_valuesDownload the redemption codes of a one-time use code batch as CSV, inline or (for large batches) to a new file via savePath.oneTimeUseCodeBatchId, savePath?
create_subscription_custom_codeCreate a custom (vanity) redemption code for a subscription offer code, optionally with an expiration date.offerCodeId, customCode, numberOfCodes, expirationDate?
list_subscription_custom_codesList the custom codes created for a subscription offer code.offerCodeId, limit?

In-App Purchase Offer Codes

ToolDescriptionParameters
list_iap_offer_codesList the offer codes configured for an in-app purchase.inAppPurchaseId, limit?
get_iap_offer_codeGet one in-app purchase offer code by ID.offerCodeId
create_iap_offer_codeCreate an in-app purchase offer code with a price per territory.inAppPurchaseId, name, customerEligibilities, prices
update_iap_offer_codeActivate or deactivate an in-app purchase offer code.offerCodeId, active
create_iap_one_time_codesGenerate a batch of one-time-use redemption codes for an offer code.offerCodeId, numberOfCodes, expirationDate, environment?
list_iap_one_time_code_batchesList the one-time-use code batches generated for an offer code, with counts and expiry dates.offerCodeId, limit?
get_iap_one_time_code_valuesGet the redemption code values of a one-time-use batch as CSV, inline or (for large batches) to a new file via savePath, with the number of non-empty lines.oneTimeUseCodeBatchId, savePath?
create_iap_custom_codeCreate a custom redemption code for an offer code.offerCodeId, customCode, numberOfCodes, expirationDate?
list_iap_custom_codesList the custom redemption codes for an offer code, with redemption counts and expiry dates.offerCodeId, limit?

Custom Product Pages

ToolDescriptionParameters
list_custom_product_pagesList the custom product pages of an app, optionally filtered by visibility.appId, visible?, limit?
get_custom_product_pageGet one custom product page by ID.customProductPageId
create_custom_product_pageCreate a custom product page for an app, with its first version and one localization (the app's primary locale unless locale is given).appId, name, locale?, promotionalText?, deepLink?
update_custom_product_pageUpdate a custom product page's name or visibility.customProductPageId, name?, visible?
delete_custom_product_pageDelete a custom product page by ID.customProductPageId
list_cpp_versionsList the versions of a custom product page, optionally filtered by review state.customProductPageId, states?, limit?
create_cpp_versionCreate a new version of a custom product page, optionally with a deep link.customProductPageId, deepLink?
list_cpp_localizationsList the per-locale localizations of a custom product page version, optionally filtered by locale.versionId, locales?, limit?
create_cpp_localizationAdd a locale with promotional text to a custom product page version.versionId, locale, promotionalText?
update_cpp_localizationSet the promotional text of a custom product page localization.localizationId, promotionalText
delete_cpp_localizationDelete a custom product page localization by ID.localizationId

Usage Examples

List Your Apps

"Show me all my apps in App Store Connect"

Claude will use list_apps to retrieve and display your apps.

Update App Description

"Update the English description for version 2.0 of MyApp to: 'A revolutionary app that simplifies your daily tasks.'"

Claude will:

  1. Find the app using list_apps
  2. Get the version using list_app_versions
  3. Find the English localization using list_version_localizations
  4. Update it using update_version_localization

Add Japanese Localization

"Add Japanese localization to MyApp version 2.0 with description '素晴らしいアプリです' and keywords 'アプリ,便利,簡単'"

Claude will use create_version_localization with locale ja.

Add a Beta Tester

"Add [email protected] as a beta tester to the Internal Testing group for MyApp"

Claude will:

  1. Find the app and beta group using list_beta_groups
  2. Add the tester using add_beta_tester

Set PPP Pricing

"Show me the equivalent prices for my $9.99 tier in India, Brazil, and Turkey"

Claude will:

  1. Find the $9.99 price point using list_app_price_points
  2. Get equivalent prices using get_price_point_equalizations
  3. Show you the PPP-adjusted prices in each territory

"Set my app to $9.99 in the US and use PPP pricing for India and Brazil"

Claude will use set_app_prices with the appropriate price point IDs for each territory.

Create a Lifetime Purchase

"Add a $99.99 lifetime unlock to MyApp with PPP pricing for India and Brazil"

Claude will:

  1. Create a non-consumable IAP with create_in_app_purchase
  2. Add a display name with create_in_app_purchase_localization
  3. Find the $99.99 tier with list_in_app_purchase_price_points, then PPP equivalents with get_in_app_purchase_price_point_equalizations
  4. Apply per-territory pricing with set_in_app_purchase_price and open availability with set_in_app_purchase_availability
  5. Confirm the result with list_in_app_purchase_prices

Check Version Status

"What's the status of all versions of MyApp?"

Claude will use list_app_versions to show version states (PREPARE_FOR_SUBMISSION, IN_REVIEW, READY_FOR_SALE, etc.)

Prepare and Submit a Version

"Set the copyright of MyApp 2.1 to '2026 Example Inc.', attach build 42, add review notes, and submit it for review"

Claude will use update_app_version, set_app_version_build (only VALID builds attach), update_review_detail, then create_review_submission, add_review_submission_item, and submit_review_submission, which refuses if the submission holds anything besides the items you expect.

Anything Without a Dedicated Tool

"Turn on Game Center for MyApp's next version"

Claude will use asc_api_search to find the operation, asc_api_describe to see its body, and asc_api_request to call it.

Security

Credential Handling

  • Private keys are never logged or exposed in error messages
  • JWT tokens are automatically redacted from any error output
  • Issuer ID is redacted from error messages and details; demo account passwords are never returned and are redacted from errors
  • Read-only mode (ASC_READ_ONLY=1) blocks writes in the HTTP client itself, not just in the tool list
  • Generic requests only reach relative /v1-/v3 paths on the App Store Connect host, with .., encoded, and absolute paths rejected; they must match Apple's spec unless allowUnknown is set. Demo account passwords and webhook secrets are masked in responses
  • Offer code CSVs are written only to new files (savePath, owner-only permissions), never over existing ones
  • Token caching minimizes key usage (15-min tokens, refreshed at 10 min)

Path Validation

  • P8 file paths are validated against directory traversal attacks (.. not allowed)
  • Only absolute paths are resolved

Best Practices

  1. Never commit credentials - Use environment variables or a secrets manager
  2. Restrict API key permissions - Use minimal required role (App Manager for most operations)
  3. Rotate keys periodically - Generate new API keys and revoke old ones
  4. Secure your .p8 file - Set file permissions to 600 (owner read/write only)
chmod 600 /path/to/AuthKey.p8

Troubleshooting

"Configuration error: APP_STORE_CONNECT_KEY_ID environment variable is required"

Ensure all required environment variables are set:

  • APP_STORE_CONNECT_KEY_ID
  • APP_STORE_CONNECT_ISSUER_ID
  • APP_STORE_CONNECT_P8_PATH or APP_STORE_CONNECT_P8_CONTENT

"Failed to read private key"

  1. Verify the path in APP_STORE_CONNECT_P8_PATH is correct and absolute
  2. Check file permissions: ls -la /path/to/AuthKey.p8
  3. Ensure the file is a valid .p8 from Apple (starts with -----BEGIN PRIVATE KEY-----)

"Authentication failed"

This usually means:

  1. The API key was revoked in App Store Connect
  2. The Key ID or Issuer ID doesn't match the .p8 file
  3. The .p8 file is corrupted or incomplete

"Rate limit exceeded"

The server includes built-in rate limiting (50 requests/minute). If you hit Apple's limits:

  1. Wait for the indicated retry time
  2. Batch your operations when possible
  3. The server automatically retries with exponential backoff

Tools Not Appearing in Claude

  1. Verify the server is running: check Claude Desktop logs
  2. Ensure the config file path is correct for your OS
  3. Restart Claude Desktop after config changes

Development

Prerequisites

  • Node.js 20+
  • npm or pnpm

Setup

# Clone the repository
git clone https://github.com/SardorbekR/appstore-connect-mcp.git
cd appstore-connect-mcp

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Lint
npm run lint

# Type check
npm run typecheck

Project Structure

src/
├── index.ts          # MCP server entry point
├── auth/
│   └── jwt.ts        # JWT token generation & caching
├── api/
│   ├── client.ts     # HTTP client with retry logic and read-only guard
│   ├── upload.ts     # Shared asset upload (reserve, upload chunks, commit, poll)
│   └── types.ts      # TypeScript interfaces
├── openapi/
│   ├── schema-index.json  # Operation index generated from spec/openapi.oas.json
│   └── index.ts           # Match, search, and describe operations
├── tools/
│   ├── index.ts      # Tool registry (toolsets, read-only filtering)
│   ├── api.tools.ts  # Generic asc_api_* tools
│   ├── apps.tools.ts
│   ├── versions.tools.ts
│   ├── localizations.tools.ts
│   ├── app-info.tools.ts
│   ├── beta.tools.ts
│   ├── screenshots.tools.ts
│   ├── bundle-ids.tools.ts
│   ├── devices.tools.ts
│   ├── users.tools.ts
│   ├── builds.tools.ts
│   ├── categories.tools.ts
│   └── ...           # One file per domain (subscriptions, release, media, ...)
└── utils/
    ├── errors.ts     # Error classes with redaction
    └── validation.ts # Zod schemas

OpenAPI Spec

spec/openapi.oas.json is Apple's App Store Connect OpenAPI spec, pinned (see spec/README.md). Tests check every request a tool sends against it.

npm run check-openapi   # fail if src/openapi/schema-index.json is stale
npm run update-openapi  # download Apple's latest spec and regenerate the index
npx tsx scripts/spec-sheet.ts "PATCH /v1/appInfos/{id}"  # print an operation's resolved shape

Running Locally

# Development mode with auto-reload
npm run dev

# Or run the built version
npm start

Releasing

Releases publish from GitHub Actions (.github/workflows/publish.yml) when a version tag is pushed. npm uses trusted publishing (OIDC, no token, provenance attached) and the MCP Registry uses GitHub OIDC.

  1. Set the new version in package.json and package-lock.json (npm version X.Y.Z --no-git-tag-version), both fields in server.json, and SERVER_VERSION in src/index.ts
  2. Merge to main
  3. git tag vX.Y.Z && git push origin vX.Y.Z

The workflow refuses to publish if any version field differs from the tag, or if typecheck, lint, tests, or the OpenAPI index check fail.

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes and add tests
  4. Run npm test and npm run lint
  5. Submit a pull request

Acknowledgements

The generic API tools, the OpenAPI index format, and several workflow details (review submissions, asset uploads, offer pricing) follow rorkai/App-Store-Connect-CLI (MIT).

License

MIT License - see LICENSE for details.

Links

From the server's repository — third-party content, read it before running anything it suggests.

More in Commerce

Listing from the official MCP Registry · repository facts from GitHub, 2h ago.