ASO tools for AI agents: keyword research, rank tracking, competitor analysis (iOS & Android).
app.trysonar/sonar (MCP) — App Store Optimization for AI agents
The app.trysonar/sonar MCP server provides ASO tools for AI agents. It supports tasks including keyword research, rank tracking, competitor analysis for iOS and Android, and additional ASO workflows mentioned in the server’s readme excerpt.
🛠️ Key Features
App Store Optimization (ASO) tooling for AI agents
Keyword research
Rank tracking
Competitor analysis for iOS and Android
Tooling surface exposed via MCP
🚀 Use Cases
Performing ASO research with MCP-compatible clients
Auditing app store performance and tracking rank changes
Comparing competitors across iOS and Android markets
⚡ Developer Benefits
MCP-compatible access to ASO functions
Designed for Model Context Protocol clients (e.g., Claude Desktop/Code and similar)
⚠️ Limitations
The provided description focuses on ASO tasks for iOS and Android; no other platforms are specified.
Look up a single app by its store ID. Returns app metadata including name, developer, category, rating, reviews, installs (Android), and price. Works without an API key (free tier, limited daily use per IP).
Parameters3
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
store_id
string
required
Store-specific app identifier. iOS: numeric track ID (e.g. "123456789"). Android: package name (e.g. "com.spotify.music").
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
Search apps in the App Store or Google Play by keyword. Returns ranked list of apps with metadata (results are returned in store ranking order). Works without an API key (free tier, limited daily use per IP).
Parameters4
query
string
required
Search query (e.g. "meditation", "meal planner").
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
Calculate an ASO (App Store Optimization) audit score (0-100) for an app. Returns the overall score plus an itemized breakdown of checks (title length, keyword usage, screenshots, ratings, etc.) so you can identify what to improve. Works without an API key (free tier, limited daily use per IP).
Parameters3
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
Extract the most likely target keywords from an app's title and description, ranked by relevance. Useful for understanding what an app (yours or a competitor) is optimizing for. Works without an API key (free tier, limited daily use per IP).
Parameters4
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
Fetch user reviews for an app. Supports filtering by star rating range and sorting by recent or helpful. Useful for sentiment analysis, feature-request mining, and competitive research.
Parameters7
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
Filter to reviews with a star rating >= this value (1-5).
max_rating
integer
optional
Filter to reviews with a star rating <= this value (1-5).
limit
integer
optional
Maximum number of reviews to return (1-200).
Raw schema
{
"type": "object",
"properties": {
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"store_id": {
"type": "string",
"minLength": 1,
"description": "Store-specific app identifier. iOS: numeric track ID. Android: package name."
},
"country": {
"default": "us",
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\", \"gb\", \"de\"). Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
},
"sort": {
"default": "recent",
"description": "Sort order. \"recent\" returns newest first, \"helpful\" returns most-voted first.",
"type": "string",
"enum": [
"recent",
"helpful"
]
},
"min_rating": {
"description": "Filter to reviews with a star rating >= this value (1-5).",
"type": "integer",
"minimum": 1,
"maximum": 5
},
"max_rating": {
"description": "Filter to reviews with a star rating <= this value (1-5).",
"type": "integer",
"minimum": 1,
"maximum": 5
},
"limit": {
"description": "Maximum number of reviews to return (1-200).",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"store",
"store_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_app_revenue
Estimate monthly revenue for an app, based on install counts, ratings, and category benchmarks. Returns the dollar estimate, a confidence grade (high/medium/low) with the factors behind it, and the methodology used — always communicate the confidence alongside the number.
Parameters3
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
Research a keyword and related terms. Returns difficulty (0-100), popularity score, and results count for the seed keyword plus related autocomplete suggestions. Use this to find keywords worth targeting.
Parameters3
query
string
required
Seed keyword to research (e.g. "meditation", "recipe app").
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
Difficulty + popularity for a specific keyword (or up to 25 in bulk). Use this when you already know which keywords you care about — costs 1 credit per keyword. Works without an API key for up to 5 keywords/day (free tier, per IP); an API key removes that cap. Use sonar_keyword_search instead when you want related keyword ideas alongside metrics.
Parameters4
keyword
string
optional
Single keyword to fetch metrics for. Use this OR `keywords`, not both.
keywords
array
optional
Bulk list of keywords to fetch metrics for (max 25). Use this OR `keyword`, not both. 1 credit per keyword.
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
Raw schema
{
"type": "object",
"properties": {
"keyword": {
"description": "Single keyword to fetch metrics for. Use this OR `keywords`, not both.",
"type": "string",
"minLength": 1
},
"keywords": {
"description": "Bulk list of keywords to fetch metrics for (max 25). Use this OR `keyword`, not both. 1 credit per keyword.",
"minItems": 1,
"maxItems": 25,
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"country": {
"default": "us",
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\", \"gb\", \"de\"). Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"store"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_keyword_suggestions
Get autocomplete suggestions for a seed keyword from the App Store or Google Play. Returns terms with a priority score (higher = more searched). Lighter and faster than sonar_keyword_search — use when you only need term ideas without difficulty/popularity scoring. Works without an API key (free tier, limited daily use per IP).
Parameters3
seed
string
required
Seed keyword. The store will return autocomplete suggestions starting from this term.
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
Raw schema
{
"type": "object",
"properties": {
"seed": {
"type": "string",
"minLength": 1,
"description": "Seed keyword. The store will return autocomplete suggestions starting from this term."
},
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"country": {
"default": "us",
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\", \"gb\", \"de\"). Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"seed",
"store"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_top_charts
Get a store top chart (free / paid / grossing, overall or by category) with day-over-day movement: per-app rank delta, apps new to the chart, biggest movers and apps that dropped out. Use to see what's rising in a market or category. Note: summary, movers and droppedApps always describe the full top 200 — `limit` truncates the returned entries only. Movement is empty on the first day a chart is requested (no previous snapshot yet). Works without an API key (free tier, limited daily use per IP).
Parameters5
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us", "gb", "de"). Default "us".
chart
string
optional
Chart type: "free", "paid" or "grossing". Default "free".
category
string
optional
Category key, e.g. "HEALTH_AND_FITNESS" (iOS) or "HEALTH_AND_FITNESS" / "GAME" (Android). Use "overall" (default) for the store-wide chart.
limit
integer
optional
Number of chart entries to return (1-200). Default 50.
Raw schema
{
"type": "object",
"properties": {
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"country": {
"default": "us",
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\", \"gb\", \"de\"). Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
},
"chart": {
"default": "free",
"description": "Chart type: \"free\", \"paid\" or \"grossing\". Default \"free\".",
"type": "string",
"enum": [
"free",
"paid",
"grossing"
]
},
"category": {
"default": "overall",
"description": "Category key, e.g. \"HEALTH_AND_FITNESS\" (iOS) or \"HEALTH_AND_FITNESS\" / \"GAME\" (Android). Use \"overall\" (default) for the store-wide chart.",
"type": "string"
},
"limit": {
"default": 50,
"description": "Number of chart entries to return (1-200). Default 50.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"store"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_list_apps
List the apps tracked in the caller's Sonar workspace (own apps + competitors), each with its latest snapshot (rating, review count, version, installs). Returns the Sonar app UUIDs needed by sonar_get_app, sonar_app_keywords, sonar_app_rankings, and sonar_app_changes. Cursor-paginated (default 100 per page). Requires an Indie plan (trial counts).
Parameters2
cursor
string
optional
Pagination cursor from a previous call's `next_cursor`. Omit for the first page.
limit
integer
optional
Page size (1-200). Server default applies when omitted.
Raw schema
{
"type": "object",
"properties": {
"cursor": {
"description": "Pagination cursor from a previous call's `next_cursor`. Omit for the first page.",
"type": "string",
"minLength": 1
},
"limit": {
"description": "Page size (1-200). Server default applies when omitted.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_get_app
Get full details for one tracked app in the caller's Sonar workspace: store metadata plus up to 90 daily snapshots of rating, review count, version, and installs. Requires an Indie plan (trial counts).
Parameters1
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_app_keywords
List the keywords tracked for an app in the caller's Sonar workspace, with latest difficulty, popularity, results count, note, and starred_at (favorite/target marker) per keyword. Returns the tracked-keyword ids used by sonar_update_keyword_note and sonar_star_keyword, and the keyword_ids used by sonar_keyword_rankings. Cursor-paginated (default 50 per page). Requires an Indie plan (trial counts).
Parameters3
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
cursor
string
optional
Pagination cursor from a previous call's `next_cursor`. Omit for the first page.
limit
integer
optional
Page size (1-200). Server default applies when omitted.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"cursor": {
"description": "Pagination cursor from a previous call's `next_cursor`. Omit for the first page.",
"type": "string",
"minLength": 1
},
"limit": {
"description": "Page size (1-200). Server default applies when omitted.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_app_rankings
Rank history for an app's tracked keywords — daily ranks over the requested window, one history array per keyword. Use this to check how rankings moved after a metadata change or to find keywords trending up or down. Cursor-paginated over keywords (default 50 per page). Requires an Indie plan (trial counts).
Parameters5
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
days
integer
optional
History window in days (1-365). Default 30.
keyword_id
string
optional
Restrict to one keyword — a keyword_id from sonar_app_keywords. Omit for all tracked keywords.
cursor
string
optional
Pagination cursor from a previous call's `next_cursor`. Omit for the first page.
limit
integer
optional
Page size (1-200). Server default applies when omitted.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"days": {
"description": "History window in days (1-365). Default 30.",
"type": "integer",
"minimum": 1,
"maximum": 365
},
"keyword_id": {
"description": "Restrict to one keyword — a keyword_id from sonar_app_keywords. Omit for all tracked keywords.",
"type": "string",
"minLength": 1
},
"cursor": {
"description": "Pagination cursor from a previous call's `next_cursor`. Omit for the first page.",
"type": "string",
"minLength": 1
},
"limit": {
"description": "Page size (1-200). Server default applies when omitted.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_app_changes
Change history for a tracked app — detected releases, metadata edits, screenshot swaps, price changes, and category moves, newest first. Useful for correlating rank movements with what the app (or a competitor) changed. Requires an Indie plan (trial counts).
Parameters3
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
type
string
optional
Filter to one change type. Omit for all types.
limit
integer
optional
Max changes to return (1-200). Default 50.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"type": {
"description": "Filter to one change type. Omit for all types.",
"type": "string",
"enum": [
"release",
"metadata",
"screenshots",
"price",
"category"
]
},
"limit": {
"description": "Max changes to return (1-200). Default 50.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_keyword_rankings
SERP history for one tracked keyword — which apps ranked in the top results on each measured day, newest first. Use this to see who competes on a keyword and how the top spots shifted over time. The keyword must be tracked in the caller's Sonar workspace. Requires an Indie plan (trial counts).
Parameters2
keyword_id
string
required
Sonar keyword UUID — a `keyword_id` from sonar_app_keywords or sonar_competitor_keywords. NOT the keyword text.
days
integer
optional
History window in days (1-365). Default 30.
Raw schema
{
"type": "object",
"properties": {
"keyword_id": {
"type": "string",
"minLength": 1,
"description": "Sonar keyword UUID — a `keyword_id` from sonar_app_keywords or sonar_competitor_keywords. NOT the keyword text."
},
"days": {
"description": "History window in days (1-365). Default 30.",
"type": "integer",
"minimum": 1,
"maximum": 365
}
},
"required": [
"keyword_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_competitor_keywords
Keywords a tracked competitor currently ranks for (last 7 days of SERP data), with difficulty and popularity per keyword. Pass own_app_id for gap analysis: keywords where the competitor ranks but your app doesn't are marked gap=missing. Cursor-paginated (default 50 per page). Requires an Indie plan (trial counts).
Parameters4
competitor_app_id
string
required
Sonar app UUID of the competitor — the `competitor.id` from sonar_track_competitor, or an `id` from sonar_list_apps where is_own is false. NOT a store id.
own_app_id
string
optional
Sonar app UUID of your own app. When set, each keyword includes your current rank and a gap marker for keywords you don't rank for.
cursor
string
optional
Pagination cursor from a previous call's `next_cursor`. Omit for the first page.
limit
integer
optional
Page size (1-200). Server default applies when omitted.
Raw schema
{
"type": "object",
"properties": {
"competitor_app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of the competitor — the `competitor.id` from sonar_track_competitor, or an `id` from sonar_list_apps where is_own is false. NOT a store id."
},
"own_app_id": {
"description": "Sonar app UUID of your own app. When set, each keyword includes your current rank and a gap marker for keywords you don't rank for.",
"type": "string",
"minLength": 1
},
"cursor": {
"description": "Pagination cursor from a previous call's `next_cursor`. Omit for the first page.",
"type": "string",
"minLength": 1
},
"limit": {
"description": "Page size (1-200). Server default applies when omitted.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"required": [
"competitor_app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_competitor_landscape
The full competitive keyword picture for one of your own apps vs every tracked competitor, in one call: live stats (keyword gaps where competitors rank and you don't, winnable gaps, competitors climbing on your tracked keywords, keywords you lead), the top gap/threat/lead rows with metrics, and the latest AI insight if one was generated (opportunity clusters, threat narratives, strengths, posture). Read this before deciding which keywords to target next. Requires an Indie plan (trial counts).
Parameters1
app_id
string
required
Sonar app UUID of YOUR OWN tracked app (an `id` from sonar_list_apps where is_own is true). NOT a store id, NOT a competitor id.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Sonar app UUID of YOUR OWN tracked app (an `id` from sonar_list_apps where is_own is true). NOT a store id, NOT a competitor id."
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_list_products
List your products with their linked store versions and competitor counts. Use it to discover product/app UUIDs. Requires an Indie plan (trial counts).
List your alert subscriptions — each rule defines a change type (rank drops, review spikes, etc.), its scope (a specific app or org-wide), threshold, and whether it's enabled. Requires an Indie plan (trial counts).
The detected alert events for your workspace, newest first — the same feed as the in-app Recent Alerts panel and the email digest: rank drops/gains, top-10 entries/exits, new rankings, rating drops, review spikes, and competitor changes, each with a type-specific payload (app/keyword names, old vs new values). Events only exist for alert types you've enabled rules for (sonar_set_alert); detection runs once daily. Poll with `since` to react to changes programmatically. Requires an Indie plan (trial counts).
Parameters4
type
string
optional
Filter to one alert type. Omit for all types.
app_id
string
optional
Filter to events about one tracked app (Sonar app UUID or store id).
since
string
optional
Only events created at/after this ISO 8601 timestamp (e.g. "2026-08-01T00:00:00Z"). Use your last poll time to fetch only new events.
limit
integer
optional
Max events to return (1-200). Default 50.
Raw schema
{
"type": "object",
"properties": {
"type": {
"description": "Filter to one alert type. Omit for all types.",
"type": "string",
"enum": [
"rank_drop",
"rank_gain",
"entered_top10",
"left_top10",
"new_ranking",
"rating_drop",
"review_spike",
"competitor_change"
]
},
"app_id": {
"description": "Filter to events about one tracked app (Sonar app UUID or store id).",
"type": "string",
"minLength": 1
},
"since": {
"description": "Only events created at/after this ISO 8601 timestamp (e.g. \"2026-08-01T00:00:00Z\"). Use your last poll time to fetch only new events.",
"type": "string",
"minLength": 1
},
"limit": {
"description": "Max events to return (1-200). Default 50.",
"type": "integer",
"minimum": 1,
"maximum": 200
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_app_overview
The dashboard's computed scoreboard for one of your apps in a single call: visibility index and share of voice (with 7-day deltas and a daily spark), ranked / top-10 keyword counts with movement, best rank, the biggest 7-day improvements and drops, the rank-distribution trend, and the actionable opportunity list (near_page_one / top_three_push / easy_target). Read this FIRST when asked how an app is doing — it's the same numbers the dashboard renders, so you don't need to recompute anything from raw rank history. Requires an Indie plan (trial counts).
Parameters2
app_id
string
required
Sonar app UUID of one of your own tracked apps — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
days
integer
optional
Rank-history window in days (7-90). Default 30.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of one of your own tracked apps — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"days": {
"description": "Rank-history window in days (7-90). Default 30.",
"type": "integer",
"minimum": 7,
"maximum": 90
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_discovered_keywords
Keywords Sonar's discovery engine surfaced for one of your tracked apps but that aren't tracked yet — ranked finds (the app already ranks, unnoticed), competitor gaps, and AI/autocomplete-sourced ideas — each with popularity, difficulty, AI relevance, and an opportunity score (0-100, best first). This is Sonar's "what should I track next" answer: read it, pick the winners, then track them with sonar_track_keywords. Requires an Indie plan (trial counts).
Parameters8
app_id
string
required
Sonar app UUID of one of your tracked apps — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
country
string
optional
Filter to one market (ISO country code). Omit for all markets.
source
string
optional
Filter by how the keyword was discovered. Omit for all sources.
status
string
optional
Filter by row status. Default "new" — the still-actionable suggestions; "all" includes rows already tracked or hidden.
bucket
string
optional
Filter by classification: "ranked" = the app already ranks for it, "gap" = a competitor ranks but the app does not, "idea" = verified research suggestion with no rank evidence yet. Omit for all.
min_relevance
integer
optional
Only rows with AI relevance at or above this value (0-100).
min_opportunity
integer
optional
Only rows with an opportunity score at or above this value (0-100).
limit
integer
optional
Max rows to return (1-500). Default 200.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of one of your tracked apps — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"country": {
"description": "Filter to one market (ISO country code). Omit for all markets.",
"type": "string",
"minLength": 2,
"maxLength": 2
},
"source": {
"description": "Filter by how the keyword was discovered. Omit for all sources.",
"type": "string",
"enum": [
"autocomplete",
"metadata",
"serp_scan",
"competitor",
"apple_ads",
"ai"
]
},
"status": {
"description": "Filter by row status. Default \"new\" — the still-actionable suggestions; \"all\" includes rows already tracked or hidden.",
"type": "string",
"enum": [
"new",
"tracked",
"hidden",
"all"
]
},
"bucket": {
"description": "Filter by classification: \"ranked\" = the app already ranks for it, \"gap\" = a competitor ranks but the app does not, \"idea\" = verified research suggestion with no rank evidence yet. Omit for all.",
"type": "string",
"enum": [
"ranked",
"gap",
"idea"
]
},
"min_relevance": {
"description": "Only rows with AI relevance at or above this value (0-100).",
"type": "integer",
"minimum": 0,
"maximum": 100
},
"min_opportunity": {
"description": "Only rows with an opportunity score at or above this value (0-100).",
"type": "integer",
"minimum": 0,
"maximum": 100
},
"limit": {
"description": "Max rows to return (1-500). Default 200.",
"type": "integer",
"minimum": 1,
"maximum": 500
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_review_insights
The latest AI review analysis for a tracked app (your own or a competitor): what users praise and complain about as named themes with frequency, verbatim quotes, and trend movement (new / persisting / growing / improving / resolved), plus overall sentiment, surfaced feature requests, and what changed vs the previous analysis. `insight` is null if none has been generated yet — use sonar_generate_review_insights. Requires an Indie plan (trial counts).
Parameters2
app_id
string
required
Sonar app UUID of a tracked app — your own or a competitor (an `id` from sonar_list_apps). NOT a store id.
country
string
optional
Reviews market (ISO country code). Insights are generated per country. Default "us".
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of a tracked app — your own or a competitor (an `id` from sonar_list_apps). NOT a store id."
},
"country": {
"default": "us",
"description": "Reviews market (ISO country code). Insights are generated per country. Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_portfolio
The whole portfolio's health in one call — for orgs managing many apps: per-app KPIs (visibility + 7-day delta, ranked/top-10 counts, net rank movement, rating, review count), org-wide totals, the biggest keyword movers in both directions, a needs-attention triage list (visibility drops, rating drops, not-ranked apps), and the best discovered-keyword opportunities across all apps. Same numbers as the /portfolio page. Requires an Agency plan (403 on other plans).
WRITE tool — creates a product in the caller's Sonar workspace and starts tracking the given app(s). A product is the cross-store unit (one iOS + one Android app, or just one of either). Returns the product id and the Sonar app ids needed by sonar_track_keywords and sonar_track_competitor. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters2
apps
array
required
1-2 store versions: a single iOS or Android app, or one of each for a cross-store product.
name
string
optional
Product name. Optional — defaults to the first app's name.
Raw schema
{
"type": "object",
"properties": {
"apps": {
"minItems": 1,
"maxItems": 2,
"type": "array",
"items": {
"type": "object",
"properties": {
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"store_id": {
"type": "string",
"minLength": 1,
"description": "Store-specific app identifier. iOS: numeric track ID. Android: package name."
},
"country": {
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\"). Optional — defaults server-side.",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"store",
"store_id"
],
"description": "One store version of the product."
},
"description": "1-2 store versions: a single iOS or Android app, or one of each for a cross-store product."
},
"name": {
"description": "Product name. Optional — defaults to the first app's name.",
"type": "string",
"minLength": 1,
"maxLength": 120
}
},
"required": [
"apps"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_track_app
WRITE tool — links the second-store version of an existing Sonar product (e.g. the product already tracks the iOS app and you want to add the Android version, or vice versa). Each product holds at most one iOS + one Android app; to start tracking a brand-new app, use sonar_create_product instead. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters4
product_id
string
required
Sonar product UUID (from sonar_create_product). NOT a store id.
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
store_id
string
required
Store-specific app identifier of the version to link. iOS: numeric track ID. Android: package name.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us"). Optional — defaults server-side.
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Sonar product UUID (from sonar_create_product). NOT a store id."
},
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"store_id": {
"type": "string",
"minLength": 1,
"description": "Store-specific app identifier of the version to link. iOS: numeric track ID. Android: package name."
},
"country": {
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\"). Optional — defaults server-side.",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"product_id",
"store",
"store_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_track_competitor
WRITE tool — adds a competitor app under a Sonar product so its keywords and rankings get tracked alongside the product's own app. The product must already have its own app linked in the same store as the competitor. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters4
product_id
string
required
Sonar product UUID (from sonar_create_product). NOT a store id.
store
string
required
App store. "ios" for Apple App Store, "android" for Google Play.
store_id
string
required
Store-specific app identifier of the COMPETITOR app to track. iOS: numeric track ID. Android: package name.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us"). Optional — defaults server-side.
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Sonar product UUID (from sonar_create_product). NOT a store id."
},
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "App store. \"ios\" for Apple App Store, \"android\" for Google Play."
},
"store_id": {
"type": "string",
"minLength": 1,
"description": "Store-specific app identifier of the COMPETITOR app to track. iOS: numeric track ID. Android: package name."
},
"country": {
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\"). Optional — defaults server-side.",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"product_id",
"store",
"store_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_track_keywords
WRITE tool — starts daily rank tracking for one or more keywords on an app in the caller's Sonar workspace. Idempotent: re-posting the same terms reports them as already_tracked instead of creating duplicates. Returns per-keyword outcomes (created / already_tracked / failed). Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters3
app_id
string
required
Sonar app UUID — the `apps[].id` returned by sonar_create_product (or sonar_track_app). NOT a store id; the store is implied by the app.
keywords
array
required
Keywords to start tracking (1-200). Duplicates and already-tracked terms are reported, not duplicated.
country
string
optional
ISO 3166-1 alpha-2 country code (e.g. "us"). Optional — defaults to the product's country.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `apps[].id` returned by sonar_create_product (or sonar_track_app). NOT a store id; the store is implied by the app."
},
"keywords": {
"minItems": 1,
"maxItems": 200,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 120
},
"description": "Keywords to start tracking (1-200). Duplicates and already-tracked terms are reported, not duplicated."
},
"country": {
"description": "ISO 3166-1 alpha-2 country code (e.g. \"us\"). Optional — defaults to the product's country.",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"app_id",
"keywords"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_update_keyword_note
WRITE tool — sets or clears the note on a tracked keyword in the caller's Sonar workspace (e.g. why it's tracked, an optimization hypothesis, a reminder). Idempotent: re-sending the same note is a no-op. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters2
tracked_keyword_id
string
required
Tracked-keyword UUID — the `id` (not keyword_id) returned by sonar_app_keywords or sonar_track_keywords.
note
any
required
Note text (max 1000 chars). Pass null or an empty string to clear the note.
Raw schema
{
"type": "object",
"properties": {
"tracked_keyword_id": {
"type": "string",
"minLength": 1,
"description": "Tracked-keyword UUID — the `id` (not keyword_id) returned by sonar_app_keywords or sonar_track_keywords."
},
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 1000
},
{
"type": "null"
}
],
"description": "Note text (max 1000 chars). Pass null or an empty string to clear the note."
}
},
"required": [
"tracked_keyword_id",
"note"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_star_keyword
WRITE tool — stars or unstars a tracked keyword in the caller's Sonar workspace. A star marks the keyword as a favorite/target the user is actively pursuing; starred keywords carry a starred_at timestamp in sonar_app_keywords results. Idempotent: re-starring refreshes the timestamp, unstarring a non-starred keyword is a no-op. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters2
tracked_keyword_id
string
required
Tracked-keyword UUID — the `id` (not keyword_id) returned by sonar_app_keywords or sonar_track_keywords.
starred
boolean
required
true to star the keyword (mark as a favorite/target), false to unstar.
Raw schema
{
"type": "object",
"properties": {
"tracked_keyword_id": {
"type": "string",
"minLength": 1,
"description": "Tracked-keyword UUID — the `id` (not keyword_id) returned by sonar_app_keywords or sonar_track_keywords."
},
"starred": {
"type": "boolean",
"description": "true to star the keyword (mark as a favorite/target), false to unstar."
}
},
"required": [
"tracked_keyword_id",
"starred"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_scan_competitor
WRITE tool — runs an AI keyword discovery scan on a tracked competitor: generates the search terms the competitor's listing is optimized for (brand terms included), queues them for SERP verification, and verifies the first batch inline (~30s), recording both apps' ranks. Returns generated/queued/verified_now counts; the rest verify in the background over the following hours — read results with sonar_competitor_keywords. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters2
competitor_app_id
string
required
Sonar app UUID of the competitor to scan — the `competitor.id` from sonar_track_competitor, or an `id` from sonar_list_apps where is_own is false. NOT a store id.
own_app_id
string
required
Sonar app UUID of your own app the scan compares against. The competitor must be linked to this app.
Raw schema
{
"type": "object",
"properties": {
"competitor_app_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Sonar app UUID of the competitor to scan — the `competitor.id` from sonar_track_competitor, or an `id` from sonar_list_apps where is_own is false. NOT a store id."
},
"own_app_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Sonar app UUID of your own app the scan compares against. The competitor must be linked to this app."
}
},
"required": [
"competitor_app_id",
"own_app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_analyze_competitors
WRITE tool — generates a fresh AI competitive insight for one of your own apps: clusters the keyword gaps vs your competitors into named opportunity themes (with a why-now narrative and per-keyword metrics), writes threat narratives for competitors climbing on your keywords, and diffs against the previous analysis. At most one analysis per app per 7 days (429 with the next available time while in cooldown — use sonar_competitor_landscape to read the current one). Requires a paid (non-trial) Indie plan and an API key with the write scope.
Parameters1
app_id
string
required
Sonar app UUID of YOUR OWN tracked app to analyze. NOT a store id, NOT a competitor id.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Sonar app UUID of YOUR OWN tracked app to analyze. NOT a store id, NOT a competitor id."
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_generate_review_insights
WRITE tool — generates a fresh AI review analysis for a tracked app from its recent reviews (praise/complaint themes, sentiment, feature requests, trend vs the previous run). At most one analysis per app+country every 90 days (429 with the next available time while in cooldown — use sonar_review_insights to read the current one); needs at least 5 recent reviews. Requires a paid (non-trial) Indie plan and an API key with the write scope.
Parameters2
app_id
string
required
Sonar app UUID of a tracked app — your own or a competitor (an `id` from sonar_list_apps). NOT a store id.
country
string
optional
Reviews market (ISO country code). Insights are generated per country. Default "us".
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of a tracked app — your own or a competitor (an `id` from sonar_list_apps). NOT a store id."
},
"country": {
"default": "us",
"description": "Reviews market (ISO country code). Insights are generated per country. Default \"us\".",
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_delete_tracked_keyword
WRITE tool — stop tracking one keyword/app pair in the caller's Sonar workspace. Identify the pair by its tracked-keyword id (from sonar_app_keywords). Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters1
tracked_keyword_id
string
required
The tracked-keyword UUID — the `id` returned by sonar_app_keywords. NOT the keyword_id.
Raw schema
{
"type": "object",
"properties": {
"tracked_keyword_id": {
"type": "string",
"minLength": 1,
"description": "The tracked-keyword UUID — the `id` returned by sonar_app_keywords. NOT the keyword_id."
}
},
"required": [
"tracked_keyword_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_untrack_keywords
WRITE tool — bulk-untrack keywords for an app in the caller's Sonar workspace. Pass `all: true` to remove every tracked keyword, OR `ids: [...]` to remove specific ones (exactly one of the two). Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters3
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
all
boolean
optional
Set true to untrack ALL keywords for the app. Mutually exclusive with `ids` — pass exactly one of `all` or `ids`.
ids
array
optional
Tracked-keyword ids to untrack (from sonar_app_keywords). Mutually exclusive with `all` — pass exactly one of `all` or `ids`.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
},
"all": {
"description": "Set true to untrack ALL keywords for the app. Mutually exclusive with `ids` — pass exactly one of `all` or `ids`.",
"type": "boolean"
},
"ids": {
"description": "Tracked-keyword ids to untrack (from sonar_app_keywords). Mutually exclusive with `all` — pass exactly one of `all` or `ids`.",
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_untrack_app
WRITE tool — untrack an app and its associated tracking data in the caller's Sonar workspace. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters1
app_id
string
required
Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id.
Raw schema
{
"type": "object",
"properties": {
"app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID — the `id` returned by sonar_list_apps or sonar_create_product. NOT a store id."
}
},
"required": [
"app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_delete_product
WRITE tool — delete a product and untrack its apps in the caller's Sonar workspace. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters1
product_id
string
required
Sonar product UUID — the `id` returned by sonar_list_products or sonar_create_product.
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Sonar product UUID — the `id` returned by sonar_list_products or sonar_create_product."
}
},
"required": [
"product_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_remove_competitor
WRITE tool — remove a competitor from a product in the caller's Sonar workspace. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters2
product_id
string
required
Sonar product UUID — the `id` returned by sonar_list_products or sonar_create_product.
competitor_app_id
string
required
Sonar app UUID of the competitor to remove (the competitor's `id`, NOT a store id).
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Sonar product UUID — the `id` returned by sonar_list_products or sonar_create_product."
},
"competitor_app_id": {
"type": "string",
"minLength": 1,
"description": "Sonar app UUID of the competitor to remove (the competitor's `id`, NOT a store id)."
}
},
"required": [
"product_id",
"competitor_app_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_set_alert
WRITE tool — create or update an alert subscription in the caller's Sonar workspace. Upserts on (type + scope): re-submitting the same type/scope updates the existing rule. Omit `threshold` for the per-type default; omit `scope_app_id` for an org-wide rule. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters4
type
string
required
The alert type to subscribe to.
scope_app_id
any
optional
Limit the alert to a single app (Sonar app UUID). Omit or null for an org-wide rule covering all tracked apps.
threshold
any
optional
Sensitivity threshold (meaning depends on type). Omit or null to use the per-type default.
enabled
boolean
optional
Whether the rule is active. Defaults to enabled when omitted.
Raw schema
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"rank_drop",
"rank_gain",
"entered_top10",
"left_top10",
"new_ranking",
"rating_drop",
"review_spike",
"competitor_change"
],
"description": "The alert type to subscribe to."
},
"scope_app_id": {
"description": "Limit the alert to a single app (Sonar app UUID). Omit or null for an org-wide rule covering all tracked apps.",
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "null"
}
]
},
"threshold": {
"description": "Sensitivity threshold (meaning depends on type). Omit or null to use the per-type default.",
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
]
},
"enabled": {
"description": "Whether the rule is active. Defaults to enabled when omitted.",
"type": "boolean"
}
},
"required": [
"type"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_delete_alert
WRITE tool — delete an alert subscription in the caller's Sonar workspace. Requires an Indie plan (trial counts) and an API key with the write scope.
Parameters1
id
string
required
The alert subscription UUID — the `id` returned by sonar_list_alerts or sonar_set_alert.
Raw schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"description": "The alert subscription UUID — the `id` returned by sonar_list_alerts or sonar_set_alert."
}
},
"required": [
"id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_screenshot_layout_guide
The layout-format reference for Sonar screenshot sets. Call this ONCE before creating or editing screenshot layouts — it documents the layout JSON schema, coordinate system, image handling (remote URLs), flowing background shapes, fonts, translation overrides, and the recommended workflow.
List the device sizes supported for app-store screenshot sets, with their canvas dimensions (the pixel coordinate space all layouts use) and which store each belongs to. Pick a device here before sonar_create_screenshot_set.
List a product's app-store screenshot sets (metadata only: store, device size, locales, studio_url). Use sonar_get_screenshot_set for full layouts.
Parameters1
product_id
string
required
Product id (find it with sonar_list_products).
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Product id (find it with sonar_list_products)."
}
},
"required": [
"product_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_create_screenshot_set
Create an app-store screenshot set for a product. Read sonar_screenshot_layout_guide first, then author the screens array. The set is immediately visible/editable for humans in the Screenshot Studio (studio_url in the response). Requires a write-scope API key.
Parameters6
product_id
string
required
Product the set belongs to.
store
string
required
Target app store.
device_size
string
required
Device id from sonar_screenshot_devices, e.g. "iphone-6.7".
name
string
optional
Display name.
template_id
string
optional
Seed from a built-in template (see sonar_screenshot_layout_guide) instead of providing screens.
screens
array
optional
Initial screens, in order (max 10). Either this or template_id, not both; with neither you get one blank screen.
Raw schema
{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"minLength": 1,
"description": "Product the set belongs to."
},
"store": {
"type": "string",
"enum": [
"ios",
"android"
],
"description": "Target app store."
},
"device_size": {
"type": "string",
"minLength": 1,
"description": "Device id from sonar_screenshot_devices, e.g. \"iphone-6.7\"."
},
"name": {
"description": "Display name.",
"type": "string",
"minLength": 1,
"maxLength": 120
},
"template_id": {
"description": "Seed from a built-in template (see sonar_screenshot_layout_guide) instead of providing screens.",
"type": "string",
"minLength": 1
},
"screens": {
"description": "Initial screens, in order (max 10). Either this or template_id, not both; with neither you get one blank screen.",
"minItems": 1,
"maxItems": 10,
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "A screenshot layout document ({background, layers}) — see sonar_screenshot_layout_guide. Image fields accept https:// URLs."
}
}
},
"required": [
"product_id",
"store",
"device_size"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_get_screenshot_set
Fetch a screenshot set in full: every screen's layout JSON plus per-screen translation overrides keyed by locale. By default inline image data is replaced with placeholders to keep the response readable.
Parameters2
set_id
string
required
Screenshot set id.
include_image_data
boolean
optional
When false (default), inline base64 images are replaced with short placeholders to keep the response small. Set true only when you need the raw data URLs (a layout containing placeholders is rejected on update).
Raw schema
{
"type": "object",
"properties": {
"set_id": {
"type": "string",
"minLength": 1,
"description": "Screenshot set id."
},
"include_image_data": {
"default": false,
"description": "When false (default), inline base64 images are replaced with short placeholders to keep the response small. Set true only when you need the raw data URLs (a layout containing placeholders is rejected on update).",
"type": "boolean"
}
},
"required": [
"set_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_update_screenshot_set
Rename a screenshot set, replace its extra-locale list, and/or reorder its screens. Returns the updated set (with image data stripped). Requires a write-scope API key.
Parameters4
set_id
string
required
Screenshot set id.
name
string
optional
New display name.
locales
array
optional
Replaces the extra-locale list (e.g. ["de-DE","fr-FR"]). Locales removed here lose their stored translations.
screen_order
array
optional
Full permutation of the set's screen ids in the new display order.
Raw schema
{
"type": "object",
"properties": {
"set_id": {
"type": "string",
"minLength": 1,
"description": "Screenshot set id."
},
"name": {
"description": "New display name.",
"type": "string",
"minLength": 1,
"maxLength": 120
},
"locales": {
"description": "Replaces the extra-locale list (e.g. [\"de-DE\",\"fr-FR\"]). Locales removed here lose their stored translations.",
"maxItems": 40,
"type": "array",
"items": {
"type": "string",
"minLength": 2,
"maxLength": 8
}
},
"screen_order": {
"description": "Full permutation of the set's screen ids in the new display order.",
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
},
"required": [
"set_id"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_delete_screenshot_set
Permanently delete a screenshot set and everything in it (screens, translations). Irreversible — confirm with the user before deleting work they may want. Requires a write-scope API key.
Replace one screen's layout in a screenshot set. Whole-document replace — fetch the current layout, modify it, send it back. The change shows up immediately in the Screenshot Studio for human review. Requires a write-scope API key.
Parameters2
screenshot_id
string
required
Screen id (from the set's screens array).
layout
object
required
The FULL replacement layout — this replaces the whole document, it does not merge. Never send a layout containing '[inline image omitted…]' placeholders; refetch with include_image_data first.
Raw schema
{
"type": "object",
"properties": {
"screenshot_id": {
"type": "string",
"minLength": 1,
"description": "Screen id (from the set's screens array)."
},
"layout": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {},
"description": "The FULL replacement layout — this replaces the whole document, it does not merge. Never send a layout containing '[inline image omitted…]' placeholders; refetch with include_image_data first."
}
},
"required": [
"screenshot_id",
"layout"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
sonar_delete_screenshot
Delete one screen from a screenshot set. A set keeps at least one screen — deleting the last one is rejected. Requires a write-scope API key.
Write a locale's translation overrides for screens in a screenshot set (text copy, localized captures/images). Geometry and styling always come from the source layout; anything not overridden falls back to it. The locale is auto-enabled on the set. Requires a write-scope API key.
Parameters3
set_id
string
required
Screenshot set id.
locale
string
required
Target locale code, e.g. "de-DE", "pt-BR", "zh-Hans".
Render a screenshot set to store-ready PNGs SERVER-SIDE (no browser needed) and save them as one ZIP per locale in output_dir — ready for App Store Connect / Play Console upload. Rendering happens through the same engine as the Screenshot Studio editor. Writes to the filesystem of the machine running the MCP server, so this tool is for local (stdio) use; over the hosted transport call GET /api/v1/screenshots/sets/:id/export directly instead.
Parameters4
set_id
string
required
Screenshot set id.
locales
array
optional
Locales to export (e.g. ["de-DE","ja"]). Use the set's source locale code for the source renders. Omit together with all_locales for source-only.
all_locales
boolean
optional
Export the source locale plus every enabled locale.
output_dir
string
required
Directory to write the ZIPs into (created if missing). One ZIP per locale, named <locale>.zip, each containing store-ready 01.png…NN.png.
Raw schema
{
"type": "object",
"properties": {
"set_id": {
"type": "string",
"minLength": 1,
"description": "Screenshot set id."
},
"locales": {
"description": "Locales to export (e.g. [\"de-DE\",\"ja\"]). Use the set's source locale code for the source renders. Omit together with all_locales for source-only.",
"maxItems": 40,
"type": "array",
"items": {
"type": "string",
"minLength": 2,
"maxLength": 8
}
},
"all_locales": {
"description": "Export the source locale plus every enabled locale.",
"type": "boolean"
},
"output_dir": {
"type": "string",
"minLength": 1,
"description": "Directory to write the ZIPs into (created if missing). One ZIP per locale, named <locale>.zip, each containing store-ready 01.png…NN.png."
}
},
"required": [
"set_id",
"output_dir"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}
Lets Claude Desktop, Claude Code, Cursor, Cline, and any Model Context Protocol-compatible client look up apps, research keywords, audit ASO, mine reviews, and estimate revenue across the iOS App Store and Google Play. Powered by Sonar.
Tools
55 tools covering the whole Sonar REST API, grouped by what they need.
Read tools — stateless (any plan with credits)
Tool
What it does
Works without a key
sonar_app_lookup
Look up app metadata by store ID
Yes
sonar_app_search
Search apps by keyword (returns store ranking order)
Yes
sonar_app_aso_score
ASO audit score (0-100) with itemized checks
Yes
sonar_app_extract_keywords
Extract target keywords from an app's listing
Yes
sonar_app_reviews
Fetch reviews with rating filters and sort options
—
sonar_app_revenue
Estimate monthly revenue with a confidence grade
—
sonar_keyword_search
Keyword research (difficulty, popularity, related terms)
—
sonar_keyword_metrics
Difficulty + popularity for specific keywords (up to 25 per call)
Yes (5 keywords/day)
sonar_keyword_suggestions
Autocomplete suggestions from the store
Yes
sonar_top_charts
Top free/paid/grossing chart with day-over-day movement
Yes
Stateless tools work on any plan with credits (API Credits, Indie or Agency), for both iOS and Android. The ones marked "Yes" also run keyless on the free tier (see "Try it free" below).
Read tools — your workspace (Indie plan)
Tool
What it does
sonar_list_products
List your products with their linked store versions and competitor counts
sonar_list_apps
List your tracked apps with latest snapshots (rating, reviews, installs)
sonar_get_app
App detail + up to 90 days of snapshot history
sonar_app_overview
Dashboard scoreboard for an app: visibility, share of voice, movement, opportunities
sonar_app_keywords
Keywords tracked for an app, with difficulty, popularity, notes and stars
Workspace reads require an Indie plan or higher (an active trial counts); the default read-scope key is enough.
Read tools — Agency plan
Tool
What it does
sonar_portfolio
Portfolio rollup: per-app KPIs, biggest movers, needs-attention list, top opportunities
sonar_app_sales
App Store Connect sales: downloads, redownloads, IAP units, approximate proceeds
sonar_app_engagement
App Store Connect funnel: impressions, page views, downloads, sources, sessions
These require the Agency plan (an Agency trial counts) and return 403 on other plans. sonar_app_sales and sonar_app_engagement are iOS-only and also need an App Store Connect connection at trysonar.app/settings/connections; engagement data needs an Admin-role App Store Connect key.
Write tools (Indie plan + write scope)
Tool
What it does
sonar_create_product
Create a product in your Sonar workspace and start tracking its app(s)
sonar_track_app
Link the second-store version (iOS ↔ Android) of an existing product
sonar_track_competitor
Add a competitor app under a product
sonar_remove_competitor
Remove a competitor from a product
sonar_delete_product
Delete a product and untrack its apps
sonar_untrack_app
Untrack an app and its tracking data
sonar_track_keywords
Start daily rank tracking for keywords on an app (bulk, idempotent)
sonar_update_keyword_note
Set or clear the note on a tracked keyword
sonar_star_keyword
Star or unstar a tracked keyword (mark it as a target)
sonar_delete_tracked_keyword
Stop tracking one keyword/app pair
sonar_untrack_keywords
Bulk-untrack an app's keywords (selected IDs or all)
sonar_scan_competitor
Run an AI keyword discovery scan on a competitor (read results with sonar_competitor_keywords)
sonar_analyze_competitors
Generate a fresh AI competitive insight for one of your apps (7-day cooldown)
sonar_generate_review_insights
Generate a fresh AI review analysis for a tracked app (90-day cooldown)
sonar_set_alert
Create or update an alert rule
sonar_delete_alert
Delete an alert rule
Write tools mutate your workspace and require an Indie plan or higher (an active trial counts) plus either an OAuth sign-in on the hosted endpoint (which carries write access) or an API key created with the write scope. The two AI generation tools, sonar_analyze_competitors and sonar_generate_review_insights, need a paid plan and are not available during the trial. The server enforces all of this — without it, calls return a 403 explaining what to fix.
Together these close the loop for agents: set up tracking with the write tools, then read back rankings, changes, and gap analyses with the workspace tools.
Screenshot Studio (Indie plan)
Tool
What it does
Scope
sonar_screenshot_layout_guide
Layout-format reference; read it once before authoring layouts
none
sonar_screenshot_devices
Supported device sizes and their canvas dimensions
read
sonar_list_screenshot_sets
A product's screenshot sets (metadata only)
read
sonar_get_screenshot_set
A full set: every screen's layout plus translation overrides
read
sonar_create_screenshot_set
Create a screenshot set for a product
write
sonar_update_screenshot_set
Rename a set, replace its locales, or reorder its screens
write
sonar_delete_screenshot_set
Delete a set and everything in it
write
sonar_add_screenshot
Append a screen to a set
write
sonar_update_screenshot
Replace one screen's layout
write
sonar_delete_screenshot
Delete one screen (a set keeps at least one)
write
sonar_set_screenshot_translations
Write a locale's translation overrides
write
sonar_export_screenshots
Render store-ready PNGs into one local ZIP per locale
read
Agents author screenshot sets as layout JSON; humans review and fine-tune the same sets in the Screenshot Studio. The layout guide is embedded in the server and needs no key. sonar_export_screenshots writes files on the machine running the server, so it's available over stdio only, not on the hosted endpoint.
Hosted endpoint — no install, no API key
OAuth-capable MCP clients (Claude Code, claude.ai custom connectors) can skip both the npm install and the API key entirely:
code
claude mcp add --transport http sonar https://trysonar.app/mcp
The first tool call that needs your account opens a browser sign-in — approve it with your Sonar login and the agent has full access to the workspace you own (read + write). Clients without OAuth support can pass an API key instead: --header "Authorization: Bearer aso_...".
ChatGPT submission and hosted behavior
Submit https://trysonar.app/mcp/chatgpt to OpenAI. This endpoint returns tool-level sign-in challenges; /mcp retains HTTP 401 challenges for Claude and other MCP clients. Both advertise OAuth per tool. Anonymous store lookups can run without linking; workspace tools return a native sign-in challenge when authorization is missing or expired. Connect an existing Sonar account and approve access to the workspace you own. Existing account permissions and entitlements apply.
The ChatGPT endpoint requires resource-bound JWT access tokens for its canonical /mcp/chatgpt audience; the existing /mcp endpoint retains Clerk opaque-token support. Provider configuration and an end-to-end login must be verified before submitting the ChatGPT endpoint.
The hosted catalog excludes sonar_export_screenshots, which writes ZIP files to the local MCP host. It remains available over stdio. A native directory listing requires separate OpenAI review and publication; hosting an MCP endpoint does not itself create a listing.
Try it free — no API key needed
The server runs without a key in free mode: sonar_app_search, sonar_app_lookup, sonar_app_aso_score, sonar_app_extract_keywords, sonar_keyword_suggestions, and sonar_top_charts share a free allowance of 30 requests/day per IP, and sonar_keyword_metrics (keyword difficulty + popularity) gets 5 keywords/day. Just install it with no env block and ask your agent about ASO. When you hit the limit, the error tells you how to sign up.
Get an API key
For everything else (tracking, rankings, competitors, higher limits) you'll need a Sonar API key — get one at trysonar.app/developers.
The cheapest path is prepaid API credits — packs from $10 (1,000 credits), with 50 free credits on signup and no subscription. Built specifically for this use case. See pricing.
Install
Claude Desktop
Add to your config file (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
The MCP server is a thin client around Sonar's REST API — it stores nothing locally and no data is logged by this package itself.
Data collected: tool inputs (app IDs, keywords, country codes) are sent to Sonar's API over HTTPS to produce results; authenticated requests include your API key as a Bearer token. Sonar logs API requests (endpoint, status, timing) for rate limiting and abuse prevention.
Data usage: inputs are used solely to serve the request (keyword metrics, app lookups, etc.); resulting JSON is returned to your AI client.
Storage & retention: the package keeps no state on disk. Server-side request logs are retained for 90 days; workspace data (tracked apps/keywords) persists in your Sonar account until you delete it.
Third-party sharing: no user data is sold or shared with third parties; queries against public app-store data (Apple, Google) contain no personal information.
"SONAR_API_KEY is not set — running in free mode" — Expected if you haven't configured a key: the free tools keep working with per-IP daily limits. If you DID configure a key, the MCP client did not pass the env var through — check the env section of your client's config file. Some clients require an absolute path to npx — try which npx and use that.
"Authentication failed" — Your key is invalid, expired, or your subscription lapsed. Visit trysonar.app/developers to check.
"Access denied. This endpoint may require an Indie plan subscription" — The 10 stateless read tools work on any plan with credits. The workspace read, write, and Screenshot Studio tools require an Indie plan or higher (an active trial counts); write tools additionally need an API key created with the write scope. sonar_portfolio, sonar_app_sales, and sonar_app_engagement require the Agency plan, and the two AI generation tools need a paid plan (not a trial). If you're on a setup or trial-expired plan, reactivate first.
Companion: CLI
Prefer the terminal? Use @sonarapp/cli (sonar binary) — same data, same API key.