Skip to main content

Changelog

Date-based log of changes to the EDITED MCP server and these docs. Newest entries at the top.

Stability policy

EDITED MCP evolves continuously. Each entry below documents what changed and, where relevant, what callers need to do; breaking changes are flagged ⚠ Breaking with migration steps. See Versioning & breaking changes for what counts as breaking, how to build agents that survive change, and how to detect a surface change from your own CI.

2026-09-16​

Added​

  • Every lookup hit now carries a match tier. The six identifier resolution tools — mdmcp-search_brands, mdmcp-search_retailers, mdmcp-search_markets, mdmcp-search_product_searches, mdmcp-search_size_group and mdmcp-search_size_options — return a match value on every hit: exact (the query is the entity's name or slug, compared leniently), lexical (text search ranked it — a typo, a partial, or the name plus or minus a word), or semantic_only (only the vector arm returned it).

    Read match; don't trust rank. When nothing matches the query strongly, the vector arm fills the remaining result slots with nearest neighbours, so a plausible-looking name can rank first without being your entity. Treat a semantic_only hit as a candidate to verify, and a result set where nothing beats semantic_only as not found. There is no score to threshold, and no tier is evidence that EDITED holds data for the entity — an exact retailer hit still needs mdmcp-get_retailer_coverage before you trust it over your window.

    The field is additive, so existing calls keep working; code that took the first hit unconditionally should now check the tier. See How to query → Identifier resolution for where this lands in a query, and the new lookup_matching topic below for the per-tool rules.

  • New lookup_matching documentation topic. mdmcp-market_data_docs accepts topic: "lookup_matching", covering what each lookup tool compares before it calls a hit exact (case, accents, punctuation and spacing are ignored, but a separator between two digits is kept, so 3-6 months is not 36 months), why the tiers are ordered labels rather than a score, and why a name match is not evidence of data behind the name. Read it before writing the code that decides whether a lookup found what the user asked for.

2026-08-26​

Added​

  • researchmcp-research_report_links now runs in both directions. It resolved report_ids to public EDITED Research article URLs; a new optional report_urls (string[], 1–20 per call) asks for the reverse. That is the call you want when the user starts from a link they were sent rather than an id — resolve it once, then pass the returned report_id to any other research tool: researchmcp-research_chunk_search for the passages behind a claim, researchmcp-research_read_report for the whole article.

    URL → report_id
    {
    "report_urls": [
    "https://my.edited.com/research/articles/assortment-mixed-trend-sleepwear-athleisure-020925"
    ]
    }

    Only the last path segment identifies the report, so a trailing slash, ?utm_* params or a fragment are all fine. A link no slug can be read from — a bare host, a click-tracking wrapper, two URLs joined into one string — refuses the whole call with invalid_input and field: "report_urls", so open a shortened link first and pass its final URL.

    The result carries a new report_ids_by_url map alongside links, and the direction you did not ask for is null:

    Response — resolving URLs
    {
    "result": {
    "links": null,
    "report_ids_by_url": {
    "https://my.edited.com/research/articles/assortment-mixed-trend-sleepwear-athleisure-020925": 152777
    }
    }
    }

    Calls that pass report_ids are unchanged: links is populated exactly as before, with report_ids_by_url: null. A null value inside either map still means what it always did — nothing resolved for that key, an unknown or unpublished report — so surface "link unavailable" / "report not found" rather than inventing one. See Concepts → Response shape for the envelope the two maps sit in.

Changed​

  • report_ids is optional, and exactly one direction is required. It is no longer a required argument, because report_urls can take its place — but passing neither or both is refused with invalid_input. Calls that pass report_ids are unaffected: the argument only widened, so no migration is needed.

2026-08-13​

Added​

  • New product_searches documentation topic. mdmcp-market_data_docs accepts topic: "product_searches", covering what a flat result table hides: the product_searches and product_details category dimensions are trees, returned as one list of rows at mixed depths with > separating the levels and no column marking a parent as a parent. An ancestor row already contains every descendant row, so adding up a category breakdown counts the same products twice — Tops and Tops > T-Shirts are one category listed twice, not two categories worth their sum. It also names what is safely summable (one depth level under one parent, and product_searches only — product_details is multi-valued and additive at no depth), the top-level roll-up row that looks like an ordinary sibling, why filtering to one category still returns its ancestors, and how to get from a path label to the integer id the filter takes. Read it before doing arithmetic across a category breakdown.

2026-08-12​

Changed​

  • The protocol revision is negotiated in initialize. The gateway previously answered every handshake with a hardcoded 2024-11-05. It now echoes the revision you offer when it speaks it — 2024-11-05, 2025-03-26 or 2025-06-18 — and answers 2025-06-18, its newest, to anything else (including no offer at all). Nothing changes for callers beyond the handshake: the MCP-Protocol-Version header is still accepted and still not validated, and negotiating an older revision doesn't narrow what any later call returns. See Versioning → Protocol version.

2026-08-11​

Added​

  • New response_shape documentation topic. mdmcp-market_data_docs accepts topic: "response_shape", covering how to read what a tool sends back: the result / error split, what each error code means (invalid_input, not_entitled, upstream_unavailable, internal) and which one is worth retrying, why an empty answer — an unknown id, a filter matching nothing — is a success rather than a failure, and the one family of refusals that still arrives as isError with a plain-text message instead. Read it before writing the code that decides whether a call failed.

2026-08-10​

⚠ Breaking​

  • Optional parameters no longer advertise null. 81 optional parameters across 16 tools — the promotions (messagingmcp-*) and research (researchmcp-*) sets — published as a union with null (string | null, string[] | null, boolean | null, integer | null) and defaulted to null. They now publish as the plain type with no default. They are still optional, and leaving one out still means "no filter".

    Omit the parameter instead of passing null. If your code maps "no filter" to an explicit null, drop the key from the arguments object:

    Before — messagingmcp-list_promos
    { "retailers": ["zara"], "regions": null }
    After
    { "retailers": ["zara"] }

    The server itself still accepts an explicit null and treats it exactly as if the parameter were absent, so calls that reach it keep working. The breakage is client-side: SDKs and agent tool-loading layers that validate arguments against the published schema reject the null before the call goes out.

    Affected tools — promotions: aggregate_promos, count_promos, enrich_with_vm, explain_promo_data, get_promo, list_promos, list_retailers, messaging_search, resolve_time_period, search_promo_text. Research: research_analyze_query, research_article_search, research_chunk_search, research_image_search, research_list_reports, research_match_images_to_text.

Added​

  • New composition documentation topic. mdmcp-market_data_docs accepts topic: "composition", covering how fabric percentages are captured, why percentage bands are not additive, and the per-retailer coverage caveats. Read it before banding fibre content or comparing retailers on it.

Changed​

  • Allowed values are now published for parameters that already enforced them. group_by (retailer, promo_type, region, shoot) and interval (day, week, month) on messagingmcp-aggregate_promos and messagingmcp-count_promos, and topic (overview, fields, identity, dates, inferred, quality) on messagingmcp-explain_promo_data. Which values the server accepts hasn't changed — it rejected anything outside these lists before too. They were hidden inside the null union, and are now visible to clients and agents choosing a value.

2026-07-29​

EDITED MCP is now in public beta. From here, this log tracks changes to the tool surface — new and changed tools, parameters, resources, and prompts — with ⚠ Breaking changes called out and migration steps where you need them.