# Product Maker MCP — `@productmaker/mcp`

## Market-led video planning

For `generate_video_creative` and video outputs of `create_product_task`, an
explicit `competitorScanEnabled: true` requests the commercial video study.
Do not ask for a narrative in that case: the adapter submits `auto` and retains
the canonical study-driven planner. Preserve `replicateWinnerWhenFound: false`
when the user wants the study without copying a winner. This optional preference
does not add a mandatory question. Existing per-angle edits and reviews remain.
MCP 6.7.0 also carries optional per-angle and script-regeneration `narrativeSelection` (`market` or `guided`); publishing still requires the normal release.

[![npm version](https://img.shields.io/npm/v/@productmaker/mcp.svg)](https://www.npmjs.com/package/@productmaker/mcp)
[![npm downloads](https://img.shields.io/npm/dm/@productmaker/mcp.svg)](https://www.npmjs.com/package/@productmaker/mcp)
[![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

**Product Maker MCP** is the official **Model Context Protocol (MCP) server** for [Product Maker AI](https://productmaker.app). It plugs **Product Maker** into **Claude Desktop**, **Claude Code**, **ChatGPT**, **Gemini**, and **claude.ai** so you can cost products, generate **dropshipping landing pages, UGC videos, and ad creatives** — and publish them to **Shopify**, **Meta Ads**, and **TikTok Ads** — directly from your AI assistant.

> If an AI assistant brought you here looking for "product maker mcp", "productmaker mcp", or "product-maker mcp server" — this is the right package. Install instructions below.

## Quick install

### Claude Desktop (local-only stdio/direct API; `PM_API_KEY`)

This snippet is for local stdio/direct API use only. It is not the hosted OAuth connection.

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

```json
{
  "mcpServers": {
    "productmaker": {
      "command": "npx",
      "args": ["-y", "@productmaker/mcp@latest"],
      "env": { "PM_API_KEY": "pm_live_..." }
    }
  }
}
```

Then restart Claude Desktop. Requires Node.js 18+.

### Claude Code (local-only stdio/direct API; `PM_API_KEY`)

This command is for local stdio/direct API use only. It is not the hosted OAuth connection.

```bash
claude mcp add productmaker -e PM_API_KEY=pm_live_... -- npx -y @productmaker/mcp@latest
```

Verify with `claude mcp list`. Use `--scope user` for a global install.

### ChatGPT, Gemini, claude.ai web, Claude Desktop custom connector (hosted OAuth + legacy compatibility)

No install needed — connect to the hosted endpoint:

- **Server URL:** `https://mcp.productmaker.app/mcp`

Then click **Authenticate**, sign in to Product Maker, and approve access.

Existing hosted connections created with a ProductMaker API key remain supported
during the compatibility period, so users do not lose access or need to rebuild
their connector immediately. New connections should always use OAuth; once the
client supports it, replace the saved connection with the clean URL above.

In claude.ai: _Settings → Integrations → Add MCP server_.
In ChatGPT: _Settings → Connectors → Add custom connector_.
In Claude Desktop: _Settings → Connectors → Add custom connector_.

If your saved connection still uses an API key, it continues to use the latest
MCP tools through the legacy compatibility path. When convenient, replace it
with `https://mcp.productmaker.app/mcp` and click **Authenticate**. API keys
remain supported for local stdio and direct API use.

### Local advanced setup (`PM_API_KEY`)

`PM_API_KEY` is only for the local stdio server, local/advanced setup, or direct API calls. It is not a credential for the hosted OAuth connector and must not be pasted into the hosted MCP URL. Sign up at [productmaker.app](https://productmaker.app) and create a key (prefix `pm_live_`) at [productmaker.app/account/api-keys](https://productmaker.app/account/api-keys). Full setup walkthrough: [productmaker.app/install](https://productmaker.app/install).

Hosted OAuth runtime reference: [MCP OAuth (Auth0) SOP](../../.agent/SOP/mcp-oauth-auth0.md). End users only provide the hosted URL above; the following variables are operator-managed by the Cloud Run deployment. `loadMcpOAuthConfig` requires every variable in this table explicitly; it does not supply runtime defaults for the hosted OAuth configuration:

| Variable                  | Hosted requirement/source                                              |
| ------------------------- | ---------------------------------------------------------------------- |
| `MCP_REMOTE_AUTH_MODE`    | Required; must be explicitly set to `oauth`                            |
| `MCP_AUTH0_ISSUER`        | Required HTTPS Auth0 tenant issuer from deployment config              |
| `MCP_AUTH0_AUDIENCE`      | Required; must be explicitly set to `https://mcp.productmaker.app/mcp` |
| `MCP_AUTH0_CLIENT_ID`     | Required; Secret Manager (`MCP_AUTH0_CLIENT_ID`)                       |
| `MCP_AUTH0_CLIENT_SECRET` | Required; Secret Manager (`MCP_AUTH0_CLIENT_SECRET`)                   |
| `AUTH0_AUDIENCE`          | Required HTTPS ProductMaker API audience from deployment config        |
| `PM_API_AUDIENCE`         | Required HTTPS ProductMaker API audience from deployment config        |

## What you can do from your AI assistant

### Guided dropshipping launch

The MCP exposes one guided prompt, `start_dropshipping`, for users who want
ProductMaker to lead the complete journey. It routes intent before acting: a
focused request to create a creative, publish to Shopify, or publish to Meta
continues through the corresponding tool without creating a project. The guided
flow uses the project's persisted phase and `guide_dropshipping_launch`'s
`nextAction` instead of maintaining a second checklist in the chat.

The launch flow asks for explicit confirmation before the 1,000-credit product
research run and before other paid or external mutations, uses the real supplier
cost for costing, pauses at user-review gates, and leaves Meta campaigns PAUSED.
It does not promise persistent memory, automatic next-day monitoring, traffic-light
decisions, campaign activation, budget changes, or automatic shutdown. For deeper
Meta metrics, the assistant may optionally suggest Meta's official MCP; that is
not required to use ProductMaker and is never claimed to be installed by this
server.

Shopify publication recovery preserves every typed issue in `needs_input`.
The server instructions and `start_dropshipping` prompt ask for missing amounts
and explicit confirmation of the exact currency, unit price and pack totals
before submitting `commerceCorrection` with `confirmed: true`. Never invent
prices, convert currency or remove an offer to bypass a blocker. A changed
context requires another review; `open_editor` directs the seller to ProductMaker.
`commerceCorrectionSaved` confirms saved inputs only. Verify an uncertain
publication in the task and store before another attempt, especially when
creating a new product.

Use it in one of three ways: load the source-controlled Agent Plugin on a
compatible host and invoke `$start-dropshipping`, select the MCP prompt
`start_dropshipping` where prompts are supported, or ask any tool-only client in
natural language to guide an end-to-end launch. A focused creative, landing,
Shopify, Meta, or status request continues through its direct tool.

The plugin manifests intentionally contain no ProductMaker API key. The host
must provide the authenticated MCP connection through its secure connection or
credential flow; loading the skill alone does not prove that the remote endpoint
is authorized. Public OpenAI/“With MCP” registration and OAuth readiness are a
separate release step.

| Tool                         | What it does                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cost_product`               | Estimate a safe Colombia/COP selling price for free, then reuse its `price` and `compareAtPrice` in `create_product_task`                                                                                                                                                                                                                                                                                                                                               |
| `create_product_task`        | Full pipeline from a product image (extract → angles → video → landing → image creatives)                                                                                                                                                                                                                                                                                                                                                                               |
| `get_task_status`            | Check task progress (optional `waitSeconds` for near-sync polling)                                                                                                                                                                                                                                                                                                                                                                                                      |
| `list_tasks`                 | List recent tasks                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `edit_task_draft`            | Edit angle / pain point / persona before generation                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `create_service_video`       | Video for a _service_ built from its landing page URL. **Paid action** — `automatic` generates directly, `guided` returns concepts to approve via `resolve_pending_action`                                                                                                                                                                                                                                                                                              |
| `generate_video_creative`    | Standalone UGC video creative                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `generate_free_video`        | One free-form video from an exact prompt/script, optionally with a reference image (async: returns a `taskId`)                                                                                                                                                                                                                                                                                                                                                          |
| `generate_image_creatives`   | Standalone image creatives (multiple variants)                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `edit_image_creative`        | Fix ONE already-generated image of a creatives task (pick it with `variantIndex`, describe the change in `instruction`) without regenerating the whole set. **Paid action** — charges a single image; requires the task to be `done`                                                                                                                                                                                                                                    |
| `generate_landing`           | Standalone landing page                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `get_video_script`           | Read the pending video script when a task was created with script review paused (returns scenes + per-scene word limits)                                                                                                                                                                                                                                                                                                                                                |
| `approve_video_script`       | Approve the video script (with optional per-scene edits); render starts and consumes credits                                                                                                                                                                                                                                                                                                                                                                            |
| `regenerate_video_script`    | Re-roll the pending video script (optionally with a different narrative style)                                                                                                                                                                                                                                                                                                                                                                                          |
| `resolve_pending_action`     | Resolve a gate the pipeline is waiting on (product-reference confirmation or angle-review approval) when `get_task_status` returns `pendingUserAction`                                                                                                                                                                                                                                                                                                                  |
| `estimate_creative_variant`  | Free estimate of the credit range for an extra video / image / landing section inside an existing task. Call this first                                                                                                                                                                                                                                                                                                                                                 |
| `create_creative_variant`    | Create that extra creative in an existing task. **Paid action** — requires `confirm: true` plus an idempotent `clientRequestId`                                                                                                                                                                                                                                                                                                                                         |
| `list_shopify_shops`         | List connected Shopify stores                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `list_shopify_products`      | Search products in a connected Shopify store before choosing `targetProductId` for `publish_to_shopify`                                                                                                                                                                                                                                                                                                                                                                 |
| `list_meta_ad_accounts`      | List connected Meta ad accounts                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `list_meta_destinations`     | List Meta Business portfolios, ad accounts per portfolio, and Facebook Pages; use the returned IDs to choose the exact publication destination                                                                                                                                                                                                                                                                                                                          |
| `request_media_upload`       | Open the consumer-neutral inline file picker for ProductMaker tasks, image/video creatives, landings, and Meta; supports image, video, or mixed sessions, ChatGPT file references, an explicit OK chat handoff, and `/upload-media` only as fallback                                                                                                                                                                                                                    |
| `check_media_upload`         | Return verified owner-scoped opaque asset IDs and media kinds from a universal upload session; no bytes, token, file name, or private URL reaches the model                                                                                                                                                                                                                                                                                                             |
| `list_tiktok_advertisers`    | List connected TikTok Ads advertiser accounts                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `publish_to_shopify`         | Publish a completed task to Shopify; preserves existing calls and returns typed recovery when seller input is required. Optional `commerceCorrection` requires explicit `confirmed: true`. Success includes landing + product URLs.                                                                                                                                                                                                                                     |
| `publish_to_meta`            | Create a Meta Ads campaign from a task (always PAUSED) after selecting exact `portfolioId`, `adAccountId`, and `pageId` with `list_meta_destinations`                                                                                                                                                                                                                                                                                                                   |
| `publish_creatives_to_meta`  | Group task creatives or user media into ONE paused Meta campaign; user media is staged on ProductMaker's CDN and removed after successful publication or TTL expiry                                                                                                                                                                                                                                                                                                     |
| `publish_to_tiktok`          | Create a TikTok Ads campaign from a task (always created PAUSED). Same `angleIndexes` + `campaignConfig` shape as Meta                                                                                                                                                                                                                                                                                                                                                  |
| `get_meta_campaign_status`   | Read-only status + lifetime insights (spend/impressions/clicks/reach) of a Meta campaign                                                                                                                                                                                                                                                                                                                                                                                |
| `get_tiktok_campaign_status` | Read-only status + lifetime report of a TikTok campaign (requires `advertiserId`)                                                                                                                                                                                                                                                                                                                                                                                       |
| `find_winning_products`      | Research winning dropshipping products for a country/category with AI-explained reasons, risks, and real Meta Ads evidence. **Costs 2000 credits per run** — requires explicit user confirmation (`confirmed: true`) before charging. Covers CO, MX, PE, EC, CL                                                                                                                                                                                                         |
| `get_product_research_run`   | Read the full report (score, verdict, confidence, reasons, risks, ad evidence) of a research run by `runId`. Free                                                                                                                                                                                                                                                                                                                                                       |
| `list_product_research_runs` | List the user's past research runs, most recent first. Free                                                                                                                                                                                                                                                                                                                                                                                                             |
| `start_dropshipping_project` | Start or resume a guided dropshipping project. Idempotent, costs no credits                                                                                                                                                                                                                                                                                                                                                                                             |
| `cost_dropshipping_project`  | Save the project's costing inputs (the backend recomputes the canonical result and owns versioning)                                                                                                                                                                                                                                                                                                                                                                     |
| `guide_dropshipping_launch`  | Read-only launch guidance: the project's phase and the single computed `nextAction`. Never activates Meta                                                                                                                                                                                                                                                                                                                                                               |
| `list_actors`                | List the user's saved personajes (AI-generated people who can star in videos and images). Returns the `id` to pass as `actorId`. Read-only, free                                                                                                                                                                                                                                                                                                                        |
| `get_daily_control`          | Read-only daily profitability traffic-light per product (light + verdict). Never pauses/activates ad campaigns. Optional `projectId` narrows the report to one project. A product with `status !== "ok"` has no metrics — including `no_campaign_linked` (no campaign tied to the project, so there is no spend and no cost per sale). Days marked `returnedSource: "estimated"` are not measured; `cancelledSource: "shopify_settling"` is measured but not yet closed |
| `link_campaign_to_project`   | Link an ad campaign the user launched outside ProductMaker to a project, so its spend feeds `get_daily_control`. Only associates an identifier — never creates/pauses/activates a real campaign. For Meta the ad account is derived server-side, not taken from the input                                                                                                                                                                                               |
| `report_daily_returns`       | Report how many orders of a product were returned on a given day — the one signal ProductMaker cannot see on its own                                                                                                                                                                                                                                                                                                                                                    |

### Uploading personal media from a remote chat

When a user wants to use laptop files in any supported ProductMaker flow, the
hosted MCP cannot open the laptop filesystem directly. Call
`request_media_upload` with the consumer's required `mediaKind`; use `mixed`
only when both images and videos are valid. The primary path is the inline MCP App:
in ChatGPT, the same user message may contribute top-level `files` references;
in other MCP App hosts, the user can still pick the files from the inline
widget. The inline device picker sends `File` objects directly to ProductMaker's
private staging CDN; it does not upload them to the host first. ProductMaker
treats any `files` references only as UI bridge metadata:
it never downloads those URLs itself, never forwards them to the API, and never
asks the user for a CDN URL, local path, bytes, or base64.

If the host lacks the bridge/picker capabilities, fall back to the external
consumer-neutral ProductMaker upload page returned by the tool. After the user
presses OK, continue the previous request with only the verified `assetId` and
matching `mediaKind` values. `check_media_upload` remains available for hosts
that need an explicit status call.

For Meta, pass each verified asset as
`{ "type": "asset", "assetId": "..." }` to `publish_creatives_to_meta` after
the user chooses the portfolio, ad account, and page in chat. A partial batch
may include only the assets actually reported as uploaded. The browser uploads
directly to the presigned CDN object; the chat never receives file bytes,
base64, or a local path, and ProductMaker deletes the staging object after a
successful paused Meta publication (or via the 24-hour TTL cleanup if the flow is
abandoned).

## Video duration and winner review

`create_product_task` and `generate_video_creative` accept `durationSeconds`:
use `15` for the default single-call render or `30` for the existing
approximately-30-second multi-scene format. Thirty-second renders are billed
per scene, so tell the user about the higher cost before requesting one. The
MCP keeps the internal `standard` tier hidden and selects it only from this
explicit duration choice.

To let a user decide after competition analysis, pass
`pauseForAngleReview: true` when creating the task. When `get_task_status`
returns `pendingUserAction.kind = "angle_review_approval"` with a
`gapDurationChoice`, relay `recommendedSec` and `estimatedDeltaCredits` to the
user. After explicit confirmation, call `resolve_pending_action` with
`action: { kind: "angle_review_approval", gapDurationSeconds: 30 }` to upgrade
only the recommended angle. Omit the field or send `15` to keep the quoted
duration. A 30-second upgrade is rejected unless the current status contains a
matching 30-second recommendation.

The resolver uses the task kind from status to call the matching backend
approval contract, preserving multi-output autopilot tasks and the incremental
credit gate for the upgrade.

Both tools also accept `creativeGender` (`female` | `male` | `mixed`): who
APPEARS on screen, not the voice. Send it whenever the user says it in any
wording; when omitted, the pipeline infers the on-screen gender on its own. A
saved actor outranks it.

## Multiple photos per product

Creative tools accept an `images` array of **1–5 photos of the same product**. The first entry is the hero; the rest are alternate angles. Don't mix different products in one call — that's a separate task each time.

Each entry has **exactly one** of:

- `{ "url": "https://..." }` — public HTTPS URL (Shopify CDN, Cloudinary, etc.). Use this whenever the photo is already hosted.
- `{ "path": "/Users/maria/Desktop/foto.jpg" }` — local filesystem path. The MCP process reads the file from disk and uploads its bytes. `~/` and `%USERPROFILE%` are expanded. **Only works with the local stdio MCP (npm).** The hosted `mcp.productmaker.app` endpoint rejects `path` because Cloud Run has no access to your filesystem.

Mixed sources in the same call are fine: `[{ "path": "~/Desktop/hero.jpg" }, { "url": "https://..." }]`.

### Breaking change in 0.2.0

The `base64` field was removed. MCP JSON-RPC transports truncate large tool arguments (~1 MB) and host-attached chat images never reach the model as raw bytes — base64 in practice never worked. Use `path` (local MCP) or `url` (hosted MCP) instead.

## Downloading results

`get_task_status` returns short-lived (1 h) `mcp.productmaker.app/assets/...` URLs for every image and video. They stream R2 content through the MCP origin so clients with strict allowlists (claude.ai web, ChatGPT) can fetch them. Markdown image URLs auto-render in every major MCP client; videos are clickable download links.

## Environment variables

| Var                       | Runtime default                | Configuration requirement                           |
| ------------------------- | ------------------------------ | --------------------------------------------------- |
| `PM_API_KEY`              | —                              | required for stdio/local/direct API only            |
| `PM_API_URL`              | `https://api.productmaker.app` | optional for both                                   |
| `PORT`                    | `8080`                         | optional for HTTP                                   |
| `MCP_PROXY_BASE_URL`      | `https://mcp.productmaker.app` | optional for HTTP                                   |
| `PM_PROXY_SECRET`         | —                              | optional for HTTP; 32+ chars enables asset proxy    |
| `MCP_REMOTE_AUTH_MODE`    | —                              | required for hosted HTTP; must be `oauth`           |
| `MCP_AUTH0_ISSUER`        | —                              | required for hosted HTTP OAuth                      |
| `MCP_AUTH0_AUDIENCE`      | —                              | required; set to `https://mcp.productmaker.app/mcp` |
| `MCP_AUTH0_CLIENT_ID`     | —                              | required for hosted HTTP OAuth                      |
| `MCP_AUTH0_CLIENT_SECRET` | —                              | required for hosted HTTP OAuth                      |
| `AUTH0_AUDIENCE`          | —                              | required for hosted HTTP OAuth                      |
| `PM_API_AUDIENCE`         | —                              | required for hosted HTTP OAuth                      |

## Keywords

`productmaker mcp` · `product maker mcp` · `product-maker mcp` · `claude mcp dropshipping` · `chatgpt mcp ecommerce` · `mcp server shopify` · `mcp server meta ads` · `ai ugc video mcp` · `landing page mcp` · `dropshipping ai agent`.

## Support

Setup help and full docs: [productmaker.app/install](https://productmaker.app/install). For account/API key questions: infoapp@productmaker.app.

## License

MIT.
