testflight-mcp
MCP server for TestFlight and App Store Connect that exposes the App Store Connect API as tools for AI agents, focusing on retrieving beta feedback (screenshots, crash logs) and related app/build/tester data, with read-only operations.
README
testflight-mcp
MCP server for TestFlight and App Store Connect that exposes the App Store Connect API as tools for AI agents.
Its focus is TestFlight beta feedback retrieval — pulling the screenshot feedback (with the tester's comment), crash feedback and crash logs your testers submit — plus the surrounding context an agent needs to make sense of it: apps, builds, beta testers/groups, analytics & sales reports, provisioning, and App Store metadata. It talks only to the official, documented API using a standard App Store Connect API key (ES256 JWT), and is read-only.
It deliberately does not scrape App Store Connect with your Apple ID / password (no headless browser, no internal
irisAPI) and does not send email to testers. Some third-party TestFlight servers do; this one stays on the supported API.
Install
The package is published as
@orellbuehler/testflight-mcp and runs
directly with npx — no clone or build needed:
claude mcp add testflight \
--env ASC_KEY_ID=ABCD123456 \
--env ASC_ISSUER_ID=12a3b456-7890-1234-5678-9abcdef01234 \
--env ASC_PRIVATE_KEY_PATH=/path/to/AuthKey_ABCD123456.p8 \
-- npx -y @orellbuehler/testflight-mcp
For any other MCP client, run the package directly — npx -y @orellbuehler/testflight-mcp with the
env vars below set. Requires Node.js 20+.
Getting an API key
The server authenticates with an App Store Connect API key (a .p8 file plus a key ID and issuer
ID), the same credentials fastlane/altool use:
- In App Store Connect, go to Users and Access → Integrations → App Store Connect API (Team Keys).
- Generate a key. A role of App Manager (or Admin) covers TestFlight feedback; Finance is additionally required for sales/finance reports.
- Download the
AuthKey_XXXXXXXXXX.p8(you can only download it once — keep it safe), and note the Key ID and the team Issuer ID shown above the keys table.
Provide the key either as a file path (ASC_PRIVATE_KEY_PATH) or inline (ASC_PRIVATE_KEY, newlines
may be escaped as \n). The key is read locally and used only to sign short-lived request tokens.
Configuration
| Variable | Required | Description |
|---|---|---|
ASC_KEY_ID |
yes | App Store Connect API Key ID. |
ASC_ISSUER_ID |
yes | App Store Connect API Issuer ID (per team). |
ASC_PRIVATE_KEY_PATH |
yes* | Path to the downloaded .p8 private key file. |
ASC_PRIVATE_KEY |
yes* | The .p8 contents inline (alternative to the path; \n escapes are unescaped). |
ASC_VENDOR_NUMBER |
no | Vendor number; required only for download_sales_report / download_finance_report. |
* Provide either ASC_PRIVATE_KEY_PATH or ASC_PRIVATE_KEY.
Usage with Claude Code
Add the server to ~/.claude/settings.json (or a project .mcp.json):
{
"mcpServers": {
"testflight": {
"command": "npx",
"args": ["-y", "@orellbuehler/testflight-mcp"],
"env": {
"ASC_KEY_ID": "ABCD123456",
"ASC_ISSUER_ID": "12a3b456-7890-1234-5678-9abcdef01234",
"ASC_PRIVATE_KEY_PATH": "/path/to/AuthKey_ABCD123456.p8"
}
}
}
}
If you built from source instead, use "command": "node" with
"args": ["/path/to/testflight-mcp/dist/index.js"]. Restart Claude Code and verify with
claude mcp list (should show testflight ✓ connected) or /mcp inside a session.
Example prompts
Once connected, ask the agent things like:
- "List the latest TestFlight screenshot feedback for my app and summarize the recurring complaints."
- "Show crash feedback for build 1.4.0 and download the crash log for the most recent one."
- "Which beta testers reported feedback this week, and what devices/OS versions were they on?"
- "Pull this month's sales summary as CSV."
Tools
Start from list_apps to get an app_id, then drill into feedback. All tools are read-only.
TestFlight feedback
| Tool | Description |
|---|---|
list_screenshot_feedback |
Screenshot feedback for an app: tester comment, screenshot URLs, device/OS, tester, build. Filter by build/platform/device/OS/tester. |
list_crash_feedback |
Crash feedback for an app: comment, device/OS, tester, build, crash-log reference. |
get_screenshot_feedback |
One screenshot submission; optionally returns the first screenshot inline as an image. |
get_crash_feedback |
One crash submission with full metadata and crash-log reference. |
get_crash_log |
Download the crash log text for a crash submission. |
Apps & builds
| Tool | Description |
|---|---|
list_apps |
Apps in the account (id, name, bundleId, sku). Filter by bundle ID. |
get_app |
One app by ID. |
list_builds |
TestFlight builds for an app (version, processing state, expiry). |
get_build |
One build with its pre-release version. |
list_customer_reviews |
Public App Store reviews for a released app (distinct from beta feedback). |
Beta testers & groups
| Tool | Description |
|---|---|
list_beta_groups |
Beta groups for an app (internal/external, public link, feedback enabled). |
list_beta_testers |
Beta testers (name, email, invite type, state). Filter by app/group/email. |
list_group_testers |
Testers in a specific beta group. |
Analytics & reports
| Tool | Description |
|---|---|
create_analytics_report_request |
Request an analytics report (the required first step). Returns a request ID. |
list_analytics_reports |
Reports available for a request, optionally filtered by category. |
list_analytics_report_segments |
Downloadable segments of a report (presigned URLs). |
download_analytics_report_segment |
Download + decompress a segment to CSV/TSV text. |
download_sales_report |
Sales & Trends report as CSV (needs ASC_VENDOR_NUMBER). |
download_finance_report |
Financial report as CSV (needs ASC_VENDOR_NUMBER and a region code). |
Provisioning & devices
| Tool | Description |
|---|---|
list_devices |
Registered devices (name, platform, UDID, status). |
list_certificates |
Signing certificates (type, name, serial, expiry). |
list_profiles |
Provisioning profiles with their bundle ID. |
list_bundle_ids |
Registered bundle IDs (identifier, name, platform). |
App metadata & localizations
| Tool | Description |
|---|---|
list_app_store_versions |
App Store versions for an app (version, platform, state). |
list_app_store_version_localizations |
Per-locale metadata (description, keywords, what's new, URLs). |
get_app_store_version_localization |
One localization by ID. |
Notes & caveats
- Read-only. The server cannot add/remove testers, edit metadata, or submit apps. The only
POSTiscreate_analytics_report_request, which requests an analytics snapshot so the data can be read; it does not change your app. - TestFlight feedback requires builds uploaded with feedback enabled and is retained by Apple for
a limited window (~90 days). The tester's typed comment is the
commentfield on a screenshot submission. - Crash logs are resolved from the submission's crash-log URL and downloaded as text. If Apple
exposes no download URL for a given submission,
get_crash_logreturns the raw attributes so you can see what's available. - Reports (
download_sales_report/download_finance_report) are gzipped CSV decompressed for you, and need the Finance role on the API key plusASC_VENDOR_NUMBER. - Your data goes to the agent/LLM. Feedback includes tester names, emails and device details. Use an API key scoped to the access you actually want.
Development
npm install
npm run build # tsc -> dist/
npm test # vitest run
npm run typecheck # tsc --noEmit
npm run lint # eslint src
npm run format:check # prettier --check .
Run a single test file:
npx vitest run src/__tests__/feedback.test.ts
CI / Releasing
- CI (
.github/workflows/ci.yml) runs on every push tomainand on pull requests:format:check,lint,typecheck(once) andtest+buildon Node 20 and 22. - Publish (
.github/workflows/publish.yml) runs when a GitHub Release is published. It builds, tests, and publishes to npm using trusted publishing (OIDC) — noNPM_TOKENsecret required, with provenance generated automatically. It skips publishing if that version is already on npm.
Cut a release:
npm version patch # bumps package.json + creates a vX.Y.Z tag (use minor/major as needed)
git push --follow-tags
gh release create "v$(node -p "require('./package.json').version")" --generate-notes
License
MIT © Orell Bühler
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。