Skip to main content
Glama
max-rousseau

asc-feedback-mcp

by max-rousseau

asc-feedback-mcp

An MCP (Model Context Protocol) server that exposes App Store Connect TestFlight beta feedback — screenshot submissions, crash submissions, crash logs, and screenshot downloads — as tools for MCP-capable clients. It authenticates to the App Store Connect API with a short-lived ES256 JWT minted from your .p8 API key, so an assistant can pull and triage beta-tester feedback without you ever pasting raw credentials into a conversation. The server runs in Docker and speaks streamable-HTTP MCP at http://127.0.0.1:8081/mcp.

Features

  • 4 tools available for listing and inspecting TestFlight beta feedback and downloading feedback screenshots.

  • Streamable-HTTP MCP transport, served at http://127.0.0.1:8081/mcp.

  • Docker-based deployment via docker compose — no local Python environment needed.

  • Binds to 127.0.0.1 only; the service is unauthenticated and must never be exposed beyond the local machine.

Related MCP server: xcode-cloud-mcp

Architecture

classDiagram
    class Config {
        +str key_id
        +str issuer_id
        +str private_key
    }
    class AscClient {
        -str _token
        -float _token_exp
        -_bearer_token() str
        +list_screenshot_feedback(asc_app_id, limit) dict
        +list_crash_feedback(asc_app_id, limit) dict
        +get_crash_log(submission_id) dict
    }
    class Server {
        +list_screenshot_feedback(asc_app_id, limit) dict
        +list_crash_feedback(asc_app_id, limit) dict
        +get_crash_log(submission_id) dict
        +download_screenshot(url) Image
    }
    Server --> AscClient : calls
    AscClient --> Config : reads credentials
sequenceDiagram
    participant Client as MCP Client
    participant Server as FastMCP server
    participant ASCClient as AscClient
    participant ASC as App Store Connect API

    Client->>Server: call tool (e.g. list_crash_feedback)
    Server->>Server: validate parameters
    Server->>ASCClient: forward request
    ASCClient->>ASCClient: reuse cached ES256 JWT (mint only if near expiry)
    ASCClient->>ASC: GET request with Bearer JWT
    ASC-->>ASCClient: JSON response
    ASCClient-->>Server: parsed result
    Server-->>Client: tool result

Usage

The server speaks MCP over streamable-http at:

http://127.0.0.1:8081/mcp

Tools

Tool

Parameters

Description

list_screenshot_feedback

asc_app_id: str, limit: int = 50

List the most recent TestFlight screenshot feedback submissions for an app. Returns raw App Store Connect API JSON. asc_app_id is the app's numeric Apple ID.

list_crash_feedback

asc_app_id: str, limit: int = 50

List the most recent TestFlight crash feedback submissions for an app. Returns raw App Store Connect API JSON. asc_app_id is the app's numeric Apple ID.

get_crash_log

submission_id: str

Fetch the crash log for one crash feedback submission. Returns raw App Store Connect API JSON (.data.attributes.logText holds the log).

download_screenshot

url: str

Download a TestFlight feedback screenshot and return it as image content. Host validation is best-effort: requires https and an Apple-owned hostname.

asc_app_id must contain digits only, and limit must be between 1 and 200 inclusive. submission_id may only contain letters, digits, and dashes.

Example MCP client config

{
  "mcpServers": {
    "asc-feedback": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:8081/mcp"
    }
  }
}

Or with Claude Code:

claude mcp add --transport http asc-feedback http://127.0.0.1:8081/mcp

The host port (8081) is configurable in docker-compose.yaml, but the bind address must always keep the 127.0.0.1: prefix — never change it to 0.0.0.0 or otherwise expose it publicly.

Getting Started

Prerequisites

  • Docker Desktop or Docker Engine with Docker Compose.

  • An App Store Connect API key.

Get an App Store Connect API key

In App Store Connect, go to Users and Access → Integrations → App Store Connect API (Team Keys) and generate a key there. This gives you the Issuer ID (shown at the top of that page), the Key ID (in the keys table), and a downloadable .p8 private key file (e.g. AuthKey_ABC123DEFG.p8) — save this file, as Apple only lets you download it once.

Value

Where it comes from

ASC_KEY_ID

Users and Access → Integrations → App Store Connect API, keys table

ASC_ISSUER_ID

Users and Access → Integrations → App Store Connect API, shown at the top of the page

ASC_PRIVATE_KEY_B64

Base64 of the .p8 file downloaded when creating the key above

asc_app_id (tool parameter)

Apps → (your app) → App Information → General Information → Apple ID

Steps

  1. Clone this repository.

  2. Copy the environment template:

    cp .env.example .env
  3. Edit .env and fill in:

    • ASC_KEY_ID — the API key id from Integrations.

    • ASC_ISSUER_ID — the issuer id from Integrations.

    • ASC_PRIVATE_KEY_B64 — the base64-encoded contents of your .p8 file, produced with:

      base64 -i AuthKey_XXXX.p8 | tr -d '\n'
  4. Build and start the server:

    docker compose up -d --build
  5. Verify it's running by initializing an MCP session against the endpoint:

    curl -i http://127.0.0.1:8081/mcp \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"verify","version":"1.0"}}}'

    Alternatively, add the server to an MCP client using the example config above, and confirm all 4 tools (list_screenshot_feedback, list_crash_feedback, get_crash_log, download_screenshot) appear.

Security

This service implements no authentication. It binds to 127.0.0.1 only and must never be exposed on 0.0.0.0 or any public/non-loopback interface — anyone who can reach the port can pull your beta feedback using your App Store Connect credentials.

Related MCP Connectors

Related MCP Servers