Skip to main content
Glama

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, сервер выполняет eval

Два инструмента, ~1k токенов, полное покрытие

Выполнение сгенерированного кода в процессе, содержащем ключ подписи

Мета-инструменты

searchcall с параметрами

Тот же выигрыш в контексте, без выполнения кода

Этот сервер использует третий вариант. Покрытие — свойство спецификации 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.

Инструменты

Инструмент

Назначение

asc_status

Проверить учётные данные, сообщить о доступности и оставшемся бюджете лимита запросов. Запускать первым при любых сбоях — он отделяет плохой ключ от плохого запроса.

asc_search_endpoints

Поиск по обоим API по ключевому слову, методу, тегу или уровню риска. Возвращает operationId и указывает, к какому инструменту относится каждый.

asc_describe_endpoint

Параметры, схема тела запроса с реальными именами полей, уровень риска.

asc_call

Чтение. Параметры пути и запроса, пагинация, оба API.

asc_write

Всё, что изменяет данные. Подтверждение, dry_run, оба API.

Чтение и запись — отдельные инструменты, потому что Claude Code игнорирует стандартную аннотацию destructiveHint, но учитывает _meta["anthropic/requiresUserInteraction"] — и этот флаг устанавливается для каждого инструмента. Один диспетчер не мог бы варьировать его для каждой операции. asc_write несёт этот флаг, поэтому запрос на запись запрашивает подтверждение у пользователя даже при bypassPermissions. Это более сильная гарантия, чем внутрипроцессный шлюз, который можно отключить с помощью --no-confirm.

Ресурсы

Справочные материалы, которые модель может целенаправленно подгружать через @asc::

Ресурс

Содержимое

asc://cookbook

Случаи, когда Apple возвращает успешный ответ, означающий не то, чем кажется — пагинация, территории в формате alpha-3, отклонённый sort, сжатые отчёты

asc://enums

Все 90 перечисляемых полей, сгенерированные из спецификации Apple, чтобы не устаревать

asc://risk

Что означает каждый уровень риска и насколько он обратим

asc://sources

Откуда взялось каждое описание API и когда

asc-response://…

Хранилище для переполнения — см. ниже

Результат, слишком большой для возврата в строке, не обрезается. Список сокращается до того, что помещается, указывается факт сокращения и способ сузить запрос, а полный ответ сохраняется как ресурс, который клиент может прочитать, не расходуя контекст. Обрезание сериализованного JSON посередине структуры даёт модели нечто неразбираемое; молчаливое обрезание ещё хуже, потому что частичный список воспринимается как полный.

Подсказки

Четыре рабочих процесса, доступные как /mcp__asc__<name>:

release-readiness · pricing-audit · review-triage · testflight-status

Каждый объединяет несколько вызовов — команда с косой чертой, оборачивающая один запрос, является синонимом, а не рабочим процессом — и каждый содержит ловушки, такие как отклонение sort для customerReviews и то, что текст отзыва является ненадёжным вводом.

Безопасность записи

HTTP-метод — плохой показатель последствий: PATCH /v1/subscriptionPrices и PATCH /v1/appInfos/{id} — оба являются записью, но только один меняет то, что платят клиенты, и ни один не отменяется повторением. Операции имеют уровень риска:

Уровень

Количество

Значение

READ

797

Без изменений.

WRITE

238

Изменяет данные.

REVENUE

61

Цены, подписки, права доступа.

DESTRUCTIVE

132

Удаляет.

RELEASE

12

Сборки, отправки, что выходит.

ACCESS

12

Кто может получить доступ к аккаунту.

INFRASTRUCTURE

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

F
license - not found
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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