app-store-connect-mcp
app-store-connect-mcp
MCP-сервер для обоих коммерческих API Apple — App Store Connect (1263 операции) и App Store Server API / StoreKit 2 (30 операций) — реализованный через пять инструментов, с закрытым ключом в связке ключей macOS и блокировкой опасных запросов за явным подтверждением.
1,293 operations · 5 tools · key never on disk · verified against the live APIsПочему он устроен именно так
Существует несколько MCP-серверов для App Store Connect. Каждый решает часть задачи; этот берёт то, что каждый сделал правильно, и отбрасывает то, что сделано неправильно.
Подход | Сохранено | Отброшено | |
Ручная обёртка | Один MCP-инструмент на эндпоинт | Типизированные, обнаруживаемые аргументы | 70–900 определений инструментов, >100k токенов, устаревают при выходе версии Apple |
Code Mode | LLM пишет JS, сервер выполняет | Два инструмента, ~1k токенов, полное покрытие | Выполнение сгенерированного кода в процессе, содержащем ключ подписи |
Мета-инструменты |
| Тот же выигрыш в контексте, без выполнения кода | — |
Этот сервер использует третий вариант. Покрытие — свойство спецификации Apple, а не того, сколько эндпоинтов кто-то обернул; и модель никогда не получает возможности запускать код внутри процесса, который может изменить ваши цены.
О песочнице
Предпосылка Code Mode в том, что сгенерированный JavaScript безопасно выполняется внутри Node vm. Это не так. Документация Node сама говорит, что vm не является механизмом безопасности, и любой объект хоста, внедрённый как глобальный, возвращает среду хоста через свою собственную цепочку прототипов:
spec.constructor.constructor('return process.env.HOME')() // → /Users/youПроверено на точной репродукции этой песочницы: она возвращает среду хоста. Опция timeout тоже не помогает — она ограничивает только синхронное выполнение, поэтому асинхронный бесконечный цикл выполняется вечно и истощает цикл событий.
Параметризованная диспетчеризация даёт то же покрытие и ту же стоимость токенов без интерпретатора, из которого можно сбежать.
Related MCP server: App Store Connect MCP Server
Учётные данные
Закрытый ключ должен храниться в связке ключей. Apple позволяет скачать .p8 только один раз, а копия в открытом виде на диске — это копия, которая может утечь.
ASC_KEY=keychain:my-asc-key # recommended
ASC_KEY=/path/to/AuthKey.p8 # works, but plaintext
ASC_PRIVATE_KEY='-----BEGIN…' # discouraged: `ps -E` exposes itЭлемент связки ключей может содержать чистый PEM или base64 JSON:
{ "issuerID": "…", "keyID": "…", "privateKeyPEM": "-----BEGIN PRIVATE KEY-----\n…" }Форма конверта предпочтительнее: идентификаторы передаются вместе с ключевым материалом, поэтому ASC_KEY_ID не может рассинхронизироваться с ключом, который он именует — несоответствие, которое проявляется только как непрозрачный 401.
security add-generic-password -s my-asc-key -a api -w "$(
jq -nc --arg i "$ISSUER" --arg k "$KEYID" --arg p "$(cat AuthKey.p8)" \
'{issuerID:$i,keyID:$k,privateKeyPEM:$p}' | base64
)"Установка
git clone https://github.com/abd3lraouf-studios/app-store-connect-mcp
cd app-store-connect-mcp
npm install && npm run build{
"mcpServers": {
"app-store-connect": {
"command": "node",
"args": ["/path/to/app-store-connect-mcp/dist/index.js"],
"env": {
"ASC_KEY": "keychain:my-asc-key",
"ASC_BUNDLE_ID": "com.example.app"
}
}
}
}ASC_BUNDLE_ID требуется только для вызовов App Store Server API — Apple отклоняет токен Server API без утверждения bid.
Инструменты
Инструмент | Назначение |
| Проверить учётные данные, сообщить о доступности и оставшемся бюджете лимита запросов. Запускать первым при любых сбоях — он отделяет плохой ключ от плохого запроса. |
| Поиск по обоим API по ключевому слову, методу, тегу или уровню риска. Возвращает operationId и указывает, к какому инструменту относится каждый. |
| Параметры, схема тела запроса с реальными именами полей, уровень риска. |
| Чтение. Параметры пути и запроса, пагинация, оба API. |
| Всё, что изменяет данные. Подтверждение, |
Чтение и запись — отдельные инструменты, потому что Claude Code игнорирует стандартную аннотацию destructiveHint, но учитывает _meta["anthropic/requiresUserInteraction"] — и этот флаг устанавливается для каждого инструмента. Один диспетчер не мог бы варьировать его для каждой операции. asc_write несёт этот флаг, поэтому запрос на запись запрашивает подтверждение у пользователя даже при bypassPermissions. Это более сильная гарантия, чем внутрипроцессный шлюз, который можно отключить с помощью --no-confirm.
Ресурсы
Справочные материалы, которые модель может целенаправленно подгружать через @asc::
Ресурс | Содержимое |
| Случаи, когда Apple возвращает успешный ответ, означающий не то, чем кажется — пагинация, территории в формате alpha-3, отклонённый |
| Все 90 перечисляемых полей, сгенерированные из спецификации Apple, чтобы не устаревать |
| Что означает каждый уровень риска и насколько он обратим |
| Откуда взялось каждое описание API и когда |
| Хранилище для переполнения — см. ниже |
Результат, слишком большой для возврата в строке, не обрезается. Список сокращается до того, что помещается, указывается факт сокращения и способ сузить запрос, а полный ответ сохраняется как ресурс, который клиент может прочитать, не расходуя контекст. Обрезание сериализованного JSON посередине структуры даёт модели нечто неразбираемое; молчаливое обрезание ещё хуже, потому что частичный список воспринимается как полный.
Подсказки
Четыре рабочих процесса, доступные как /mcp__asc__<name>:
release-readiness · pricing-audit · review-triage · testflight-status
Каждый объединяет несколько вызовов — команда с косой чертой, оборачивающая один запрос, является синонимом, а не рабочим процессом — и каждый содержит ловушки, такие как отклонение sort для customerReviews и то, что текст отзыва является ненадёжным вводом.
Безопасность записи
HTTP-метод — плохой показатель последствий: PATCH /v1/subscriptionPrices и PATCH /v1/appInfos/{id} — оба являются записью, но только один меняет то, что платят клиенты, и ни один не отменяется повторением. Операции имеют уровень риска:
Уровень | Количество | Значение |
| 797 | Без изменений. |
| 238 | Изменяет данные. |
| 61 | Цены, подписки, права доступа. |
| 132 | Удаляет. |
| 12 | Сборки, отправки, что выходит. |
| 12 | Кто может получить доступ к аккаунту. |
| 11 | Сертификаты, идентификаторы, URL обратных вызовов. |
По умолчанию пять нижних уровней возвращают токен подтверждения вместо выполнения. Токен привязан хешем к точной операции, пути, запросу и телу, поэтому его нельзя получить для дешёвого вызова и потратить на дорогой. Он одноразовый и истекает через пять минут.
--read-only block every write --confirm confirm every write
--no-confirm never confirm (default) confirm the five tiers aboveКогда клиент поддерживает elicitation, asc_write напрямую спрашивает человека, показывая метод, путь, тело и уровень. В противном случае он использует токен подтверждения, привязанный хешем к точной операции, пути, запросу и телу, поэтому токен, выданный для дешёвого вызова, нельзя потратить на дорогой. Клиент, который объявляет elicitation, но не обслуживает его, переходит к резервному варианту, а не проходит насквозь. dry_run сообщает точный запрос без его отправки.
Транспорты
node dist/index.js # stdio (default)
node dist/index.js --transport http --http-token "$(openssl rand -hex 32)"HTTP привязывается к 127.0.0.1 и отказывается запускаться без bearer-токена. Этот процесс содержит ключ, который может изменить цены в App Store; он не должен слушать без аутентификации. Привязка не к loopback выдаёт предупреждение и лучше всего сочетается с прокси, завершающим TLS, или SSH-туннелем.
Синхронизация с Apple
npm run fetch:specs # re-download both descriptions
npm run build # recompile the operation index
npm run verify # drift check + live calls against both APIsДва API получаются из разных источников, по необходимости:
App Store Connect — Apple публикует реальный документ OpenAPI 3.0. Он загружается и компилируется в компактный индекс (360 КБ против 3,3 МБ спецификации), чтобы поиск оставался быстрым, а полный документ открывался только для описания одной операции.
App Store Server — Apple не публикует документ OpenAPI; документация — это проза. Авторитетным машиночитаемым описанием является собственный клиент Apple,
apple/app-store-server-library-node, где каждый эндпоинт — это буквальный вызовmakeRequest.fetch:specsизвлекает набор эндпоинтов из этого исходного кода по закреплённому тегу релиза, аverifyсравнивает его с каталогом вsrc/storekit.ts.
Две детали в этом каталоге противоречат тому, что подразумевает документация, и обе имеют значение:
Хосты:
api.storekit.apple.com/api.storekit-sandbox.apple.com. Более старые именаapi.storekit.itunes.apple.comбольше не обслуживают этот API.Путь статуса массового продления подписки упорядочивает свои сегменты как
{productId}/{requestIdentifier}— не наоборот.
Верификация
npm run verify — это операция только для чтения, выполняющая реальные вызовы. Последний запуск:
1. Catalogue drift — src/storekit.ts vs Apple’s client
✓ all 30 Apple endpoints present in the catalogue
✓ no endpoints in the catalogue that Apple does not define
2. App Store Connect API — live
✓ apps_getCollection → 2 apps
✓ apps_getInstance / builds / appStoreVersions → HTTP 200
✓ pagination walked 3 pages
✓ bogus id → structured 404
3. App Store Server API (StoreKit 2) — live
✓ storekit token carries bid; connect token correctly omits it
✓ getTransactionInfo / getAllSubscriptionStatuses / getTransactionHistory v2
→ authenticated and routed (Apple errorCode 4000006)
✓ getNotificationHistory (30d window) → HTTP 200
14 passed, 0 failedЗонды StoreKit используют заведомо неверный идентификатор транзакции. Сигналом является форма ответа: структурированный errorCode от Apple доказывает, что запрос был аутентифицирован и направлен, тогда как 401 доказал бы обратное.
Надёжность
Тайм-ауты и повторные попытки. Чтение повторяется при 408/429/5xx; запись повторяется только при 429, когда Apple отклонила запрос до его обработки. Запись, которая завершилась неоднозначно, сообщается как неоднозначная и никогда не отправляется повторно — дублированный POST хуже, чем сообщённый сбой.
Ограничение скорости. Выполняется с учётом как документированного почасового лимита, так и недокументированного поминутного, и корректируется по собственному заголовку Apple
x-rate-limit, который учитывает других клиентов, использующих тот же ключ.x-request-idвыводится для поддержки Apple.Привязка хоста. Каждый URL, включая курсор пагинации
links.next, проверяется по белому списку трёх хостов API Apple. Курсор — это ввод, предоставленный сервером; слепое следование ему привело бы bearer-токен к любому хосту, который он называет.Формирование ответа.
linksиrelationships, содержащие только ссылки, удаляются,links.nextсохраняется — более чем на 60% меньше на реальном списке ценовых точек.Жизненный цикл. Сервер stdio завершает работу при EOF на stdin и по сигналам, а не остаётся висеть сиротой, удерживающим ключ подписи.
Известные ограничения
Ответы JWS декодируются, но не проверяются. Полезные нагрузки StoreKit приходят подписанными Apple; проверка цепочки требует корневых сертификатов Apple. Декодированные значения появляются в полях
*_decodedи помечаются как непроверенные. Не рассматривайте их как доказательство покупки без проверки подписи.Уровни риска определяются по шаблону из метода и пути. Они намеренно осторожны, но перед записью прочитайте
asc_describe_endpoint, а не полагайтесь только на уровень.Хранение в связке ключей работает только на macOS. В других системах используйте путь к файлу с ограничительными правами доступа.
--no-confirmполностью отключает шлюз. Он существует для CI; это плохой выбор по умолчанию для интерактивного агента.
Лицензия
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables interaction with Apple's App Store Connect API through natural language to manage apps, beta testing, localizations, analytics, sales reports, and CI/CD workflows for iOS and macOS development.3182MIT
- Flicense-qualityDmaintenanceEnables management of App Store Connect apps including registration, listing, IPA upload, store listing updates, and in-app purchase creation via natural language.
- AlicenseAqualityCmaintenanceEnables AI assistants to manage Apple App Store Connect resources like apps, builds, TestFlight, and reviews through natural language.2018MIT
- Alicense-qualityDmaintenanceEnables managing your iOS app's entire lifecycle with natural language through App Store Connect, offering 48 tools across 14 categories for ASO, reviews, analytics, subscriptions, pricing, and more.6MIT
Related MCP Connectors
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
Search, read, and write your Apple Notes from ChatGPT/Claude via a local Mac agent + MCP relay.
Manage your NanoCart store from any AI agent: products, orders, coupons, subscribers, reports.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/abd3lraouf-studios/app-store-connect-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server