{
  "product": "Vendooly",
  "summary": "MCP connector that links Amazon Seller Central (SP-API) and Amazon Ads to AI assistants. The AI reads real data and prepares actions; write actions are gated as described in write_safety.",
  "operator": {
    "company": "Vendooly S.r.l.",
    "vat": "IT03382570590",
    "address": "Via Alessandro Manzoni 58, 04100 Latina (LT), Italy",
    "note": "Italian innovative startup (single-member S.r.l.), incorporated by notarial deed on 17 July 2026; Business Register enrollment in progress. Terms, Privacy and DPA are being updated to the new entity.",
    "contacts": {
      "general": "hello@vendooly.com",
      "legal": "legal@vendooly.com",
      "security": "security@vendooly.com",
      "privacy": "privacy@vendooly.com"
    }
  },
  "mcp_endpoint": "https://mcp.vendooly.com/mcp",
  "documents": {
    "trust_page": "https://vendooly.com/trust/",
    "terms": "https://vendooly.com/legal/terms.html",
    "privacy": "https://vendooly.com/legal/privacy.html",
    "dpa": "https://vendooly.com/legal/dpa.html",
    "security": "https://vendooly.com/security.html",
    "llms": "https://vendooly.com/llms.txt"
  },
  "oauth_scopes": {
    "amazon.read": "Read-only SP-API tools: catalog, listings, orders, inventory, pricing, Buy Box, account health.",
    "amazon.write": "SP-API write tools: listings, prices, stock, feeds. Implies read.",
    "amazon.ads": "Amazon Ads tools: Sponsored Products campaigns, ad groups, keywords, bids, reports.",
    "enforcement": "Scopes are enforced server-side at runtime: a token calling an out-of-scope tool by name receives insufficient_scope. Out-of-scope tools are also hidden from tools/list."
  },
  "write_safety": {
    "host_approval": "On Claude/ChatGPT connectors the host itself asks for human approval before every write tool call.",
    "strict_mode": "Headless/autonomous connections can be placed in server-enforced two-phase confirmation: the first write call does NOT execute and returns a preview plus a single-use confirm code bound to a hash of the exact arguments (10-minute expiry). The write executes only on a second call with identical arguments and that code. Available on request: security@vendooly.com.",
    "hard_caps": {
      "max_bulk_items_per_call": 25,
      "max_ads_daily_budget_eur": 200,
      "max_price_delta_pct": 50,
      "note": "Product defaults, configured server-side; no confirmation overrides a hard cap. The price-delta baseline is the last known price in the Vendooly data hub; without a baseline the check fails open."
    },
    "audit_log": "Every tool call, pending confirmation and blocked write is logged with org/user context."
  },
  "counts": {
    "total": 93,
    "read": 62,
    "write": 31
  },
  "tools": [
    {
      "name": "ads_list_portfolios",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List Amazon Ads portfolios (groups of campaigns with optional shared budget)"
    },
    {
      "name": "ads_list_profiles",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List Amazon Ads profiles for this account"
    },
    {
      "name": "ads_list_sp_ad_groups",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Read-only list of Sponsored Products ad groups (id, name, state, default bid)"
    },
    {
      "name": "ads_list_sp_campaigns",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "LIVE: stato corrente delle campagne SP. Campi chiave per campagna: name, campaignId, state, targetingType (AUTO|MANUAL) e daily_budget = budget giornaliero NUMERICO nella valuta del marketplace (es. 50, 150). NON esiste un \"bid\" a livello campagna (i bid sono su keyword/target). Usa per VERIFICARE prima di agire o per avere nomi/ID. NON ritorna performance: per ACoS/spesa/ROAS/vendite/click usa execute_sql su fact_campaign_daily."
    },
    {
      "name": "ads_list_sp_keywords",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "LIVE: keyword SP con bid e stato ATTUALI — per agire o verificare. NON ritorna performance: per spesa/vendite/ACoS o keyword che sprecano usa execute_sql su fact_keyword_daily."
    },
    {
      "name": "ads_list_sp_negative_keywords",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List SP negative keywords"
    },
    {
      "name": "ads_list_sp_negative_targets",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List SP negative product targets"
    },
    {
      "name": "ads_list_sp_product_ads",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "LIVE: product ads SP attivi (asin/sku, stato) — per verificare/agire. NON ritorna performance per ASIN: per spesa/vendite advertised usa execute_sql (data-hub)."
    },
    {
      "name": "ads_list_sp_targets",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List SP targeting clauses — SIA i target MANUAL (ASIN/categoria) SIA i 4 gruppi AUTO che Amazon genera da solo nelle campagne AUTO. Ogni clause ritorna il suo targetId, lo state e (se impostato) il bid. Mappatura gruppi AUTO (expression.type → nome UI): QUERY_HIGH_REL_MATCHES=close-match, QUERY_BROAD_REL_MATCHES=loose-match, ASIN_SUBSTITUTE_RELATED=substitutes, ASIN_ACCESSORY_RELATED=complements. PER CAMBIARE IL BID DI UN GRUPPO AUTO: chiama questo tool con campaign_id → prendi il targetId del gruppo → ads_update_sp_target_bid(target_id, bid). NON usare ads_create_* sulle AUTO (i target esistono già)."
    },
    {
      "name": "ads_stockout_check",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. Cross-references catalog days of cover (30d cached velocity) with active SP product ads: finds where you are paying for clicks on products close to stock-out. Use for \"am I wasting ads budget?\", \"are ads pushing products that are running out?\"."
    },
    {
      "name": "audit_catalog_quality",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Run catalog quality audit"
    },
    {
      "name": "audit_compliance",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Audit compliance/GPSR del catalogo (EU/IT). Per ogni SKU verifica gli attributi compliance REALI del suo product type (schema-aware): manufacturer, rtip_manufacturer_contact_information (contatto fabbricante), country_of_origin, safety_warning, safety_data_sheet_url e — dove il product type li prevede — i GPSR: gpsr_safety_attestation, gpsr_manufacturer_reference, dsa_responsible_party_address (responsabile EU). Incrocia gli ISSUE Amazon a tema compliance (Amazon dice cosa manca/è rifiutato). Ritorna gli SKU con gap, priorità (alta = issue ERROR Amazon o GPSR mancante), conteggi per attributo e i gap più frequenti. Flagga \"mancante\" SOLO se il product type prevede davvero l'attributo. NB: i numeri EPR (Francia / LUCID DE / RAEE-batterie) sono a livello ACCOUNT in Seller Central → Conformità, NON attributi listing: SP-API ne legge l'alert ma non li imposta. Per correggere usa update_listing. READ-ONLY. mode=\"full\" = verifica TUTTI I REQUISITI del product type: ogni attributo `required` dello schema Amazon della categoria (inclusi i requisiti di categoria, es. pharma/parafarmacia) + TUTTE le issue Amazon di qualsiasi categoria. Usa mode=\"full\" quando l'utente chiede di verificare \"tutti i requisiti di conformità\" dei prodotti; il default (standard) resta il check rapido compliance/GPSR."
    },
    {
      "name": "audit_title_compliance",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Audit all listings for Amazon title limit (75 chars, enforced from July 2026). Returns titles over the limit with excess character count + bullet/highlight counts per SKU. L'azione per un titolo troppo lungo è ACCORCIARLO (action=TRIM_TITLE): gli Item Highlights NON rendono conforme un titolo lungo, e su molti marketplace (es. amazon.it) non sono nemmeno un attributo scrivibile (lì la leva sono i bullet_point). highlight_count è indicativo, non un'azione."
    },
    {
      "name": "check_feed_status",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Check feed processing status"
    },
    {
      "name": "diagnose_sales_drop",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Diagnose a sales drop: compares the last N days with the previous period, checks account health and returns likely causes plus suggested actions. Use for \"why are my sales dropping?\"."
    },
    {
      "name": "download_feed_result",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Download the processing result document"
    },
    {
      "name": "download_report",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Download a report document"
    },
    {
      "name": "exchange_auth_code",
      "access": "read",
      "required_scope": "amazon.write",
      "description": "Exchange OAuth authorization code for refresh/access tokens"
    },
    {
      "name": "execute_sql",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Esegue UNA query SQL di sola lettura sul data-hub storico dell'account (DuckDB, un file per org). È LA STRADA PRIMARIA per OGNI domanda di ANALYTICS, in particolare la PERFORMANCE Amazon Ads: ACoS, ROAS, spesa, click, impression, vendite/ordini per campagna o keyword, keyword che sprecano, campagne zombie (tabelle fact_campaign_daily, fact_keyword_daily). Idem storico/trend/velocity/giorni-di-copertura/analisi incrociate. È anche la strada per il MARGINE REALE e il P&L: fee Amazon, commissioni, rimborsi/refund, reimbursement, netto incassato (tabella fact_settlement_txn, dal Settlement Report V2 — ciò che Amazon paga davvero). Per lo STATO CORRENTE (prezzi, stock, bid, budget, stato campagne live) usa invece i tool SP-API/Ads (ads_list_*). Solo SELECT/WITH/SHOW/DESCRIBE/EXPLAIN/SUMMARIZE, una sola query, output limitato. Non serve (e non si può) specificare l'account: la query gira automaticamente sui dati dell'org collegata."
    },
    {
      "name": "fba_inbound_discrepancies",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. \"Check FBA shipments and show me the discrepancies / what to recover\": reads the inventory ledger (Receipts) which gives, per shipment, units received and the UNRECONCILED quantity that Amazon itself flags (potential loss), plus an estimated recoverable value (× listing price); and cross-references reimbursements ALREADY granted (lost/damaged/returns) so you do not claim what is already refunded. Use for \"controlla le spedizioni FBA / unità mancanti / cosa recuperare / rimborsi FBA\". Opening the reconciliation case is done in Seller Central (no public API). Note: uses async SP-API reports (first call may take ~30-60s while Amazon generates them)."
    },
    {
      "name": "generate_oauth_link",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Generate OAuth authorization URL for a new seller"
    },
    {
      "name": "generate_vendor_oauth_link",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor Central OAuth link"
    },
    {
      "name": "get_account_health",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Read-only aggregated account health metrics: marketplace participation plus order/cancellation counts and rates. No order-level or customer data."
    },
    {
      "name": "get_all_dashboards",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Read-only aggregated KPI summary across all accounts in the org (aggregates only, no customer data)"
    },
    {
      "name": "get_buybox_prices",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. BULK Buy Box / Featured Offer export for a LIST of ASINs (up to 100). Returns a clean table per ASIN: buy_box_price (all-in for the customer), lowest_price, offer_count, whether you win the Buy Box, FBA/FBM of the winner, and a reason when there is no Buy Box (suppressed / no offers). Use for \"give me the Buy Box price for these ASINs\" / export. Note: Amazon rate limits make long lists slow (~1 batch of 20 every 10s). For the Buy Box across your WHOLE OWN catalog, do NOT loop this — query the cached daily snapshot via execute_sql (table fact_buybox_snapshot), which the worker fills nightly."
    },
    {
      "name": "get_buybox_snapshot",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Buy Box snapshot from the cached daily hub for the WHOLE own catalog of the selected account (no live SP-API). Returns per-ASIN status (win / has Buy Box / reason when none) plus coverage (covered/total catalog ASINs) and last update. Powers the catalog Buy Box column. Hidden from the model (use execute_sql on fact_buybox_snapshot)."
    },
    {
      "name": "get_catalog_item",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Live SP-API catalog item lookup"
    },
    {
      "name": "get_client_status",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Get status/details of the selected Amazon seller account"
    },
    {
      "name": "get_competitive_pricing",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. Buy Box / Featured Offer price per ASIN (max 20 per Amazon call, auto-batched). Returns buy_box_price (listing) + buy_box_landed_price (incl. shipping), condition, whether you win the Buy Box, and source. Falls back to live offers when Amazon has no competitive price, so it returns far fewer nulls than the raw SP-API. Use for a few ASINs; for a long list use get_buybox_prices."
    },
    {
      "name": "get_context_document",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Get a built-in documentation topic by name (see list_context_topics)."
    },
    {
      "name": "get_daily_sales",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Daily sales time series for the last N days (default 30): per-day units, returns and revenue, days with no sales filled at 0. Served from the cache/Data-Hub — never hits the Orders API and never throttles (429). Omit account_id for the org-wide series across all accounts; pass account_id for a single venue. This is the right tool for \"daily orders/sales chart\", \"trend del mese\", revenue over time."
    },
    {
      "name": "get_dashboard_data",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Read-only aggregated KPI summary for this account (listing counts, 7d revenue total, issue count). Aggregates only, no customer data."
    },
    {
      "name": "get_fba_inventory",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "FBA inventory summaries"
    },
    {
      "name": "get_fee_estimate",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Estimate Amazon fees (referral + FBA + variable closing) and net proceeds for a given selling price, via the official Amazon Product Fees API (getMyFeesEstimate). Pass asin OR sku, the price, currency and fulfillment_channel (FBA default, or FBM). Returns referral_fee, fba_fee, closing_fee, total_fees and net_proceeds (price minus Amazon fees, before your cost of goods). Use it for real margins: margin = net_proceeds - purchase cost. Read-only."
    },
    {
      "name": "get_feed_document_input",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Retrieve a previously submitted feed input payload"
    },
    {
      "name": "get_inbound_plans",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. List FBA inbound plans (new \"Send to Amazon\" workflow, Fulfillment Inbound v2024-03-20): inbound plan id, name, status (ACTIVE/SHIPPED/VOIDED), marketplaces, created/updated. This is the API that sees shipments created with the current Amazon flow (the legacy get_inbound_shipments v0 returns nothing for them). Use to list the seller's actual inbound plans/shipments and their status."
    },
    {
      "name": "get_inbound_shipment_items",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. Items of one FBA inbound shipment with QuantityShipped vs QuantityReceived per SKU (raw reconciliation data)."
    },
    {
      "name": "get_inbound_shipments",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY. List FBA inbound shipments (Fulfillment Inbound API) updated in the last N days: Shipment ID, name, status (WORKING/SHIPPED/RECEIVING/CLOSED…), destination FC. Use to see shipments and their status."
    },
    {
      "name": "get_listing",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Fetch one listing (summaries, issues, offers, fulfillment availability). Pass include_data:[\"attributes\"] for the full attribute set."
    },
    {
      "name": "get_listing_issues",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Listing issues per SKU"
    },
    {
      "name": "get_my_catalog_detail",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Catalog detail from local cache"
    },
    {
      "name": "get_my_pricing",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Your own pricing per SKU"
    },
    {
      "name": "get_order_items",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Items for a specific order"
    },
    {
      "name": "get_orders",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List individual orders (last N days): order ids, status, dates and totals only — no buyer data. Live Amazon Orders API, throttled (≈1 req/min): use ONLY when you need order-level rows. For daily sales/orders charts or trends over a period use get_daily_sales; for a single revenue total use get_revenue_summary — both are served from cache and never throttle."
    },
    {
      "name": "get_product_types",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Get product type definition. product_type is REQUIRED (e.g. PUZZLE, SAFETY_AND_HEALTH, LUGGAGE). By default fetches the JSON Schema server-side and returns allowed enum values per attribute (attribute_enums) + required_attributes — no need to open the S3 link. Set raw_schema=true for the full schema, include_enums=false to skip the fetch."
    },
    {
      "name": "get_revenue_summary",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Aggregate revenue total over the last N days (cache-first, no throttling). Omit account_id to get the org-wide total ACROSS ALL connected accounts in one call (no need to pick an account or sum manually); pass account_id for a single venue. This is the right tool for \"how much did I sell in total in the last 30 days\" — do NOT loop get_orders per account. For a per-day breakdown/chart use get_daily_sales instead."
    },
    {
      "name": "get_sales_velocity",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Sales velocity over N days (cache-first; set live_fallback=true for per-SKU report)"
    },
    {
      "name": "get_subscriptions",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List subscriptions"
    },
    {
      "name": "get_vendor_invoices",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor invoices — SP-API non espone un endpoint di lettura per le fatture vendor retail (solo POST submitInvoices). Questo tool restituisce una spiegazione della limitazione e rimanda a get_vendor_remittances per gli importi stimati e a Vendor Central per le fatture reali."
    },
    {
      "name": "get_vendor_po_summary",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor PO aggregate summary"
    },
    {
      "name": "get_vendor_purchase_order_details",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor PO details"
    },
    {
      "name": "get_vendor_purchase_orders",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor POs"
    },
    {
      "name": "get_vendor_remittances",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor: importi stimati dai PO (SP-API non espone remittance reali in lettura)"
    },
    {
      "name": "get_vendor_trading_terms",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Vendor trading terms — SP-API non espone termini commerciali (payment terms, sconti, accordi) in lettura. Questo tool restituisce una spiegazione della limitazione e rimanda a Vendor Central e a get_vendor_remittances per i netCost per PO."
    },
    {
      "name": "list_clients",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List the connected Amazon outposts (an outpost = one seller on one marketplace; the account_id of each is what you pass to other tools). Org-scoped."
    },
    {
      "name": "list_context_topics",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List built-in documentation topics (guides and recipes for using Vendooly tools correctly: write confirmation flow, catalog cache fields, rate limits, multi-account, cross analyses). Read the relevant guide BEFORE an operation you are not familiar with."
    },
    {
      "name": "list_my_products",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "List own products from local cache (SKU, ASIN, title, price, stock FBA+MFN, fulfillment channel, velocity = avg units/day last 30d, days_cover = stock/velocity — paginated, default 50 rows, no customer data). Use velocity/days_cover for stock-out risk (\"sells 3.2/day, runs out in ~4 days\"). Filter channel:\"FBM\" for merchant-fulfilled only. NB: sorted by sales rank, so unranked FBM items appear in the last pages — use the channel filter instead of paginating."
    },
    {
      "name": "ping",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Healthcheck tool"
    },
    {
      "name": "request_report",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Request a SP-API report"
    },
    {
      "name": "search_catalog",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Search the Amazon catalog. IMPORTANT: use identifiers (ASIN/EAN/ISBN) for reliable, compact results. Keyword search returns up to 10 items (summaries only) and may be incomplete — prefer identifiers when you know the ASIN or EAN."
    },
    {
      "name": "send_feedback",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "Send the user's feedback (a bug, an idea, a question or a general comment) straight to the Vendooly team — they read every one. Use it whenever the user reports a problem, is frustrated, hits an error, or suggests something. ALSO proactively OFFER to send it when something clearly is not working (\"vuoi che lo segnali al team Vendooly?\") and call it once they agree. Put the user's words in `message`; use `ai_context` to summarize what they were trying to do, which account/tool, and any error you saw. Confirm to the user once it is sent."
    },
    {
      "name": "weekly_recap",
      "access": "read",
      "required_scope": "amazon.read",
      "description": "READ-ONLY operational recap, aggregates only (no customer data): revenue, orders, FBA/FBM split, account health and top products by sales velocity. Use when the user asks \"how did it go\", \"recap\", \"how am I doing\"."
    },
    {
      "name": "ads_create_portfolio",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create an Amazon Ads portfolio to group campaigns (no portfolio-level budget cap; campaigns can then be assigned to it). Same scope as campaigns — no extra authorization needed.",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_ad_group",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create a SP ad group in an existing campaign. Defaults to PAUSED so it can be populated before delivery. IMPORTANTE — un ad group è O keyword-targeted O product-targeted, MAI entrambi: Amazon RIFIUTA (otherError) una keyword in un ad group che ha già product target, e viceversa. Quindi se ti servono SIA keyword SIA target di prodotto, crea DUE ad group separati nella stessa campagna: uno popolato con ads_create_sp_keywords, l'altro con ads_create_sp_product_targets. Le NEGATIVE keyword/target invece convivono con qualsiasi tipo.",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_campaign",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create a SP campaign. campaign.targeting_type: \"AUTO\" (Amazon sceglie automaticamente i target — NON aggiungere keyword/target manuali; per modulare i bid dei 4 gruppi auto usa ads_create_sp_product_targets con auto_match) oppure \"MANUAL\" (default; poi attacchi keyword via ads_create_sp_keywords o ASIN via ads_create_sp_product_targets). Placement bidding: passa placement_bidding [{placement, percentage}] con placement PLACEMENT_TOP|PLACEMENT_PRODUCT_PAGE|PLACEMENT_REST_OF_SEARCH (0-900%). Strategy via dynamic_bidding.strategy (LEGACY_FOR_SALES|AUTO_FOR_SALES|MANUAL|RULE_BASED). Optionally assign to a portfolio via portfolio_id.",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_keywords",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create SP keywords. L'ad group bersaglio deve essere keyword-targeted: se ha GIÀ product target Amazon rifiuta con otherError (un ad group è keyword O product, mai entrambi) → in quel caso crea un ad group dedicato alle keyword. Ogni keyword: { campaign_id, ad_group_id, keyword_text, match_type (BROAD|PHRASE|EXACT), bid }.",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_negative_keywords",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create SP negative keywords",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_negative_targets",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create SP negative product targets. Each: { campaign_id, ad_group_id, asin (or raw expression) }.",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_product_ads",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create SP product ads",
      "category": "ads"
    },
    {
      "name": "ads_create_sp_product_targets",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Create SP targets. MANUAL (campagne MANUAL): ogni target { campaign_id, ad_group_id, bid, e uno tra: asin (ASIN target), category_id (category target), expression (raw v3) }. AUTO (campagne AUTO): per impostare il bid sui 4 gruppi di matching automatico usa { campaign_id, ad_group_id, bid, auto_match: \"close\"|\"loose\"|\"substitutes\"|\"complements\" } (close=ricerche strettamente correlate, loose=genericamente correlate, substitutes=prodotti alternativi, complements=accessori). ATTENZIONE: su una campagna AUTO GIÀ ESISTENTE i 4 gruppi sono già stati creati da Amazon — ri-crearli qui dà errore INVALID_ARGUMENT. Per cambiarne solo il bid NON usare questo tool: usa ads_list_sp_targets per leggere il targetId del gruppo e poi ads_update_sp_target_bid.",
      "category": "ads"
    },
    {
      "name": "ads_delete_sp_campaign",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Archivia (elimina) una o più campagne SP. È l'UNICO modo di archiviare una campagna: ads_update_sp_campaign accetta solo ENABLED|PAUSED (Amazon rifiuta ARCHIVED sul PUT). IRREVERSIBILE — una campagna archiviata non si riattiva, va ricreata. campaign_ids: [id, ...].",
      "category": "ads"
    },
    {
      "name": "ads_delete_sp_negative_keywords",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Delete SP negative keywords",
      "category": "ads"
    },
    {
      "name": "ads_delete_sp_negative_targets",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Delete (archive) SP negative product targets",
      "category": "ads"
    },
    {
      "name": "ads_delete_sp_targets",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Delete (archive) SP product targets",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_ad_group",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Update a SP ad group",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_campaign",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Aggiorna una o PIÙ campagne SP. SINGOLA: campaign_id + patches (patches.daily_budget numero → convertito nel payload v3 budget{budgetType:DAILY,budget}; patches.state ENABLED|PAUSED). BATCH (consigliato per agire su più campagne in una volta, es. \"sistema 10 campagne\"): items=[{campaign_id, daily_budget?, state?}], ogni campagna con valori diversi, MAX 25. Esito verificato per-id (budget e/o stato).",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_keyword_bid",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Aggiorna il bid di una o PIÙ keyword SP. SINGOLA: keyword_id + bid. BATCH (consigliato per agire su molte keyword in una volta — meno chiamate, niente raffica): items=[{keyword_id, bid}], ogni keyword può avere un bid diverso, MAX 25 per chiamata. Esito verificato PER-ID (read-after-write).",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_keyword_state",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Aggiorna lo stato (ENABLED/PAUSED) di una o PIÙ keyword SP. SINGOLA: keyword_id + state. BATCH: items=[{keyword_id, state}], MAX 25 per chiamata. Esito verificato PER-ID.",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_target_bid",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Aggiorna il bid di uno o PIÙ target SP (MANUAL ASIN/categoria o i 4 gruppi AUTO close/loose/substitutes/complements). Il target_id si ottiene da ads_list_sp_targets; è QUESTA (non ads_create_*) la via per modulare i bid dei gruppi auto su una campagna AUTO già esistente. SINGOLA: target_id + bid. BATCH (consigliato per molti target): items=[{target_id, bid}], ognuno con bid diverso, MAX 25. Esito verificato per-id.",
      "category": "ads"
    },
    {
      "name": "ads_update_sp_target_state",
      "access": "write",
      "required_scope": "amazon.ads",
      "description": "Aggiorna lo stato (ENABLED/PAUSED) di uno o PIÙ target SP. SINGOLA: target_id + state. BATCH: items=[{target_id, state}], MAX 25. Esito verificato per-id.",
      "category": "ads"
    },
    {
      "name": "bulk_update_inventory",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Bulk inventory updates",
      "category": "inventario"
    },
    {
      "name": "bulk_update_listings",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Bulk listing attribute updates (title, bullet_point, any patch). updates: [{sku, title?, bullets?: string[], patches?: [...], product_type?, validate_only?}]. Use when you need to update titles or bullets on multiple SKUs at once instead of calling update_listing one by one. Returns {total, ok, errors, results[]}. SAFETY: show preview and require confirm before sending.",
      "category": "listing"
    },
    {
      "name": "bulk_update_prices",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Bulk price updates",
      "category": "prezzo"
    },
    {
      "name": "create_listing",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Crea/sostituisce una listing (PUT). product_data accetta campi SEMPLICI auto-mappati nel formato attributi SP-API: title, brand, price, quantity, condition, ean/upc/gtin, description, bullets[]. Per agganciare un'offerta a un ASIN GIA' a catalogo usa requirements:\"LISTING_OFFER_ONLY\" + asin (NON servono title/brand: li fornisce il catalogo). Puoi anche passare attributes gia' strutturati. validate_only:true = dry-run (valida contro Amazon senza scrivere).",
      "category": "listing"
    },
    {
      "name": "create_subscription",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Create a notifications subscription",
      "category": "config"
    },
    {
      "name": "delete_listing",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Delete a listing",
      "category": "listing"
    },
    {
      "name": "delete_subscription",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Delete a subscription",
      "category": "config"
    },
    {
      "name": "reprice_to_buybox",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "ACTION. Reprices the given SKUs to win the Buy Box: compares your price with the Buy Box price and proposes a new one (`delta` below the Buy Box, never below `floor`). With confirm=false it returns a PREVIEW (before→after); with confirm=true it applies the prices. ALWAYS show the preview and get the user's explicit approval before calling with confirm=true.",
      "category": "prezzo"
    },
    {
      "name": "submit_listings_feed",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Submit a batch listings feed",
      "category": "listing"
    },
    {
      "name": "update_item_highlights",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Update Item Highlights on a listing. ATTENZIONE: item_highlights NON è esposto come attributo scrivibile su tutti i marketplace — su amazon.it (e gli altri EU verificati) NON esiste, e il tool rifiuta con esito chiaro (not_supported) rimandando ai bullet_point (update_listing → bullet_point). Dove è supportato: chiama senza confirm per il dry-run (VALIDATION_PREVIEW), confirm=true per scrivere. Gli Item Highlights non rendono conforme un titolo troppo lungo (per il cap 75 char vai di update_listing sul titolo).",
      "category": "listing"
    },
    {
      "name": "update_listing",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Modifica una listing esistente. SHORTCUT amichevoli (consigliati — costruiscono la struttura attributo corretta, niente schema SP-API a mano): bullets:[...] → bullet_point (\"Funzionalità principali\", la leva dei punti-elenco su amazon.it/EU, fino a 5 ~100 char l'uno), title → item_name. In alternativa patches:[...] grezzi (JSON Patch SP-API). validate_only:true = dry-run (Amazon valida senza applicare).",
      "category": "listing"
    },
    {
      "name": "update_mfn_quantity",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Update MFN inventory quantity for a SKU",
      "category": "inventario"
    },
    {
      "name": "update_price",
      "access": "write",
      "required_scope": "amazon.write",
      "description": "Update price for a SKU",
      "category": "prezzo"
    }
  ],
  "generated_at": "2026-07-17",
  "generated_from": "mcp-server/core/serverFactory.js (TOOL_DEFS, requiredScope) + mcp-server/core/safety.js (WRITE_TOOLS, caps)"
}
