addrbookFor publishers
← The evidence ledger

Evidence row 3717943

Observed , by probe.mcp/1.

Kind
mcp.tools
About
endpoint 1580af2a-7b9f-419c-922a-54c33d25c3d2
Recorded
Previous row
#293394
Body SHA-256
ba536f7262dab0f1098bdb4ad2981f6fa7756807170f8fdb5dcd7097cdd245d8
Leaf
0x6fb28a9db81270c492c6981e30b68fbc8f138086081d29d965467d36c623801b

What was observed

{
  "count": 16,
  "tools": [
    {
      "description": "Start tracking a competitor for an extension.\n\nTakes the store and id of a search_catalog row (as external_id), so a\nlisting you just found can be promoted without looking anything up in\nbetween.\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 5 competitors per store on the Free\nplan and 20 on Premium, because each costs a\nfetch of that store on every refresh. The two stores are counted separately.\nOn plan_limit_reached explain the cap and offer upgrading, or ask which\ncompetitor in that store the user wants removed. Never remove automatically or retry unchanged.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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, as a search_catalog row's id gives it.",
            "type": "string"
          },
          "store": {
            "enum": [
              "chrome",
              "firefox"
            ],
            "type": "string"
          }
        },
        "required": [
          "extension_id",
          "store",
          "external_id"
        ],
        "type": "object"
      },
      "name": "add_competitor"
    },
    {
      "description": "Track the user's own extension from its Chrome Web Store and/or Firefox Add-ons URL.\nResolve a name with search_catalog first; pass the selected result's url. Do not guess\nbetween ambiguous listings or start tracking research results without the user's request.\n\nSupply both URLs in one call only when they are the same product: they share one\nextension_id and consume one plan slot. Repeating an existing URL is a no-op, including\nat the cap. If one URL matches existing tracking, its missing store is attached and\nexisting keywords are adopted. Conflicting listings are refused, never replaced or merged.\n\nFree allows 1 tracked extension; Premium allows 10.\nThe response includes current usage and limits. A plan_limit_reached error is not retryable\nunchanged: explain it, offer the pricing link, or ask which existing extension the user\nwants removed with remove_extension. Never delete tracking automatically to free a slot.\n\nCached metrics may be available immediately; fresh metrics run in the background.\nUse get_extension and list_scrape_runs to check progress; do not promise a completion time.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\n",
      "inputSchema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "chrome_url": {
            "description": "HTTPS Chrome Web Store listing URL; at least one store URL is required.",
            "maxLength": 2048,
            "type": "string"
          },
          "firefox_url": {
            "description": "HTTPS Firefox Add-ons listing URL, optionally paired with the same product's Chrome URL.",
            "maxLength": 2048,
            "type": "string"
          }
        },
        "type": "object"
      },
      "name": "add_extension"
    },
    {
      "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\nAn extension tracks at most 10 keywords on the\nFree plan and 50 on Premium, counted per\nlanguage: \"ad blocker\" in en and de is two. Past that this returns a limit\nerror. Explain the limit and offer upgrading, or ask which keyword the\nuser wants removed with remove_keyword. Never remove automatically or retry unchanged.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "description": "One extension in full: every store listing's latest numbers plus its\ntracked keywords and their current positions.\n\nEach listing's rank is its position by users within its store, computed\nfrom the current user count; ties share a rank (rank_tied = others at the\nsame count); rank_change is the move since last week's recorded rank.\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, use get_listing instead.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "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\nEach series has a source. \"store\" is the store's own search. \"google\" is\nwhere the listing page ranks in Google: organic results only (ads and\nother blocks are not counted), top 50, desktop, in the keyword\nlanguage's country (English: the United States). A null Google position\nmeans Google was searched 50 deep and the listing was not there.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
          },
          "source": {
            "description": "Store search or Google. Omit for both.",
            "enum": [
              "store",
              "google"
            ],
            "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"
    },
    {
      "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 this when you want movement, or the same page the\ndashboard 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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "description": "One extension's full listing from the catalog -- any extension, tracked by this account or\nnot: description, users, rating, reviews, version, languages, categories, permissions and\npublisher. Pass the store and id of a search_catalog row as store and external_id.\nrank is the position by users within the store; ties share a rank (rank_tied = others at the same\ncount); recomputed weekly on rank_on; rank_change is the move since the week before, positive = up.\n\nEnglish copy, refreshed weekly from the store; refreshed_at says when. This never fetches,\nnever answers \"pending\" and never starts tracking. users, rating and reviews are null when\nthe store shows no number, which is not zero. For an extension this account tracks,\nget_metrics_history has its numbers over time. Shares search_catalog's\n60 calls a minute per account.\n\nWorks without an account too.\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, as a search_catalog row's id gives it.",
            "maxLength": 100,
            "type": "string"
          },
          "store": {
            "enum": [
              "chrome",
              "firefox"
            ],
            "type": "string"
          }
        },
        "required": [
          "store",
          "external_id"
        ],
        "type": "object"
      },
      "name": "get_listing"
    },
    {
      "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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "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.\nIncludes effective plan limits and extension usage (null caps mean unlimited).\nIf empty, help the user choose a store listing and call add_extension when asked.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\n",
      "inputSchema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {},
        "type": "object"
      },
      "name": "list_extensions"
    },
    {
      "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 in\nthe row's store language: for English, in the United States or\nworldwide as the account's profile setting says (United States unless\nchanged), and in one country for the others (Germany for de, Spain for\nes, Brazil for pt-BR, and so on).\nIt is web search demand, not searches inside the store, and is the same\nfor both stores. null means not fetched yet, Google has no data, or the\nterm can't be looked up (symbols such as + or %, over 80 characters or\n10 words, or a store language Google Ads has no country for, such as\nru); search_volume_fetched_at says which.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "description": "Stop tracking one of this account's extensions, using an extension_id from list_extensions.\nRemove only the extension the user asked to remove; clarify ambiguous names first.\nNever remove an extension automatically to make room at a plan limit.\n\nThis deletes this account's extension record, notes, keyword tracking and competitor\nconfiguration for it, across both stores. Re-adding does not restore that configuration.\nShared store listings, collected metrics/rank history and other users' tracking remain.\nA missing or already removed id returns the same error as another account's id.\n\nNeeds an ExtensionDash account: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\n",
      "inputSchema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "extension_id": {
            "description": "The user's chosen extension_id from list_extensions.",
            "type": "integer"
          }
        },
        "required": [
          "extension_id"
        ],
        "type": "object"
      },
      "name": "remove_extension"
    },
    {
      "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 are unaffected, including ones\nthat track the same store listing: every extension's keywords are its own.\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: sign in from your app, e.g. `claude mcp login extensions-dashboard` or `codex mcp login extensions-dashboard`.\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"
    },
    {
      "description": "Search one store's catalog of extensions fetched so far, for market and niche research:\nstore \"chrome\" (default) or \"firefox\", one per call -- Chrome users are a rounded weekly\ncount, Firefox's an exact daily average, so the two are never mixed. listed and known in\neach answer show how much of that store the catalog covers.\nrank is the position by users within the store; ties share a rank (rank_tied = others at the same\ncount); recomputed weekly on rank_on; rank_change is the move since the week before, positive = up.\n\nFilter by name words (match \"all\" or \"any\"; case and punctuation are ignored, and an exact\nname comes first unless you sort), by one category of that store (a slug such as\n\"productivity/developer\" or \"privacy-security\"; an unknown one is refused with the store's\nlist) and by inclusive ranges on users, rating, reviews, language count and description\nlength; sort by any of those or by last update. This never fetches the store. users,\nrating and reviews are null when the store shows no number, which is not zero. Each row\nsays whether it is one of yours or a competitor you track; pass its store and id to\nadd_competitor to start tracking it. For one extension's full listing, call get_listing.\n\nAllows 60 calls a minute per account.\n\nWorks without an account too.\n",
      "inputSchema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "additionalProperties": false,
        "properties": {
          "category": {
            "description": "One category slug of the chosen store, as rows return it.",
            "maxLength": 64,
            "type": "string"
          },
          "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": "Name words, 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"
          },
          "screenshots_max": {
            "maximum": 2147483647,
            "minimum": 0,
            "type": "integer"
          },
          "screenshots_min": {
            "maximum": 2147483647,
            "minimum": 0,
            "type": "integer"
          },
          "sort": {
            "description": "Defaults to users, with an exact name match first when query is given.",
            "enum": [
              "users",
              "rating",
              "reviews",
              "langs",
              "description_length",
              "screenshots",
              "updated",
              "added"
            ],
            "type": "string"
          },
          "store": {
            "description": "Defaults to chrome.",
            "enum": [
              "chrome",
              "firefox"
            ],
            "type": "string"
          },
          "users_max": {
            "maximum": 2147483647,
            "minimum": 0,
            "type": "integer"
          },
          "users_min": {
            "maximum": 2147483647,
            "minimum": 0,
            "type": "integer"
          }
        },
        "type": "object"
      },
      "name": "search_catalog"
    }
  ]
}

What the leaf hashes

{"body":"ba536f7262dab0f1098bdb4ad2981f6fa7756807170f8fdb5dcd7097cdd245d8","id":3717943,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793964654666076,"prev":293394,"subject":"1580af2a-7b9f-419c-922a-54c33d25c3d2","subject_kind":"endpoint"}

Proof

Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (303443 rows).

  1. 0x6fb282fd53d311afa57e3db4fe0d8134109779c36cd70143620e823d50cd5973
  2. 0x3e0b549b4d1636a826214babbdfbb8797f9fe720b6abf34cb5806a6ef8bca327
  3. 0x577ad41db6df7811daa67d3fff22a7b1eba5fc20b3a7da8422edbe47c76e410e
  4. 0xeaf594f628098de72c6cd8519af80fd5d948f71fc4a7686c6a1dea4741f01713
  5. 0x8a98c43fefa25abb90e0a35dce9561b693c5fbac96d7e324a2a4071878013382
  6. 0xba08203163bcfbce47b2778b0fafa7e0ab329bfbc5a983aa4c5a07adfef178c1
  7. 0xab95dbee7d38ab07112b3031b544bf5d89bbe96ed829107a6d831455afbc392a
  8. 0x4b74759542c9b7b97f3e2c2335828681f36aff60110a8086a81c03935f2ec039
  9. 0xd59984edc9bfa9858a45fadafb670520267c0f0c081abc9e14841c7fe5725aae
  10. 0x98080f943d68e5b48f227a538a02a2be5c9c07fef7d8de03c50729d40f77345a
  11. 0xe2bc08176eb85df296ca9e0338155887e8db6e0c4e97205cdea084746a5b6814
  12. 0x4092077bc27d3aaff9a0e6f5102e2cba1b449ddc82c585e89d1fd755282a3000
  13. 0x4bdc3c91420724e924497ba1567e5ea70ec605a97ebac60412342e656a06f913
  14. 0x9d64f8255961253ea4f756bf8c6a5a4a57b070af0bf9a71a9871268a306d0024
  15. 0x76ebf1850cd69318e55f7c76c298e951486d7eb89da9726d99a973873bd3e0a8
  16. 0xa020619e8f130eeb03f3c2beaba0422017bd8b95688ddf44db1c31cf0fd40a6a
  17. 0xe98c6c6b56a21a2fc4c1edfe2563812e690a6a4336d11aef772ac1799d1ee7ca
  18. 0xd422a75f6c3780ed53eca52b50bf40b8f17dc14cffb804142e44fc9f2672029d
  19. 0xc0d08d48601d1be90bcfc025e66bcaa0030120d688dd9c919b36c2c4446f4948
Day root
0xb30ccefe7182c6f767e1fcbfb5f64ffd649da831f665f65c5ff39cd40512284f
Chained
0xc383f7ef68d2914082484765aa09e42c12c59a74a096ae64127c562618c506d3
Published
On Arc Testnet, block 71111178: 0xfba13cb7ee4ada7f2fee3702a786a2201596be2ffea37dfc281ab4c8e9942fe1

How to check it · This row as JSON