# PCDCK/ozon-mcp [Health: Active]

**Category:** 🛒 E-Commerce  
**Repository:** https://github.com/PCDCK/ozon-mcp  
**GitHub Stars:** 21  
**Views:** 2  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/pcdck-ozon-mcp

## Description
Knowledge-rich MCP server for the full Ozon Seller + Performance API (466 methods, 15 MCP tools). Auto-pagination over 4 cursor styles, subscription-tier pre-flight, rate-limit management with exponential back-off, and 13 curated analytical workflows (OOS risk, cabinet health, content audit, pricing, warehouse distribution). Russian + English BM25 search across the catalog.

## Tools
Capabilities this server exposes over MCP:

- **ozon_call_method** — Execute any Ozon API method with safety + subscription guards
- **ozon_fetch_all** — Auto-paginate — get every page, not just the first
- **ozon_describe_method** — Full docs for a method: schema, examples, rate limit, quirks
- **ozon_search_methods** — BM25 search across 466 methods (Russian or English, with stemming)
- **ozon_list_sections** — Browse the API by section
- **ozon_get_section** — All methods inside one section
- **ozon_list_workflows** — List ready-made analytical workflows (filterable by category)
- **ozon_get_workflow** — Full step-by-step plan for one workflow
- **ozon_get_related_methods** — Methods that work well together (auto-extracted graph)
- **ozon_get_examples** — Curated request/response examples for a method
- **ozon_get_rate_limits** — Per-method, per-section, or all
- **ozon_get_subscription_status** — Read your current cabinet's subscription tier
- **ozon_list_methods_for_subscription** — What you unlock on a given tier
- **ozon_get_swagger_meta** — Check that bundled API specs are still fresh
- **ozon_get_error_catalog** — Look up any Ozon error code

## Claude Desktop Quick Installation
Heuristic fallback — verify the package name and runner against the repository README before running it. Uses `npx` (confidence: low):

```json
"mcpServers": {
  "ozon-mcp": {
    "command": "npx",
    "args": ["-y","pcdck-ozon-mcp"],
    "env": {
      "OZON_CLIENT_ID": "",
      "OZON_API_KEY": "",
      "OZON_PERFORMANCE_CLIENT_ID": "",
      "OZON_PERFORMANCE_CLIENT_SECRET": ""
    }
  }
}
```

**Requires environment variables:** `OZON_CLIENT_ID`, `OZON_API_KEY`, `OZON_PERFORMANCE_CLIENT_ID`, `OZON_PERFORMANCE_CLIENT_SECRET` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation & README

# ozon-mcp

> MCP server for the Ozon Seller & Performance APIs.
> Connect any AI agent to your Ozon cabinet in minutes.

[![CI](https://github.com/PCDCK/ozon-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/PCDCK/ozon-mcp/actions/workflows/ci.yml)
![Python](https://img.shields.io/badge/python-3.12%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)
![MCP](https://img.shields.io/badge/MCP-compatible-orange)

ozon-mcp is a knowledge-rich MCP server that turns the entire Ozon
seller toolkit into 15 high-leverage tools. AI agents (Claude, Cursor,
Cline, Continue, Goose, Zed, …) can search the API in Russian or
English, drill into any of 466 methods with a fully-resolved JSON
Schema, and execute calls with built-in safety guards. Subscription-
aware, automatic pagination over all 4 cursor styles, retry/back-off
on 429s, and 13 ready-to-use analytical workflows.

**Key facts:** 466 indexed methods (420 Seller + 46 Performance),
55 sections, 5 subscription tiers modelled, 38 paginated endpoints
auto-walked, 43 destructive methods double-gated, 13 curated
workflows for typical seller scenarios.

---

## Quick start

### Prerequisites

- Python 3.12 or 3.13
- `uv` package manager — install with
  `curl -LsSf https://astral.sh/uv/install.sh | sh`
- Ozon Seller API credentials (Client-Id + Api-Key) — get them at
  <https://seller.ozon.ru/app/settings/api-keys>

### Installation

```bash
git clone https://github.com/PCDCK/ozon-mcp.git
cd ozon-mcp
uv sync
```

### Verify it works

```bash
uv run ozon-mcp --help
```

You should see the FastMCP usage line. The server speaks the MCP stdio
protocol — point any compatible client at it (instructions below).

---

## Connecting to your AI agent

ozon-mcp uses the standard MCP stdio transport. Every example below
exposes the same 15 tools — pick whichever client you already use.

### Claude Desktop

Edit:
`~/Library/Application Support/Claude/claude_desktop_config.json`
(macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).

```json
{
  "mcpServers": {
    "ozon": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/ozon-mcp",
                "run", "ozon-mcp"],
      "env": {
        "OZON_CLIENT_ID": "your-seller-client-id",
        "OZON_API_KEY": "your-seller-api-key",
        "OZON_PERFORMANCE_CLIENT_ID": "your-perf-client-id",
        "OZON_PERFORMANCE_CLIENT_SECRET": "your-perf-secret"
      }
    }
  }
}
```

### Claude Code (CLI)

```bash
cd /path/to/ozon-mcp
claude mcp add ozon -- uv run ozon-mcp
```

Or add to `~/.claude/mcp.json` with the same shape as the Claude
Desktop config above.

### Cursor

Settings → MCP → Add new MCP Server, or edit `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "ozon": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/ozon-mcp",
                "run", "ozon-mcp"]
    }
  }
}
```

### Windsurf

Edit `~/.codeium/windsurf/mcp_config.json`:

```json
{
  "mcpServers": {
    "ozon": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/ozon-mcp",
                "run", "ozon-mcp"]
    }
  }
}
```

### Cline (VS Code extension)

Cline → Settings → MCP Servers → Add:

```json
{
  "ozon": {
    "command": "uv",
    "args": ["--directory", "/absolute/path/to/ozon-mcp",
              "run", "ozon-mcp"]
  }
}
```

### Continue.dev

Edit `~/.continue/config.json`:

```json
{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "uv",
          "args": ["--directory", "/absolute/path/to/ozon-mcp",
                    "run", "ozon-mcp"]
        }
      }
    ]
  }
}
```

### Goose, Zed, or any other MCP client

Any client that speaks MCP stdio will work. Generic config:

```yaml
command: uv
args: ["--directory", "/absolute/path/to/ozon-mcp", "run", "ozon-mcp"]
transport: stdio
env:
  OZON_CLIENT_ID: ...
  OZON_API_KEY: ...
```

Browse the official MCP client list at
<https://modelcontextprotocol.io/clients>.

---

## Usage examples

All examples below show realistic responses copied from
[`tests/fixtures/responses/`](https://github.com/PCDCK/ozon-mcp/blob/HEAD/tests/fixtures/responses/) — anonymized
identifiers (`99000001`, `TEST-SKU-001`) but real shape.

### Example 1 — Get all your products

> **You:** Use `ozon_fetch_all` with `operation_id="ProductAPI_GetProductList"`
> to get all my products.

The agent calls:

```json
{
  "operation_id": "ProductAPI_GetProductList",
  "params": {"filter": {"visibility": "ALL"}},
  "max_items": 10000
}
```

Server walks the `last_id` cursor automatically and returns:

```json
{
  "ok": true,
  "items": [
    {"product_id": 99000001, "offer_id": "TEST-SKU-001", "archived": false},
    {"product_id": 99000002, "offer_id": "TEST-SKU-002", "archived": false},
    {"product_id": 99000003, "offer_id": "TEST-SKU-003", "archived": true}
  ],
  "total_fetched": 3,
  "truncated": false,
  "pages_fetched": 1
}
```

### Example 2 — Find products at risk of going out of stock

> **You:** Run the `oos_risk_analysis` workflow for my cabinet.

Agent first inspects the workflow:

```json
ozon_get_workflow({"name": "oos_risk_analysis"})
```

→ tells the agent to call `AnalyticsAPI_StocksTurnover` (rate-limited
to 1 req/min — the server's per-endpoint queue handles that for you)
and how to interpret `turnover_grade`. The call returns:

```json
{
  "items": [
    {"sku": 99000001, "current_stock": 12, "ads": 1.5,
     "idc": 8.0, "turnover_grade": "DEFICIT",
     "turnover_grade_cluster": "DEFICIT_GROWING"},
    {"sku": 99000002, "current_stock": 25, "ads": 0.8,
     "idc": 31.25, "turnover_grade": "OPTIMAL",
     "turnover_grade_cluster": "OPTIMAL_FALLING"},
    {"sku": 99000003, "current_stock": 0, "ads": 0.0,
     "idc": 0.0, "turnover_grade": "NO_SALES",
     "turnover_grade_cluster": "NO_SALES"}
  ]
}
```

The workflow's `interpret` field tells the agent to flag SKUs where
`idc < 14` or `turnover_grade ∈ {DEFICIT, NO_SALES}` and surface them
sorted by `idc asc`.

### Example 3 — Full cabinet health check

> **You:** Check the health of my Ozon cabinet using the
> `cabinet_health_check` workflow.

The workflow tells the agent to read three endpoints in parallel —
`RatingAPI_RatingSummaryV1`, `SellerAPI_SellerInfo`,
`AverageDeliveryTimeSummary`. The first call returns:

```json
{
  "groups": [
    {
      "group_name": "Выполнение заказов",
      "items": [
        {"rating": "rating_on_time", "name": "Процент заказов вовремя",
         "current_value": 97.5, "status": "OK", "value_type": "PERCENT"},
        {"rating": "rating_review_avg_score", "name": "Средняя оценка",
         "current_value": 4.7, "status": "OK", "value_type": "RATING"}
      ]
    },
    {
      "group_name": "Качество сервиса",
      "items": [
        {"rating": "rating_price_index", "name": "Индекс цен",
         "current_value": 1.01, "status": "OK", "value_type": "INDEX"}
      ]
    }
  ],
  "premium_scores": [
    {"rating": "rating_on_time", "value": 97.5,
     "penalty_score_per_day": 0, "scope": "premium_plus"}
  ]
}
```

### Example 4 — Analyze product pricing

> **You:** Which of my products have a red price index?

Agent runs the `pricing_analysis` workflow and inspects the
`price_indexes.color_index` field on every item:

```json
{
  "product_id": 99000001, "offer_id": "TEST-SKU-001",
  "price": {"price": "399.0000", "marketing_seller_price": "399.0000",
             "min_price": "299.0000"},
  "price_indexes": {
    "color_index": "WITHOUT_INDEX",
    "ozon_index_data": {"minimal_price": "395.0000",
                          "price_index_value": 1.01}
  },
  "commissions": {"sales_percent_fbo": 0.13, "sales_percent_fbs": 0.13}
}
```

The workflow's `common_mistakes` list reminds the agent to compare
against `marketing_seller_price` (the actual buyer-facing price), not
just the base `price`.

### Example 5 — Content audit

> **You:** Find products with low content rating and tell me what to
> improve.

Agent runs `content_audit`, gets per-SKU ratings + the list of
attributes that would lift the score:

```json
{
  "products": [
    {
      "sku": 99000001, "rating": 85,
      "groups": [
        {"key": "media", "rating": 100},
        {"key": "characteristics", "rating": 75,
         "improve_attributes": [
           {"id": 4191, "name": "Цвет"},
           {"id": 8292, "name": "Материал"}
         ],
         "improve_at_least": 4}
      ]
    }
  ]
}
```

The workflow tells the agent that a `+10` lift to `rating` measurably
improves search ranking — so filling in those two attributes is worth
~4 points.

---

## Available tools (15)

| Tool | What it does |
|---|---|
| `ozon_call_method` | Execute any Ozon API method with safety + subscription guards |
| `ozon_fetch_all` | Auto-paginate — get every page, not just the first |
| `ozon_describe_method` | Full docs for a method: schema, examples, rate limit, quirks |
| `ozon_search_methods` | BM25 search across 466 methods (Russian or English, with stemming) |
| `ozon_list_sections` | Browse the API by section |
| `ozon_get_section` | All methods inside one section |
| `ozon_list_workflows` | List ready-made analytical workflows (filterable by category) |
| `ozon_get_workflow` | Full step-by-step plan for one workflow |
| `ozon_get_related_methods` | Methods that work well together (auto-extracted graph) |
| `ozon_get_examples` | Curated request/response examples for a method |
| `ozon_get_rate_limits` | Per-method, per-section, or all |
| `ozon_get_subscription_status` | Read your current cabinet's subscription tier |
| `ozon_list_methods_for_subscription` | What you unlock on a given tier |
| `ozon_get_swagger_meta` | Check that bundled API specs are still fresh |
| `ozon_get_error_catalog` | Look up any Ozon error code |

---

## Ready-made workflows (13)

Workflows are curated step-by-step recipes. Use
`ozon_get_workflow("name")` to fetch the full plan, including
`interpret`, `when_to_use`, `common_mistakes`, and the recommended
DB schema for sync-style workflows.

| Workflow | Category | What it solves |
|---|---|---|
| `oos_risk_analysis` | analytics | Find products about to go out of stock |
| `cabinet_health_check` | health | Check all seller-rating metrics in one shot |
| `content_audit` | content | Find low-content-rating cards + actionable attributes |
| `pricing_analysis` | pricing | Find products with non-competitive pricing |
| `warehouse_stock_distribution` | warehouse | Per-warehouse stock breakdown for FBO |
| `sync_products_catalog` | catalog | Full product catalog snapshot |
| `sync_orders_fbo` | orders | Incremental FBO order sync |
| `sync_orders_fbs` | orders | Incremental FBS / rFBS order sync |
| `sync_finance_transactions` | finance | Finance transactions for unit economics |
| `sync_analytics_daily` | analytics | Daily revenue / orders time series |
| `sync_advertising_campaigns` | advertising | Performance API ads catalog |
| `sync_warehouse_stocks` | warehouse | FBS warehouse stocks |
| `sync_returns_rfbs` | returns | rFBS returns sync |

---

## API coverage

| API | Methods | Sections |
|---|---|---|
| Ozon Seller API | 420 | 49 |
| Ozon Performance API | 46 | 6 |
| **Total** | **466** | **55** |

Subscription tiers modelled (low → high):
`LITE → STANDARD → PREMIUM → PREMIUM_PLUS → PREMIUM_PRO`.

---

## Key features

### Subscription-aware

The server knows which methods are gated on Premium tiers and refuses
the call before it leaves your machine — saves your API quota:

```json
{
  "error": "subscription_gate",
  "error_type": "subscription_gate",
  "code": 7,
  "message": "Endpoint requires PREMIUM_PRO, cabinet has PREMIUM_PLUS",
  "operation_id": "ProductPricesDetails",
  "required_tier": "PREMIUM_PRO",
  "cabinet_tier": "PREMIUM_PLUS",
  "retryable": false,
  "http_call_skipped": true
}
```

### Rate-limit management

- Auto-retry with exponential back-off on 429.
- Honours `Retry-After` (both delta-seconds and RFC 7231 HTTP-date).
- Per-endpoint semaphore for slow methods (e.g.
  `/v1/analytics/turnover/stocks` is hard-limited to 1 req/min on the
  Ozon side — the server queues parallel calls automatically).

### Auto-pagination

`ozon_fetch_all` handles all four pagination patterns Ozon uses:
`offset/limit`, `cursor`, `last_id`, `page_number`. It also detects
the rare case where the server returns the same cursor twice in a
row and breaks the loop instead of spinning forever.

```python
ozon_fetch_all(
  operation_id="ProductAPI_GetProductList",
  params={"filter": {"visibility": "ALL"}},
  max_items=10_000,
)
# → {"items": [...all products...], "total_fetched": 847,
#    "truncated": false, "pages_fetched": 1}
```

### Unified error envelope

Every tool that can fail returns the same shape — easy to branch on
in any agent or downstream code:

```json
{
  "error": "rate_limit_exceeded",
  "error_type": "rate_limit | subscription_gate | not_found | invalid_params | server_error | timeout | auth | forbidden | conflict | ...",
  "message": "Human-readable explanation",
  "code": 429,
  "operation_id": "AnalyticsAPI_StocksTurnover",
  "endpoint": "/v1/analytics/turnover/stocks",
  "retryable": true,
  "retry_after_seconds": 60
}
```

### Safety classification baked into the catalog

Every method carries a `safety` field — `read`, `write`, or
`destructive`. Write requires `confirm_write=True`; destructive
requires both `confirm_write=True` AND
`i_understand_this_modifies_data=True`. Heuristics from the schema
extractor are reinforced by 43 curated `safety_warning` entries in
`quirks.yaml` so the agent always sees a clear reminder before
mutating anything.

---

## Keeping the API specs up to date

Ozon refreshes their swagger periodically. To sync:

```bash
cd parser/                               # the parser repo / drop-zone
python parse_swagger.py                  # downloads + sanitises both APIs
cp seller_swagger.json ../src/ozon_mcp/data/
cp perf_swagger.json   ../src/ozon_mcp/data/
cp swagger_meta.json   ../src/ozon_mcp/data/
```

Run `ozon_get_swagger_meta` to confirm the bundled snapshot is fresh
(the CI also fails the build when the snapshot is older than 14
days).

---

## Development

```bash
git clone https://github.com/PCDCK/ozon-mcp.git
cd ozon-mcp
uv sync --extra dev

# Tests (≈25s, 274 currently)
uv run pytest tests/ --ignore=tests/live

# Code quality
uv run ruff check src tests
uv run mypy src/ozon_mcp

# Coverage
uv run pytest tests/ --ignore=tests/live --cov=src/ozon_mcp \
    --cov-report=term-missing
```

See [CONTRIBUTING.md](https://github.com/PCDCK/ozon-mcp/blob/HEAD/CONTRIBUTING.md) for how to add knowledge
(workflows, examples, quirks, subscription overrides).

---

## License

[MIT](https://github.com/PCDCK/ozon-mcp/blob/HEAD/LICENSE)

