# AppGoat (remote · api.appgoat.ai)

App Store and Google Play data: apps, reviews, keywords, charts, competitors, ASO playbooks.

- Trust score: 73/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-23

## Components

- remote · `api.appgoat.ai`: 73/100 (this document), [markdown](https://verifymcp.io/servers/ai-appgoat-mcp/api.md), [page](https://verifymcp.io/servers/ai-appgoat-mcp/api)

## Channel facts

- Endpoint: `https://api.appgoat.ai/mcp`
- Transports: `streamable-http`
- Auth: `required`
- Version: `0.2.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-23.

- **Endpoint Security**: 78/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS enforcement could not be verified: the plaintext port answered with HTTP 401, which proves neither a plaintext path nor enforcement.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 7503 tokens (~258/item across 29 items; 29 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 29 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 29 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: authentication we do not have, an unreachable endpoint, or not enough scan history. We only credit what we can confirm.

## Install

### How do I install the AppGoat MCP server?

AppGoat is a hosted endpoint at https://api.appgoat.ai/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add --transport http ai-appgoat-mcp 'https://api.appgoat.ai/mcp'
```

### Cursor

```json
{
  "mcpServers": {
    "ai-appgoat-mcp": {
      "url": "https://api.appgoat.ai/mcp"
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "ai-appgoat-mcp": {
      "type": "http",
      "url": "https://api.appgoat.ai/mcp"
    }
  }
}
```

### Codex

```toml
[mcp_servers.ai-appgoat-mcp]
url = "https://api.appgoat.ai/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ai-appgoat-mcp": {
      "type": "remote",
      "url": "https://api.appgoat.ai/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ai-appgoat-mcp --url 'https://api.appgoat.ai/mcp' --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  ai-appgoat-mcp:
    url: "https://api.appgoat.ai/mcp"
```

### Netclaw

```json
{
  "McpServers": {
    "ai-appgoat-mcp": {
      "Transport": "http",
      "Url": "https://api.appgoat.ai/mcp"
    }
  }
}
```

### Vellum

```bash
assistant mcp add ai-appgoat-mcp -t streamable-http -u 'https://api.appgoat.ai/mcp'
```

### Other

```json
{
  "mcpServers": {
    "ai-appgoat-mcp": {
      "type": "http",
      "url": "https://api.appgoat.ai/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-23 (score 73)

First indexed and scored.

## MCP tools (29)

### `get_app` (~432 tokens)

Get App

Look up one App Store or Google Play app: title, subtitle, developer, category, price, rating and histogram, installs (Play), version and dates, description, languages, and the same app in the other store. Accepts any id, bundle id, package, store URL or a name. Reads stored data (refreshed from the store only when older than max_age, default 7 days) for one country (default us); add include sections for markets, versions, IAP, privacy, estimates and chart positions. Cost: 1 + 1 per country refreshed from the store (max 10) credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): ISO country code(s): `us` (default), a comma list (paid plans), or `all` (Studio). Example: us,de
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `full_text` (boolean): Return long text (description, release notes, review bodies) in full instead of cut short
- `include` (array): Extra sections: markets (every storefront), iap, versions (history with release notes), privacy (App Store labels), estimates (modelled downloads/revenue), charts (current top-chart positions)
- `max_age` (integer): Refresh from the store when our data is older than this many seconds (0 = always). Default 604800 (7 days).
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `wait` (boolean): Block up to ~25 s for a refresh (default). false = answer immediately from cache with a job id.

### `get_reviews` (~558 tokens)

Get Reviews

Read an app's user reviews, newest first, up to 100 per page: rating, title, text, version, date, developer reply and AI tags (sentiment, intent, severity, topic) where tagged. Filter by stars (rating='1-2' for complaints), version, date range, text (q) or AI tags (intent='bug,crash'; tag filters skip untagged reviews). Page with cursor. Cost: 1 per page + 1 if the US reviews are refreshed credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): ISO country code(s): `us` (default), a comma list (paid plans), or `all` (Studio). Example: us,de
- `cursor` (string): `meta.next_cursor` from the previous page.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `full_text` (boolean): Return long text (description, release notes, review bodies) in full instead of cut short
- `intent` (string): AI intent filter (comma list): bug, crash, feature_request, pricing, ux, praise, spam, other. Example: bug,crash
- `limit` (integer): Max items to return. Default: 50.
- `max_age` (integer): Refresh the latest US reviews when older than this many seconds. Default 86400 (1 day).
- `q` (string): Case-insensitive text search in the title and body. Example: crash
- `rating` (string): Star rating filter, `1`, `1,2` or a range `1-3`. Example: 1-2
- `sentiment` (string): AI sentiment filter (comma list): positive, neutral, negative. Example: negative
- `since` (string): Only items at or after this ISO date / datetime. Example: 2026-10-01
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `topic` (string): AI topic filter (comma list of topic labels, case-insensitive, or topic ids).
- `until` (string): Only reviews created before this ISO date / datetime.
- `version` (string): Only reviews written for this app version.

### `get_app_history` (~283 tokens)

Get App History

An app's daily metric history per country: rating, ratings count, reviews count, installs (Play), star histogram and price, one row per day a value changed (default the last 90 days), with the change over the period. Use it to chart growth or spot rating drops after a release. Cost: 1 + 1 per country refreshed (max 10) credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): ISO country code(s): `us` (default), a comma list (paid plans), or `all` (Studio). Example: us,de
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `from` (string): Start date (ISO), default 90 days before `to`.
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `to` (string): End date (ISO), default today.

### `get_app_changes` (~321 tokens)

Get App Changes

What changed in an app's store listing, newest first, with old and new values: version, release notes, title, subtitle, description, screenshots, icon, price, IAP, privacy, in-app events, badges, featuring, installs, content rating. Use it to monitor competitors ("what did X change this month?"). Cost: 1 + 1 if the US listing is refreshed credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): Only changes seen in these storefronts (comma list). Default all storefronts.
- `cursor` (string): `meta.next_cursor` from the previous page.
- `field` (string): Only these fields (comma list), e.g. `version,title,subtitle`.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): Max items to return. Default: 50.
- `since` (string): Only items at or after this ISO date / datetime. Example: 2026-10-01
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).

### `get_app_keywords` (~260 tokens)

Get App Keywords

The search terms an app ranks for in a country, best rank first, with popularity (5–100) and difficulty (0–100): from the weekly keyword universe plus your tracked keywords. Call it for the app and a competitor to find keyword gaps. Cost: 1 credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): Two-letter country code (default 'us').
- `cursor` (string): `meta.next_cursor` from the previous page.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): Max items to return. Default: 100.
- `max_rank` (integer): Only terms where the app ranks at or above this position.
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).

### `get_competitors` (~219 tokens)

Get Competitors

An app's competitors, best first, scored from search terms both apps rank for (shared keywords) plus the store's similar-apps list. Feed the app ids into get_app or get_app_changes for a competitor digest. Cost: 1 credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): Two-letter country code (default 'us').
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): Max items to return. Default: 20.
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).

### `search_apps` (~215 tokens)

Search Apps

Find apps by name or id in AppGoat's catalog of both stores (~5M apps): exact title matches first, then prefix, then substring, most-rated first. Returns store, app_id, title, developer, category, rating, ratings and price; pass the app_id to the other tools. Cost: 1 credits.

Input parameters:

- `category` (string): Store category name, e.g. `Photo & Video` (App Store) or `PHOTOGRAPHY` (Play).
- `cursor` (string): `meta.next_cursor` from the previous page.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): Max items to return. Default: 20.
- `q` (string, required): App name (≥ 2 characters) or exact id. Example: photo editor
- `store` (string): Limit to one store: 'apple' or 'play'. Omit for both.

### `get_charts` (~241 tokens)

Get Charts

A top free, paid or grossing chart for a store, country and category, today or on a past date: rank, app, developer, rating and the move since the previous capture (new entries marked), plus apps that dropped out. Charts are captured daily for every country and category. Cost: 1 credits.

Input parameters:

- `category` (string): App Store genre id (`36` or `all` = all apps, `6014` = games, …) or Play category (`GAME_PUZZLE`; `APPLICATION` = all apps).
- `chart` (string): 'free' (default), 'paid' or 'grossing'.
- `country` (string): Two-letter country code (default 'us').
- `date` (string): The chart as of this date (ISO). Default the latest capture.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): How many ranks to return (default 100, max 200).
- `store` (string): 'apple' (default) or 'play'.

### `keyword_research` (~314 tokens)

Keyword Research

Keyword metrics and research for App Store / Google Play search terms: popularity (5–100), difficulty (0–100), result count and the #1 result's estimated daily downloads. include adds related terms with metrics, the store's autocomplete and the current top 10 apps; app adds that app's rank and metadata relevance per term (the core of an ASO keyword audit). Unmeasured terms are measured live (a few per call) or come back pending. Cost: 1 per keyword; 5 per seed with include=related or suggestions credits.

Input parameters:

- `app` (string): Any app identifier (as in `{app}`); adds `app.rank` and `app.relevance` per term.
- `country` (string): Two-letter ISO country code (storefront), e.g. us, gb, de. Default: us.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `include` (array): related (~10 related terms with metrics), suggestions (store autocomplete), top_apps (current top 10). related/suggestions cost 5 credits per term
- `store` (string): Required unless `app` is given.
- `terms` (array, required): Search terms, 1–25 (at most 5 with include related or suggestions)
- `wait` (boolean): Block up to ~25 s for a refresh (default). false = answer immediately from cache with a job id.

### `track_keywords` (~227 tokens)

Track Keywords

Deprecated: use watch with kind keyword (also reports rank moves as events). Starts tracking the search ranking of terms in one or both stores and the given countries: ranked apps are captured daily from now on (idempotent; already tracked terms are reported as such). Each term × store × country uses one keyword slot of the plan; a request over the limit tracks nothing (plan_limit). Read history with get_keyword_ranks. Cost: 0 credits.

Input parameters:

- `countries` (array): Two-letter country codes to track in (default ['us'])
- `depth` (integer): How many results to keep per ranking (default 100 Apple / 50 Play).
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `store` (string, required): 'apple', 'play' or 'both' (tracks each term in each store)
- `tags` (array): Free-form labels.
- `terms` (array, required): Search terms to track, e.g. ['habit tracker', 'streaks']

### `untrack_keywords` (~62 tokens)

Untrack Keywords

Deprecated: use unwatch for keyword watches. Stops tracking keywords by id (from list_tracked_keywords or track_keywords): no new rankings are recorded and their plan slots are freed. Cost: 0 credits.

Input parameters:

- `ids` (array, required): Tracked keyword ids

### `list_tracked_keywords` (~143 tokens)

List Tracked Keywords

Deprecated: use list_watches (keyword watches list their slots). Your tracked keywords with id, store, country, popularity, depth, cadence, last ranking and current top 3. Filter by store, country or a term substring. Cost: 0 credits.

Input parameters:

- `country` (string): Only this two-letter country code.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `q` (string): Only terms containing this text.
- `store` (string): 'apple' = Apple App Store (iOS), 'play' = Google Play (Android).

### `get_keyword_ranks` (~193 tokens)

Get Keyword Ranks

Ranking history of a watched keyword: per capture the top 10 app ids, or with app, that app's rank over time (best, worst, latest). Default the last 90 days. The id is a keyword slot of a keyword watch (list_watches and watch show the slot ids) or a list_tracked_keywords id. Cost: 1 credits.

Input parameters:

- `app` (string): Store app id; returns `rank` per point instead of the full id list.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `from` (string): Start, ISO date or datetime (default 90 days ago)
- `id` (integer, required): Keyword slot id (from a keyword watch, or list_tracked_keywords)
- `to` (string): End date or datetime (ISO), default now.

### `watch` (~514 tokens)

Watch

Watch an app, a set of competitors or a set of keywords; significant changes become events (get_events, webhooks, daily email). kind app {app}: new versions, metadata and price changes, featuring, rating drops, review and ratings spikes, chart entries. kind competitor_set {competitors, app?}: the same for every competitor. kind keyword {terms, store or app}: the app's rank moves per term and new apps in the top N. Watched apps count against the plan's watch limit, keyword watches use one keyword slot per term × store × country; over a limit nothing changes (plan_limit). With id, changes that watch instead (send only what changes; settings are merged; active=false pauses it). Cost: 0 credits.

Input parameters:

- `active` (boolean): false pauses the watch, true resumes it
- `app` (string): Any app id, bundle id, package, store URL or name. kind app: the app (required); competitor_set: your own app (optional); keyword: the app whose ranks to report (optional)
- `competitors` (array): kind competitor_set: the apps to watch (any identifiers), up to 50
- `countries` (array): Two-letter country codes to watch in (default ['us'])
- `event_types`: Only these event types (default: every type of the kind)
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (integer): Watch id to change (from list_watches). Omit to create a watch
- `kind` (string): 'app' (one app), 'competitor_set' (several apps) or 'keyword' (search terms). Required when creating
- `name`: A label for the watch
- `settings` (object): Thresholds: significance (0–1, default 0.5, minimum for an event), rank_move (default 5), keyword_top_n (10), chart_top_n (100), rating_drop (stars over 7 days, 0.1), spike_factor (3), email_digest (…
- `store` (string): 'apple', 'play' or 'both' (keyword watches without app; default both). Also disambiguates app inputs
- `terms` (array): kind keyword: search terms, e.g. ['habit tracker', 'streaks']

### `unwatch` (~66 tokens)

Unwatch

Stop watches by id (from list_watches or watch): no new events, and their watched apps and keyword slots are freed. Past events are kept. To pause instead, call watch with id and active=false. Cost: 0 credits.

Input parameters:

- `ids` (array, required): Watch ids

### `list_watches` (~170 tokens)

List Watches

Your watches (apps, competitor sets, keyword sets), newest first, with id, apps, terms, countries, event types and whether they are paused, plus watched apps and keyword slots used vs the plan's limits. Filter by kind or by an app they include. Cost: 0 credits.

Input parameters:

- `app` (string): Only watches that include this app (any id, bundle id, package, URL or name).
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `kind` (string): Only this kind: 'app', 'competitor_set' or 'keyword'.
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).

### `get_events` (~341 tokens)

Get Events

Significant changes on your watched apps and keywords, newest first: type, one-line title, AI summary, significance (0–1), app, country and the key payload fields (version, changes old → new, rating drop, rank move, chart rank…). Filter by type, app, watch, since and min_significance. To check for news, pass since = the created_at of the newest event already handled. Cost: 0 credits.

Input parameters:

- `app` (string): Only events of this app (any id, bundle id, package, URL or name).
- `cursor` (string): `meta.next_cursor` from the previous page.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `limit` (integer): Max items to return. Default: 50.
- `min_significance` (number): Only events at least this significant (0–1).
- `since` (string): Only items at or after this ISO date / datetime. Example: 2026-10-01
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `type` (string): Comma list of event types, e.g. 'new_version,rating_drop'. Types: new_version, metadata_change, price_change, featured, in_app_event, installs_milestone, rating_drop, ratings_spike, review_spike, neg…
- `watch` (integer): Only events of this watch id.

### `get_developer` (~170 tokens)

Get Developer

A developer's profile: name, website, country, app count, total ratings and installs, all their apps (most-rated first) and the same company in the other store. get_app shows the developer id as dev <store>:<id>. Cost: 1 credits.

Input parameters:

- `dev` (string, required): `apple:<artist id>`, `play:<developer id>`, a numeric Apple artist id, a Play developer id (often the name), or the website domain (`spotify.com`). Example: apple:324684583
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).

### `get_job` (~105 tokens)

Get Job

Poll a background store fetch that another call started (its output said refreshing or still being fetched, with a job id): status, per-country progress. When it is done, repeat the original call. Cost: 0 credits.

Input parameters:

- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (string, required): `meta.freshness.job_id`, e.g. `fetch_123`.

### `list_connections` (~135 tokens)

List Connections

The user's connected App Store Connect, Play Console and Apple Ads accounts: connection id, provider, mode (actions or read_only), status and the linked apps. Start here before read_connection or propose_action; secrets are never returned. No connections yet: the user adds them at https://dash.appgoat.ai/connections. Cost: 0 credits.

Input parameters:

- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `provider` (string): Only this provider: 'asc' (App Store Connect), 'play_console' or 'apple_ads'.

### `read_connection` (~592 tokens)

Read Connection

Read live data from one of the user's connected accounts. what='reviews' (asc, play_console): the app's own reviews with reply status, unanswered=true for those without a developer reply; their review_id feeds propose_action review.reply (Play only returns reviews from the last 7 days). what='listing' (asc, play_console): the current listing text for one locale with lengths and which fields are editable right now (App Store name, subtitle, description, keywords and what's new need a version in Prepare for Submission). what='ads' (apple_ads): view=campaigns → ad_groups (campaign_id) → keywords (campaign_id, ad_group_id) gives the ids the ads.* actions take, view=negatives lists negative keywords, view=report with level=campaigns|adgroups|keywords|searchterms returns impressions, taps, installs, spend, CPT and CPA for start..end (default the last 7 days). Cost: 1 credits.

Input parameters:

- `ad_group_id` (string): ads: ad group id (needed for keywords; optional for negatives)
- `app` (string): A linked app (App Store id or package name); required for reviews and listing
- `campaign_id` (string): ads: campaign id (needed for ad_groups, keywords, negatives and every report level except campaigns)
- `country` (string): reviews: App Store territory filter (two-letter code)
- `cursor` (string): reviews: next_cursor from the previous page
- `end` (string): ads report: end date YYYY-MM-DD (default yesterday, UTC)
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `full_text` (boolean): Return long text (description, release notes, review bodies) in full instead of cut short
- `id` (string, required): Connection id (con_…) from list_connections
- `level` (string): ads report: 'campaigns' (default), 'adgroups', 'keywords' or 'searchterms'
- `limit` (integer): Max rows: reviews up to 200 (default 100), ads up to 1000 (default 200)
- `locale` (string): listing: locale such as en-US, de-DE (default en-US)
- `rating` (string): reviews: star filter, '1', '1,2' or '1-3'
- `start` (string): ads report: start date YYYY-MM-DD (default 7 days before end)
- `unanswered` (boolean): reviews: only reviews without a developer reply
- `view` (string): ads: 'campaigns' (default), 'ad_groups', 'keywords', 'negatives' or 'report'
- `what` (string, required): 'reviews', 'listing' or 'ads' (Apple Ads)

### `propose_action` (~500 tokens)

Propose Action

Prepare a change to the user's connected account as a DRY RUN: nothing is written. AppGoat reads the live account and returns the before → after diff, guardrail results (AI probabilities for store policy, tone and risky claims, plus checks such as character limits and bid jumps) and an action id. ALWAYS show the diff and any guardrail flags to the user and get their go-ahead before calling apply_action. Types and params (app = a linked App Store id or package name, locale like en-US): review.reply {app, review_id, text} (review ids from read_connection what=reviews; Play replies ≤ 350 chars); listing.update {app, locale, fields: {name|title, subtitle, description, promotional_text, whats_new, marketing_url, support_url, privacy_policy_url}} (Play: title, short_description, full_description, video); keywords.set {app, locale, keywords: [..] or 'a,b,c', mode?: replace|add|remove} (App Store, 100 bytes comma-joined); screenshots.upload {app, locale, display_type: APP_IPHONE_67… (asc) or image_type: phoneScreenshots… (play), images: [{url}], replace?}; ads.keyword.bid {campaign_id, ad_group_id, keywords: [{id, bid?, status?: ENABLED|PAUSED}], max_increase?}; ads.keyword.add {campaign_id, ad_group_id, keywords: [{text, match_type?: EXACT|BROAD, bid?}]}; ads.negative.add {campaign_id, ad_group_id?, keywords: [{text, match_type?}]} (Apple Ads ids from read_connection what=ads). Cost: 0 credits.

Input parameters:

- `connection` (string): Connection id from list_connections; optional when exactly one active connection fits the type and app
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `params` (object, required): Params for the type (see the tool description)
- `playbook` (string): The playbook proposing this, e.g. 'reply-to-every-review' (shown to approvers); omit outside a playbook
- `type` (string, required): What to change: review.reply, listing.update, keywords.set, screenshots.upload, ads.keyword.bid, ads.keyword.add or ads.negative.add

### `apply_action` (~244 tokens)

Apply Action

Go ahead with an action from propose_action, after the user has seen its diff and agreed. Outcomes: applied (written to the store / Apple Ads account, 1 credit; when the org has an auto-apply rule the guardrail score clears, or allows agents to approve); pending_approval (a person must approve it in the AppGoat dashboard: give the user the approve link, nothing is written until then); needs a person (it was already pending and agents may not approve: hand over the link, do not retry); changed (the account changed since the dry run: the new diff is shown; show it to the user and call again with force=true only if they accept it, or propose_action again). Cost: 1 credit when applied, else 0 credits.

Input parameters:

- `force` (boolean): Apply the recomputed diff even though the account changed since the dry run. Only after the user has seen the new diff
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (string, required): Action id (act_…) from propose_action

### `get_action` (~112 tokens)

Get Action

One action from propose_action: its status (draft, pending_approval, approved, applied, failed, rejected), diff, guardrail scores, the provider result or error, the approve link and the audit trail. Use it to check whether a pending action was approved and applied. Cost: 0 credits.

Input parameters:

- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (string, required): Action id (act_…)

### `reject_action` (~90 tokens)

Reject Action

Discard a draft or pending action the user does not want; nothing is written to the account. Cost: 0 credits.

Input parameters:

- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (string, required): Action id (act_…)
- `reason` (string): Why (shown in the audit log)

### `audit_app` (~432 tokens)

Audit App

Run an App Audit of one app in one country: a 0–100 score, prioritised ASO actions with evidence, title / subtitle / keyword rewrites within the store character limits, and findings from listing, ratings, reviews, keywords and competitors, plus a shareable report page. Takes 1–3 minutes: waits about 25 s, then returns the audit id to pass to get_audit. An audit of the same app, country and mode from the last 24 h is returned again for free unless fresh=true; failed audits are not charged. The first audit of an organization is free (free_only=true runs only that one). Cost: 100 credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): Two-letter country code, one storefront (default 'us').
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `free_only` (boolean): Only run when it is the free first audit (402 free_audit_used otherwise). Default: false.
- `fresh` (boolean): Run again even if a recent audit exists. Default: false.
- `label`: Your label for the audit list, e.g. the client or prospect name.
- `mode` (string): lite = cached data, fewer reviews and keywords (cheaper and faster for us; same price). Default: full.
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `white_label` (boolean): Studio: the shareable report shows the organization's branding (set in the dashboard under Settings → Report branding) instead of AppGoat's, e.g. for client or prospect reports.

### `get_audit` (~142 tokens)

Get Audit

Check on an App Audit that audit_app started (by its id, e.g. aud_3fK9aQ2mXc81LpRt): waits up to about 25 s for it to finish, then returns the report (score, actions, metadata rewrites, findings, report page) or its status. Cost: 0 credits.

Input parameters:

- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `id` (string, required): Audit id from audit_app, e.g. aud_3fK9aQ2mXc81LpRt

### `get_insights` (~295 tokens)

Get Review Insights

What an app's users praise and complain about, from the AI tags on its reviews: top issues (topics behind negative, bug, crash, UX and pricing reviews) with last-30-days vs previous-30-days counts and sample reviews, topics, what each recent version changed in rating, sentiment and topics, and weekly sentiment. Use it for "what do users complain about since v2.3?" before reading individual reviews with get_reviews. Cost: 25 credits.

Input parameters:

- `app` (string, required): Any app identifier: App Store id (`284882215`, `id284882215`), Play package (`com.spotify.music`), Apple bundle id (`com.spotify.client`), store URL (URL-encoded), `apple:<id>` / `play:<id>`, or a na…
- `country` (string): One storefront; omit for every storefront we hold reviews for.
- `format` (string): 'markdown' (default): compact tables for reading. 'json': the API's raw { data, meta }
- `since_days` (integer): How many days of reviews to analyse, 7–730 (default 180).
- `store` (string): Disambiguates `{app}` (a bundle id vs a Play package, or a name).
- `versions` (integer): How many of the latest versions to break down. Default: 6.

### `list_playbooks` (~127 tokens)

List Playbooks

AppGoat playbooks: step-by-step recipes (which tools to call, credit budget, decision rules, output format) for app audits, app idea research, ASO metadata rewrites, weekly competitor digests, turning reviews into GitHub issues, and, on connected accounts, replying to every review, optimizing Apple Ads and pushing localized listings. Without name, lists them; with name, returns the full playbook to follow. Also offered as MCP prompts. Free.

Input parameters:

- `name` (string): A playbook name from the list, e.g. 'app-audit-lite'

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/ai-appgoat-mcp/api#diagnostics

## Score history

- 2026-10-23: 73

## Common questions

### What is the AppGoat MCP server?

AppGoat is an MCP server listed in the public MCP registry as ai.appgoat/mcp. App Store and Google Play data: apps, reviews, keywords, charts, competitors, ASO playbooks. This page covers its hosted endpoint (https://api.appgoat.ai/mcp).

### Is the AppGoat MCP server safe to use?

AppGoat scores 73 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the AppGoat MCP server expose?

AppGoat exposes 29 tools: get_app, get_reviews, get_app_history, get_app_changes, get_app_keywords, and 24 more. Their descriptions and schemas cost roughly 7,503 tokens of context every time the server is loaded.

### Does the AppGoat MCP server require authentication?

Yes. AppGoat asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.

### Is the AppGoat MCP server still maintained?

AppGoat is still listed as active in the MCP registry. We last reached this channel on 23 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

## Links

- Remote endpoint: https://api.appgoat.ai/mcp
- Website: https://appgoat.ai/
- Changelog RSS feed: https://verifymcp.io/servers/ai-appgoat-mcp/api.xml
- Changelog JSON feed: https://verifymcp.io/servers/ai-appgoat-mcp/api.json
- HTML version of this page: https://verifymcp.io/servers/ai-appgoat-mcp/api
