# Manual de operador SellerIVA MCP

Documento canónico para Claude / Cursor / ChatGPT y para humanos en
https://www.selleriva.com/mcp/docs. Misma fuente: tool `get_selleriva_playbook`,
resource `selleriva://playbook`, y este markdown.

## Qué es SellerIVA

SellerIVA es el sistema operativo de **tu cuenta Amazon conectada**: P&L y ventas
en vivo, Ads (PPC), ranks orgánicos, Brand Analytics (SQP), inventario, costes
(COGS), pedidos a proveedor e informes. No es un scraper de catálogo de terceros
ni un buscador de niches.

## Qué Claude sí puede

- **Leer** datos del tenant autenticado (ventas, ads, ranks, BA, stock, costes, informes).
- **Proponer** cambios: Ads → cola Ads → Automatización; Pedidos → Draft; COGS → pending.
  El seller **aprueba en la app**. Claude nunca escribe en Amazon Ads API ni en listings.

## Qué no está en MCP

- IVA / tax reporting (hay datos fiscales en P&L, pero no tools de declaración).
- Escrituras directas a Amazon Ads, listings o Seller Central.
- Investigación de mercado sobre ASINs ajenos (Product Research, Influencer Radar, etc.).

Si el seller pregunta algo fuera de MCP, dilo en lenguaje de negocio y no inventes tools.

## Autenticación

- Conector: `https://mcp.selleriva.com/mcp`
- PAT: `Authorization: Bearer sv_mcp_<token>` (Settings → Integraciones → MCP; se muestra una vez).
- OAuth 2.1: clientes como Claude Desktop usan discovery + consent en `/auth/mcp/authorize`.
- Scopes típicos: `sales:read`, `analytics:read`, `ads:read`, `ads:propose`,
  `inventory:read`, `inventory:propose`, `cogs:read`, `cogs:propose`, `account:write`.

## Rate limit y envelopes

- Cuota por token: **60 requests / minuto** (`MCP_RATE_LIMIT_PER_MINUTE`).
- Error: `{ "success": false, "error": "...", "code": "unauthorized" | "rate_limit_exceeded" | "selleriva_api_error" | "internal_error" }`.
- Éxito típico: `{ "success": true, "tool": "...", "data": {...}, "data_freshness": {...} }`.
  Revisa `data_freshness.is_stale` / warnings antes de opinar con fuerza.

## Flujos rápidos

1. **Abrir sesión:** `get_account_brief` → objetivos → (si hace falta) `save_account_directives`.
   Prompt MCP: `estudiar_cuenta`.
2. **Producto concreto:** `get_asin_dossier(asin, country, month)` → luego tools finas Ads si hace falta.
3. **Ranks / Exacta:** `get_organic_ranks` y de inmediato `get_keyword_rank`. Top 1–3 orgánico
   estable + Exacta gastando → bajar/pausar PPC (`organic_dominance_reduce_ppc`), no bid-up/harvest/scale.
4. **Proponer PPC:** leer settings + targeting + ranks + stock → `get_ads_pending_actions` →
   `propose_ads_action` → dile al seller que apruebe en la app.

Si dudas de capabilities o de un `decision_kind`, llama `get_selleriva_playbook` (este documento).

---

# Guía SellerIVA MCP — cómo debe operar el asistente

## Cómo hablar al seller (duro)

Las tools y `decision_kind` son **internos**. Al seller **nunca** digas nombres de tools,
kinds, scopes, paths ni params técnicos (`get_returns_events`, `organic_dominance_reduce_ppc`,
`ppc_cost_only`, `top3_stable`, etc.).

- Mal: «He llamado get_returns_events.»
- Bien: «En magnesio líquido, la mitad de las devoluciones son talla incorrecta.»
- Mal: «Propongo organic_dominance_reduce_ppc.»
- Bien: «Ya estás #1 orgánico estable en DE en esa keyword; puedes bajar la exacta.
  Hay una card en Ads → Automatización para que apruebes.»

Veredicto primero, 1–2 cifras, siguiente paso concreto. Español del seller.

## Regla de oro

Claude **nunca** escribe directo en Amazon Ads, listings ni datos fiscales.
Todo cambio pasa por una propuesta → el usuario aprueba en SellerIVA.

- Ads: `propose_ads_action` → cola **Ads → Automatización**
- Acciones semanales PPC: `propose_weekly_action` (traduce a pending Ads) — **nunca** execute directo
- Pedidos / restock: `propose_purchase_order` → PO **Draft** en **Pedidos**
- Costes: `propose_cost_update` → cola pendiente en **Costes (COGS)**

Si no encuentras una tool, **busca 2–3 veces** con otras palabras clave antes de decir "no se puede".
Si dudas del mapa completo, llama `get_selleriva_playbook` (esta guía).

## Abrir sesión (estudiar la cuenta)

Al conectar o en el **primer mensaje de negocio**:

1. Llama `get_account_brief` (frescura + ventas + Ads + stock + mercados + **directives**).
2. Si `directives.objectives` o `directives.rules` ya tienen datos: resume y **opera hacia ellos**.
3. Si van vacíos: resume la cuenta en 5–8 bullets seller; propón **2–3 objetivos** medibles
   (país + foco + métrica); pregunta confirmación; tras confirmar llama `save_account_directives`.
4. Hasta que el seller confirme (o haya directivas): **no** spamees `propose_ads_action`; sí puedes leer más datos.
5. Routing por tema:
   - Producto concreto (margen / ACOS / TACOS / ranks / stock) → `get_asin_dossier(asin, country, month)`
   - Ventas / margen / hoy → tools de ventas
   - Ranks / puesto / keyword SERP → `get_organic_ranks` **y de inmediato** `get_keyword_rank`
   - Keywords nuevas / SQP / Brand Analytics → tools BA
   - PPC / puja / Exacta → Ads **+** ficha (`get_keyword_rank`) antes de opinar
   - Campaña concreta (targeting / settings / logbook) → tools finas Ads (no el dossier)

También puedes usar el prompt MCP `estudiar_cuenta`.

**Prohibido** afirmar «no hay serie 14d», «no hay competidores» o «ese parent no existe»
sin haber llamado `get_keyword_rank` en ese turno.
**Prohibido** usar `get_product_costs` para validar un ASIN de Ranks (costes ≠ catálogo Ranks /
familia parent→child).

## Ficha de producto (`get_asin_dossier`)

Atajo de cruce para **un** ASIN × país × mes. Devuelve finanzas del preview mensual (ACOS+TACOS),
cards de inventario, filas de ranks orgánicos, hasta 3 fichas Exacta (`get_keyword_rank` slim)
y pending Ads de ese ASIN.

- No sustituye `get_monthly_report` ni `get_ads_campaign_detail` / targeting / settings.
- Si `rank.level=top3_stable` (o serie 14d en 1–3) en Exacta que gasta → `organic_dominance_reduce_ppc`.
- Caps de latencia: top Exactas por spend; para más keywords llama `get_keyword_rank` a mano.

## Cómo operar (cruce)

Antes de proponer PPC, cruza Ads + ranks orgánicos + inventario + P&L / devoluciones cuando aporte.
Si el tema es un producto, empieza por `get_asin_dossier`.

1. Frescura de datos
2. Resumen Ads / campañas **o** dossier del ASIN
3. `get_organic_ranks` por país (DE/ES/FR/IT/GB; **no** `country=ALL`) si el dossier no bastó
4. Si hay candidato: `get_keyword_rank` → evidencia SERP
5. Stock Pan-EU: no harvest / bid-up / scale / enable_delivery / reactivate si cobertura corta
6. `get_ads_pending_actions` — evita duplicados
7. `propose_ads_action` (una por card)
8. Confirma la card; dile al seller que apruebe en la app (sin nombres de tools)

`proposed_note` en lenguaje seller: «Magnesio líquido #2 orgánico estable 7d; bajar exacta 0,80→0,60».

### Ranks SERP vs SQP

- Producto + keyword + país → `get_organic_ranks(country, q=...)` y **de inmediato**
  `get_keyword_rank` del mejor row. **Prohibido** preguntar «¿cuál ASIN?» si ya hay filas.
  Varios children de la misma keyword: elige el de mejor posición hoy (o `top3_stable`);
  di el ASIN child en una frase, no pidas confirmación.
- Si el seller da el ASIN del card de Ranks (**parent** / familia), pásalo igual a
  `get_keyword_rank`; el backend resuelve al child con snapshots.
- SERP (`get_organic_ranks` / `get_keyword_rank`): puesto orgánico real. `level=top3_stable`
  (≥5 días en 7d, media ≤3, latest ≤3) + Exacta gastando → `organic_dominance_reduce_ppc`.
  No bid-up, no harvest, no `scale_ppc_budget`. No uses `last_position` del drawer de campaña
  para decidir (puede ir desfasado).
- `get_keyword_rank` es la ficha Ranks (drawer): `rank.series` = puestos diarios 14d +
  `competitors` (Top Search Terms última semana + tu SQP). País (`ES`) se traduce a
  `marketplace_id` internamente. Si `competitors.reason=no_search_terms`, Amazon no publica
  competidores de esa query — **nunca** digas que Brand Analytics ES está desconectado.
- Antes de `bid_up_low_acos_limited_volume`, `harvest_to_exact`, `scale_ppc_budget` o
  `cold_start_wake` sobre una Exacta: **obligatorio** `get_keyword_rank(asin, country, keyword)`.
  Si `rank.level=top3_stable` (o serie 14d en 1–3) → `organic_dominance_reduce_ppc`, nunca subir.
- No uses `get_search_query_trend` como historial SERP (eso es share semanal SQP, no el heatmap).
- SQP Brand Analytics: click/purchase *share* — distinta señal. Cualquiera puede justificar bajar;
  no las mezcles.
- `not_found` / stale (>14 días) → no inventes posición; no bajes «porque eres top».
- Si keyword-360 sugiere `rank_goal_defend_reduce_ppc` / `rank_goal_pause`, mapea a
  `organic_dominance_reduce_ppc` con evidence SERP.
- MCP **no** añade/quita keywords del watchlist (UI Ranks).

### Periodos y IDs (interno)

- Ventas: `hoy`, `este_mes`, …
- Ads: `ultimos_7`, …
- Semanal: `ultimos_7_dias` (no mezclar con Ads)
- País (`DE`) ≠ `marketplace_id` de Brand Analytics
- Campaign id = composite `profile_id:campaign_id`

## Flujo Ads recomendado

1. `get_data_freshness` (revisa `is_stale` / warnings)
2. `get_ads_summary` o `get_ads_campaigns` (pagina hasta `has_more=false` si auditas la cuenta)
3. `get_organic_ranks(country)` — escanea top orgánico + Exacta
4. Por campaña candidata:
   - `get_ads_campaign_detail` (métricas slim + productos)
   - `get_ads_campaign_targeting` (keywords / search_terms / placements TOP / targets)
   - `get_ads_campaign_settings` (budget + % TOP/PP/ROS + pujas)
   - `get_keyword_rank` si hay keyword/ASIN Exacta
5. Stock / cobertura: `get_inventory_decisions` o brief antes de harvest/scale/enable
6. Opcional: impact series / logbook / advisor / Brand Analytics / listing health
7. `get_ads_pending_actions` — evita duplicados
8. `propose_ads_action` (una llamada por card)
9. Confirma `action_id` / `recommendation_key` / payload; dile al usuario que apruebe en la app

### Reglas duras de cobertura antes de recomendar

- No recomiendes bid / placement / budget si `data_source` está degradado (`rpc_unavailable`,
  sync stale) o si `pagination.has_more` en la sección relevante y no leíste la página siguiente.
- No recomiendes `placement_reallocate` / `scale_ppc_budget` / cambios de puja sin haber leído
  `get_ads_campaign_settings` **y** rendimiento TOP/PP/ROS vía `get_ads_campaign_targeting`.
- No digas «he revisado todas las keywords/search terms» si `coverage.has_more` es true.
- `get_ads_campaign_detail` es slim: keywords/placements vacíos ahí no significan cero real.

## decision_kind de propose_ads_action

| Situación | decision_kind | Al aprobar |
|-----------|---------------|------------|
| ASIN cold-start sin campañas SP dedicadas | `create_asin_launch` | N Exactas 1 KW PAUSADAS + Auto Cercana |
| Exacta harvest en hermano/SKU equivocado | `repoint_harvest_asin` | Cambia product ad + renombra (no crea campaña) |
| Ganador Low PPC o SQP sin exacta | `harvest_to_exact` | Nueva campaña Exacta dedicada |
| ACOS alto con historial | `bid_down_high_acos` | Baja puja |
| ACOS bajo, volumen limitado | `bid_up_low_acos_limited_volume` | Sube puja |
| Auto con pocas impresiones | `auto_low_impressions_bid_up` | Sube puja auto |
| Search term gasto sin conversión | `negative_candidate` | Negativiza (exacta o frase n-gram) |
| Exacta pausada que funcionaba | `reactivate_paused_exact` | Reactiva |
| Exacta ACTIVA pero ad group/keyword pausado (0 impresiones) | `enable_delivery` | Enciende campaña + grupo + keyword + anuncio |
| Exacta enabled a 0 impresiones | `cold_start_wake` | Sube puja base por peldaños (TOS 0%; Rankear sin techo fijo; Profit con techo económico); mix TOS tras impresiones |
| Exacta con gasto PP/ROS ineficiente | `placement_reallocate` | Reasigna base + TOS % |
| Ajuste fino de exacta existente | `optimize_existing_exact` | Ajustes (nunca proxy de listing) |
| Dominancia orgánica SQP **o** SERP top 1–3 estable | `organic_dominance_reduce_ppc` | Baja/pausa PPC |
| Subir presupuesto con evidencia | `scale_ppc_budget` | Budget up |
| CTR / listing / Buy Box | `review_listing` (alias `low_ctr`) | Solo revisión, no ejecutable |

### Reglas duras Ads

- Nunca bid-up dentro de Low PPC → `harvest_to_exact`
- Tras harvest, no negativices el término en Low PPC
- Nunca uses `optimize_existing_exact` como proxy de listing → `review_listing` / `get_listing_health`
- No harvest / bid-up / scale_ppc_budget / enable_delivery / reactivate_paused_exact si el ASIN tiene cobertura operativa Pan-EU corta (pool FBA+inbound 0 o COB. OP. ≤21 días en el explorador de inventario; no usar cards MYI por marketplace)
- `create_asin_launch`: payload mínimo `{asin, country, sku?}`. Si omites `campaigns[]`, el backend expande seeds chalk DE a **N Exactas 1 KW + Auto** (mismo naming que harvest). Cada MANUAL en `campaigns[]` debe tener exactamente 1 keyword. `proposed_note` no alimenta keywords.
- No digas que hace falta CLI/`--execute`

## Acciones semanales → Ads pending

| quick_action.kind | decision_kind |
|-------------------|---------------|
| `promote_to_exact` | `harvest_to_exact` |
| `negative_keywords` | `negative_candidate` |
| `review_bid` | `bid_down_high_acos` o `review_listing` según evidencia |
| `full_stop_candidate` | `bid_down_high_acos` / pause vía optimize — o `review_listing` si no hay bid claro |
| `external_listing` | `review_listing` |

Usa `propose_weekly_action` con el `quick_action` de la card, o llama `propose_ads_action` a mano.
Nunca llames execute de `/api/actions/execute` desde MCP.

## Lecturas fuera de Ads

- Briefing de sesión: `get_account_brief` (abrir chat / primer mensaje; incluye `directives`)
- Memoria: `save_account_directives` (máx 3 objectives + 10 rules; tras confirmación del seller)
- Ficha producto: `get_asin_dossier(asin, country, month)` — finanzas + stock + ranks + Exactas + pending
- Inventario: `get_inventory_decisions` (RestockCritical, AgingFeeRisk, OverstockWarning, …)
- Costes: `get_product_costs` (COGS — **no** para validar ASINs de Ranks)
- Pedidos: `get_purchase_orders`
- Ventas / BA / tráfico: `get_sales_*`, `get_brand_analytics_*`, `get_traffic_report`
- Ranks: `get_organic_ranks`, `get_keyword_rank`
- Listing: `get_listing_health` (listing_blocker / buy box / SQP improve listing)
- Devoluciones: `get_returns_summary` (+ filtros) / `get_returns_events`
- P&L activity: `get_sales_breakdown` con `activity_type` (`sale` | `return` | `ppc_cost_only`)
- Claims FBA: `get_fba_fee_claims` (solo lectura; el seller presenta en Seller Central)
- Informes: `get_client_reports` / `get_monthly_report` (JSON preview, no PDF/HTML)

## Ventas e IVA (contrato fiscal)

- `amazon_net_amount` / payout es el neto exacto de Amazon; no lo “ajustes” por perfil fiscal.
- `tax_amount` es IVA cobrado al cliente, **no** dinero que recibe el seller.
- `marketplace_withheld_vat` (Marketplace Facilitator) reduce el payout y el IVA pendiente del seller (fiscal). Con `revenue_eur` TTC, el P&L operativo sigue restando el IVA de producto completo; no netees withheld del beneficio (inflaría el margen).
- `non_deductible_tax_cost` solo aplica cuando el perfil tiene `input_vat_recovery=none` (p. ej. recargo) y hay evidencia de IVA de fees.
- Perfiles fiscales versionados (`tenant_tax_profiles`) se resuelven por fecha; la evidencia Amazon de retención prevalece sobre el perfil para IVA pendiente.
- En breakdown/KPI: no interpretes `tax_amount` como ingreso del seller ni mezcles snapshots con distinta `metrics_version` / `tpv`.

## Propuestas operativas (no Ads)

- Restock: `propose_purchase_order` → Draft PO `source=mcp` → usuario confirma en Pedidos
- COGS: `propose_cost_update` → pending en Costes → usuario aprueba/rechaza

## Errores a no repetir

1. Decir "no existe forma de crear campañas" sin buscar `create_asin_launch` / playbook
2. Asumir que hace falta script OAuth externo a Amazon Ads API
3. Dar por buena una propose sin mirar payload / `created` vs `updated` en pending
4. Ejecutar acciones semanales directo en Amazon en vez de pending
5. Nombrar tools o decision_kind al seller en el chat
6. Bid-up / harvest / scale cuando ya hay top 1–3 orgánico estable en esa Exacta

## Verificar propose

Tras `propose_*`, confirma con la tool de lectura correspondiente (`get_ads_pending_actions`, `get_purchase_orders` status=Draft, o listado de propuestas COGS). `created: false` + `updated: true` suele ser upsert de la misma `recommendation_key`.

---

# Catálogo de tools MCP

## Meta

### `get_account_brief`

Briefing de cuenta / estudiar cuenta / snapshot del tenant al abrir sesión.

- **Scope:** `sales:read`

_Sin parámetros._

### `get_asin_dossier`

Ficha de un ASIN × país × mes: finanzas (ACOS+TACOS), stock, ranks orgánicos,     ficha keyword de Exactas top spend, y pending Ads de ese ASIN.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `asin` | `string` | yes |
| `country` | `string` | yes |
| `month` | `string` | yes |

### `get_selleriva_playbook`

Manual SellerIVA MCP: capabilities, qué puedes hacer, create campaign, harvest,     cold start ASIN, decision_kind, inventario, restock, COGS, costes, pedido, playbook.

- **Scope:** `(sin scope — texto estático)`

_Sin parámetros._

### `save_account_directives`

Guarda objetivos/reglas de la cuenta (memoria entre chats). Máx 3 objectives y 10 rules.

- **Scope:** `account:write`

| Param | Type | Required |
| --- | --- | --- |
| `objectives` | `{'items': {'additionalProperties': True, 'type': 'object'}, 'type': 'array'} | {'type': 'null'}` | no |
| `rules` | `{'items': {'type': 'string'}, 'type': 'array'} | {'type': 'null'}` | no |

## Sales

### `get_data_freshness`

Devuelve el estado de sincronización y frescura de datos del tenant.

- **Scope:** `sales:read`

_Sin parámetros._

### `get_products_performance`

Devuelve rendimiento por producto (SKU/ASIN): unidades, ingresos, margen visible.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `sort` | `string` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_returns_events`

Eventos de devolución línea a línea (motivos, ASIN/SKU, disposición). Solo lectura.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `marketplace_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `reason_code` | `{'type': 'string'} | {'type': 'null'}` | no |
| `disposition` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |

### `get_returns_summary`

Resumen de devoluciones: KPIs, razones, insights y frescura.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `marketplace_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `reason_code` | `{'type': 'string'} | {'type': 'null'}` | no |
| `disposition` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_sales_breakdown`

Devuelve desglose financiero P&L.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `scope` | `string` | no |
| `country_code` | `{'type': 'string'} | {'type': 'null'}` | no |
| `sku` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |
| `activity_type` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_sales_kpis`

Devuelve KPIs de ventas del tenant autenticado: ingresos, unidades, márgenes y devoluciones.     Ventas / sales / revenue / units.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

## Reports

### `get_client_reports`

Lista metadatos de informes cliente (HTML enviados + PDF mensuales). Sin binarios.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `limit` | `integer` | no |

### `get_fba_fee_claims`

Claims FBA de tarifas detectados / listos (solo lectura).

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `status` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |

### `get_monthly_report`

Preview JSON del informe mensual (insights / P&L). month=YYYY-MM.

- **Scope:** `sales:read`

| Param | Type | Required |
| --- | --- | --- |
| `month` | `string` | yes |
| `lang` | `string` | no |

## Analytics

### `get_brand_analytics_products`

Devuelve oportunidades Brand Analytics agregadas por producto (ASIN).

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `weeks_back` | `{'type': 'integer'} | {'type': 'null'}` | no |
| `marketplace_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `week_start` | `{'type': 'string'} | {'type': 'null'}` | no |
| `recommendation_type` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `brand` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_brand_analytics_queries`

Devuelve recomendaciones Brand Analytics (SQP) por search query.

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `weeks_back` | `{'type': 'integer'} | {'type': 'null'}` | no |
| `marketplace_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `week_start` | `{'type': 'string'} | {'type': 'null'}` | no |
| `recommendation_type` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `brand` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_keyword_competitors`

Devuelve competidores top clicados para una keyword (Search Terms vs hero ASIN).

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `search_query` | `string` | yes |
| `marketplace_id` | `string` | yes |

### `get_listing_health`

Señales de salud de listing (no scrape): weekly listing_blocker/buybox_leak,     SQP improve_search_card/improve_detail_page, y buy box / CVR de tráfico.

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `limit` | `integer` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_search_query_trend`

Devuelve la evolución semanal de una search query para un ASIN y marketplace.

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `search_query` | `string` | yes |
| `asin` | `string` | yes |
| `marketplace_id` | `string` | yes |

### `get_traffic_report`

Devuelve informe de tráfico (sesiones, page views, CVR, buy box) por ASIN.

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `granularity` | `string` | no |
| `weeks_back` | `{'type': 'integer'} | {'type': 'null'}` | no |
| `week_start_date` | `{'type': 'string'} | {'type': 'null'}` | no |
| `week_end_date` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `marketplace_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |

### `get_weekly_product_actions`

Devuelve acciones semanales por producto / weekly actions (veredicto, severidad, plan).

- **Scope:** `analytics:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `period_mode` | `string` | no |
| `week_start_date` | `{'type': 'string'} | {'type': 'null'}` | no |
| `week_end_date` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `status` | `{'type': 'string'} | {'type': 'null'}` | no |

## Inventory

### `get_inventory_decisions`

Inventario FBA / restock / reposición / stock decisions (RestockCritical, AgingFeeRisk,     OverstockWarning, ListingOptimization, Healthy). Solo lectura.

- **Scope:** `inventory:read`

| Param | Type | Required |
| --- | --- | --- |
| `region` | `{'type': 'string'} | {'type': 'null'}` | no |
| `marketplace` | `{'type': 'string'} | {'type': 'null'}` | no |
| `decision_type` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |

### `get_product_costs`

Costes de producto / COGS / unit cost / márgenes (catálogo unificado). Solo lectura.

- **Scope:** `cogs:read`

| Param | Type | Required |
| --- | --- | --- |
| `sku` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |

### `get_purchase_orders`

Pedidos a proveedor / purchase orders / POs / restock orders. Solo lectura.

- **Scope:** `inventory:read`

| Param | Type | Required |
| --- | --- | --- |
| `status` | `{'type': 'string'} | {'type': 'null'}` | no |
| `search` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |

## Ads

### `get_ads_advertised_products`

Productos anunciados (ASIN/SKU) del tenant con métricas del periodo. Paginado.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `country` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_ads_advisor_recommendations`

Devuelve recomendaciones del Amazon Ads Advisor (pujas, negativas, scale, etc.).

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `country` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |

### `get_ads_campaign_detail`

Detalle slim de una campaña Ads: métricas, serie diaria corta y productos anunciados.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `campaign_id` | `string` | yes |
| `period` | `string` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_ads_campaign_impact_series`

Serie diaria de rendimiento de una campaña (spend, sales, ACOS, CTR, CPC, CVR) + markers.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `campaign_id` | `string` | yes |
| `period` | `string` | no |

### `get_ads_campaign_logbook`

Bitácora de cambios y decisiones de una campaña Ads.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `campaign_id` | `string` | yes |

### `get_ads_campaign_settings`

Configuración vigente de una campaña: presupuesto, estrategia de puja,     ajustes TOP/PP/ROS (%), ad groups (default bid) y keywords (bid/state).

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `campaign_id` | `string` | yes |

### `get_ads_campaign_targeting`

Targeting / rendimiento de una campaña: keywords, search terms, placements TOP/PP/ROS,     ad groups o targets (product/category/auto). Paginado por sección.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `campaign_id` | `string` | yes |
| `section` | `string` | no |
| `period` | `string` | no |
| `country` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_ads_campaigns`

Lista campañas Ads / PPC / anuncios con métricas (gasto, ventas, ACOS, ROAS, CPC, CTR, CVR).

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `country` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
| `offset` | `integer` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_ads_pending_actions`

Lista acciones PPC pendientes de aprobación humana en Selleriva.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `status` | `string` | no |
| `limit` | `integer` | no |

### `get_ads_search_term_actions`

Devuelve acciones puntuadas de search terms (negativas, promote-to-exact, review bid).

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `limit` | `integer` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_ads_summary`

KPIs agregados de Ads / PPC / anuncios del tenant (gasto, ventas, ACOS, ROAS) + decisiones recientes.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `period` | `string` | no |
| `country` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `date_to` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_keyword_rank`

Keyword 360 slim: posición SERP (serie 14d), Exacta, PPC 7d, competidores y recomendación.

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `asin` | `string` | yes |
| `country` | `string` | yes |
| `keyword` | `string` | yes |
| `parent_asin` | `{'type': 'string'} | {'type': 'null'}` | no |

### `get_organic_ranks`

Señales de rank orgánico SERP por país (puesto + Exacta asociada).

- **Scope:** `ads:read`

| Param | Type | Required |
| --- | --- | --- |
| `country` | `string` | yes |
| `limit` | `integer` | no |
| `organic_level` | `{'type': 'string'} | {'type': 'null'}` | no |
| `q` | `{'type': 'string'} | {'type': 'null'}` | no |
| `has_exact` | `{'type': 'boolean'} | {'type': 'null'}` | no |

## Propose

### `propose_ads_action`

Crea una card en Selleriva → Ads → Automatización para que el usuario apruebe.     NO escribe en Amazon Ads. Si solo describes la recomendación en el chat, NO llega a la app:     DEBES llamar esta tool.

- **Scope:** `ads:propose`

| Param | Type | Required |
| --- | --- | --- |
| `decision_kind` | `string` | yes |
| `action_payload` | `any` | no |
| `evidence` | `any` | no |
| `action_payload_json` | `any` | no |
| `evidence_json` | `any` | no |
| `recommendation_key` | `{'type': 'string'} | {'type': 'null'}` | no |
| `profile_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `campaign_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `campaign_name` | `{'type': 'string'} | {'type': 'null'}` | no |
| `country_code` | `{'type': 'string'} | {'type': 'null'}` | no |
| `proposed_note` | `{'type': 'string'} | {'type': 'null'}` | no |

### `propose_cost_update`

Propone un cambio de COGS / unit_cost para aprobación humana en SellerIVA → Costes.     NO escribe el coste hasta que el usuario apruebe la propuesta.

- **Scope:** `cogs:propose`

| Param | Type | Required |
| --- | --- | --- |
| `sku` | `string` | yes |
| `asin` | `string` | yes |
| `marketplace` | `string` | yes |
| `unit_cost` | `number` | yes |
| `currency` | `{'type': 'string'} | {'type': 'null'}` | no |
| `cost_effective_from` | `{'type': 'string'} | {'type': 'null'}` | no |
| `proposed_note` | `{'type': 'string'} | {'type': 'null'}` | no |
| `cost_fabricacion` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_inspeccion` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_transporte_intl` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_transporte_local` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_tarifas_importacion` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_otros` | `{'type': 'number'} | {'type': 'null'}` | no |
| `cost_transporte_fbm` | `{'type': 'number'} | {'type': 'null'}` | no |

### `propose_purchase_order`

Crea un pedido a proveedor en estado Draft (source=mcp) a partir de un restock sugerido.     NO envía a Amazon ni cambia el status del PO. El usuario lo ve en Pedidos y lo confirma.

- **Scope:** `inventory:propose`

| Param | Type | Required |
| --- | --- | --- |
| `supplier_name` | `string` | yes |
| `marketplace` | `string` | yes |
| `order_date` | `string` | yes |
| `lines` | `any` | yes |
| `supplier_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `reference` | `{'type': 'string'} | {'type': 'null'}` | no |
| `currency` | `string` | no |
| `expected_delivery_date` | `{'type': 'string'} | {'type': 'null'}` | no |
| `comment` | `{'type': 'string'} | {'type': 'null'}` | no |
| `inventory_card_id` | `{'type': 'string'} | {'type': 'null'}` | no |

### `propose_weekly_action`

Traduce una quick action de acciones semanales (/actions) a cards pending de Ads.     Nunca escribe en Amazon Ads API ni llama /actions/execute.

- **Scope:** `ads:propose`

| Param | Type | Required |
| --- | --- | --- |
| `quick_action_kind` | `string` | yes |
| `terms` | `any` | no |
| `weekly_card_id` | `{'type': 'string'} | {'type': 'null'}` | no |
| `asin` | `{'type': 'string'} | {'type': 'null'}` | no |
| `sku` | `{'type': 'string'} | {'type': 'null'}` | no |
| `country_code` | `{'type': 'string'} | {'type': 'null'}` | no |
| `proposed_note` | `{'type': 'string'} | {'type': 'null'}` | no |
| `limit` | `integer` | no |
