MCP for agents
ASOMaster ships an MCP server, asomaster-mcp, so an AI agent you already use can read your keyword boards and do the same work you do in the app: add apps, check ranks, find keywords, draft and localize listings. Every change shows up live in the app.
On this page
- What MCP is and what agents can do
- Requirements
- Install from the app
- Manual setup per client
- How work runs: jobs and waiting
- Reading the numbers
- Safety
- Common workflows
- Things to ask
- Tool reference (57 tools)
- Troubleshooting
What MCP is and what agents can do
The Model Context Protocol is an open standard that lets AI clients call tools exposed by other programs. Your agent starts asomaster-mcp as a local process and talks to it over standard input and output. The bridge forwards each call to the ASOMaster app running on the same computer, through a private local socket (a named pipe on Windows). Nothing goes through our servers.
With it, an agent can:
- Read every tracked app, its keyword board per market, the detail of one keyword in one market (rank history, the apps ranking for it) and your rank alerts.
- Add your own apps from App Store Connect or Google Play Console, rivals from a store search, or a niche idea with no app yet.
- Suggest, add, localize, rename, hide and remove keywords, and set the exact phrase used in each market.
- Queue rank checks and fetch real popularity from Apple Ads or Google Ads.
- Run Listing Studio end to end: draft options, compare, choose, localize, review each language and, only with your explicit go-ahead, publish.
- Talk to the in-app assistant, change settings, import keyword files and export data.
Requirements
- ASOMaster installed and activated with a license that includes MCP access. Without it every tool answers
license_requiredand the agent should ask you to activate. - An MCP client: Claude Code, Codex, Cursor, Claude Desktop, Windsurf, OpenCode, or any client that can start a stdio MCP server.
- The app doesn't need to be open. If it's closed, the bridge starts it and keeps retrying for up to 30 seconds while it launches.
Install from the app
The quickest way: open Settings › MCP clients. ASOMaster lists the clients it finds on this computer and writes the entry for you.
- Install adds ASOMaster to Claude Code, Codex, OpenCode, Cursor, Claude Desktop or Windsurf.
- Update appears when an entry points at a moved, reinstalled or missing bridge. One click rewrites it.
- Remove deletes only the ASOMaster entry and leaves the rest of the client's config alone.
- Add to Cursor opens Cursor's own install prompt.
Using Cursor with the app in /Applications? This button does the same thing from the web:
Restart the client or start a new chat after installing so it loads the new tools.
Manual setup per client
Point your client at the bridge that ships inside the app:
| System | Bridge path |
|---|---|
| macOS | /Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp |
| Windows | %LOCALAPPDATA%\ASOMaster\asomaster-mcp.exe |
The snippets use the macOS path. On Windows, swap in the Windows path (in JSON, write backslashes as \\).
Run once in a terminal. --scope user makes it available in every project.
claude mcp add --scope user asomaster -- /Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp
Add to ~/.codex/config.toml.
[mcp_servers.asomaster] command = "/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp" args = []
Use the Add to Cursor button above, or add this to ~/.cursor/mcp.json.
{
"mcpServers": {
"asomaster": {
"command": "/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp",
"args": []
}
}
}
Add to claude_desktop_config.json: on macOS in ~/Library/Application Support/Claude/, on Windows in %APPDATA%\Claude\. Quit and reopen Claude Desktop afterwards.
{
"mcpServers": {
"asomaster": {
"command": "/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp",
"args": []
}
}
}
Add to ~/.codeium/windsurf/mcp_config.json.
{
"mcpServers": {
"asomaster": {
"command": "/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp",
"args": []
}
}
}
Add to ~/.config/opencode/opencode.json, merged with anything already in the mcp block.
{
"mcp": {
"asomaster": {
"type": "local",
"command": ["/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp"],
"enabled": true
}
}
}
Any client that starts stdio MCP servers from a JSON config. The bridge speaks MCP protocol versions 2024-11-05, 2025-03-26, 2025-06-18 and 2025-11-25.
{
"mcpServers": {
"asomaster": {
"type": "stdio",
"command": "/Applications/ASOMaster.app/Contents/MacOS/asomaster-mcp",
"args": [],
"env": {}
}
}
}
How work runs: jobs and waiting
Reading is instant. Anything that searches the stores or asks an AI model (adding an app, rank checks, popularity, keyword suggestions, localization, Listing Studio runs, the assistant, imports, publishing) is queued as a background job, and the tool returns straight away with the job.
Inspect. Start with
get_overviewfor project ids, markets, running jobs and the license state.Act. Call the tool that queues the work.
Wait. Call
wait_for_jobs. Each call waits up to 50 seconds and returns early when the queue is idle; repeat untilidleis true. PassprojectIdto wait for one app only.Read again. Fetch the board, Listing Studio state or assistant thread before deciding the next step.
The stores rate-limit searches, so a large check can take minutes. When a job reports pausedUntil, the app is backing off on purpose and resumes by itself. stop_job cancels one job by id.
Reading the numbers
estVolandestDiffare ASOMaster's estimates (0 to 100) of search volume and difficulty, modelled from the store's own search results. Every checked keyword has them.popis real popularity from a connected source: Apple Ads, Google Ads Keyword Planner or an imported file. It only exists after a source is connected and fetched. The two are never mixed; agents are told to say which one they use.rankis the app's position in that market's store search. A missing rank means the app wasn't found in the checked results.- A missing value means "not measured", never zero.
- Markets are lower-case country codes such as
usorde; listing locales look likeen-US. App Store and Google Play versions of the same app are separate projects.
More on what the numbers mean: Metrics explained.
Safety
- Publishing needs you, twice.
publish_listingchanges the live store page. The agent must passownerApproved: trueand quote your explicit go-ahead from the conversation. Then the app itself shows a native confirmation dialog, "Publish listing requested by an AI agent", that only you can answer. Anything but clicking Publish (Don't publish, closing it, no answer) cancels. Nothing is ever submitted for review. - Removing an app needs its name.
remove_projectdeletes only whenconfirmNamematches the project's exact name, so a stale or mistyped id can't remove the wrong app. - Destructive tools are marked. Tools that delete or overwrite carry the MCP
destructiveHint, so clients that ask before risky calls will ask you. Agents are also told to ask first. - Secrets stay put. Console and ads credentials are passed as file paths (
privateKeyPath,serviceAccountPath). The bridge reads the file locally, the app stores the secret in the OS keychain, and no tool ever returns it. - Local only. The socket is owner-only on macOS and Linux, and the Windows pipe needs a per-user token.
Common workflows
Track your own apps
list_console_apps, then add_console_apps (or add_app for one), wait_for_jobs, get_overview, run_rank_check, wait_for_jobs, get_project_board.
Track a rival
search_store (results say which apps you already track), then add_app with kind competitor, wait_for_jobs, get_project_board.
Research a niche before you build
brainstorm_project with a short brief, wait_for_jobs, run_rank_check in the markets you care about, wait_for_jobs, get_project_board sorted by opportunity. Ask for suggest_keywords to go wider.
Refresh ranks
run_rank_check (pass force to ignore today's cached searches), wait_for_jobs, then list_rank_alerts for what moved.
Reposition an app
update_project with the new brief, suggest_keywords, run_rank_check, wait_for_jobs, then promote winners with add_keywords in the listing section and hide losers with edit_keyword. Follow with a Listing Studio run.
Listing Studio: draft, choose, localize, publish
optimizer_start, wait_for_jobs, get_optimizer (options with reach and difficulty vs now), tweak with optimizer_save_option or ask for optimizer_more_options, then optimizer_choose, optimizer_localize, wait_for_jobs, review each language with optimizer_edit_locale and optimizer_pick_phrase. Show the owner the exact text. Only after they say so: get_next_version and publish_listing. If some languages failed, optimizer_localize with remaining finishes only those.
Things to ask
- Which keywords did I lose ground on this week, and in which countries?
- Where am I outside the top 10 in Germany? Sort by opportunity.
- Add Japan and Korea to my sleep app and check them.
- Track the top three rivals for "white noise" in the US and tell me where they beat me.
- Find 15 long-tail ideas for a habit tracker for ADHD and check them in the US and UK.
- Draft new listing options, compare the best one with my current listing, and localize it. Don't publish.
Tool reference
All 57 tools, grouped. This reference is generated from the bridge's own tool list at every site build, so names, parameters and hints always match the app. Each tool has a closed JSON Schema (unknown parameters are rejected) and MCP annotations.
- Read the workspace
- Apps, rivals, niches and folders
- Keywords and local phrases
- Rank checks, popularity and alerts
- Listing Studio
- Assistant
- Store consoles and popularity sources
- Settings, AI, import and export
- Jobs
Read the workspace
Read-only views of projects, boards, single keywords, markets, alerts and the store search. Start every session with get_overview.
get_overview Overview
Start here. Lists every tracked project (id, store, kind, markets, keyword and top-10 counts, searches checked vs never checked, audit step, last check), folders, running and recently finished jobs, key settings, license state and unread rank alerts. Use the ids it returns with every other tool.
| Parameter | Type | Description |
|---|---|---|
folderId | string | Only projects in this folder. |
kind | "mine" | "competitor" | "brainstorm" | Only this kind of project. |
store | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
get_project_board Project keyword board
Keyword x market grid for one project, summarised per market: for each keyword its id, label, row summary and, per shown market, rank / previous rank, ESTIMATED volume & difficulty (estVol/estDiff), REAL popularity (pop, only when a provider is connected), verdict and opportunity. Also the top competitors. With more than 4 tracked markets only the main market is shown unless you pass markets. Hidden keywords are excluded unless section is hidden/all.
| Parameter | Type | Description |
|---|---|---|
limit | integer 1–1000 | Max rows per section (default 150). |
markets | array of string | Countries to show (default: all if <= 4 tracked, else the main market). |
projectId required | string | Project id (from get_overview). |
section | "active" | "listing" | "idea" | "hidden" | "all" | Which rows: active = listing + idea (default). |
sort | "board" | "opportunity" | "rank" | "estVolume" | "popularity" | Row order (default: board order). |
get_term_detail Keyword detail in one market
Everything about one keyword in one market: the current cell (rank, estimates, real popularity, verdict), rank/estimate history by day, and the apps currently ranking for it (position, rating count, installs, whether the phrase matches their title/subtitle).
| Parameter | Type | Description |
|---|---|---|
historyPoints | integer 0–400 | Most recent history points to return (default 30). |
keywordId required | string | Keyword id (from get_project_board). |
market required | string | Market = ISO 3166-1 alpha-2 country code, e.g. "us", "de". |
projectId required | string | Project id (from get_overview). |
topApps | integer 0–50 | How many ranking apps to return (default 10). |
list_markets Markets
Markets (countries) available for a store with search language, listing locales and a 0-10 potential score. Use the country codes as market ids.
| Parameter | Type | Description |
|---|---|---|
featuredOnly | boolean | Only the curated featured markets. |
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
list_rank_alerts Rank alerts
Rank-change alerts raised by checks (keyword, market, from -> to rank), newest first.
| Parameter | Type | Description |
|---|---|---|
limit | integer 1–500 | Max alerts (default 50). |
projectId | string | Only alerts for this project. |
unreadOnly | boolean | Only unread alerts (default true). |
search_store Search the store
Live store search in one market (max 10 apps). Accepts a search term or a pasted store URL. Apps already tracked carry trackedAs {projectId, kind}. Use it to find app ids before add_app.
| Parameter | Type | Description |
|---|---|---|
country required | string | Market = ISO 3166-1 alpha-2 country code, e.g. "us", "de". |
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
term required | string | Search term, app name or store URL. |
Apps, rivals, niches and folders
Add your own apps (from search, a link or your connected console), rivals and niche ideas; organise them in folders.
list_console_apps Developer console apps
Connected developer console accounts for a store (App Store Connect / Google Play Console) and the apps they can see, with whether each app is already tracked.
| Parameter | Type | Description |
|---|---|---|
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
add_app Track an app
Start tracking an app as a project: your own app (kind mine) or a competitor. Accepts an App Store / Play id, bundle / package name or store URL (find it with search_store). Imports the live listing and seeds keywords in the background; the new project appears in get_overview when the job finishes.
| Parameter | Type | Description |
|---|---|---|
app required | string | App id, package name or store URL. |
brief | string | Product facts, upcoming features and positioning, saved before the first AI brainstorm (keep upcoming features apart from the current listing). |
folderId | string | Folder to put it in. |
kind required | "mine" | "competitor" | mine = an app the owner publishes; competitor = someone else's. |
markets | array of string | Markets to track (default: the owner's default markets). |
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
add_console_apps Track all console apps
Track every app visible in the connected developer console account(s) for a store as 'mine' projects (skips ones already tracked).
| Parameter | Type | Description |
|---|---|---|
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
brainstorm_project Brainstorm a new app idea
Create a brainstorm project for an app that does not exist yet: the AI proposes keywords from a short brief and checks them in the chosen markets. Requires a ready AI provider.
| Parameter | Type | Description |
|---|---|---|
brief required | string | What the app does and for whom. |
markets | array of string | Markets to evaluate (default: owner defaults). |
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
update_project Edit project
Rename a project, change its brief (context used by the AI) or its automatic rank-check schedule.
| Parameter | Type | Description |
|---|---|---|
autoCheck | "inherit" | "off" | "daily" | "weekly" | "biweekly" | "monthly" | Automatic check schedule (inherit = global setting). |
brief | string | Short description of the app used by the AI. |
name | string | Display name. |
projectId required | string | Project id (from get_overview). |
set_project_markets Set tracked markets
Replace the list of markets (countries) tracked for a project. New markets are empty until run_rank_check runs for them.
| Parameter | Type | Description |
|---|---|---|
markets required | array of string | Full list of markets to track. |
projectId required | string | Project id (from get_overview). |
move_project Move project
Move a project into a folder (null = top level), optionally placing it before another project.
| Parameter | Type | Description |
|---|---|---|
beforeId | string | Place before this project id. |
folderId required | string or null | Target folder id, or null for no folder. |
projectId required | string | Project id (from get_overview). |
resync_project Refresh app metadata
Re-import the app's live listing / metadata from the store (and console when connected).
| Parameter | Type | Description |
|---|---|---|
projectId required | string | Project id (from get_overview). |
remove_project Delete project
Permanently delete a project with its keywords, rank history and optimizer drafts. Only when the owner asked for this exact project: pass its name (from get_overview) as confirmName; a mismatch deletes nothing.
| Parameter | Type | Description |
|---|---|---|
confirmName required | string | The project's exact name, as get_overview lists it. |
projectId required | string | Project id (from get_overview). |
save_folder Create or rename folder
Create a folder (omit folderId) or rename an existing one.
| Parameter | Type | Description |
|---|---|---|
folderId | string | Folder to rename; omit to create a new folder. |
name required | string | Folder name. |
remove_folder Delete folder
Delete a folder. Its projects are kept and move to the top level.
| Parameter | Type | Description |
|---|---|---|
folderId required | string | Folder id. |
Keywords and local phrases
Add, suggest, localize and tidy keywords. Each keyword has its own phrase in every tracked market.
add_keywords Add keywords
Add one or more keywords (search phrases) to a project. section 'listing' = phrases the listing targets now; 'idea' = candidates to evaluate (default). localize=true asks the AI to translate each phrase into every tracked market's search language (otherwise the same phrase is used everywhere). New keywords have no ranks until run_rank_check.
| Parameter | Type | Description |
|---|---|---|
keywords required | array of string | Phrases to add. |
localize | boolean | Translate per market with AI (default false). |
projectId required | string | Project id (from get_overview). |
section | "listing" | "idea" | Board section (default idea). |
suggest_keywords AI keyword suggestions
Ask the AI for new keyword ideas for a project based on its listing, brief and current board; they land in the 'idea' section.
| Parameter | Type | Description |
|---|---|---|
count | integer 1–100 | How many ideas (default chosen by the app). |
hint | string | Focus for the ideas, e.g. "budgeting for students". |
projectId required | string | Project id (from get_overview). |
localize_keyword Localize keyword
Have the AI translate a keyword into the search language of each market (or the given markets), replacing non-overridden per-market phrases.
| Parameter | Type | Description |
|---|---|---|
keywordId required | string | Keyword id (from get_project_board). |
markets | array of string | Only these markets (default: all tracked). |
set_market_phrase Set phrase for one market
Override the exact search phrase used for a keyword in one market (e.g. a better local wording). An empty phrase removes the override.
| Parameter | Type | Description |
|---|---|---|
keywordId required | string | Keyword id (from get_project_board). |
market required | string | Market = ISO 3166-1 alpha-2 country code, e.g. "us", "de". |
phrase required | string | Phrase to search in that market; empty = remove override. |
edit_keyword Edit keyword
Rename a keyword and/or hide it (hidden keywords stay tracked but leave the active board) or unhide it.
| Parameter | Type | Description |
|---|---|---|
hidden | boolean | true = hide, false = show again. |
keywordId required | string | Keyword id (from get_project_board). |
label | string | New label. |
remove_keywords Delete keywords
Permanently delete keywords and their rank history. Prefer edit_keyword hidden:true unless the owner wants them gone.
| Parameter | Type | Description |
|---|---|---|
keywordIds required | array of string | Keywords to delete. |
Rank checks, popularity and alerts
Queue store searches, fetch real popularity from a connected source, and read or clear rank alerts.
run_rank_check Check ranks
Search the store for every keyword in the project's markets and record ranks, estimated volume/difficulty and competitors. Runs as a background job (the store is rate-limited, so large boards take minutes). Results already checked today are reused unless force is true.
| Parameter | Type | Description |
|---|---|---|
force | boolean | Re-check even if already checked today. |
markets | array of string | Only these markets (default: all tracked). |
projectId required | string | Project id (from get_overview). |
fetch_popularity Fetch real popularity
Pull REAL search popularity for the project's keywords from the connected source (Apple Ads popularity or Google Ads Keyword Planner). Separate from rank checks and from ASOMaster's estimates; requires a connected source (get_popularity_status).
| Parameter | Type | Description |
|---|---|---|
markets | array of string | Only these markets (default: all tracked). |
projectId required | string | Project id (from get_overview). |
get_popularity_status Popularity sources
Which REAL popularity sources (Apple Ads, Google Ads Keyword Planner, imported files) are connected, for which store, and when they last fetched. Credentials are never returned.
acknowledge_alerts Mark alerts read / clear
Mark rank alerts as read (given ids, or all when ids is omitted). With clear:true, delete all alerts instead.
| Parameter | Type | Description |
|---|---|---|
clear | boolean | Delete all alerts (ignores ids). |
ids | array of string | Alerts to mark read (default: all). |
Listing Studio
Draft listing options, choose one, localize it, review each language and publish. Publishing needs the owner's explicit approval.
get_optimizer Optimizer state
Listing optimizer state for a project: step, current live listing, generated listing options (with reach/difficulty, covered phrases and validation problems), the chosen option, core phrases and per-locale drafts with translation candidates. Descriptions are cut unless full is true.
| Parameter | Type | Description |
|---|---|---|
full | boolean | Return full descriptions (default false). |
locale | string | Only show this locale's draft in full; others are listed by status. |
projectId required | string | Project id (from get_overview). |
optimizer_start Generate listing options
Start the listing optimizer for a project: scouts the board's keywords in the main locale and has the AI write several complete listing options (title, subtitle/short description, keyword field, description) scored for reach and difficulty. Replaces previous options. Background job; then read get_optimizer.
| Parameter | Type | Description |
|---|---|---|
ai | "claude_code" | "codex" | "opencode" | "ollama" | AI provider used by the app for generation (see get_ai_status). |
directions | string | Optional creative direction for the AI, e.g. "emphasise offline use". |
locale required | string | Main listing locale, e.g. "en-US". |
projectId required | string | Project id (from get_overview). |
optimizer_more_options More listing options
Generate additional listing options next to the existing ones.
| Parameter | Type | Description |
|---|---|---|
count required | integer 1–10 | How many more options. |
directions | string | Optional creative direction for the AI, e.g. "emphasise offline use". |
projectId required | string | Project id (from get_overview). |
optimizer_save_option Add or edit a listing option
Add your own listing option (omit optionId) or replace the listing of an existing option. The app re-scores it and reports validation problems (length limits, repeated words) in get_optimizer.
| Parameter | Type | Description |
|---|---|---|
label | string | Name for a new option. |
listing required | object | |
listing.description | string | Full description (4000 chars). |
listing.keywords | string | Apple keyword field, comma separated (100 chars). |
listing.locale required | string | Listing locale, e.g. "en-US". |
listing.promotionalText | string | Apple promotional text (170 chars). |
listing.shortDescription | string | Google short description (80 chars). |
listing.subtitle | string | Apple subtitle (30 chars). |
listing.title | string | App name / title (Apple 30 chars, Google 30). |
optionId | string | Option to replace; omit to add a new one. |
projectId required | string | Project id (from get_overview). |
optimizer_remove_option Remove listing option
Delete one listing option (generated or custom) from the optimizer.
| Parameter | Type | Description |
|---|---|---|
optionId required | string | Option id. |
projectId required | string | Project id (from get_overview). |
optimizer_choose Choose listing option
Pick the listing option to ship and the core phrases it must carry into every locale. Next step: optimizer_localize.
| Parameter | Type | Description |
|---|---|---|
corePhrases required | array of string | Main-locale phrases to keep in every locale. |
optionId required | string | Chosen option id. |
projectId required | string | Project id (from get_overview). |
optimizer_localize Localize chosen listing
Write per-locale drafts of the chosen listing: the core phrases are translated, candidate local phrasings are measured in each locale's test market, and the best are used. A locale that fails does not stop the others; get_optimizer lists failedLocales and lastError. Background job.
| Parameter | Type | Description |
|---|---|---|
directions | string | Optional creative direction for the AI, e.g. "emphasise offline use". |
locales | array of string | Only these locales (default: see scope). |
projectId required | string | Project id (from get_overview). |
remaining | boolean | Only locales without a draft yet or that failed last time (finish an interrupted run). |
scope | "markets" | "all" | Without locales: the tracked markets' locales (markets, default) or every listing locale of the store in fast mode (all: batched AI candidates, parallel, measured in each locale's test market only). |
optimizer_edit_locale Edit a locale draft
Change fields of one locale's draft listing (empty string clears a field).
| Parameter | Type | Description |
|---|---|---|
fields required | object | Fields to change; an empty string clears the field. |
fields.description | string | Full description (4000 chars). |
fields.keywords | string | Apple keyword field, comma separated (100 chars). |
fields.promotionalText | string | Apple promotional text (170 chars). |
fields.shortDescription | string | Google short description (80 chars). |
fields.subtitle | string | Apple subtitle (30 chars). |
fields.title | string | App name / title (Apple 30 chars, Google 30). |
locale required | string | Locale of the draft. |
projectId required | string | Project id (from get_overview). |
optimizer_pick_phrase Pick local phrasing
In one locale draft, use a different measured candidate phrase for a core phrase (from that locale's candidates in get_optimizer).
| Parameter | Type | Description |
|---|---|---|
keyword required | string | Core phrase (main locale) being translated. |
locale required | string | Locale of the draft. |
phrase required | string | Candidate phrase to use. |
projectId required | string | Project id (from get_overview). |
optimizer_reset Reset optimizer
Discard all options, the choice and every locale draft for the project.
| Parameter | Type | Description |
|---|---|---|
projectId required | string | Project id (from get_overview). |
get_next_version Next app version
The editable app version on the developer console (if any) and the version string the app would suggest for publishing.
| Parameter | Type | Description |
|---|---|---|
projectId required | string | Project id (from get_overview). |
publish_listing Publish listing to the store
DESTRUCTIVE / LIVE: pushes the chosen listing and every ready locale draft to App Store Connect or Google Play Console, changing what real users see. Only call after the owner has reviewed the exact listing text and explicitly told you to publish in this conversation; never on your own initiative and never as part of a larger plan they approved in general terms. Requires a connected console. The app then shows the owner a confirmation dialog listing the store, app, version, locales and fields; nothing is published unless they click Publish there (no answer within ~2 minutes = denied, error code not_approved). Background job once approved; follow with wait_for_jobs and report the outcome.
| Parameter | Type | Description |
|---|---|---|
approval required | string | Quote the owner's explicit go-ahead. |
ownerApproved required | true | Must be true: the owner explicitly approved publishing this listing. |
projectId required | string | Project id (from get_overview). |
versionString | string | App version to attach the listing to (see get_next_version); default: the app's suggestion. |
Assistant
Talk to the in-app assistant. It proposes changes; they apply only when approved.
ask_assistant Ask the ASO assistant
Send a message to the in-app ASO assistant for a project (keywords or optimizer scope). It PROPOSES keyword / listing changes (status proposed) but applies nothing by itself; review them with the owner, then call apply_assistant_changes or dismiss_assistant_changes. Background job; read the reply with get_assistant_thread after wait_for_jobs.
| Parameter | Type | Description |
|---|---|---|
ai | "claude_code" | "codex" | "opencode" | "ollama" | AI provider used by the app for generation (see get_ai_status). |
projectId required | string | Project id (from get_overview). |
scope required | "keywords" | "optimizer" | Conversation scope. |
text required | string | Message. |
get_assistant_thread Assistant conversation
Recent messages of the in-app ASO assistant for a project (keywords or optimizer scope), including keywords it mentioned and the changes it proposed with their status (proposed / applied / dismissed / failed).
| Parameter | Type | Description |
|---|---|---|
lastMessages | integer 1–100 | How many recent messages (default 10). |
projectId required | string | Project id (from get_overview). |
scope required | "keywords" | "optimizer" | Conversation scope. |
apply_assistant_changes Apply assistant proposals
Apply changes the assistant proposed in one of its messages (ids from get_assistant_thread, e.g. "c0"; omit changeIds for every still-proposed change). Already applied or dismissed changes are skipped. Only apply what the owner agreed to.
| Parameter | Type | Description |
|---|---|---|
changeIds | array of string | Changes to apply (default: all proposed). |
messageId required | string | Assistant message id (get_assistant_thread). |
projectId required | string | Project id (from get_overview). |
dismiss_assistant_changes Dismiss assistant proposals
Mark changes the assistant proposed in one of its messages as dismissed (omit changeIds for every still-proposed change). Nothing in the project changes.
| Parameter | Type | Description |
|---|---|---|
changeIds | array of string | Changes to dismiss (default: all proposed). |
messageId required | string | Assistant message id (get_assistant_thread). |
projectId required | string | Project id (from get_overview). |
clear_assistant Clear assistant conversation
Delete the assistant conversation history of a project.
| Parameter | Type | Description |
|---|---|---|
projectId required | string | Project id (from get_overview). |
Store consoles and popularity sources
Connect App Store Connect, Google Play Console, Apple Ads or Google Ads. Pass key files by path; secrets go to the OS keychain and are never returned.
connect_console Connect developer console
Connect an App Store Connect API key (apple: keyId, issuerId, private key .p8) or a Google Play service account (google: service-account JSON, optional package names). Pass FILE PATHS (privateKeyPath / serviceAccountPath; files must be .p8/.pem/.json/.txt in the owner's Downloads, Desktop or Documents folder) so secrets never enter the conversation; the bridge reads them locally and the app stores them in the OS keychain. Credentials are never returned. Needed for console apps, publishing and own-app metadata.
| Parameter | Type | Description |
|---|---|---|
issuerId | string | apple: issuer id. |
keyId | string | apple: API key id. |
label | string | Account label shown in the app. |
packageNames | array of string | google: package names this account manages. |
privateKeyPath | string | apple: path to the AuthKey_XXXX.p8 file. |
privateKeyPem | string | apple: PEM contents (prefer privateKeyPath). |
serviceAccountJson | string | google: service-account JSON contents (prefer serviceAccountPath). |
serviceAccountPath | string | google: path to the service-account JSON file. |
store required | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
test_console Test console account
Verify a connected console account still works (updates its status in list_console_apps).
| Parameter | Type | Description |
|---|---|---|
accountId required | string | Console account id (list_console_apps). |
disconnect_console Disconnect console account
Remove a console account and delete its stored key from the keychain. Ask the owner first.
| Parameter | Type | Description |
|---|---|---|
accountId required | string | Console account id. |
connect_popularity Connect popularity source
Connect a source of REAL keyword popularity: apple_ads (Apple Ads API: clientId, teamId, keyId, private key, optional orgId), google_ads_planner (Google Ads Keyword Planner: developerToken, customerId, refreshToken, oauthClientId, oauthClientSecret, optional loginCustomerId) or imported (a popularity export file at filePath). Prefer file paths for keys. Secrets go to the OS keychain and are never returned. Then call fetch_popularity.
| Parameter | Type | Description |
|---|---|---|
clientId | string | apple_ads: client id. |
customerId | string | google_ads_planner: customer id. |
developerToken | string | google_ads_planner: developer token. |
filePath | string | imported: path to the export file (CSV / JSON). |
keyId | string | apple_ads: key id. |
loginCustomerId | string | google_ads_planner: manager account id. |
oauthClientId | string | google_ads_planner: OAuth client id. |
oauthClientSecret | string | google_ads_planner: OAuth client secret. |
orgId | string | apple_ads: org id when several are visible. |
privateKeyPath | string | apple_ads: path to the private key PEM. |
privateKeyPem | string | apple_ads: PEM contents (prefer privateKeyPath). |
refreshToken | string | google_ads_planner: OAuth refresh token. |
source required | "apple_ads" | "google_ads_planner" | "imported" | Popularity source. |
store | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
teamId | string | apple_ads: team id. |
disconnect_popularity Disconnect popularity source
Disconnect a popularity source and delete its stored credentials. Ask the owner first.
| Parameter | Type | Description |
|---|---|---|
source required | "apple_ads" | "google_ads_planner" | "imported" | Popularity source. |
Settings, AI, import and export
Change app settings, pick and test the AI provider, import keyword files and export data.
update_settings Update settings
Change app settings; only the keys you pass change. Use set_ai_provider for the AI provider/model.
| Parameter | Type | Description |
|---|---|---|
settings required | object | |
settings.aiConcurrency | integer 1–16 | Parallel AI requests. |
settings.aiEffort | "low" | "medium" | "high" | AI reasoning effort. |
settings.aiFallback | boolean | Fall back to another ready provider on failure. |
settings.alerts | object | |
settings.autoUpdate | boolean | Install updates automatically. |
settings.blurMode | boolean | Blur app names for screenshots. |
settings.cellDisplay | "rank" | "estimate" | "popularity" | What board cells show. |
settings.checkSchedule | "off" | "daily" | "weekly" | "biweekly" | "monthly" | Global automatic check schedule. |
settings.checkSpeed | "normal" | "fast" | Store request pacing (fast risks throttling). |
settings.defaultMarkets | object | |
settings.metricDriver | "estimate" | "popularity" | Which metric drives colours, verdicts and opportunity: ASOMaster estimate or real popularity. |
settings.parallelApps | integer 1–4 | Projects checked at the same time. |
settings.theme | "system" | "light" | "dark" | UI theme. |
settings.updateChannel | "stable" | "beta" | App update channel. |
get_ai_status AI providers
Status of the local AI providers the app uses for brainstorming, suggestions, the optimizer and the assistant: installed / signed in / ready, current model and the next setup step when not ready.
set_ai_provider Choose AI provider
Select the local AI provider (and optionally model) the app uses for generation. Check readiness with get_ai_status first.
| Parameter | Type | Description |
|---|---|---|
model | string | Model id from get_ai_status (default: provider default). |
provider required | "claude_code" | "codex" | "opencode" | "ollama" | AI provider used by the app for generation (see get_ai_status). |
test_ai_provider Test AI provider
Send a tiny test prompt through a provider and record latency / errors (see get_ai_status).
| Parameter | Type | Description |
|---|---|---|
provider required | "claude_code" | "codex" | "opencode" | "ollama" | AI provider used by the app for generation (see get_ai_status). |
import_file Import keywords file
Import an Astro export or a CSV of apps / keywords from a local path (must be a .csv/.tsv/.txt/.json file in the owner's Downloads, Desktop or Documents folder). format astro without path reads Astro's own database on this Mac: its popularity becomes real popularity and each Astro app's phrases join the tracked app with the same App Store id. previewOnly:true just reports what would be imported (rows, apps, keywords, countries). With projectId the phrases are added as keywords of that project; otherwise apps become projects (optionally in folderId). Background job.
| Parameter | Type | Description |
|---|---|---|
folderId | string | Folder for imported projects. |
format required | "astro" | "csv" | File format. |
path | string | Absolute path of the file (omit with format astro to read Astro's local database). |
previewOnly | boolean | Only preview (default false). |
projectId | string | Add the imported phrases to this project. |
store | "apple" | "google" | Store: "apple" (App Store) or "google" (Google Play). |
export_data Export board / history / optimizer
Export a project's board, rank history or optimizer drafts as CSV or JSON. By default returns the content (cut at maxChars); with saveToFile:true writes the file into the app's exports folder instead.
| Parameter | Type | Description |
|---|---|---|
format required | "csv" | "json" | File format. |
maxChars | integer 100–2000000 | Max characters of content to return (default 50000). |
projectId required | string | Project id (from get_overview). |
saveToFile | boolean | Write to <dataDir>/exports instead of returning content. |
what required | "board" | "history" | "optimizer" | What to export. |
Jobs
Store and AI work runs as background jobs. Wait for them, or stop one.
wait_for_jobs Wait for background work
Block until background work changes state: returns as soon as a job finishes (done / failed / stopped), or when nothing is queued or running, or after timeoutSeconds (max 50). With jobId, waits for that job only; with projectId, for that project's jobs. Call it repeatedly after any tool that queued work until idle is true, then read the results. Reports progress of jobs still running.
| Parameter | Type | Description |
|---|---|---|
jobId | string | Wait for this job only. |
projectId | string | Only this project's jobs (a finished fetch can start brainstorming, then a check). |
timeoutSeconds | integer 1–50 | Max seconds to wait (default 45, max 50). |
stop_job Stop a job
Stop a queued or running background job (rank check, AI generation, import, ...). Work already done is kept.
| Parameter | Type | Description |
|---|---|---|
jobId required | string | Job id (get_overview / wait_for_jobs). |
Troubleshooting
The ASOMaster tools disappeared after I moved or reinstalled the app
The client still points at the old bridge path. Open Settings › MCP clients: affected clients say "Needs update". Click Update, then restart the client.
The agent says the app is unavailable
The bridge couldn't reach the app within 30 seconds. Open ASOMaster yourself and try again. If you set ASOMASTER_NO_LAUNCH=1 the bridge never starts the app. If you use a custom data folder, ASOMASTER_DATA_DIR must match the app's.
Every tool answers license_required
Activate ASOMaster on this computer, or renew the subscription. See License and computers.
ai_not_configured
The tool needs an AI provider and none is ready. Ask the agent to call get_ai_status, or set one up in Settings › AI. See AI providers.
console_not_connected
Reading the keyword field, analytics and publishing need App Store Connect or Google Play Console. Connect it in Settings › Store consoles, or let the agent call connect_console with the key file path. See App Store Connect and Google Play Console.
A job seems stuck
get_overview lists running jobs with progress. A job with pausedUntil is waiting out a store rate limit and will resume. To cancel, call stop_job with its id, or stop it in the app's Jobs view.
Calls time out
Each request has a 90 second limit by default. Long work should go through jobs and wait_for_jobs; raise the limit with ASOMASTER_MCP_CALL_TIMEOUT_MS only if your client needs it.
Environment variables
All optional. Set them in the client's server entry (env).
| Variable | Effect |
|---|---|
ASOMASTER_DATA_DIR | Use a different app data folder. Must match the app's. |
ASOMASTER_IPC_ENDPOINT | Override the socket path or pipe name. |
ASOMASTER_APP_PATH | App to launch when it isn't running (a .app bundle or an executable). |
ASOMASTER_NO_LAUNCH=1 | Never launch the app; fail with a clear error instead. |
ASOMASTER_MCP_CALL_TIMEOUT_MS | Per-request timeout in milliseconds (default 90000). |
Still stuck? Write to asomaster@cressu.com with the client you use and the error the agent showed.