tools / coverage
coverage
read-onlyMetadata keyword coverage
Which searches can this metadata draft actually rank for?
Apple indexes a localization's title (30 chars), subtitle (30) and hidden keyword field (100) as one combined word pool: an app can rank for any phrase assembled from words across those fields. coverage operationalizes that model, locally and instantly — no network, no quota.
Give it a draft and target phrases, and it returns the pool with strongest-field attribution, cross-field duplicates (pure reclaimable waste), per-field character budgets, keyword-field waste accounting (commas count; spaces around commas don't have to), and a verdict per phrase: covered verbatim, covered cross-field, or missing specific words.
Weight phrases with {phrase, value} — typically popularity from volume — and wordValues aggregates each word's total search value across every phrase it serves, with unlockValue (what adding an absent word would newly cover) and atRiskValue (what dropping a word would break) as the marginal numbers character-budget decisions should be made on.
worked example
Evaluate HabitKit's live title and subtitle plus a drafted keyword field against weighted target phrases.
tools/call → coverage
{
"name": "coverage",
"arguments": {
"title": "Habit Tracker - HabitKit",
"subtitle": "Streaks & Accountability",
"keywords": "daily, goals,routine,streak,habits,widget,grid,minimal",
"phrases": [
{
"phrase": "habit tracker",
"value": 82
},
{
"phrase": "streak tracker",
"value": 76
},
"routine planner",
"habit grid"
]
}
}coverage → structuredContent (excerpt)
{
"fields": [
{ "field": "title", "chars": 24, "limit": 30, "remaining": 6 },
{ "field": "subtitle", "chars": 24, "limit": 30, "remaining": 6 },
{ "field": "keywords", "chars": 54, "limit": 100, "remaining": 46 }
],
"phrases": [
{ "phrase": "habit tracker", "covered": true, "exactIn": "title", "value": 82 },
{ "phrase": "streak tracker", "covered": true, "exactIn": null, "crossField": true,
"words": [ { "word": "streak", "match": "plural", "field": "subtitle" },
{ "word": "tracker", "match": "exact", "field": "title" } ], "value": 76 },
{ "phrase": "routine planner", "covered": false, "missing": ["planner"] },
{ "phrase": "habit grid", "covered": true, "crossField": true }
],
"keywordFieldWaste": { "spaces": 1, "duplicates": 0, "stopwords": 0, "total": 1 },
"wordValues": [
{ "word": "tracker", "inPool": "title", "phrases": ["habit tracker", "streak tracker"],
"totalValue": 158, "unlockValue": 0, "atRiskValue": 158 },
{ "word": "planner", "inPool": null, "chars": 7, "phrases": ["routine planner"],
"totalValue": 1, "unlockValue": 1, "atRiskValue": 0 },
…
]
}real response, captured 2026-07-29 — trimmed only where marked with …
streak tracker (demand 76) is covered without appearing anywhere verbatim: plural Streaks in the subtitle assembles with tracker from the title. That is the cross-field model most ASO tooling misses.keywordFieldWaste.spaces: 1 caught the space in daily, goals — one character of the 100 doing nothing.tracker carries atRiskValue: 158 — drop it and both weighted phrases break. planner costs 7 chars to unlock routine planner; with 46 keyword-field characters remaining, that is an easy add.
when to use it
- Drafting metadata: iterate title/subtitle/keyword-field candidates locally until target coverage is total and waste is zero — then verify with live rank calls.
- Regression-checking a rewrite: pass every phrase you currently rank for; any that comes back
covered: false is a ranking you are about to silently give up. - Budgeting the 100-char keyword field: waste accounting plus
unlockValue tells you exactly which 7 characters earn their place. - Understanding a competitor's reach: their title + subtitle (from app) is two-thirds of their pool — see which phrases it already assembles.
description — as served to agents
Which search phrases a metadata draft can rank for, computed locally (no network). Apple indexes the title (30 chars), subtitle (30) and hidden keyword field (100) of a localization as ONE combined word pool: an app can rank for any query assembled from words across those fields — "photo" in the title plus "resize" in the keyword field can rank for "resize photo". Title words weigh most, then subtitle, then keyword field; word order and case do not gate what can rank (a phrase kept intact in the title/subtitle is a mild extra signal); repeating a word in a second field adds nothing. Reports per-field character budgets, the combined pool, cross-field duplicates (reclaimable characters), and for each target phrase whether it is covered — verbatim in the title/subtitle, assembled cross-field, or missing words. In the keyword field, commas count toward the 100 characters; redundant characters (spaces around commas, duplicated words, stopwords) are reported in keywordFieldWaste. Weight phrases with {phrase, value} (e.g. value = popularity from the volume tool) and wordValues aggregates each word's total search value across every phrase it combines into — "photo" serves "photo editor", "photo maker" and "take photo" at once. totalValue credits a phrase to all of its words (not additive across words); use unlockValue (absent words whose addition alone covers new phrases) and atRiskValue (pool words whose removal breaks covered phrases) for marginal decisions. Evaluates one localization; storefronts may index extra localizations (e.g. the US storefront also indexes Spanish (Mexico)). Cross-field combinations tend to rank weaker than same-field phrases, so confirm real positions with rank.
input
App title draft (30-char limit)
Subtitle draft (30-char limit)
Hidden keyword field draft, comma-separated (100-char limit; commas count, spaces are waste)
Target search phrases to check coverage for; weight with {phrase, value} to aggregate per-word search value in wordValues
output
field *"title" | "subtitle" | "keywords"
Apple's limit: title 30, subtitle 30, keywords 100
characters left; negative = over the limit
combined indexable word pool, attributed to the strongest field containing each word
field *"title" | "subtitle" | "keywords"
strongest field containing the word
filler word Apple's search largely ignores — reclaimable
alsoIn *("title" | "subtitle" | "keywords")[]
weaker fields repeating the word (reclaimable characters)
words spent in more than one field — repeating adds no ranking benefit
fields *("title" | "subtitle" | "keywords")[]
every substantive word is available in the combined pool (stopwords assumed ignored; false when the phrase has no substantive match at all)
exactIn *"title" | "subtitle" | null
whole phrase appears verbatim in this field (never keywords — that field is unordered); a kept-intact phrase is a mild extra relevance signal
covered only by combining substantive words from different fields (ranks, but tends to rank weaker)
match *"exact" | "plural" | "stopword" | null
"plural" is a suffix heuristic; null when missing
field *"title" | "subtitle" | "keywords" | null
strongest field supplying the match; null for stopword/missing
words in no field — the pool alone cannot produce the phrase (Apple can still rank it via developer name, in-app purchase names or query expansion)
the phrase's relative search value (input weight; 1 when unweighted)
keywordFieldWaste *object | null
keyword-field characters that deleting the waste would actually free (null when no keywords draft was given)
whitespace around commas or at the ends — a space that is a word's only separator is char-neutral and not counted
chars of words already in title/subtitle or repeated in the field
commas/spaces freed by removing the wasted words
per-word aggregate search value across all target phrases, sorted by totalValue. A word serves every phrase it can combine into, but a phrase's value is credited in full to EACH of its words — totals are not additive across a word set; budget with unlockValue/atRiskValue
inPool *"title" | "subtitle" | "keywords" | null
strongest field containing — or plural-matching — the word; null if absent
characters of the word itself; a keyword-field entry additionally costs one separating comma
summed value of every target phrase containing the word
absent words: summed value of phrases covered by adding just this word
in-pool words: summed value of covered phrases that would actually lose coverage if the word were dropped from every field (a surviving plural variant keeps a phrase safe)
pairs with
endpoint
https://mcp.openaso.ai/mcp · auth
Authorization: Bearer <key> ·
get a key