app-store-connect-mcp
This MCP server lets Claude (or any MCP client) operate an App Store Connect account without exposing pricing keys, covering 1,293 Apple API operations and StoreKit 2 through 13 tools.
Verify setup –
asc_statuschecks credentials, reachability, and remaining rate-limit budget.Discover anything –
asc_search_endpointsfinds operations by keyword, method, tag, or risk tier across both Apple APIs;asc_describe_endpointshows full parameters, body schema, and risk.Read Apple data –
asc_callperforms read-only calls with pagination, filters, sparse fieldsets, and StoreKit environment support.Write safely –
asc_writehandles creates, updates, and deletes, with dry-run validation, risk-tier confirmation, and a--read-only/--no-confirmmode.Manage pricing –
asc_pricing_getreads subscription pricing with territory currencies resolved;asc_pricing_setchanges prices while forcing thepreserve_current_pricedecision into the open.Check release readiness –
asc_preflight_versionreturns GO/NO-GO across build state, export compliance, localisations, screenshots, review contact, and open submissions.Handle screenshots –
asc_listing_screenshotslists sets/states;asc_upload_screenshotandasc_upload_iap_screenshotperform the full reserve–upload–commit sequence.Fetch analytics –
asc_analytics_reportwalks the report chain, downloads signed URLs, gunzips TSV rows, and stitches every segment — while refusing to create ongoing report requests.Control availability –
asc_availability_settoggles an app on/off per territory, re-reading results to confirm the store matches the request.Stay current with Apple – weekly spec re-fetching and generated enum tables keep operation coverage aligned with Apple's API.
Provides tools to interact with Apple's App Store Connect and App Store Server (StoreKit 2) APIs, enabling management of apps, pricing, subscriptions, reviews, builds, and TestFlight across both commerce APIs.
Integrates with Apple's App Store Connect and App Store Server API to manage app store operations including app metadata, pricing, subscriptions, submissions, and analytics.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@app-store-connect-mcpList my apps"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
App Store Connect MCP Server
Give Claude your App Store Connect account without giving it the keys to your pricing. An MCP server covering the App Store Connect API and the App Store Server API (StoreKit 2) — 1,293 operations behind 13 tools, for Claude Code, Claude Desktop, Cursor and anything else that speaks Model Context Protocol.
1,293 operations · 13 tools · key never on disk · Apple signatures verifiedflowchart LR
A["Claude<br/>Cursor · any MCP client"] -->|"search · call · write"| B["app-store-connect-mcp<br/>13 tools"]
B --> C{"risk tier"}
C -->|"READ · 811 ops"| D["Apple<br/>App Store Connect API"]
C -->|"WRITE · 482 ops"| E["ask a human first"]
E -->|approved| D
E -->|declined| F["nothing is sent"]
B --> G["App Store Server API<br/>StoreKit 2 · signatures verified"]
style E fill:#ffe8b3,stroke:#c98a00,color:#000
style F fill:#ffd6d6,stroke:#c00,color:#000
style D fill:#d6f5d6,stroke:#2a2,color:#000
style G fill:#d6f5d6,stroke:#2a2,color:#000Don't install this
Genuinely. There are cheaper ways to spend your afternoon, and several kinds of person should close the tab now:
You want an agent that just does things. This one stops and asks before it changes a price, deletes anything, or touches who can access your account — and it asks you, not itself. If that sounds like friction, it is. That is the product.
You want every endpoint as its own tool. Some servers register 890. Yours would spend six figures of context on tool definitions before answering a single question. This registers 11 and finds the rest by searching.
tool definitions loaded into context, before you ask anything
one tool per endpoint ███████████████████████████████████ >100k tokens
this server ▌ ~1k tokensYou're on Windows or Linux and wanted Keychain. Keychain storage is macOS only. You can use a file path elsewhere, but the best part of this is macOS-shaped.
You want it to write your App Store copy. It will fetch your reviews and your localisations. It will not invent marketing prose and push it live, and there is no flag to make it.
You're evaluating this for a product you sell. Read the licence first. Internal use is free; reselling it isn't.
Still here? Then the rest is probably for you.
Related MCP server: App Store Connect MCP Server
What it refuses to do
Most of the engineering here went into restraint, so it is the honest place to start.
It won't run generated code. The elegant way to cover a huge API is to let
the model write JavaScript and eval it in a sandbox. Node's vm is not a
sandbox — its own documentation says so — and any host object handed in leaks
the whole realm back through its prototype chain:
spec.constructor.constructor('return process.env.HOME')() // → /Users/youThat is a reproduction of a real shipping MCP server's sandbox, and it returns
your home directory. Its 15-second timeout doesn't help either: it bounds only
synchronous code, so an async loop runs forever. This server dispatches
parameters, not code. Same coverage, same token cost, nothing to escape.
It won't let a write pretend to be a read. Reads and writes are separate
tools. asc_write carries _meta["anthropic/requiresUserInteraction"], which
Claude Code honours even under bypassPermissions. The model cannot talk
its way past it; only the operator can, by starting the server with
--no-confirm — which drops the flag, the prompt and the token together, for
runs where nobody is present to answer.
It won't decide your pricing intent for you. preserve_current_price is a
required parameter with no default. Apple defaults it to false — meaning your
existing subscribers get moved to the new price. Making it required forces that
decision into the open, where a person can see it.
It won't create ongoing commitments to answer a question. Fetching analytics
needs a report request, and accessType: ONGOING is a standing obligation on
your account, not a query. The tool reads reports; it will not create one
silently.
It won't pretend it sanitised your reviews. Customer review text is written by strangers and lands in your model's context verbatim. Results carrying it lead with a note saying it is data to report on, not instructions to follow. It is deliberately not filtered for injection phrases — that is a game attackers iterate against, and passing such a filter would imply a safety it cannot deliver.
It won't tell you a signature is fine when it hasn't checked. See below.
Install
Claude Code, one line:
claude mcp add --scope user app-store-connect \
--env ASC_KEY=keychain:my-asc-key \
--env ASC_BUNDLE_ID=com.example.app \
--env ASC_APP_APPLE_ID=1234567890 \
-- npx -y @abd3lraouf/app-store-connect-mcpNothing to clone or build. Or from source, if you'd rather read it first:
git clone https://github.com/abd3lraouf-studios/app-store-connect-mcp
cd app-store-connect-mcp && npm install && npm run buildOr, for Claude Desktop, Cursor and friends:
{
"mcpServers": {
"app-store-connect": {
"command": "npx",
"args": ["-y", "@abd3lraouf/app-store-connect-mcp"],
"env": {
"ASC_KEY": "keychain:my-asc-key",
"ASC_BUNDLE_ID": "com.example.app",
"ASC_APP_APPLE_ID": "1234567890"
}
}
}
}Then ask it "check the App Store Connect connection" — that runs asc_status,
which verifies your credentials with one lightweight request and tells you
exactly what is missing if anything is.
Your key belongs in the Keychain
Apple lets you download a .p8 exactly once. A plaintext copy on disk is a
copy that can leak.
ASC_KEY=keychain:my-asc-key # recommended
ASC_KEY=/path/to/AuthKey.p8 # works, but plaintext
ASC_PRIVATE_KEY='-----BEGIN…' # discouraged: ps -E exposes itStore it as base64 JSON so the identifiers travel with the key material —
ASC_KEY_ID then cannot drift out of sync with the key it names, a mismatch
that surfaces only as an opaque 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
)"The thirteen tools
Five core, covering everything:
Tool | |
| Credentials, reachability, remaining rate-limit budget. Run this first when anything fails — it separates a bad key from a bad request. |
| Search 1,293 operations across both APIs by keyword, method, tag or risk tier. |
| Parameters, request-body schema with real field names, risk tier. |
| Reads. Path and query parameters, pagination, both APIs. |
| Everything that changes data. Confirmation, |
Eight composite, for chains the raw API cannot express in a single call. A
tool that merely saved one request was left out — it would need keeping in step
with Apple forever and buys nothing asc_call doesn't already do:
Tool | What it collapses |
| ~175 lookups → a handful, for subscriptions and one-time purchases. The currency lives on the territory, not the price row, so reading prices by hand gives ambiguous numbers. |
| The same chain plus the write, with the subscriber decision forced into the open. |
| Six resources → GO / NO-GO, each gap naming the operation that fixes it. |
| A request per locale → four, via |
| Apple's reserve → PUT-at-offsets → commit-with-MD5 sequence, across two hosts. |
| The same sequence for an in-app purchase's review screenshot — the field that keeps an IAP in |
| One PATCH per territory (up to 175; Apple has no bulk endpoint), then re-reads every one and reports what did not take. |
| Five hops → signed URL → gunzip → rows, with every segment stitched. |
Apple's asset flow spans two hosts and ends in a checksum that fails silently
if you get it wrong — the upload simply sits in AWAITING_UPLOAD looking like
nothing happened. uploadOperations appears in Apple's OpenAPI document only as
a value in a fields[] enum, so an agent reading the spec can see the field
exists and still have no idea it must act on it.
sequenceDiagram
participant M as Claude
participant S as this server
participant A as App Store Connect
participant U as Apple asset host
M->>S: asc_upload_screenshot(set, file)
S->>A: POST /v1/appScreenshots (fileName, fileSize)
A-->>S: id + uploadOperations[]
loop each byte range
S->>U: PUT bytes at offset, Apple's headers
Note over S,U: pre-signed URL — no bearer token sent
end
S->>A: PATCH uploaded=true + MD5 checksum
A-->>S: assetDeliveryState
S-->>M: state, and how to clean up if it failedPlus four resources (@asc:cookbook, @asc:enums, @asc:risk,
@asc:sources) and four workflows as slash commands:
/mcp__asc__release-readiness, pricing-audit, review-triage,
testflight-status.
Write safety
An HTTP method is a poor proxy for consequence. PATCH /v1/subscriptionPrices
and PATCH /v1/appInfos/{id} are both writes; only one changes what customers
are charged, and neither is undone by repeating it. So every operation carries a
tier (counts are App Store Connect; StoreKit 2 adds 14 reads and 16 writes):
Tier | Count | |
| 797 | No change. |
| 238 | Changes data. |
| 61 | Pricing, subscriptions, entitlements. |
| 132 | Deletes. |
| 12 | Builds, submissions, what ships. |
| 12 | Who can reach the account. |
| 11 | Certificates, identifiers, callback URLs. |
flowchart TD
A["asc_write called"] --> B{"--read-only?"}
B -->|yes| Z["blocked"]
B -->|no| N{"--no-confirm?"}
N -->|yes| S["send it"]
N -->|no| C{"risk tier"}
C -->|"WRITE"| S["send it"]
C -->|"REVENUE · DESTRUCTIVE<br/>INFRASTRUCTURE · ACCESS · RELEASE"| D{"client supports<br/>elicitation?"}
D -->|yes| E["ask the person<br/>method · path · body · tier"]
D -->|no| F["issue a token<br/>hash-bound to this exact request"]
E -->|accepted| S
E -->|declined| Z
F --> G["caller repeats the call<br/>with the token"]
G --> S
style Z fill:#ffd6d6,stroke:#c00,color:#000
style E fill:#ffe8b3,stroke:#c98a00,color:#000
style F fill:#ffe8b3,stroke:#c98a00,color:#000
style S fill:#d6f5d6,stroke:#2a2,color:#000The bottom five ask before running. Where your client supports elicitation, it asks you directly, showing the method, path, body and tier. Otherwise it issues a confirmation token bound by hash to the exact operation, path, query and body — so one obtained for a cheap call cannot be spent on an expensive one. A client that claims elicitation but fails to deliver it falls back rather than sailing through.
--read-only block every write --confirm confirm every write
--no-confirm never confirm (default) confirm the five tiers above
dry_run: true report the exact request without sending it (a parameter of asc_write)--no-confirm is the unattended mode, and it is total: no elicitation prompt,
no confirmation token, and the write tools stop declaring
requiresUserInteraction, so Claude Code does not stop for them either. Anything
short of that would hand an unattended run a confirmation it cannot answer.
Signature verification
Decoding a JWS tells you what the bytes say. Verifying it tells you Apple said it. That distinction matters here more than most places, because these payloads are the evidence behind "is this person a paying subscriber?" — and a decoded but unverified transaction is exactly the shape a forged one takes.
Every signed field is checked against Apple Root CA - G3, vendored in
certs/ so verification cannot be switched off by a network failure. Chain
validation, expiry, revocation and the bundle/environment checks go through
Apple's own library, because those are precisely where a plausible-looking
implementation accepts bad input.
Outcomes are per field, not per response — one bad signature in a history of two hundred is the case that matters:
"signedTransactionInfo_decoded": { "productId": "premium.monthly" },
"signedTransactionInfo_verification": { "verified": true }Where it cannot run, payloads are still decoded and every field says so. Silence would be the dangerous outcome.
How it compares
Approach | Kept | Rejected | |
Hand-wrapped tools | One tool per endpoint | Typed, discoverable arguments | 70–900 tool definitions, >100k tokens, stale the moment Apple ships a version |
Code Mode | Model writes JS, server | Two tools, ~1k tokens, full coverage | Runs generated code in a process holding a signing key |
Meta-tools |
| Same context win, no code execution | — |
Credit where due: several ideas here were adapted from reading erayendes/app-store-connect-mcp and TrialAndErrorAI/appstore-connect-mcp. No code was copied. Heimdall in particular is the most developed server in this space, and if you want 890 typed tools organised into profiles, use it instead — it is good, and it is a different trade to this one.
Receipts
Claims are cheap. These are checkable:
378 tests · 90% line coverage · offline, no credentials, runs on every PRBoth directions of signature verification. A verifier that rejected everything would look just as healthy as a correct one, so a generated chain carrying the two Apple OIDs the verifier insists on proves the accept path, while forged, tampered, wrong-bundle and wrong-environment payloads are all rejected.
The protocol version is measured, not assumed. Claude Code 2.1.235 negotiates MCP
2025-11-25and declareselicitation— recorded by having it connect to a probe server. That is why this stays on SDK v1: the v2 packages implement 2026-07-28, which replaces elicitation with MRTR, and elicitation is what makesasc_writeask a human.MSW, not nock, for HTTP mocking —
nockpatchesnode:http, and Node's globalfetchis undici, which bypasses it entirely. It would have intercepted nothing, silently.One test spawns the real binary and asserts every stdout line parses as JSON, because a single stray
console.logcorrupts the JSON-RPC channel and no in-process harness can catch it.
npm test # 378 tests, offline
npm run verify # 14 read-only checks against the live APIs
npm run fetch:specs # re-download both API descriptions from AppleKeeping current with Apple
Coverage is a property of Apple's spec, not of how many endpoints somebody got around to wrapping.
App Store Connect — 1,263 operations, spec v4.4.1. Apple publishes an OpenAPI document; it is downloaded and compiled into a slim index (360KB against a 3.3MB spec).
App Store Server — 30 operations. Apple publishes no OpenAPI document for this one, so the endpoint set is parsed out of Apple's own client library at a pinned release tag, and diffed against this repo's catalogue on every
verifyrun.Enum tables are generated, all 90 of them. A widely-copied cookbook elsewhere lists an
eventStatevalue Apple does not have and omits two it does; generating them makes that impossible here.A weekly job re-fetches both and opens a branch if Apple moved.
Transports
node dist/index.js # stdio (default)
node dist/index.js --transport http --http-token "$(openssl rand -hex 32)"HTTP binds to loopback and refuses to start without a bearer token. It
validates Host and Origin too: a browser page can otherwise reach a
loopback-bound server as same-origin, where a token alone is no defence.
Docker builds distroless and runs as non-root. Note that stdio needs
docker run -i and must not get -t — a TTY mangles the JSON-RPC stream.
The skill
The server answers questions. It cannot stop a model drawing the wrong
conclusion from a correct answer — an empty list because a territory was written
US instead of USA, one page of thirty read as the whole account, "no
subscriptions" for an app that sells a one-time purchase. There is no error to
catch in any of those; the response was a 200.
That judgement ships as a Claude Code skill:
npx -p @abd3lraouf/app-store-connect-mcp asc-mcp-skillIt installs into ~/.claude/skills/app-store-connect (--scope project for
./.claude/skills, --link to symlink a checkout so edits are live). It adds
nothing to settings.json.
The skill is a list of checks that fire before a conclusion, not a tour of the
API. It hand-copies nothing that can be derived — no enum tables, no endpoint
lists — and a test asserts that every tool name, resource URI, prompt and
enum-shaped value in it still traces back to src/ or to Apple's spec.
Failures are recorded
Today a failure exists only as a tool result in a transcript. When the
conversation ends, so does Apple's x-request-id — the one value Apple support
asks for — along with any evidence of which operations a model tried and could
not find.
Both halves now write to failures.jsonl: the server records its own HTTP,
network and swallowed failures, and the skill records the ones the server cannot
see, the interpretation failures that arrived as a 200.
npm run triage # what keeps failing, and what the cookbook never warned aboutWhere it writes, in order: ASC_FAILURE_LOG_DIR if set (and then nowhere else —
an explicit destination that silently becomes a different destination is worse
than none); otherwise a working checkout of this package, identified by
carrying src/ and .git/, which npm pack publishes neither of; otherwise the
installed skill's own directory; otherwise ~/.claude.
On a machine with no checkout and no installed skill, it writes nothing
unless ASC_FAILURE_LOG=1 says otherwise. ASC_FAILURE_LOG=0 disables it
everywhere.
What it will not write: request headers or request bodies, ever — only body
keys, because appStoreReviewDetails carries a live demoAccountPassword in
a plain body. Response payloads are reduced to Apple's error object. Pre-signed
asset URLs are recorded as a hostname, since the signature is in the path. JWTs,
bearer tokens, PEM blocks and email local-parts are scrubbed as a second line of
defence.
Records are appended as single bounded writes to an O_APPEND descriptor, so
the server and the skill can share one file without a lock. That guarantee is
POSIX's and does not hold on NFS — point ASC_FAILURE_LOG_DIR at local disk.
Known limits
Stated plainly, because you will find them anyway:
Risk tiers are pattern-matched from method and path. Deliberately cautious, but heuristics. Read
asc_describe_endpointbefore a write.Keychain storage is macOS-only. Elsewhere, use a file path with restrictive permissions.
--no-confirmdisables every gate — token, elicitation and therequiresUserInteractionflag. It exists for CI and unattended agents, and is a poor default anywhere a person is present.--no-online-checksskips OCSP, which means accepting a revoked certificate.The failure log's lock-free append relies on
O_APPENDatomicity, which network filesystems do not honour.npm run triageskips torn lines rather than failing, but a network mount can lose records.The accept path for signatures is proven against a substituted trust anchor, not Apple's — getting a genuinely Apple-signed payload needs a real customer transaction. The chain logic is Apple's own library.
Releasing
Bump, merge, done. Both registries authenticate with the workflow's own OIDC identity, so there is no token to rotate and no tag to remember:
npm run release:version patch # or minor, major, or an exact version
git commit -am "Release v1.0.1" && git pushCI notices a version that is not yet on npm, runs the full gate, then publishes to npm and the MCP Registry, tags the commit and opens a GitHub Release. The trigger is the version rather than a tag, which makes the job idempotent — re-running it publishes nothing.
Licence
Business Source License 1.1. Free for internal use, evaluation and development; offering it to third parties as a hosted or embedded service, or redistributing it inside a commercial product, needs a licence. Converts to Apache-2.0 on 2030-08-19.
Apple's OpenAPI description and root certificate are vendored here under Apple's terms, not this licence — see NOTICE.
Apple, App Store, App Store Connect, StoreKit and TestFlight are trademarks of Apple Inc. This project is not affiliated with Apple.
Available Tools
13 toolsasc_analytics_reportARead-only
Fetch an analytics report as rows. Walks request → report → instance → every segment, downloads the signed URLs, gunzips the TSV and returns parsed rows. Reading only the first segment — the obvious mistake — yields a plausible subset with nothing marking it partial. Call without report_name to list what exists. Never creates a report request: accessType ONGOING is a standing commitment on the account, not a query.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| date | No | Processing date, YYYY-MM-DD. Omit for the newest instance. | |
| max_rows | No | Default 5000, cap 50000. | |
| list_only | No | List available reports without fetching one. | |
| granularity | No | ||
| report_name | No | Omit to list the available reports. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although annotations declare readOnlyHint and openWorldHint, the description adds substantial behavioral detail: it walks request → report → instance → every segment, downloads signed URLs, gunzips TSV, returns parsed rows, and warns that reading only the first segment yields a plausible but partial result. It also clarifies the account-level semantics of ONGOING accessType, going far beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with the core purpose in the first sentence. Every subsequent sentence contributes distinct information: the retrieval mechanics, the partial-data pitfall, the list mode, and the non-creating side-effect warning. There is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description sufficiently explains what the tool returns (parsed rows from TSV), how it traverses all data segments, how to use list mode, and that it never creates report requests. An agent has enough information to invoke the tool correctly and understand its scope and limitations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high at 83%, with app, date, max_rows, list_only, and report_name already explained in the schema. The description reinforces the report_name list behavior but does not add meaningful semantics for granularity or the other parameters, so it meets the baseline without exceeding it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Fetch an analytics report as rows', giving a specific verb and resource. It then describes the full retrieval pipeline and explicitly distinguishes this tool from report-creating operations with 'Never creates a report request', which separates it from write-oriented siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear operational guidance: omit report_name to list available reports, and never use this to create a report request because ONGOING accessType is a standing commitment. It does not explicitly name sibling alternatives for report creation, so it falls just short of the most explicit alternative-routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_availability_setADestructive
Turn an app’s App Store availability on or off, territory by territory. Apple offers no bulk endpoint — appAvailabilities answers 403 "does not allow UPDATE" once the record exists — so this is one PATCH per territory, up to 175 of them. Territories already in the target state are skipped, a failure part-way does not abandon the rest, and every territory is re-read afterwards and compared against the request, because a loop that finishes is not evidence that the store matches what was asked for. Cannot set availableInNewTerritories: that is web-UI only.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| state | Yes | on = downloadable, off = removed from sale. | |
| confirm | No | Confirmation token from a previous gated call. Not needed when the user is prompted directly. | |
| territories | No | ISO alpha-3 codes, e.g. ["USA","GBR"]. Omit for every territory the app has. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint/openWorldHint annotations, the description discloses important behavioral traits: territories already in the target state are skipped, a partial failure does not abandon the remaining territories, and every territory is re-read and compared afterwards. This is exactly the kind of operational nuance an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, technical constraint, failure semantics, verification behavior, and a known limitation. The main action is front-loaded and the supporting details follow a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the operation, scale, failure handling, verification process, and a key limitation. There is no output schema, so return-value details are not required; the confirmation token is already documented in the input schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All parameters already have schema descriptions with 100% coverage, so the description does not need to restate them. It adds little parameter-specific meaning beyond what the schema already provides, which is acceptable but not exceptional.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Turn an app's App Store availability on or off, territory by territory.' It clearly establishes the tool's scope and mechanical nature (one PATCH per territory, up to 175), leaving no doubt about what the tool accomplishes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains why bulk usage is impossible ('Apple offers no bulk endpoint') and explicitly calls out a limitation ('Cannot set availableInNewTerritories: that is web-UI only'). It would be stronger with an explicit mention of sibling alternatives, but the conditions and constraints are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_callARead-only
Read from Apple. Handles both APIs, path and query parameters, and pagination. READ operations only — anything that changes data goes through asc_write. A short list may just be one page: if the result says truncated, say so rather than treating it as complete.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Query parameters. Arrays are sent as repeated keys. Filters look like {"filter[bundleId]": "com.x"}; sparse fieldsets like {"fields[apps]": "name,bundleId"}; "limit" caps at 200. Territories are ISO alpha-3 (USA, not US) — the two-letter form returns an empty list, not an error. | |
| paginate | No | Follow links.next and concatenate. | |
| max_pages | No | Default 10, cap 50. | |
| environment | No | StoreKit only; overrides the server default for this call. | |
| operationId | Yes | From asc_search_endpoints. | |
| path_params | No | Values for {placeholders}, e.g. {"id": "6763390896"}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true; the description reinforces this and adds genuinely new behavior: it handles both API styles, follows/concatenates pagination, and warns that short lists may be one page where 'truncated' should not be treated as complete. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earns its place: role, capabilities, and a pagination caveat. The phrase 'both APIs, path and query parameters' is slightly awkward/ambiguous, but the description remains compact and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a generic read call with six parameters and no output schema, the description covers the crucial behavior: read-only safety, pagination/truncation, and routing writes to asc_write. It does not describe error handling or return shapes, but the schema covers parameter semantics and the tool's generic nature makes exhaustive return documentation impractical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed parameter documentation for query, paginate, max_pages, environment, operationId, and path_params. The description itself adds no parameter-level meaning beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a clear verb and scope: 'Read from Apple' and explicitly says 'READ operations only', with writes routed to asc_write. It also names core capabilities (both APIs, path/query params, pagination), so the generic name asc_call does not leave the agent guessing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit exclusion: 'anything that changes data goes through asc_write', and it gives operational guidance about truncated pages. It does not name alternative read-only siblings like asc_pricing_get or asc_analytics_report, so it is clear but not fully exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_describe_endpointARead-only
Full detail for one operation: every parameter, the request body schema with real field names, and its risk tier. Call this before any write.
| Name | Required | Description | Default |
|---|---|---|---|
| operationId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint=true, the safety profile is already known, but the description adds value by disclosing the output content (parameters, request body schema, risk tier). This is especially useful because there is no output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded, and every sentence earns its place. The core value is stated first, followed by a clear usage directive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with no output schema, the description adequately covers what the tool returns and when to call it. Minor omissions are the source of operationId and a definition of the risk tier, but these are not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for the parameter semantics. It implies operationId selects the operation, but it does not explain where to get an operationId or what format it takes. The parameter is simple and self-describing, but the gap prevents a higher score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns full detail for one operation: every parameter, request body schema, and risk tier. This is specific and distinguishable from siblings like asc_search_endpoints (search/discovery) and asc_write/asc_call (execution).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Call this before any write' explicitly states when the tool should be used. It does not name alternatives explicitly, but the reference to write operations effectively excludes the sibling write tools and provides a clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_listing_screenshotsARead-only
List the screenshot sets and screenshots on a version, with each asset’s delivery state. Uses included resources to turn what is otherwise a request per locale per set into a handful.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| locale | No | e.g. en-US. Omit to inspect the primary locale only. | |
| version | No | Version string. Omit for the newest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the read-only nature is covered. The description adds value beyond that by revealing that the tool baches requests via 'included resources' and that it returns delivery state, which is behavioral/payload context not present in the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences. The primary action and resource are front-loaded in the first sentence, and the second sentence provides a valuable efficiency context without fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity read-only list tool, this description is complete: it names the resource, the scope ('on a version'), the included output detail ('delivery state'), and the batching behavior. The schema covers all three parameters, and annotations cover the read-only safety profile, so nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents app, locale, and version. The description only loosely references locale and version ('per locale per set', 'on a version') without adding format or relationship details, so it does not meaningfully improve on the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List') and a specific resource ('screenshot sets and screenshots on a version'), and adds the useful detail that each asset's delivery state is included. It is clearly distinguishable from sibling tools like asc_upload_screenshot and asc_pricing_get because the action and resource are explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to prefer this tool over alternatives, nor any statement of when not to use it. The efficiency note about included resources implies a bulk-listing use case, but it does not tell an agent 'use this to inspect current screenshots' or 'use asc_upload_screenshot to modify them.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_preflight_versionARead-only
Answer "can this version actually be submitted?" across build state, export compliance, every localisation, screenshots, review contact details and any open submission. Returns GO or NO-GO with each gap naming the operation that fixes it. Catches the states that stall a release without explaining themselves — a build still PROCESSING, or an unanswered export-compliance question that parks the version at WAITING_FOR_EXPORT_COMPLIANCE.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| version | No | Version string. Omit for the newest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint/openWorldHint annotations already signal a read-only external-facing check; the description goes further by disclosing the specific states inspected and the outcome format (GO or NO-GO, with each gap naming a fixing operation). It reveals the tool can catch ambiguous states like PROCESSING builds or WAITITNG_FOR_EXPORT_COMPLIANCE, so there are no surprises in behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: the first defines scope and output, the second illustrates the hidden states it catches. No filler or redundant restatement of the schema. The key question is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's multi-dimensional check and no output schema, the description is complete: it names the return type, the categories evaluated, and the action-oriented gap reporting. An agent can decide when to call it and what to expect without further documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both parameters at 100% coverage: app is a Bundle ID/store name/numeric Apple ID, version is an optional version string. The description does not add anything about parameter formats or defaults beyond the schema, so it sits at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool's purpose with a specific verb ('Answer... can this version actually be submitted?') and a clear resource ('a version'). It enumerates the dimensions checked (build state, export compliance, localisations, screenshots, review contact details, open submission), which differentiates it from sibling status or write tools. The GO/NO-GO return is explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It establishes a clear use case: determine submission readiness before release. It implies this is a diagnostic to run before acting, and notes it catches non-obvious blocking states, but it does not explicitly name alternatives or when not to use it. Context is clear enough, though exclusions and sibling routing are left to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_pricing_getARead-only
Read subscription pricing across every territory for an app, with the currency resolved and territories grouped by price so outliers stand out. Collapses a four-hop walk and ~175 lookups into a handful of requests. The currency lives on the territory, not the price row, which is why reading prices by hand tends to produce ambiguous numbers.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| territory | No | ISO alpha-3, e.g. USA. Omit for every territory. | |
| subscription | No | Product ID, name or id. Omit for all of them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnly and openWorld. The description goes further by explaining the underlying multi-hop data model, the currency-ons-territory quirk, and the collapse of ~175 lookups into a few requests. This is genuinely useful behavioral context beyond structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with the purpose front-loaded. Each sentence earns its place: scope/result organization, efficiency/scale, and a domain gotcha. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 100% parameter schema coverage and readOnly/openWorld annotations, the definition covers what is read, how results are organized, and why this tool is preferable to manual lookups. A formal response shape is not specified, and alternatives are not directly named, but the description is strong enough for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all three parameters explicitly, including examples and 'omit for all' guidance, so the baseline is 3. The description adds related context about currency resolution but does not add new syntactic or constraint-level param details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb and resource: 'Read subscription pricing...'. It also specifies scope (every territory, per app), output behavior (currency resolved, territories grouped by price), and the read-versus-write distinction is clear against the asc_pricing_set sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes the intended use clear: efficiently reading pricing across territories and spotting outliers, while avoiding manual multi-hop lookups. It doesn't explicitly name alternatives or state when not to use it, but the read framing and performance benefit supply enough context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_pricing_setADestructive
Change a subscription price. preserve_current_price is required and has no default: true keeps existing subscribers on what they pay now, false moves them at their next renewal. Apple defaults it to false, so leaving it implicit silently re-prices your existing base. Find a price point id with asc_call subscriptions_pricePoints_getToManyRelated.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Bundle ID, store name, or numeric Apple ID. | |
| confirm | No | Confirmation token from a previous gated call. Not needed when the user is prompted directly. | |
| territory | No | ISO alpha-3. Omit to apply to the price point’s own territory. | |
| start_date | No | YYYY-MM-DD. Omit to apply as soon as Apple allows. | |
| subscription | Yes | Product ID, name or id. | |
| price_point_id | Yes | From the subscription’s price points. | |
| preserve_current_price | Yes | REQUIRED. true = existing subscribers keep their price. false = they are moved to the new one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, destructiveHint=true), the description discloses the exact destructive consequence: Apple defaults preserve_current_price to false, so omitting it silently re-prices existing subscribers at renewal. This is precisely the kind of behavioral warning an agent needs before invoking a mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the action, the critical required-parameter behavior, and the prerequisite lookup. The warning is front-loaded immediately after the action, so an agent is unlikely to miss the risk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive 7-parameter write with no output schema, it covers the core behavior, the dangerous default, and the prerequisite lookup. It does not contextualize the gated confirm field or territory/start_date semantics, though those are documented in the schema, so the description is strong but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description adds real value by explaining the boolean semantics of preserve_current_price and by telling the agent where price_point_id comes from. It does not need to repeat the schema's existing parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource — 'Change a subscription price' — and the rest of the description sharpens the action by explaining the preserve_current_price effect. This is clearly distinct from the sibling asc_pricing_get (read) and asc_write (generic write) tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the clear use case: changing a subscription price and choosing whether existing subscribers keep or migrate their price. It also gives a concrete prerequisite step for obtaining a price point id, but it does not explicitly name when to prefer this over asc_write or call out when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_search_endpointsARead-only
Find operations across the App Store Connect API (1263 operations, v4.4.1) and the App Store Server API / StoreKit 2 (30). Search by keyword, method, tag or risk tier; returns operationIds for asc_call and asc_write. Start here rather than guessing a path — some resources are not where the URL pattern implies.
| Name | Required | Description | Default |
|---|---|---|---|
| api | No | Default "both". | |
| tag | No | App Store Connect tag, e.g. "Apps", "Builds". | |
| risk | No | ||
| limit | No | Default 25, max 200. | |
| query | No | Keyword, e.g. "subscription price", "builds", "refund". | |
| method | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description aligns with that by presenting this as a search/find operation. It adds useful context beyond the annotations: API versions, operation counts, and the warning that some resources are not where the URL pattern implies. No side effects are claimed, so there is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences and every clause earns its place: scope, API versions, search dimensions, output use, and a routing heuristic. Key information is front-loaded, with no filler or redundant restating of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search tool with no output schema, the description covers the essential return contract ('returns operationIds for asc_call and asc_write'), the targeted APIs, and valid search dimensions. It is slightly light on how filters combine and what response metadata accompanies the operationIds, but an agent has enough context to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, so the description partially carries the burden for undocumented parameters. 'Search by keyword, method, tag or risk tier' maps query, method, tag, and risk to their intended roles, and api/limit have schema descriptions with defaults. However, the risk tier values are not explained, and the combination semantics of multiple filters are left implicit, so the description only partially compensates for the schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with an unambiguous verb and resource: 'Find operations across the App Store Connect API... and the App Store Server API / StoreKit 2.' It also states the search dimensions and the concrete output: 'returns operationIds for asc_call and asc_write.' This clearly differentiates the tool from siblings like asc_call and asc_describe_endpoint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Start here rather than guessing a path' establishes when this tool should be used before calling or writing operations, and naming asc_call and asc_write as consumers of the returned operationIds gives the agent a natural next step. It does not explicitly enumerate when to skip this tool and go directly to a sibling, so it stops short of a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_statusARead-only
Verify credentials and report what this server can reach, including the remaining rate-limit budget. Run this first when anything fails — it distinguishes a bad key from a bad request.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint=true, so the read-only nature is known. The description adds meaningful context beyond that: it verifies credentials, reports server reachability, and includes rate-limit budget. These details clarify what the tool actually does during execution and what kind of information it surfaces.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tightly packed sentences with no filler. The primary action is front-loaded in the first sentence, and the diagnostic use case follows in the second. Every word contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only status tool with no output schema, this description is complete. It explains what the tool does, what it reports (reachability, rate-limit budget), and when to invoke it. Nothing essential is missing for an agent to select and call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter burden. With 100% schema description coverage (vacuously) and no parameters to explain, the baseline of 4 applies. The description needs to add no parameter detail and appropriately focuses on behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Verify credentials and report what this server can reach.' It clearly identifies a status/health-check operation distinct from sibling tools like asc_call, asc_write, or asc_pricing_get. The purpose is unambiguous and action-oriented.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: 'Run this first when anything fails — it distinguishes a bad key from a bad request.' This tells the agent when to use the tool and what diagnostic value it provides. It doesn't name alternatives or when-not-to-use, but the conditional use case is strong and practical.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_upload_iap_screenshotADestructive
Upload the App Store review screenshot for an in-app purchase, performing Apple’s reserve → upload → commit sequence. This is a different resource from a listing screenshot and is the usual reason an in-app purchase stays in MISSING_METADATA when everything else about it is complete — it is the one required field with no text to type. Apple rejects non-standard aspect ratios: a window capture at 1706x1610 fails IMAGE_BAD_ASPECT_RATIO, while 2880x1800 passes. Validation is asynchronous, so a rejected image commits cleanly and only then reports FAILED.
| Name | Required | Description | Default |
|---|---|---|---|
| iap | Yes | Numeric in-app purchase id. asc_pricing_get lists them. | |
| confirm | No | Confirmation token from a previous gated call. Not needed when the user is prompted directly. | |
| dry_run | No | Report what would be sent, including the checksum, without sending it. | |
| file_name | No | Name to store it under. Defaults to the file’s own name. | |
| file_path | Yes | Absolute path to the image on this machine. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses the reserve→upload→commit sequence, asynchronous validation, and the surprising behavior that a rejected image commits cleanly and only then reports FAILED. The aspect-ratio example adds concrete failure context. No contradiction with the annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each dense and non-redundant: the action, the resource distinction, a concrete validation constraint, and the async failure model. It is appropriately sized for the complexity and front-loads the main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with destructive annotations and no output schema, the description covers the operation's side-effect sequence, validation behavior, and failure mode well. It could add what success returns or how confirm interacts with gating, but overall it is strong and nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and parameter descriptions already document iap, file_path, confirm, dry_run, and file_name, so the baseline is 3. The aspect-ratio guidance adds useful context for file_path, but the description does not substantially extend parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: uploading the App Store review screenshot for an in-app purchase, and names the reserve→upload→commit sequence. It also differentiates this from a listing screenshot, which helps disambiguate against sibling tools like asc_upload_screenshot.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear use case: this is the usual reason an in-app purchase stays in MISSING_METADATA when everything else is complete, so an agent knows when it is needed. It also explicitly says this resource is different from a listing screenshot, but it does not name the sibling tool to use as an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_upload_screenshotADestructive
Upload a screenshot image, performing Apple’s full reserve → upload → commit sequence: reserve a slot, PUT each byte range to Apple’s asset host with the headers Apple supplies, then commit with an MD5 checksum. The raw API cannot do this in one call, and a wrong checksum or offset does not error — it leaves the asset stuck, which looks like nothing happened.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Confirmation token from a previous gated call. Not needed when the user is prompted directly. | |
| dry_run | No | Report what would be sent, including the checksum, without sending it. | |
| file_name | No | Name to store it under. Defaults to the file’s own name. | |
| file_path | Yes | Absolute path to the image on this machine. | |
| screenshot_set_id | Yes | From asc_listing_screenshots. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a non-obvious failure mode: a wrong checksum or offset silently leaves the asset stuck, appearing as if nothing happened. This goes well beyond the annotations (destructiveHint=true, openWorldHint=true) by explaining the side-effectful behavior and exact sequencing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with a clear structure: the first defines the core workflow, the second explains why it exists and what can go wrong. Every clause contributes meaningful operational detail without repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully conveys the multi-step process, the dependence on Apple-supplied headers, and the critical silent-failure risk, giving an agent the operational context needed to invoke it correctly. It does not cover the return value or prerequisites in detail, but the schema and annotations already handle parameter and safety context, and no output schema exists to constrain expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters already have meaningful schema-level descriptions. The tool description mentions checksum and offset concepts but does not map them to specific input parameters, adding little parameter-level value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Upload') and resource ('screenshot image') and adds the concrete reserve → upload → commit workflow, making the tool's unique function clear. However, it does not explicitly distinguish itself from the sibling asc_upload_iap_screenshot, so it lacks direct sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: it exists because the raw API cannot perform the full upload sequence in one call. It does not mention alternative sibling tools or explicit when-not conditions, but the underlying rationale effectively guides usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
asc_writeADestructive
Change something in App Store Connect: create, update or delete. Consequential tiers (REVENUE, DESTRUCTIVE, INFRASTRUCTURE, ACCESS, RELEASE) ask the user to confirm before anything is sent. Use dry_run first when you are unsure what a call will do — it validates and reports the exact request without sending it. Read asc_describe_endpoint first to get the body schema right.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | JSON:API request body. For binary uploads, a base64 string. | |
| query | No | Query parameters. Arrays are sent as repeated keys. Filters look like {"filter[bundleId]": "com.x"}; sparse fieldsets like {"fields[apps]": "name,bundleId"}; "limit" caps at 200. Territories are ISO alpha-3 (USA, not US) — the two-letter form returns an empty list, not an error. | |
| confirm | No | Confirmation token from a previous gated call. Not needed when the user is prompted directly. | |
| dry_run | No | Validate and report the request that would be sent, without sending it. | |
| environment | No | StoreKit only; overrides the server default for this call. | |
| operationId | Yes | From asc_search_endpoints. | |
| path_params | No | Values for {placeholders}, e.g. {"id": "6763390896"}. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations already flag readOnly=false and destructive=true, the description adds meaningful behavioral context: consequential tiers (REVENUE, DESTRUCIVE, INFRASRUCTURE, ACCESS, RELEASE) prompt for user confirmation, and dry_run validates without sending. This helps an agent anticipate side effects and safety gating beyond the raw annotation booleans.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences with no wasted words. The purpose is front-loaded, consequential behaviors are stated next, and the dry_run and schema-discovery guidance are packed into the final two sentences. Every sentence justifies its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex write tool with no output schema, the description covers the key operational concerns: mutation scope, user confirmation gates, dry-run safety, and where to find the correct body schema. It does not describe return values or error behavior, but given that the response depends on the endpoint and the agent is pointed to asc_describe_endpoint, this is a reasonable completeness level.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all 7 parameters thoroughly (100% coverage), including JSON:API body, base64 uploads, query filter syntax, and the confirm token. The description adds value only by directing the agent to asc_describe_endpoint for the operation-specific body schema and recommending dry_run, but it does not substantially expand parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-plus-resource statement: 'Change something in App Store Connect: create, update or delete,' which clearly identifies the tool as a writ operation and differentiates it from read-oriented siblings like asc_call and asc_status. It is immediately clear what the tool does and what category of operations it covers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance to 'Use dry_run first when you are unsure what a call will do' and to 'Read asc_descibe_endpoint first to get the body schema right,' which are concrete stepps for safe and correct usage. It also explains that consequential tiers require user confirmation before anything is sent. However, it does not explicitly state when not to use asc_write in favor of a read-only sibling like asc_call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
13 tool updates
v1.2.0- First observed
asc_analytics_report - First observed
asc_availability_set - First observed
asc_call - First observed
asc_describe_endpoint - First observed
asc_listing_screenshots - First observed
asc_preflight_version - First observed
asc_pricing_get - First observed
asc_pricing_set - First observed
asc_search_endpoints - First observed
asc_status - First observed
asc_upload_iap_screenshot - First observed
asc_upload_screenshot - First observed
asc_write
TDQS
Each tool has a clearly distinct role: generic read/write, endpoint discovery, pricing, submission readiness, screenshot uploads, analytics, and availability. Even the two upload tools are explicitly differentiated by resource type, and the specialized tools are described as collapsing multi-step workflows rather than duplicating asc_call/asc_write.
All tools share the asc_ prefix and use snake_case, but the pattern after the prefix varies: some are verb-noun (asc_search_endpoints, asc_upload_screenshot), some are noun-verb (asc_pricing_get, asc_availability_set), and some are bare or noun-like (asc_call, asc_status, asc_analytics_report). The set remains readable, but the naming convention is not uniform.
Thirteen tools is well within the ideal range for a cohesive server. The generic asc_call and asc_write cover the huge underlying API surface, while the specialized tools earn their place by handling complex, multi-step workflows that would otherwise be error-prone.
The generic read/write tools plus endpoint discovery and schema description provide full lifecycle coverage for the App Store Connect API, with no obvious dead ends. The high-level tools deliberately cover the most painful real-world flows like pricing, submission readiness, screenshot uploads, analytics, and availability.
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 Connectors
- app-managerOAuthapp.lance
App Store Connect operator for AI agents: icons, TestFlight builds, listings, IAP, rejection fixes.
Analyze and manage Apple Ads from your AI assistant with RevenueCat insights and safety controls.
Run App Store Connect from your IDE: pricing, listings, screenshots, releases, AI visibility.
Read products, sales, subscribers and offer codes; verify, enable and disable product licenses.
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.31123MIT
- FlicenseNot gradedqualityDmaintenanceEnables 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.2021MIT
- AlicenseNot gradedqualityDmaintenanceEnables 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
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