# Shopify Products Scraper, Audit & Price Comparison | PAL (`practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite`) Actor

Export permitted public Shopify product feeds or your own JSON. Audit SKUs and image quality, compare cross-store prices, track public price/availability changes, estimate margins from supplied costs, and download CSV.

- **URL**: https://apify.com/practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite.md
- **Developed by:** [Practical AI Lab](https://apify.com/practical_ai_lab_jp) (community)
- **Categories:** E-commerce, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 commerce intelligence reports

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Shopify Products Scraper, Audit & Price Comparison | PAL

Shopify products scraper and catalog intelligence: export authorized public Shopify products.json feeds when robots.txt allows, or analyze your own product JSON. Combine catalog quality audits, SKU validation, earlier-snapshot price and public availability changes, competitor SKU comparisons, buyer-supplied cost-margin estimates, and CSV exports. Protected data is never scraped.

**A Shopify catalog operations toolkit in one Apify Actor:** turn authorized public Shopify product feeds or your own product JSON into an exportable intelligence report. Built for Shopify merchants, ecommerce agencies, product-data teams and competitive intelligence workflows. Rather than stitching together multiple small checkers, receive structured catalog data, quality findings, change reports, and a prioritized action queue in one run.

### What one run can do

| Operation | What you get |
| --- | --- |
| Catalog export | Product and variant rows, prices, published availability, variants, SKUs, vendors, image URLs, and descriptions |
| Product health | Missing/duplicate SKUs, missing images, explicitly empty image alt, weak titles and descriptions, invalid prices, variant option collisions |
| Price changes | Current vs supplied previous snapshot: price rise/drop, sale signal change |
| Availability changes | Newly available or unavailable flags; **not private stock units or confirmed sales** |
| Competitor SKU comparison | Cross-store matches by SKU; price spread **only if the buyer declares the same currency for both stores** |
| Merchandising dashboard | Available/unavailable variant mix, discount incidence, price distribution, vendor counts |
| Gross-margin what-if | Unit margin from **buyer-supplied** costs and listed prices in the same currency, before all overhead |
| Action queue | Critical and high-priority quality findings and observed changes with suggested manual fixes |
| Operational exports | Multiple CSV files, all JSON dataset rows, JSON executive summary, downloadable Markdown executive report |
| Apify integration | API/SDK datasets and key-value store files, suitable for scheduled reruns and your own workflow tools |

Each function uses the same bounded input. A failed input does **not** trigger a report event. There is no need to buy several other PAL actors to use the core workflow.

### Quick start — a zero-network demonstration

The default input is **fictional**: two products at a demo storefront, one historical product snapshot, and one sample competitor product. Press Start to see a price decrease, an availability flag change, overlapping SKUs, image quality issues, a same-currency competitor comparison and a margin example. **A run may incur usage charges.** Check the live Pricing tab before pressing Start.

For your own data, replace \`products\`, \`previousProducts\` and \`competitorProducts\` with authorized Shopify products.json-style records, setting \`storeHost\` per product if comparing multiple stores. For public store feeds, remove the fictional records and add up to 3 URLs to \`publicStores\`; only robots-allowed public \`/products.json\` is accessed. Stores that block access are recorded as unavailable; no proxy or bypass is attempted.

### Outputs

All output records appear in the default dataset. The default key-value store holds: \`EXECUTIVE_SUMMARY\` and downloadable \`CATALOG_PRODUCTS_CSV\`, \`CATALOG_VARIANTS_CSV\`, \`PRIORITY_ACTIONS_CSV\`, \`OBSERVED_CHANGES_CSV\`, \`CROSS_STORE_COMPARISON_CSV\`, \`GROSS_MARGIN_ESTIMATES_CSV\`, and \`EXECUTIVE_SUMMARY_MD\`. Download files via Apify Console or the API. CSV output escapes spreadsheet formulas.

### Recurring competitor monitoring

Save your own previous snapshot and pass it back as \`previousProducts\` for each subsequent run, or orchestrate snapshots through Apify schedules and your own automation. **No persistent comparison state or automatic alerts are claimed** in this release. If the input is a partial sample, an absent variant is marked *not observed*, not definitively discontinued. Cross-store SKU matching is a heuristic—different products can share SKUs, and you must verify identity.

### Data quality and compliance

- Public feed access is limited: max 3 stores, max 5 pages each, max 100 products per page; all requests use HTTPS, safe DNS resolution with pinned public addresses, robots.txt checks, no redirects and no anti-bot circumvention.
- Uploaded input is limited to 1,000 current products and 1,000 previous products. No private Shopify Admin API, order history, customer or email harvesting.
- \`available\` is a **published Boolean flag**, not inventory quantities. Listed prices are not confirmed historical transaction prices. Currencies are **not inferred** from public products.json; to compare, supply \`currencyByStore\`.
- Optional \`costBySku\` is buyer-supplied. Gross margin figures exclude shipping, taxes, refunds, platform fees, discounts other than those already reflected in the listed price, and marketing costs.
- Quality flags are **review suggestions**, not automatic Shopify edits or guaranteed improvements. An item may be intentionally free or have decorative images without alt text.
- "All-in-one" describes the ten supported catalog workflows above, **not universal website crawling, protected-data scraping, payment processing, forecasting, AI-generated prose or guaranteed revenue**.

### Pricing

One Apify pay-per-event \`commerce-intelligence-report\` event is charged **after** successful dataset and report storage. Apify's live Pricing tab controls the actual current price and any actor-start usage. Network-denied stores, malformed input or unavailable data cannot generate a billed report event. No hidden external API bills or paid proxies.

### Buyer support

Use the included fictional demo to check output schema, then test a **small permitted** real dataset. If a public store blocks access, import an authorized product export rather than trying to bypass restrictions. Keep snapshots and declared currency codes for accurate comparisons.

### Better Shopify products scraper support

Use a public Shopify store homepage or an individual collection URL (for example, https://myshop.com/collections/summer). The Actor requests a bounded public products.json feed for that collection, only when allowed by robots.txt; no credential, private API, rate-limit bypass or anti-bot evasion is used.

For storefront URLs, the default is up to three pages of 100 products per store (300 per store), with three permitted stores, and a maximum of five pages per store if configured. Some shops restrict or disable public feeds. A bounded result cannot be represented as a complete catalog.

CATALOG_PRODUCTS_CSV now includes all_image_urls, a JSON array of every public HTTPS image URL present in each product record (not just the featured image). CATALOG_VARIANTS_CSV retains SKUs, barcodes, listed prices, variants and published availability flags. Actual inventory counts and customer orders are never inferred.

### Low-volume introductory pricing (automatically selected)

The Actor has two **mutually exclusive report events**:

- **Small report: $0.003** when the combined output contains up to 25 products and up to 50 variants, and either the data is entirely supplied by you or only one public Shopify store was requested with maxPages set to 1.
- **Standard report: $0.02** for all other completed reports, including higher-volume or wider public-feed scans.
- **Actor start: $0.00005** for runs up to 1 GB RAM. Actual prices are governed by the live Apify Store Pricing tab and user's settings. The Actor does not separately pass platform usage to users for normal runs.
- Exactly **one** report event is billed after a successful report is saved; the two report events are not stacked. Runs that fail before report creation do not incur a report event, but the Actor-start charge may apply.

#### Free-to-view sample (no run required)

The fictional sample in the description can be inspected without starting an Actor run. It demonstrates 3 current products across 2 sample stores, 2 quality issues, 5 observed changes, 1 cross-store SKU comparison and CSV exports. These **illustrative results are not evidence of real customer sales**. Running the sample or your own input is not completely free because the Actor-start and applicable report fees may apply.

To keep the low-volume rate for a public store, clear the fictional product inputs, enter **one** allowed public Shopify store or collection URL, and set maxPages to 1. If more than 25 products or 50 variants are returned, the standard event applies; check the charge limit before running.

# Actor input Schema

## `products` (type: `array`):

Current Shopify products.json-style products. Each row can include storeHost. Clear to scan publicStores only.

## `previousProducts` (type: `array`):

Previous Shopify products.json-style rows for price, discount and public availability changes; matched by store host and variant ID.

## `competitorProducts` (type: `array`):

Authorized competitor product records with their own storeHost for SKU matching and declared-currency price comparison.

## `publicStores` (type: `array`):

Up to three HTTPS Shopify store or /collections/<handle> URLs. Uses robots-allowed public /products.json or collection feed. Clear fictional demo records when scanning live stores. No credentials or rate-limit bypass.

## `currencyByStore` (type: `object`):

User-provided currencies only. Price spread between stores is displayed only when currencies match; the feed itself does not provide verified currencies.

## `costBySku` (type: `object`):

If supplied in the same currency as each store's price, estimate gross margin before shipping, ads, fees, taxes or returns. Never infers private unit costs.

## `maxPages` (type: `integer`):

Up to 3 pages per store by default (up to 300 products per store); capped at five pages.

## `pageSize` (type: `integer`):

Up to 100 public product records per feed page; actual Shopify access and data vary.

## `fullSnapshotConfirmed` (type: `boolean`):

Set true only when you verified complete comparable catalogs; otherwise missing variants are flagged not-observed rather than removed.

## Actor input object example

```json
{
  "products": [
    {
      "id": 101,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "sky-blue-widget",
      "title": "Sky Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/widget-blue.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "WIDGET-BLUE",
          "price": "29.00",
          "compare_at_price": "39.00",
          "available": true,
          "option1": "Blue"
        }
      ]
    },
    {
      "id": 102,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "bright-red-widget",
      "title": "Bright Red Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A colorful durable accessory with helpful product measurements, materials information and intended use explained clearly.</p>",
      "images": [],
      "variants": [
        {
          "id": 1002,
          "sku": "WIDGET-RED",
          "price": "21.00",
          "available": false,
          "option1": "Red"
        }
      ]
    }
  ],
  "previousProducts": [
    {
      "id": 101,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "sky-blue-widget",
      "title": "Sky Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/widget-blue.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "WIDGET-BLUE",
          "price": "35.00",
          "compare_at_price": "39.00",
          "available": false,
          "option1": "Blue"
        }
      ]
    }
  ],
  "competitorProducts": [
    {
      "id": 201,
      "storeHost": "sample-competitor.myshopify.com",
      "handle": "blue-competitor-widget",
      "title": "Competitor Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/competitor-blue.jpg",
          "alt": "Blue accessory"
        }
      ],
      "variants": [
        {
          "id": 2001,
          "sku": "WIDGET-BLUE",
          "price": "27.50",
          "available": true,
          "option1": "Blue"
        }
      ]
    }
  ],
  "publicStores": [],
  "currencyByStore": {
    "demo-shop.myshopify.com": "USD",
    "sample-competitor.myshopify.com": "USD"
  },
  "costBySku": {
    "WIDGET-BLUE": "12.00"
  },
  "maxPages": 3,
  "pageSize": 100,
  "fullSnapshotConfirmed": false
}
```

# Actor output Schema

## `results` (type: `string`):

Download rows from the latest run in JSON/CSV.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "products": [
        {
            "id": 101,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "sky-blue-widget",
            "title": "Sky Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [
                {
                    "src": "https://cdn.example.org/widget-blue.jpg",
                    "alt": ""
                }
            ],
            "variants": [
                {
                    "id": 1001,
                    "sku": "WIDGET-BLUE",
                    "price": "29.00",
                    "compare_at_price": "39.00",
                    "available": true,
                    "option1": "Blue"
                }
            ]
        },
        {
            "id": 102,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "bright-red-widget",
            "title": "Bright Red Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A colorful durable accessory with helpful product measurements, materials information and intended use explained clearly.</p>",
            "images": [],
            "variants": [
                {
                    "id": 1002,
                    "sku": "WIDGET-RED",
                    "price": "21.00",
                    "available": false,
                    "option1": "Red"
                }
            ]
        }
    ],
    "previousProducts": [
        {
            "id": 101,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "sky-blue-widget",
            "title": "Sky Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [
                {
                    "src": "https://cdn.example.org/widget-blue.jpg",
                    "alt": ""
                }
            ],
            "variants": [
                {
                    "id": 1001,
                    "sku": "WIDGET-BLUE",
                    "price": "35.00",
                    "compare_at_price": "39.00",
                    "available": false,
                    "option1": "Blue"
                }
            ]
        }
    ],
    "competitorProducts": [
        {
            "id": 201,
            "storeHost": "sample-competitor.myshopify.com",
            "handle": "blue-competitor-widget",
            "title": "Competitor Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [
                {
                    "src": "https://cdn.example.org/competitor-blue.jpg",
                    "alt": "Blue accessory"
                }
            ],
            "variants": [
                {
                    "id": 2001,
                    "sku": "WIDGET-BLUE",
                    "price": "27.50",
                    "available": true,
                    "option1": "Blue"
                }
            ]
        }
    ],
    "publicStores": [],
    "currencyByStore": {
        "demo-shop.myshopify.com": "USD",
        "sample-competitor.myshopify.com": "USD"
    },
    "costBySku": {
        "WIDGET-BLUE": "12.00"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "products": [
        {
            "id": 101,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "sky-blue-widget",
            "title": "Sky Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [{
                    "src": "https://cdn.example.org/widget-blue.jpg",
                    "alt": "",
                }],
            "variants": [{
                    "id": 1001,
                    "sku": "WIDGET-BLUE",
                    "price": "29.00",
                    "compare_at_price": "39.00",
                    "available": True,
                    "option1": "Blue",
                }],
        },
        {
            "id": 102,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "bright-red-widget",
            "title": "Bright Red Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A colorful durable accessory with helpful product measurements, materials information and intended use explained clearly.</p>",
            "images": [],
            "variants": [{
                    "id": 1002,
                    "sku": "WIDGET-RED",
                    "price": "21.00",
                    "available": False,
                    "option1": "Red",
                }],
        },
    ],
    "previousProducts": [{
            "id": 101,
            "storeHost": "demo-shop.myshopify.com",
            "handle": "sky-blue-widget",
            "title": "Sky Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [{
                    "src": "https://cdn.example.org/widget-blue.jpg",
                    "alt": "",
                }],
            "variants": [{
                    "id": 1001,
                    "sku": "WIDGET-BLUE",
                    "price": "35.00",
                    "compare_at_price": "39.00",
                    "available": False,
                    "option1": "Blue",
                }],
        }],
    "competitorProducts": [{
            "id": 201,
            "storeHost": "sample-competitor.myshopify.com",
            "handle": "blue-competitor-widget",
            "title": "Competitor Blue Everyday Widget",
            "vendor": "PAL Demo",
            "product_type": "Accessories",
            "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
            "images": [{
                    "src": "https://cdn.example.org/competitor-blue.jpg",
                    "alt": "Blue accessory",
                }],
            "variants": [{
                    "id": 2001,
                    "sku": "WIDGET-BLUE",
                    "price": "27.50",
                    "available": True,
                    "option1": "Blue",
                }],
        }],
    "publicStores": [],
    "currencyByStore": {
        "demo-shop.myshopify.com": "USD",
        "sample-competitor.myshopify.com": "USD",
    },
    "costBySku": { "WIDGET-BLUE": "12.00" },
}

# Run the Actor and wait for it to finish
run = client.actor("practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "products": [
    {
      "id": 101,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "sky-blue-widget",
      "title": "Sky Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/widget-blue.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "WIDGET-BLUE",
          "price": "29.00",
          "compare_at_price": "39.00",
          "available": true,
          "option1": "Blue"
        }
      ]
    },
    {
      "id": 102,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "bright-red-widget",
      "title": "Bright Red Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A colorful durable accessory with helpful product measurements, materials information and intended use explained clearly.</p>",
      "images": [],
      "variants": [
        {
          "id": 1002,
          "sku": "WIDGET-RED",
          "price": "21.00",
          "available": false,
          "option1": "Red"
        }
      ]
    }
  ],
  "previousProducts": [
    {
      "id": 101,
      "storeHost": "demo-shop.myshopify.com",
      "handle": "sky-blue-widget",
      "title": "Sky Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/widget-blue.jpg",
          "alt": ""
        }
      ],
      "variants": [
        {
          "id": 1001,
          "sku": "WIDGET-BLUE",
          "price": "35.00",
          "compare_at_price": "39.00",
          "available": false,
          "option1": "Blue"
        }
      ]
    }
  ],
  "competitorProducts": [
    {
      "id": 201,
      "storeHost": "sample-competitor.myshopify.com",
      "handle": "blue-competitor-widget",
      "title": "Competitor Blue Everyday Widget",
      "vendor": "PAL Demo",
      "product_type": "Accessories",
      "body_html": "<p>A reusable everyday accessory with durable materials, practical sizing and detailed care instructions for reliable daily use.</p>",
      "images": [
        {
          "src": "https://cdn.example.org/competitor-blue.jpg",
          "alt": "Blue accessory"
        }
      ],
      "variants": [
        {
          "id": 2001,
          "sku": "WIDGET-BLUE",
          "price": "27.50",
          "available": true,
          "option1": "Blue"
        }
      ]
    }
  ],
  "publicStores": [],
  "currencyByStore": {
    "demo-shop.myshopify.com": "USD",
    "sample-competitor.myshopify.com": "USD"
  },
  "costBySku": {
    "WIDGET-BLUE": "12.00"
  }
}' |
apify call practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,practical_ai_lab_jp/pal-shopify-commerce-intelligence-suite"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3OKeF4firaTNw3JNb/builds/N9AR3pBlG1nRhCj1L/openapi.json
