Overt

Overt over MCP.

Overt runs a Model Context Protocol server, so Claude, Cursor or any other MCP client can drive it directly — search the App Store, score a listing, track keywords and read daily rank history, by asking in plain English rather than opening a dashboard.

There are 20 tools, listed in full below. Agent access itself is included on every plan, Free included, and an agent is held to exactly the same plan limits you are — it cannot exceed your app or keyword allowance.

The one exception is generate_metadata, which needs a paid plan to run from an agent. On Free it returns an explanation and spends nothing; the account’s generation allowance is unchanged and can still be used in the dashboard. Every other tool here — search, scores, ranks, keyword difficulty, competitors, charts — works on Free.

Getting a key

Create an API key under Settings → API. The key is shown once, when you create it. Treat it like a password: anything holding it can read and change what your account tracks. Revoking a key stops it working on the very next call.

Connecting a client

The server speaks streamable HTTP at a single endpoint:

https://overt.live/api/mcp

For Claude Desktop, add this to claude_desktop_config.json and restart the app. Cursor and most other clients take the same object in their own MCP settings.

{
  "mcpServers": {
    "overt": {
      "type": "http",
      "url": "https://overt.live/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Replace YOUR_API_KEY with the key you created. Authentication is a bearer token on every request, and there is no session to keep alive.

Connecting a client that uses OAuth

Some clients discover authentication rather than taking a pasted key. Overt publishes protected-resource metadata at /.well-known/oauth-protected-resource, and its unauthenticated replies carry a WWW-Authenticate header pointing at it, so a client can find the authorization server on its own.

The authorization server is Clerk, not Overt. Overt never sees your password, never issues a token and never stores one — it only verifies the token you present and checks on every request that it has not been revoked or expired. Revoking access in Clerk stops the next call, not the one after some cache expires.

What an agent can do

Each tool below shows the parameters it takes, a prompt that would reach for it, and the response it really returns. Tool output is plain text rather than JSON, because agents read it more reliably.

One thing worth knowing before reading the rank tools: rank is a position, so a smaller number is better — a keyword going from #40 to #12 improved. A rank reported as not in top 200 means the app was checked and genuinely not found, which is different from a day with no check at all. The server tells clients this in its own instructions, so a competent agent gets the direction right without being reminded.

search_app_storeSearch the App Store

Search Apple's App Store by name or keyword and return matching apps with their App Store ids. Use this to find the numeric id an app must be referred to by elsewhere.

ParameterRequiredDescription
termYesSearch term, e.g. an app name or a keyword.
countryNoApp Store storefront. One of: us, gb, ca, au, de, fr, es, it, nl, se, jp, kr, in, br, mx. Defaults to us.

Ask
Find the App Store id for Loopwell.

Returns

1. Loopwell — Habit Tracker — Loopwell Studio (App Store id: 6443218870)
2. Loopwell Focus — Loopwell Studio (App Store id: 6501120043)
3. Habit Loop — Northbend (App Store id: 1544820117)

score_listingScore an app's listing

Compute Overt's listing health score (0-100) for any App Store app, with a breakdown of title, description, screenshots and reputation, and what to improve. Works on any app, including competitors — it reads only public App Store data.

ParameterRequiredDescription
appStoreIdYesNumeric App Store id, from search_app_store.
countryNoApp Store storefront. One of: us, gb, ca, au, de, fr, es, it, nl, se, jp, kr, in, br, mx. Defaults to us.

Ask
How strong is Loopwell's listing? Compare it to Momentum's.

Returns

Loopwell — Habit Tracker — Loopwell Studio
Overall listing health: 84/100

Title: 95/100
Description: 90/100
Screenshots: 50/100 — Only 2 screenshot(s) — the App Store supports up to 10; more visual real estate converts better.
Reputation: 85/100 — Average rating is 3.9 — below 4.0 measurably hurts conversion in App Store search.
Freshness: 95/100

list_tracked_appsList tracked apps and ranks

List the apps this account tracks, with every tracked keyword, its storefront, its latest rank and its movement since the previous check.

Takes no parameters.

Ask
What am I ranking for?

Returns

Loopwell — Habit Tracker (App Store id: 6443218870, app id: lw_84210)
  "habit tracker" [US] — #14 (up 6 since the previous check), last checked 2026-07-29 (keyword id: kw_9f21)
  "daily routine" [US] — #38 (down 2 since the previous check), last checked 2026-07-29 (keyword id: kw_7a02)
  "streak app" [US] — not in top 200, last checked 2026-07-29 (keyword id: kw_3b88)

get_rank_historyGet a keyword's rank history

Daily rank history for one tracked keyword, oldest first. A rank of 'not in top 200' means checked and not found, which is different from a date with no entry at all.

ParameterRequiredDescription
keywordIdYesKeyword id, from list_tracked_apps.
daysNoHow far back to look. Defaults to 90.

Ask
Has “habit tracker” been improving over the last two weeks?

Returns

"habit tracker" [US] — 14 checks

2026-07-16: #16
2026-07-17: #15
2026-07-18: #14
2026-07-19: #13
2026-07-20: #14
2026-07-21: #12
2026-07-22: #11
2026-07-23: #10
2026-07-24: #9
2026-07-25: #9

list_competitor_changesList competitor listing changes

Recent metadata changes Overt detected on the apps this account watches — the day a competitor rewrote a title or subtitle, changed price, or swapped screenshots.

ParameterRequiredDescription
daysNoHow far back to look. Defaults to 30.

Ask
Did any of my competitors change their listing this week?

Returns

2026-07-24 — app 1234567890, subtitle
  was: Daily Habits & Routines
  now: Habit Tracker, Streaks & Goals

2026-07-21 — app 1234567890, price
  was: 0
  now: 2.99

suggest_keywordsSuggest keywords to track

Suggest keywords worth tracking for one of this account's apps, mined from the listings of its competitors and the apps already ranking for its keywords. Ranked by how many of those apps use each phrase. This is not search volume — Apple does not publish that, so it is not estimated here.

ParameterRequiredDescription
appIdYesOvert app id, from list_tracked_apps or track_app.
limitNoHow many suggestions to return. Defaults to 25.

Ask
What keywords should I be tracking for Loopwell?

Returns

"daily routine" — used by 7 apps (Momentum — Daily Habits, Streaks, Routinery)
"habit streaks" — used by 5 apps (Streaks, Loop Habit Tracker, Done)
"morning routine" — used by 4 apps (Routinery, Fabulous, Momentum — Daily Habits)

get_keyword_difficultyScore how hard a keyword is

Score how hard it would be to rank for a keyword, from 0 to 100, where HIGHER means HARDER — the opposite direction to a listing health score. Measured from how established the apps already at the top are and how many of them target the phrase in their name. Works for any keyword, tracked or not. Pass appId to also learn where that app already ranks for it, which is the best available signal for whether a keyword is worth taking.

ParameterRequiredDescription
keywordYesThe search term to score.
countryNoApp Store storefront. One of: us, gb, ca, au, de, fr, es, it, nl, se, jp, kr, in, br, mx. Defaults to us.
appIdNoOptional Overt app id. When given, also reports where that app currently ranks for the term.

Ask
How hard would it be to rank for “habit tracker”?

Returns

"habit tracker" [US] — 74/100 (Hard). Higher is harder.

Incumbent strength: The typical app in the top 10 has 14,009 ratings.
Title targeting: 8 of the top 10 put “habit tracker” in their app name.

compare_with_competitorCompare a listing against a competitor's

Compare one of this account's apps against a competitor it watches, field by field — title, description length, screenshots, rating, ratings, price and version — from the daily snapshots already stored. Only fields with a defensible direction report who is ahead; price and version never do.

ParameterRequiredDescription
appIdYesOvert app id, from list_tracked_apps.
competitorAppStoreIdYesNumeric App Store id of a competitor already watched for that app.

Ask
How does Loopwell stack up against Momentum?

Returns

Loopwell — Habit Tracker vs Momentum — Daily Habits
Captured 2026-07-29 and 2026-07-29.

Title: Loopwell — Habit Tracker  |  Momentum — Daily Habits
Title length: 24 chars  |  26 chars
Description: 812 chars  |  340 chars  (you are ahead)
Screenshots: 4  |  8  (they are ahead)
Rating: 4.6  |  4.8  (they are ahead)
Ratings: 2,412  |  18,905  (they are ahead)
Price: Free  |  Free
Version: 2.1.0  |  4.7.2

get_top_chartRead an App Store top chart

Read Apple's top-app chart for a country and optionally a single category, and report where one of this account's apps sits on it. Category charts are far more meaningful than the overall chart, which almost no app competes in. Not appearing on a chart is the ordinary result, not an error.

ParameterRequiredDescription
appIdYesOvert app id, from list_tracked_apps.
feedNoWhich chart. One of: topfreeapplications, toppaidapplications, topgrossingapplications. Defaults to topfreeapplications.
categoryNoApp Store category name. Omit for the overall chart across all categories.
limitNoHow many chart entries to list. Defaults to 20.

Ask
Where does Loopwell sit in the Health & Fitness chart?

Returns

Health & Fitness — topfreeapplications [US]
This account's app is #38 on this chart.

1. MyFitnessPal — MyFitnessPal, Inc.
2. Calm — Calm.com, Inc.
3. Strava — Strava, Inc.
4. Flo Period & Pregnancy Tracker — Flo Health, Inc.
5. Planet Fitness Workouts — Planet Fitness

track_appTrack an app

Start tracking an App Store app on this account, so its keyword ranks are checked daily. Subject to the account's plan limit on number of apps.

ParameterRequiredDescription
appStoreIdYesNumeric App Store id, from search_app_store.
countryNoApp Store storefront. One of: us, gb, ca, au, de, fr, es, it, nl, se, jp, kr, in, br, mx. Defaults to us.

Ask
Start tracking Loopwell in the US store.

Returns

Now tracking Loopwell — Habit Tracker (app id: lw_84210). Add keywords with track_keyword.

track_keywordTrack a keyword

Track a keyword for one of this account's apps, in a specific storefront. The same keyword can be tracked in several storefronts independently. First rank appears after the next daily check. Subject to the account's plan limit on number of keywords.

ParameterRequiredDescription
appIdYesOvert app id, from list_tracked_apps or track_app.
keywordYesThe search term to track.
countryNoApp Store storefront. One of: us, gb, ca, au, de, fr, es, it, nl, se, jp, kr, in, br, mx. Defaults to us.

Ask
Track “habit streaks” and “routine builder” for Loopwell.

Returns

Tracking "habit streaks" [US] (keyword id: kw_5e13). Its first position appears after the next rank check.

untrack_keywordStop tracking a keyword

Stop tracking a keyword. Its recorded rank history is removed with it and cannot be recovered, so confirm with the user before calling this.

ParameterRequiredDescription
keywordIdYesKeyword id, from list_tracked_apps.

Ask
Stop tracking “streak app” — it’s never going to rank.

Returns

Keyword removed, along with its rank history.

Destructive. Clients that honour tool annotations will ask you to confirm before running this one. Rank history accumulates a day at a time and cannot be backfilled, so removing it is permanent.

untrack_appStop tracking an app

Stop tracking an app. This also removes every keyword tracked for it, all of their recorded rank history, and the competitors watched against it. None of that can be recovered or backfilled. Always confirm with the user before calling this.

ParameterRequiredDescription
appIdYesOvert app id, from list_tracked_apps.

Ask
I’ve pulled Loopwell Focus from the store — stop tracking it.

Returns

Stopped tracking Loopwell Focus. 6 keywords and their rank history were removed with it.

Destructive. Clients that honour tool annotations will ask you to confirm before running this one. Rank history accumulates a day at a time and cannot be backfilled, so removing it is permanent.

add_competitorWatch a competitor

Start watching a competitor's App Store listing against one of this account's apps. Their metadata is snapshotted daily, so list_competitor_changes reports the day they rewrite a title, subtitle or description. Subject to the account's plan limit on number of competitors.

ParameterRequiredDescription
appIdYesOvert app id to watch this competitor against.
competitorAppStoreIdYesNumeric App Store id of the competitor, from search_app_store.

Ask
Watch HabitKit against Loopwell.

Returns

Now watching HabitKit (competitor id: 4f2a91e0). Their first metadata snapshot is taken on the next daily run, and changes appear in list_competitor_changes from the following day.

remove_competitorStop watching a competitor

Stop watching a competitor. Metadata changes already recorded for them are kept; only future snapshots stop.

ParameterRequiredDescription
competitorIdYesCompetitor id, from list_competitors.

Ask
Stop watching HabitKit.

Returns

Competitor removed. Changes already recorded for them are kept.

Destructive. Clients that honour tool annotations will ask you to confirm before running this one. Rank history accumulates a day at a time and cannot be backfilled, so removing it is permanent.

list_competitorsList watched competitors

List the competitors this account watches, with the id each must be referred to by in remove_competitor and the app each is watched against.

Takes no parameters.

Ask
Who am I watching?

Returns

HabitKit (App Store id: 1573497225, competitor id: 4f2a91e0) — watched against app 9c1f...
Streaks (App Store id: 963034692, competitor id: 7b30ca44) — watched against app 9c1f...

generate_metadataGenerate App Store metadata

Generate App Store listing metadata for an app: ranked title/subtitle candidates with the reasoning behind each, plus a full store description. Every field is measured against Apple's real limits (30 characters for title and subtitle, 100 BYTES for the keyword field, 4000 characters for the description) and anything over is flagged. Claims are grounded in features evidenced by the app's own listing, because Apple rejects metadata that misrepresents what an app does. This SPENDS one of the account's monthly generation credits and costs real money — confirm with the user before calling it, and call get_plan_usage first if you need to know how many remain. How many candidates come back, and whether the keyword field is included, depend on the account's plan. Generating from an agent requires a paid plan. On the free plan this returns an explanation instead and spends nothing — the account can still generate in the Overt dashboard, so do not tell the user that generation is unavailable to them.

ParameterRequiredDescription
appStoreIdYesNumeric App Store id of the app to write metadata for.
seedKeywordYesThe search term to optimise for. Its top-ranking apps become the competitive set the generation reasons against, so pick the phrase the app should be found by.

Ask
Rewrite Loopwell’s listing for “habit tracker”.

Returns

Loopwell — Habit Tracker — metadata generated for "habit tracker"
Generation 3 of 5 this month.

Candidate 0:
  Title (28/30 chars): Loopwell: Habit Tracker
  Subtitle (31/30 chars): Build daily routines that stick
  Why: "habit tracker" is absent from the current title, and it is the term with the
       highest search volume this app already ranks in the top 60 for.
  OVER LIMIT — subtitle is 31 characters against Apple's 30. Not auto-trimmed:
       cutting prose mid-word produces garbage. Edit it before shipping.

Description (2841/4000 chars):
Loopwell turns the habits you keep meaning to start into ones you actually keep…

Keyword gaps this was built from: streak, daily routine, habit builder

On the Free plan, 2 more candidates and the keyword field Apple indexes are not
included. The full result was generated and stored either way — upgrading reveals
it without regenerating.

Recorded as generation a81c…. Once the user publishes one of these, call
mark_shipped with that id so Overt can measure what it did to rank.

list_generationsList past generations

List metadata generations already produced for this account, newest first, with the id each must be referred to by in mark_shipped and whether it has been shipped. Costs no credit — it reads what was already generated.

ParameterRequiredDescription
appIdNoOptional Overt app id to narrow to one app. Omit for all apps.
limitNoHow many to return. Defaults to 10.

Ask
What listings have I generated?

Returns

2026-07-28 — Loopwell, seeded with "habit tracker" (generation id: a81c4d2f)
  Shipped 2026-07-29, candidate 0.
  [0] Loopwell: Habit Tracker — Build routines that stick
  [1] Loopwell — Daily Habits — Track streaks, build routines

2026-07-14 — Loopwell, seeded with "routine" (generation id: 3e90b17a)
  Not marked as shipped, so its effect cannot be measured.
  [0] Loopwell — Daily Routine — Small habits, every day

mark_shippedMark a generation as shipped

Record which candidate from a past generation was actually put live on the App Store. This is what closes the loop: Overt then compares rank in the seven days before shipping against the days after, so the user can see whether the rewrite worked. Only call this once the user confirms they have actually published the change.

ParameterRequiredDescription
suggestionIdYesGeneration id, from list_generations.
chosenCandidateYesWhich candidate was shipped, numbered from 0 as listed in list_generations.

Ask
I published the first option — record that.

Returns

Recorded "Loopwell: Habit Tracker" / "Build routines that stick" as shipped today. Overt compares the seven days before against the days after — the after-window starts tomorrow, because Apple's indexing lag means same-day movement still reflects the old listing.

get_plan_usageCheck plan usage and limits

Report where this account stands against its plan: apps, keywords and competitors used versus allowed, generation credits left this month, how often ranks refresh, and how much of a generation this plan returns. Call this BEFORE bulk tracking or generating, so you can tell the user what will fit instead of hitting a limit part-way through.

Takes no parameters.

Ask
How much of my plan have I used?

Returns

Plan: Free
Apps: 1 of 1 used — full
Keywords: 7 of 10 used (3 free)
Competitors: 1 of 1 used — full
Generations this month: 3 of 5 used (2 free)
Rank refresh: weekly
Generation returns 1 candidate, without the keyword field.

Tracking the same keyword in two storefronts uses two keyword slots.

Prompts

As well as tools, Overt publishes 5 prompts — ready-made workflows that appear in your client’s prompt picker. They exist so someone who has just connected Overt has somewhere to start without first learning 20 tool names. Each one expands into instructions the agent then carries out with the tools above.

PromptArgumentsWhat it does
audit_listingapp Score an app's listing, explain what is weakest, and say what to change first. Read-only — spends no generation credit.
plan_keywordsappId Look at an app's current keywords and ranks, suggest new ones, and score how hard each would be to win. Read-only — spends no generation credit.
review_competitorsdays Summarise recent competitor metadata changes and what they imply. Read-only — spends no generation credit.
rewrite_listingapp seedKeyword Generate new title, subtitle and description candidates for a tracked app. SPENDS one generation credit — asks for confirmation first.
check_progressappId Review shipped listing changes against what ranks did next. Read-only — spends no generation credit.

Only rewrite_listing can cost anything, and it is written to make the agent check your remaining credits and ask before it generates.

Rate limits

The tools that reach Apple — search_app_store, score_listing, track_app, add_competitor, get_keyword_difficulty, get_top_chart and generate_metadata— spend from Apple’s public API budget of roughly 20 requests a minute, which is shared across all of Overt and is the same budget that runs daily rank checks for every paying customer. They are throttled per credential, so an agent looping over a list gets slowed down rather than being allowed to starve everyone’s rank checks for the day. An API key and an OAuth token draw on separate buckets and cannot exhaust each other. The tools that only read your tracked data are not affected.

Generation costs money

generate_metadata is the one tool here that spends something. Each call uses one of your monthly generation credits and makes a real model call, so it is deliberately not marked idempotent — a client must never silently retry it, because a retry spends a second credit and returns different text. Call get_plan_usage first if you want to know how many you have left.

The ceiling is enforced in Postgres before any model call, and the claim is atomic — an agent calling in a loop is refused at the limit rather than running up a bill. If a generation fails after the credit is claimed, the credit is returned. How many candidates come back, and whether the keyword field is included, depend on your plan; when something is withheld the response says so rather than quietly returning less.

Troubleshooting

  • 401 Unauthorized — the key is missing, malformed, or revoked. Confirm the header is Authorization: Bearer <key> and mint a fresh key if unsure.
  • An agent reports a keyword has “no rank” — check whether the response said not in top 200 (checked, not found) or not checked yet (tracked, but the next daily check has not run). They mean different things.
  • A write fails on a plan limit — an agent cannot raise your app or keyword allowance. The limit is the one on your plan.

Create an API key to get started, or try Overt in the browser first — it is free, with no card.