App audit (lite)
Runs a quick App Store / Google Play audit of one app with live AppGoat data – listing quality, ratings trend, recent complaints, keyword rankings, competitors and their recent changes – and ends with a prioritized fix list.
A 10-minute audit of one app from public store data: what the listing says, how users rate it, what they complain about, which searches it wins, and what competitors changed recently. It ends with at most 7 fixes, ordered by expected impact.
This is the cheap "lite" path (~25–40 credits), assembled from the AppGoat read tools. The full
App Audit is live as the audit_app MCP tool (POST /v1/apps/{app}/audit): an AI-written,
evidence-checked report with a 0–100 score, prioritised actions, metadata rewrites within the
character limits, ~20 probed search terms and a shareable report page. It takes 1–3 minutes:
audit_app waits about 25 s and returns an audit id, which get_audit follows up on (free). The
first audit of an organization is free, later ones cost 100 credits, and re-running the same app,
country and mode within 24 h returns the earlier audit for free.
Install
The appgoat/skills repository is private until its public release, so the plugin and git commands below are coming soon. Today, run the playbooks as prompts of the AppGoat MCP server (Claude, Cursor, ChatGPT) or download the SKILL.md from this page.
Install the AppGoat plugin (all playbooks plus the AppGoat MCP server), then run /mcp to sign in.
/plugin marketplace add appgoat/skills
/plugin install appgoat-playbooks@appgoatRun it by asking for it in plain words, or by name:
/app-audit-lite <app> [country]Add the connector: Settings → Connectors → Add custom connector → https://api.appgoat.ai/mcp.
Pick app-audit-lite from the “+” menu → AppGoat (it is served as a prompt), or upload the skill folder as a zip in Settings → Capabilities → Skills.
Add the MCP server to .cursor/mcp.json:
{ "mcpServers": { "appgoat": { "url": "https://api.appgoat.ai/mcp" } } }Type / in the chat and pick app-audit-lite, or save the SKILL.md as .cursor/rules/app-audit-lite.mdc.
In developer mode (Settings → Apps & Connectors → Advanced), add a connector with https://api.appgoat.ai/mcp and sign in. Then ask:
Use the AppGoat list_playbooks tool and run the app-audit-lite playbook.Copy the skill folder into your agent’s skills directory and add the MCP server:
git clone https://github.com/appgoat/skills /tmp/appgoat-skills
cp -r /tmp/appgoat-skills/skills/app-audit-lite ~/.claude/skills/
claude mcp add --transport http appgoat https://api.appgoat.ai/mcpWhen to use
- The user wants an assessment of their own app or a competitor's ("audit", "teardown", "what should I fix").
- Before an ASO rewrite (run
aso-keywords-metadata-rewriteafterwards for the metadata itself). - Prefer
audit_appinstead when the user wants the full report or a link to share, or has not used their free audit yet (call it withfree_only: trueto run it only if it is free). Stay on this lite flow when credits are tight or for a quick check. - Not for idea hunting (use
find-app-ideas) or for turning reviews into tickets (usereviews-to-github-issues).
Inputs
app(required): anything that identifies the app - store URL, Apple id (284882215), Play package (com.spotify.music), bundle id or a name. If a name resolves to the wrong app (check the warning in the tool output), ask the user for the store link.country(optional, defaultus): two-letter storefront code. Audit one country per run.
Steps
Call the AppGoat MCP tools in this order. Costs are AppGoat credits; every tool output ends with a
footer showing credits_used and credits_remaining - stop and tell the user if remaining credits
drop below 50. Without the MCP, use the REST equivalents in the REST calls below.
| # | Call | Credits | What you need from it |
|---|---|---|---|
| 1 | get_app {app, country, include: ["versions", "charts"]} | 1 (+1 if older than 7 days and refreshed) | title, subtitle, description, category, rating, ratings_count, histogram, version, updated_at, release notes of the last 5 versions, screenshots count, languages, chart positions, linked app in the other store |
| 2 | get_app_history {app, country} | 1 | rating and ratings_count over the last 90 days |
| 3 | get_reviews {app, country, rating: "1-2", limit: 100} | 1 (+1 refresh) | recent complaints; group by theme yourself |
| 4 | get_reviews {app, country, rating: "5", limit: 50} | 1 | what users love (words to reuse in the listing) |
| 5 | get_app_keywords {app, country, limit: 100} | 1 | ranked terms, rank, popularity, difficulty |
| 6 | get_competitors {app, country, limit: 5} | 1 | top 5 competitors |
| 7 | get_app {app: <competitor app_id>, store, country} for each of the 5 | 5 | competitor title, subtitle, rating, ratings_count, updated_at |
| 8 | get_app_changes {app: <competitor app_id>, store, field: "title,subtitle,description,screenshots,price,version", since: <today − 60 days>} for the top 3 | 3 | what competitors changed recently |
| 9 | keyword_research {terms: up to 10 high-popularity terms competitors rank for but the app does not (from step 5 vs competitor titles/subtitles), store, country, app} | 10 | popularity, difficulty, the app's rank and relevance per gap term |
Budget: about 25 credits (up to ~40 with refreshes and a second reviews page). Do not page through more reviews unless the user asks.
If a call answers that data is still being refreshed (refreshing, a job_id), call get_job
{id} (free) every few seconds until it is done, then repeat the original call once.
Decision rules
Score each area Good / Needs work / Problem using these thresholds:
- Rating: Problem if rating < 4.0 or the 90-day history shows a drop ≥ 0.1; Needs work if 4.0–4.4; Good if ≥ 4.5. Flag if 1★ share of the histogram > 15%.
- Rating volume: Needs work if ratings_count grew < 1% in 90 days while competitors' median ratings_count is ≥ 5× higher (prompt for ratings in the app).
- Freshness: Problem if updated_at > 180 days ago; Needs work if > 60 days. Release notes that are generic ("bug fixes and improvements") in ≥ 3 of the last 5 versions: Needs work.
- Title / subtitle (Apple 30 / 30 characters; Play title 30, short description 80): Needs work if either uses < 70% of its limit, if the title has no non-brand keyword, or if the subtitle repeats title words.
- Keywords: count ranked terms with rank ≤ 10 and popularity ≥ 30 ("winning"), and terms with rank 11–50 and popularity ≥ 30 ("striking distance"). Problem if winning = 0; every striking-distance term with relevance < 0.7 is a metadata opportunity.
- Complaints: a theme counts when ≥ 3 of the 1–2★ reviews mention it, or ≥ 1 mentions a crash,
data loss, a billing/subscription problem or a login lockout. Unanswered 1–2★ reviews (no
reply)50%: Needs work.
- Competitors: note every competitor that changed its title or subtitle in the last 60 days (they are targeting new terms) and any competitor with rating ≥ 0.3 higher than the app.
- Localization: Needs work if
languageshas 1 entry and any competitor has ≥ 5.
Fix list: at most 7 items, each tied to a finding above, ordered by (impact × ease). Crashes and billing complaints always come first, then title/subtitle keyword gaps, then everything else. Never invent numbers; if a value is missing, say "no data".
Output format
# App audit: <title> (<store>, <country>) - <date>
**Verdict:** <one sentence>
| Area | Status | Evidence |
|---|---|---|
| Rating | Good / Needs work / Problem | 4.6★ (42,310 ratings), −0.05 in 90 days, 1★ 6% |
| Freshness | … | v3.2.1, updated 12 days ago |
| Title & subtitle | … | "…" (24/30), "…" (18/30) |
| Keywords | … | 4 winning, 9 striking distance |
| Complaints | … | login loop (7), sync lost data (2) |
| Competitors | … | X changed subtitle to "…" on <date> |
| Localization | … | English only; 3 of 5 competitors ≥ 5 languages |
## Top fixes
1. **<fix>** - why (evidence), expected effect.
2. …
## Keyword opportunities
| Term | Popularity | Difficulty | Your rank | Relevance | Action |
|---|---|---|---|---|---|
## What users say
- Love: "<≤ 120-char quote>" (5★, v3.2)
- Hate: <theme> - "<quote>" (1★, v3.2)
## Competitors
| App | Rating | Ratings | Updated | Recent change |
|---|---|---|---|---|
_Credits used: <sum of the footers>._
**Automate this →** weekly competitor changes and review alerts: see the `reviews-to-github-issues`
playbook; metadata fixes: `aso-keywords-metadata-rewrite`.
Automate it
Run the audit monthly and commit the report, so changes are visible in git history.
GitHub Action (.github/workflows/appgoat-audit.yml, secrets ANTHROPIC_API_KEY and APPGOAT_API_KEY):
name: AppGoat monthly audit
on:
schedule:
- cron: "0 7 1 * *"
workflow_dispatch:
permissions:
contents: write
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install AppGoat playbooks
run: |
git clone --depth 1 https://github.com/appgoat/skills /tmp/appgoat-skills
mkdir -p .claude/skills
cp -r /tmp/appgoat-skills/skills/* .claude/skills/
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Use the app-audit-lite skill for the app https://apps.apple.com/us/app/id000000000 in country us.
Write the report to reports/audit-<YYYY-MM>.md (current month), then commit and push it.
claude_args: |
--mcp-config '{"mcpServers":{"appgoat":{"command":"npx","args":["-y","@appgoat/mcp"],"env":{"APPGOAT_API_KEY":"${{ secrets.APPGOAT_API_KEY }}"}}}}'
--allowedTools mcp__appgoat__get_app,mcp__appgoat__get_app_history,mcp__appgoat__get_reviews,mcp__appgoat__get_app_keywords,mcp__appgoat__get_competitors,mcp__appgoat__get_app_changes,mcp__appgoat__keyword_research,mcp__appgoat__get_job,Write,Bash(git:*)
Claude Code routine (paste into Claude Code with the AppGoat connector added):
/schedule monthly on the 1st at 08:00 - Run the app-audit-lite playbook for <app link> in <country>. Compare it with last month's report in reports/, call out what improved and what got worse, and open a PR with the new report.
Without MCP: the REST calls
Without the AppGoat MCP server, call the API directly. Base URL https://api.appgoat.ai/v1,
header x-api-key: $APPGOAT_API_KEY (create a key at https://dash.appgoat.ai). Responses are
{ "data": …, "meta": { "credits_used", "credits_remaining", "freshness", "next_cursor", "warnings" } };
errors are { "error": { "code", "message", "hint" } } - read hint. {app} must be URL-encoded.
| MCP tool | REST call |
|---|---|
get_app | GET /apps/{app}?country=us&include=versions,charts |
get_app_history | GET /apps/{app}/history?country=us&from=YYYY-MM-DD |
get_reviews | GET /apps/{app}/reviews?country=us&rating=1-2&limit=100 |
get_app_keywords | GET /apps/{app}/keywords?country=us&limit=100 |
get_competitors | GET /apps/{app}/competitors?country=us&limit=5 |
get_app_changes | GET /apps/{app}/changes?field=title,subtitle&since=YYYY-MM-DD |
keyword_research | GET /keywords?qs=term1,term2&store=apple&country=us&app={app} |
get_job | GET /jobs/{id} (free) |
audit_app (full audit) | POST /apps/{app}/audit with body {"country": "us"} (100 credits, first one free; 202 while running) |
get_audit | GET /audits/{id} (free) |
curl -s -H "x-api-key: $APPGOAT_API_KEY" \
"https://api.appgoat.ai/v1/apps/$(python3 -c 'import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=""))' 'https://apps.apple.com/us/app/id284882215')?country=us"
More playbooks
/find-app-ideas~150–250 credits a runFind app ideas
Finds underserved App Store / Google Play niches with live AppGoat data – search demand (keyword popularity) against weak supply (low ratings, abandoned incumbents, few strong apps) – and returns a ranked shortlist of app ideas with evidence and user pain points.
/aso-keywords-metadata-rewrite~40–80 credits a runASO keywords → metadata rewrite
Researches App Store / Google Play keywords for one app with live AppGoat data (current ranks, competitor keyword gaps, popularity, difficulty, relevance) and rewrites the title, subtitle, keyword field and description within the store character limits.
/competitor-digest~15–55 credits a runCompetitor digest
Writes a weekly competitor digest for one App Store / Google Play app from an AppGoat competitor watch – what each competitor changed (title, subtitle, description, screenshots, icon), price and in-app purchase changes, new versions with release-note summaries, rating and chart moves, keyword gains and losses against the user's app, keyword gaps and review themes – and ends with 3 recommended actions linked to other playbooks. Sets up or reuses the competitor_set watch.
/reviews-to-github-issues~2–10 credits a runReviews → GitHub issues
Turns recent negative App Store / Google Play reviews into deduplicated GitHub issues – one issue per problem topic, with linked and quoted reviews, new reviews added as comments to the existing issue instead of duplicates. Uses AppGoat review data and the gh CLI (or the GitHub MCP server).
/reply-to-every-review~1–3 + 1 per posted reply credits a runReply to every review
Drafts a reply to every unanswered App Store and Google Play review of the user's own app, in the app's voice, through their connected App Store Connect / Play Console account – each reply is a dry run with a before/after diff and AppGoat guardrail scores (policy, tone, claims), and only the replies the user approves are posted.
/apple-ads-optimizer~5–8 per campaign + 1 per applied change credits a runApple Ads optimizer
Optimizes the user's Apple Ads (Search Ads) campaigns through their connected Apple Ads account – reads the last 14 days of keyword and search term reports, raises bids on keywords that convert under the target CPA (capped +30% per run), lowers or pauses keywords that spend without installs, adds converting search terms as exact keywords and wasteful ones as negatives – every change a dry run with a diff the user approves.
/localization-push~35–60 per locale + 1 per applied change credits a runLocalization push
Localizes the user's own App Store / Google Play listing into new languages through their connected App Store Connect or Play Console account – picks target locales from markets with demand, researches the keywords people actually search in each country with AppGoat, writes a localized name, subtitle, keyword field and promotional text (Play title, short and full description) within the store limits, and pushes each locale as a dry run with a before/after diff the user approves.