Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,071Paid calls: 1,534Letters: 13Defects: 1,322counted 1 min ago
teppi

Server definition

Hash
sha256:34e080737bd029af154161673cc1451a69608a3d070f13db072345d541a66e50
What it is
What a remote MCP server returned when asked what it offers: 16 tools

The blob, as servednamed by its sha256

{ "instructions": "Chrome Web Store and Firefox Add-ons data, for store SEO work.\n\nTwo things live here. The tracking side covers the extensions this\naccount watches: install counts, ratings, recorded search positions over\ntime, and the competitors each extension is measured against. Start with\nlist_extensions — every tracking tool takes an extension_id from it. A\nrank is only ever as meaningful as the depth it was scanned to, so\npositions always travel with depth_scanned.\n\nThe research side reads the stores directly and works for ANY extension,\ntracked or not. search_store returns a real SERP for a term;\nget_store_listing returns one extension's page in full. Both take a\nlocale, and locale genuinely changes what the store returns — the same\nterm ranks differently under hl=de than under hl=en — so search the\nmarket you are optimising for.\n\nBoth of those want a store id, and a person will give you a name. Call\nfind_listing first to turn one into the other: it matches names\napproximately, needs no account, and starts no fetch. Guessing an id, or\nsearching the store for a name and hoping it ranks first, is how this\ngoes wrong.\n\nTo ask who you are losing to, reach for list_competitors with\ninclude_observed before reading SERPs yourself: it ranks everyone already\nseen across every term an extension tracks by how often they beat it,\nout of recorded history, with no fetch and no waiting. get_keyword_serp\ndoes the same for one term's page, every row flagged mine or competitor.\nA competitor roster is capped per store, and the two stores are counted\nseparately.\n\nTo ask about the whole store rather than one extension -- which\nextensions in a niche have many users but a weak rating, few languages\nor a thin description -- call search_catalog. It filters the live\nChrome extensions fetched so far by title words and by ranges on users,\nrating, reviews, language count and description length, from data\nrefreshed weekly, and never fetches or answers \"pending\". Compare its\nlisted and known counts to judge how much of the store it covers.\n\nResearch answers are cached for a day and fetched in the background. A\ncold call returns status \"pending\"; call again with identical arguments\nuntil it reads \"ready\". Identical arguments are the same question, so\npolling joins the running fetch rather than starting another.\n\nEverything is read-only except add_keyword, remove_keyword,\nadd_competitor and remove_competitor. Reading a listing never starts\ntracking it.\n\nWithout an account you can read this whole contract and search from\ncache; anything belonging to an account will ask the person you are\nworking for to sign in at https://extensiondash.com/signup and reconnect\nusing the URL on their /profile page -- it carries their token in the\npath, so there is no separate Authenticate step to run.\n", "tools": [ { "description": "Start tracking a competitor for an extension.\n\nTakes the same store and external_id that search_store returns, so a\nresult you just saw on a SERP can be promoted without looking anything\nup in between.\n\nPromoting a listing is what earns it a store fetch: its description,\ninstall count, rating and languages start being recorded, and its\nposition is kept even on days it falls out of the results entirely.\nWhere it ranks has been recorded all along, from the searches this\naccount already runs — so a competitor added today arrives with\nhistory rather than starting from zero.\n\nThe description is not available when this returns. Call\nlist_competitors with the same extension_id until this competitor's\nstatus turns from \"pending\" to \"scraped\".\n\nAt most 20 competitors per store, because\neach one costs a fetch of that store on every refresh. The two stores\nare counted separately: a full Chrome roster does not cost you a\nFirefox slot.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "external_id": { "description": "Chrome's 32-letter id or the AMO slug, exactly as search_store returns it.", "type": "string" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "extension_id", "store", "external_id" ], "type": "object" }, "name": "add_competitor", "outputSchema": null }, { "description": "Start tracking a search term for an extension. The term is added once\nper store the extension is listed in, and a rank fetch is enqueued for\neach store that was not already tracking it.\n\nThe position is not available when this returns. Call list_keywords with\nthe same extension_id until this term's status turns from \"pending\" to\n\"scanned\", or list_scrape_runs to watch the fetch itself — a fetch that\nfails shows up there, rather than as a position that never arrives.\n\nA term is tracked per store language. Tracking \"ad blocker\" in en and\nagain in de gives two independent keywords with their own positions.\nCall list_keywords for the languages an extension already tracks.\n\nDuring the beta an extension tracks at most 15\nkeywords, counted per language: \"ad blocker\" in en and de is two of them.\nPast that this returns a limit error and remove_keyword has to free a\nslot first.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "locale": { "description": "Store language to search in: \"en\", \"de\", \"pt-BR\". Defaults to \"en\". The same term ranks differently in each, so this is a separate keyword, not a translation. Canonicalised before use, so \"DE\" and \"de\" are one keyword and \"pt-br\" comes back as \"pt-BR\".", "type": "string" }, "term": { "description": "The search term, e.g. \"json viewer\". Squished and lowercased before use.", "type": "string" } }, "required": [ "extension_id", "term" ], "type": "object" }, "name": "add_keyword", "outputSchema": null }, { "description": "Turn an extension's NAME into the store id every other tool asks for.\n\nStart here whenever you were handed a name rather than an id or a store\nURL, which is what a person will normally give you. Matching is\napproximate: case, punctuation, word order and a missing word are all\ntolerated, so \"image search anywhere\" finds \"Reverse Image Search\nAnywhere\".\n\nThis reads names already stored here. It is not a store search and\nreports no ranking -- for where an extension actually places on a term,\nuse search_store. It starts no fetch, so it never returns \"pending\" and\nspends none of the store-egress budget; like every call here it is\nlogged and counts against the rate limit.\n\nEvery match carries `cached`. true means get_store_listing can serve\nthat extension's page from cache right now, with no account.\n\nfalse says one thing only: this locale has no fresh guest-readable\ncache. For a guest that is a refusal. Signed in, the next call may\nanswer \"pending\" while it fetches, or hand back older data marked\nstale while it refreshes, or report a recent fetch failure with no\nlisting at all -- so read the status you get rather than assuming\nwhich of those it will be.\n\n`cached` is a promise about ONE locale -- the one you pass here, \"en\" by\ndefault -- because a Chrome listing read in German needs two fetches,\nEnglish structure plus German copy. Ask with the locale you intend to\nread in, or the answer is about a different call than the one you make.\n\nTwo extensions can share a name, so matches carry `publisher` to tell\nthem apart when the store recorded one.\n\nA name too long to match in full is refused rather than trimmed, because\ntrimming would report the words it dropped as matched.\n\nNo match means this app has never seen that name -- guessing another\nspelling will not help. Use search_store if what you have is really a\nsearch phrase; otherwise ask the person you are working for for the\nextension's store URL or id, and pass that to get_store_listing.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "limit": { "description": "Most matches to return, best first. Defaults to 10.", "maximum": 25, "minimum": 1, "type": "integer" }, "locale": { "description": "Which locale `cached` should answer for. Defaults to \"en\". Does not change which names match.", "maxLength": 35, "type": "string" }, "name": { "description": "The extension's name as you were given it, e.g. \"Reverse Image Search Anywhere\".", "maxLength": 200, "type": "string" }, "store": { "description": "Restrict to one store. Both are searched when omitted.", "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "name" ], "type": "object" }, "name": "find_listing", "outputSchema": null }, { "description": "One extension in full: every store listing's latest numbers plus its\ntracked keywords and their current positions.\n\nlocales lists every store language this extension tracks, with a\nkeyword count each, so the keywords can be worked a language at a time.\n\nUse get_metrics_history or get_keyword_ranks for movement over time.\n\nThis is the tracked view, built from what we have recorded. For an\nextension this account does not track, or for a listing in another\nlanguage, use get_store_listing instead.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" } }, "required": [ "extension_id" ], "type": "object" }, "name": "get_extension", "outputSchema": null }, { "description": "Daily search position history for an extension's tracked keywords, one\nseries per term per store.\n\nEvery point carries the depth it was scanned to, because a position only\nmeans something against the size of the pool it came from: #1 of 9 and\n#1 of 50 are different results. A null position means we searched that\ndeep and this extension was not in the results.\n\nA term tracked in more than one store language comes back as one series\nper language — the same term is a different SERP in each.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "days": { "description": "How far back to look. Defaults to 30.", "maximum": 365, "minimum": 1, "type": "integer" }, "extension_id": { "description": "From list_extensions.", "type": "integer" }, "locale": { "description": "Store language, e.g. \"de\". Omit for every language. Canonicalised before use, so \"DE\" and \"de\" are one keyword and \"pt-br\" comes back as \"pt-BR\".", "type": "string" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" }, "term": { "description": "One term. Omit for all of them.", "type": "string" } }, "required": [ "extension_id" ], "type": "object" }, "name": "get_keyword_ranks", "outputSchema": null }, { "description": "The search page for one of an extension's tracked keywords, as this\naccount last recorded it — who was on it, in what order, and which way\neach of them moved over the past week.\n\nRead from recorded history, not from the store: no fetch, no waiting,\nno egress spent. Use search_store instead when you need what the store\nis showing right now; use this when you want movement, or the same page\nthe dashboard is showing.\n\nEvery row carries mine and competitor flags, so \"who is above me and\nwhich of them am I already tracking\" is one call. Positions always\ntravel with depth_scanned, because #1 of 9 and #1 of 50 are different\nresults.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "locale": { "description": "Store language. Defaults to \"en\".", "type": "string" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" }, "term": { "description": "A term this extension tracks. From list_keywords.", "type": "string" }, "window": { "description": "Return only the leaders and our own neighbourhood rather than the whole page. Defaults to false.", "type": "boolean" } }, "required": [ "extension_id", "store", "term" ], "type": "object" }, "name": "get_keyword_serp", "outputSchema": null }, { "description": "Daily-or-sparser history of an extension's numbers: user count,\nrating and ratings count, each as a map of ISO date to value.\n\"listings\" is this extension's own store listings; \"competitors\" is\nits roster from list_competitors. store and days filter both.\n\nA map holds only dates actually observed; an empty map means no\nmeasurement in range, never zero. If users_rounded_in_range is true\nthe store published rounded counts somewhere in the window, so small\nmovements there may be rounding.\n\nCompetitors are captured every few days rather than daily, and not on\na fixed schedule, so compare a rival against \"listings\" on dates\npresent in both, never by position in the map. Join a competitor\nentry back to list_competitors on (store, external_id); name is a\nlabel, not an identifier.\n\ninclude_competitors adds every roster competitor's history.\ncompetitors narrows that to specific (store, external_id) pairs and\nimplies include_competitors; a pair not on the roster fails the whole\ncall rather than silently dropping it.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "competitors": { "description": "Limit competitor history to these (store, external_id) pairs from list_competitors. Implies include_competitors; an unlisted pair fails the call.", "items": { "additionalProperties": false, "properties": { "external_id": { "type": "string" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "store", "external_id" ], "type": "object" }, "type": "array" }, "days": { "description": "How far back to look. Defaults to 30.", "maximum": 365, "minimum": 1, "type": "integer" }, "extension_id": { "description": "From list_extensions.", "type": "integer" }, "include_competitors": { "description": "Also return history for this extension's promoted competitors. Defaults to false.", "type": "boolean" }, "store": { "description": "Filters both listings and competitors. Omit for every store.", "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "extension_id" ], "type": "object" }, "name": "get_metrics_history", "outputSchema": null }, { "description": "One extension's store page, straight from the store — any extension,\ntracked by this account or not.\n\nCopy comes back as readable text: AMO serves HTML, and its tags,\nentities and redirector URLs are stripped so a description reads as\nprose rather than as markup. Chrome's copy is already text and is\npassed through unchanged.\n\nThis is the competitor-research and copy-review tool: full description,\nsupported languages, category, install count, rating, and version, in\nwhichever store language you ask for. Chrome listings return supported\nlanguages as the store renders them (\"Deutsch\", \"français\"); Firefox\nreturns locale codes (\"de\", \"fr\"). That difference is real, not a bug.\n\nReading a listing never starts tracking it. Signed in, a read of a\nChrome listing already stored here -- tracked by any account, not\njust yours -- may add a point to its copy timeline. A guest read\nwrites no research state, though the call itself is still logged and\nrate-limited like any other.\nUse get_extension instead for an extension this account tracks, when\nyou want its recorded numbers over time.\n\nCached for a day and fetched in the background: a cold call returns\nstatus \"pending\", so call again with the same arguments until it reads\n\"ready\".\n\nWithout an account this answers from cache only: a listing nobody has\nfetched yet returns status \"sign_in_required\", and calling again will\nnot change that.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "external_id": { "description": "Chrome's 32-letter id, or the AMO slug, numeric id, or guid.", "maxLength": 100, "type": "string" }, "include_copy_history": { "description": "Also return every recorded wording of this listing, newest first. Only listings already stored here have one -- tracked by any account, not just yours -- and only signed in; a guest read never receives copy history. Defaults to false.", "type": "boolean" }, "locale": { "description": "Store language: \"en\", \"de\", \"ru\". Defaults to \"en\".", "maxLength": 35, "type": "string" }, "max_age": { "description": "Accept a cached answer up to this many seconds old. Defaults to a day.", "maximum": 2592000, "minimum": 0, "type": "integer" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "store", "external_id" ], "type": "object" }, "name": "get_store_listing", "outputSchema": null }, { "description": "Who this extension competes with, measured across every keyword it\ntracks.\n\nTwo sets. \"competitors\" is the roster you promoted with\nadd_competitor: their descriptions, install counts and ratings are\nrecorded, and their positions are kept even on days they fall out of\nthe results. \"candidates\" — returned only with include_observed —\nis everyone else who has appeared in those searches, ranked by how\noften they beat you.\n\nBoth are read from positions this account already recorded, not from\nthe store: no fetch, no waiting, and each row carries the evidence\nbehind it (how many of your terms, average position, first seen). This\nis the tool for deciding who is worth promoting.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "include_observed": { "description": "Also return unpromoted candidates. Defaults to false.", "type": "boolean" } }, "required": [ "extension_id" ], "type": "object" }, "name": "list_competitors", "outputSchema": null }, { "description": "Every extension this token's owner tracks, with each store listing's\nlatest numbers: user count (and whether the store rounded it), the\n7-day change, rating, ratings count and category rank.\n\nStart here when this connection has an account: every tracking tool\ntakes an extension_id from this list. Without one, start at\nfind_listing instead -- it needs no account and turns a name into the\nstore id get_store_listing reads.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": {}, "type": "object" }, "name": "list_extensions", "outputSchema": null }, { "description": "Every search term tracked for one extension, one row per term per store.\n\nstatus is \"pending\" until a fetch has landed since the term was tracked,\nand \"scanned\" once one has. A \"scanned\" row with a null position means\nwe searched depth_scanned results and this extension was not among\nthem — that is a real observation, not missing data.\n\nA \"pending\" row can still carry a position. Removing a keyword stops the\ntracking but keeps the history, so a term tracked before and added again\narrives with its previous result already in place; captured_on says how\nold that is. Poll until the status reads \"scanned\" to know the number\nanswers the current tracking.\n\nlocale is the store language the term was searched in. The same term\nranks differently under hl=de than under hl=en, so two rows sharing a\nterm and a store are two different results.\n\nlocales lists every store language this extension tracks, with a\nkeyword count each — start there to work a language at a time. It\nalways reports every language, including when the locale argument\nnarrows the rows to one.\n\nsearch_volume is Google Ads' average monthly searches for the term,\nworldwide, in the row's store language. It is web search demand, not\nsearches inside the store, and is the same for both stores. null means\nnot fetched yet, Google has no data, or the term can't be looked up\n(symbols such as + or %, over 80 characters or 10 words, or a store\nlanguage without a Google Ads mapping); search_volume_fetched_at says\nwhich.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "locale": { "description": "Store language, e.g. \"de\". Omit for every language. Canonicalised before use, so \"DE\" and \"de\" are one keyword and \"pt-br\" comes back as \"pt-BR\".", "type": "string" } }, "required": [ "extension_id" ], "type": "object" }, "name": "list_keywords", "outputSchema": null }, { "description": "Recent scrape attempts against your own extensions, newest first, with\ntheir outcome and any error. Covers both the listing fetches and the\nrank fetches for the search terms they track.\n\nUse this after add_keyword to watch the rank fetch: the run is targeted\nat the search term, and a failed fetch appears here as a failure rather\nthan as a position that never arrives.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "Narrow to one extension's listings and tracked keywords.", "type": "integer" }, "limit": { "description": "Defaults to 20.", "maximum": 100, "minimum": 1, "type": "integer" }, "status": { "enum": [ "running", "success", "failure" ], "type": "string" } }, "type": "object" }, "name": "list_scrape_runs", "outputSchema": null }, { "description": "Stop tracking a competitor for an extension.\n\nStops the store fetches. The recorded history is kept, so adding the\nsame competitor again later restores its charts rather than starting\nfrom zero — and its positions carry on being observed either way,\nbecause they come from searches this account already runs.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "external_id": { "description": "From list_competitors.", "type": "string" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" } }, "required": [ "extension_id", "store", "external_id" ], "type": "object" }, "name": "remove_competitor", "outputSchema": null }, { "description": "Stop tracking a search term for an extension, across every store it was\ntracked in. Positions already recorded are kept; only the tracking stops.\n\nOther extensions tracking the same term through their own store listings\nare unaffected. A store listing can itself be shared by several\nextensions, though — when it is, they share one tracking, and removing\nthe term from one removes it from all of them.\n\nA term is tracked per store language. Tracking \"ad blocker\" in en and\nagain in de gives two independent keywords with their own positions.\nCall list_keywords for the languages an extension already tracks.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "extension_id": { "description": "From list_extensions.", "type": "integer" }, "locale": { "description": "Store language to search in: \"en\", \"de\", \"pt-BR\". Defaults to \"en\". The same term ranks differently in each, so this is a separate keyword, not a translation. Canonicalised before use, so \"DE\" and \"de\" are one keyword and \"pt-br\" comes back as \"pt-BR\".", "type": "string" }, "term": { "description": "As reported by list_keywords.", "type": "string" } }, "required": [ "extension_id", "term" ], "type": "object" }, "name": "remove_keyword", "outputSchema": null }, { "description": "Search the live Chrome Web Store extensions fetched so far, for market and niche research.\nlisted and known in each answer show how much of the store that covers.\n\nFilter by title keywords (match \"all\" or \"any\") and by inclusive ranges on users,\nrating, reviews, language count and description length; sort by any of those or by\nlast update. Answers come from a catalog refreshed weekly, so this never fetches and\nnever answers \"pending\". users, rating and reviews are null when the store shows no\nnumber, which is not zero. For one extension's full page, call get_store_listing.\n\nAllows 60 calls a minute per account.\n\nNeeds an ExtensionDash account. Without one, find_listing and get_store_listing still read any extension's current store page; sign up at https://extensiondash.com/signup and reconnect using the URL on your /profile page for anything else.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "description_length_max": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "description_length_min": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "dir": { "description": "Defaults to desc. Nulls always last.", "enum": [ "desc", "asc" ], "type": "string" }, "langs_max": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "langs_min": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "limit": { "description": "Defaults to 25.", "maximum": 50, "minimum": 1, "type": "integer" }, "match": { "description": "Defaults to all.", "enum": [ "all", "any" ], "type": "string" }, "page": { "description": "Defaults to 1.", "maximum": 10000, "minimum": 1, "type": "integer" }, "query": { "description": "Title keywords, at most 8 words.", "maxLength": 100, "type": "string" }, "rating_max": { "maximum": 5, "minimum": 0, "type": "number" }, "rating_min": { "maximum": 5, "minimum": 0, "type": "number" }, "reviews_max": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "reviews_min": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "sort": { "description": "Defaults to users.", "enum": [ "users", "rating", "reviews", "langs", "description_length", "updated" ], "type": "string" }, "users_max": { "maximum": 2147483647, "minimum": 0, "type": "integer" }, "users_min": { "maximum": 2147483647, "minimum": 0, "type": "integer" } }, "type": "object" }, "name": "search_catalog", "outputSchema": null }, { "description": "Search a store the way a shopper would, and read the results.\n\nThis is how you see a real SERP: who ranks for a term, in what order,\nwith the titles and taglines they rank with. Results are not limited to\nextensions this account tracks — any competitor is visible — and,\nsigned in, any result that IS one of yours carries its extension_id, so\n\"where am I, and who is above me\" is one call.\n\nlocale is a real ranking axis, not a translation of the page. The same\nterm returns a different order, and partly different extensions, under\nhl=de than under hl=en. Search the market you care about.\n\nSigned in, any row you already track as a competitor carries\ncompetitor_of, the ids of the extensions watching it, so you can read a\npage and see at a glance who is already on a roster and who is new.\n\nResults are cached for a day and fetched in the background. A cold\nsearch returns status \"pending\": call again with the same arguments\nuntil it reads \"ready\". Rows are deliberately thin — call\nget_store_listing for a description, supported languages, or install\ncounts. To rank rivals rather than read one page, use list_competitors\nwith include_observed: it scores everyone already seen across every\nterm you track, from recorded history, with no fetch at all.\n\nWithout an account this answers from cache only: a term nobody has\nfetched yet returns status \"sign_in_required\", and calling again will\nnot change that.\n", "inputSchema": { "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "locale": { "description": "Store language: \"en\", \"de\", \"ru\". Defaults to \"en\". Changes the results, not just the wording.", "maxLength": 35, "type": "string" }, "max_age": { "description": "Accept a cached answer up to this many seconds old. Defaults to a day; never refetches more than once every 15 minutes.", "maximum": 2592000, "minimum": 0, "type": "integer" }, "page": { "description": "Defaults to 1.", "minimum": 1, "type": "integer" }, "page_size": { "description": "Defaults to 20.", "maximum": 50, "minimum": 1, "type": "integer" }, "store": { "enum": [ "chrome", "firefox" ], "type": "string" }, "term": { "description": "e.g. \"ad blocker\". Squished and lowercased.", "maxLength": 200, "type": "string" } }, "required": [ "store", "term" ], "type": "object" }, "name": "search_store", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:34e080737bd029af154161673cc1451a69608a3d070f13db072345d541a66e50 | sha256sum