Skip to main content
Glama
ApparelHub-AI

apparelhub-mcp

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
APPARELHUB_API_KEYYesYour ApparelHub API key. Required. Not needed on the hosted connector.
APPARELHUB_MCP_PYTHONNoPath to the Python 3 interpreter for the local image tools.python3
APPARELHUB_MCP_TELEMETRYNoSet to `off` to disable the coarse usage signal.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
check_setup_readinessA

What this account already has, what it still needs, and the single next action to take. Returns ready_to_design / ready_to_fulfill / ready_to_sell, a per-store breakdown, and an ordered next_steps list. Start here for any first-time setup, and call it again after each connection to confirm the state actually changed. Read-only, makes no provider calls, and is safe to poll.

[#01f20c]

list_connectable_providersA

Fulfillment providers and sales channels this account may connect, each marked with how it connects: connect_mode "in_chat" means you can complete it here by asking for a credential, "browser" means you must dispatch an authorization link with start_channel_connect and poll. Also returns where the merchant generates the credential, when there is one. Use this before asking a user for anything, so you ask for the right thing.

[#21af2f]

connect_fulfillment_providerA

Connect an API-token fulfillment provider (Printify, Gelato) to a store, entirely in chat. Validates the token first, so a bad token fails before anything is stored. If the token maps to more than one shop the result asks you to pick one and lists them — call again with shop_id set. For Printful use start_channel_connect instead: it needs a browser. Never repeat the token back to the user.

[#98598c]

connect_sales_channelA

Connect an API-key sales channel (WooCommerce, Wix) to a store, entirely in chat. For Shopify and TikTok Shop use start_channel_connect instead: they need a browser. Credentials are write-only and are never returned.

[#c9093d]

start_channel_connectA

Begin a browser-based connection (Printful, Shopify, TikTok Shop, Fourthwall). Shopify additionally requires shop_url, the merchant myshopify domain — ask for it before calling. Returns an authorization URL to give the user. THE CONNECTION IS NOT FINISHED WHEN THIS RETURNS. You must keep polling check_connection_status (passing the same provider_uuid) until it reports connected, then tell the user. The browser tab where they authorize is NOT this conversation and cannot report back to you, so polling is the only way you or they will learn it worked. Poll every few seconds, up to about two minutes, and if it has not landed by then ask whether they finished authorizing rather than giving up silently. If they need to create an upstream account first, let them, then call this again for a fresh link.

[#6d4006]

check_connection_statusA

Poll whether a dispatched connection has completed. Call this repeatedly after start_channel_connect while the user authorizes in their browser, and announce the result when it lands: they cannot see this conversation from the tab they authorized in, so if you do not tell them, nobody does. Read-only, makes no provider call, and is safe to poll every few seconds. connected true means say so and continue setup. connected false means keep waiting. needs_reconnect means retrying will never work and you must dispatch a fresh link with start_channel_connect.

[#807361]

list_my_workspacesA

List the workspaces this account can act in, each with its uuid. Agency / multi-brand accounts have more than one (e.g. a workspace per client); a single account just has Default. The store / product / order / design tools operate on the Default workspace unless you pass workspace=. Use this FIRST to resolve a workspace by name (e.g. a client's name) to the uuid those tools need. Read-only.

[#358d40]

list_my_storesB

List the merchant's ApparelHub stores, each with its fulfillment providers (Printful/Printify) and connected sales channels (Shopify/WooCommerce/Wix). Read-only.

[#739377]

list_my_designsA

List the merchant's generated design images (newest first). Read-only. Use these design_uuids with the design/product tools. Pass on_products=false to find orphan designs (designs not used by any live product), the supported way to audit a workspace for unused designs before archiving them. Pass archived=true to list already-archived designs. A design with no full_url carries processing_status: "pending"/"processing" means it is still being made and is worth polling, while "failed" means it gave up and processing_error says why. Branch on processing_error_code rather than matching the message text, and do not retry a design whose failure is a content block — it will fail the same way every time.

[#58124e]

list_my_productsA

List the merchant's products with their fulfillment and sales-channel sync status. Each channel entry also carries health — what the channel last said about the listing. A channel can remove or deactivate a listing at any time, so check health, not just sync_status: a product can read 'Synced' historically and still be gone. Pass store_uuid to scope to one store; omit for all products. Read-only.

[#06afd6]

list_my_ordersC

List the merchant's recent orders across channels. Read-only.

[#c5f34c]

get_order_detailsB

Full detail for one order: line items, payment + fulfillment status, and shipments/tracking. Read-only.

[#c40849]

browse_catalogA

Browse ONE fulfillment provider's catalog for garments to print on. category is resolved against THAT provider's own taxonomy (providers use different vocabularies for the same idea) and an unknown category is rejected with the valid list rather than quietly returning everything. keyword matches product names across the whole catalog. ALWAYS read warnings in the response: they tell you when your results are narrower than you asked for -- e.g. a category that only exists inside one department. Each garment carries decoration_method / accepts_photoreal (accepts_photoreal absent means the provider publishes no signal -- unchecked, NOT unsuitable). This searches a SINGLE provider: to ask what the whole account can do, or before concluding a garment cannot take a design, use find_garments. Read-only.

[#5e449d]

get_garment_detailsB

Full detail for one garment: the variant matrix (colors/sizes/costs), print templates, ApparelHub pricing floor, and quality tier. Read-only.

[#16a079]

find_garmentsA

Search EVERY fulfillment provider on the account at once for garments matching a capability. USE THIS BEFORE TELLING A USER AN ITEM CANNOT BE BUILT. A capability limit is almost always scoped to one provider, not to the category of garment: one provider carrying only embroidered headwear says nothing about another's printed caps. browse_catalog answers 'what does THIS provider carry'; this answers 'what on this ACCOUNT can take this design'. Provider scope defaults to every provider available — pass providers only to deliberately narrow it. Returns a compact ranked shortlist (confirmed capability first), plus providers_searched so you can state your coverage honestly rather than implying you checked everything. An empty result means nothing matched THESE filters on THESE providers; it is not proof the garment does not exist, and the warnings say so. Read-only.

[#e5ad81]

recommend_garmentA

Recommend a garment type for a design/use-case, encoding ApparelHub's garment trade-offs (BC 3001 vs Comfort Colors, budget vs premium, pricing floors). Returns a pick + rationale + alternatives. Advisory / knowledge-based.

[#66d03b]

list_catalog_providersA

List the fulfillment providers this account can browse catalogs from. Use this to discover valid provider values for browse_catalog / get_garment_details — the set is account-specific and auth-gated on the platform (a provider only appears if this account is entitled to it), so never assume a fixed list. Read-only.

[#f0ed53]

generate_imageA

Generate a design image (split primitive of design_apparel). Returns the raw generated image; follow with process_transparency for apparel that needs a transparent background. Rate-limit errors are classified (model_rate_limited = one model's provider vs platform_rate_limited = this key's ApparelHub throttle vs request_not_sent = the call never reached ApparelHub), and fallback_trail shows any model substitutions.

[#e8fffe]

process_transparencyA

Key a solid background out of a generated image to true RGBA transparency (flood-fill + enclosed-region sweep + tight crop) and upload the result. Runs server-side (Python + Pillow). If the generator produced a tinted/muted green instead of pure #00FF00, it auto-recovers by re-keying in green-dominance mode (safe for art with no bright-green/lime elements). Returns a NEW image_uuid plus keying_mode.

[#3cd7e7]

verify_design_textA

Read the text in a design with local OCR (tesseract) when available, so the agent can confirm spelling. Advisory: pass expected_text to get a match verdict, otherwise the detected text is returned for visual review. has_text is null when OCR is unavailable, meaning UNKNOWN — not "no text"; read the design image yourself in that case.

[#57c0af]

design_apparelA

End-to-end apparel design with the platform lessons baked in: solid-green-background prompt, transparency keying, and (optionally) a local text check. Returns ready-to-use design(s). Streams progress. Set needs_transparency=false for all-over-print products. Rate-limit errors are classified (model_rate_limited = one model's provider vs platform_rate_limited = this key's ApparelHub throttle vs request_not_sent = the call never reached ApparelHub), and each design's fallback_trail shows any model substitutions. This GENERATES new artwork — when the merchant already owns the file (a logo, a brand mark, a cleared cover), use upload_design instead and do not regenerate their mark.

[#d84efc]

iterate_designA

Generate a variation of an existing design via img2img (e.g. "make the cactus blue"). Almost every source supports editing; only Google Imagen 4 is text-to-image-only (rejected). Multi-reference edits (several source images) work on Seedream, Flux 2 Pro, and Wan; slow-model edits return 202 and are polled automatically.

[#63592e]

fit_aspectA

Fit an EXISTING design image to a target aspect ratio without generating a new one. mode="pad" letterboxes it onto a background (keeps the whole design, nothing cropped); mode="crop" center-crops (trims the edges to fill the shape). QUOTA-FREE: this reshapes an existing image and does NOT consume an image-generation credit. Use to adapt a square design to a product's print area (e.g. a tall 9:16 for a phone case or poster, a wide 16:9 for a mug or banner). Returns a NEW design (image uuid + url). Note: for an AI-generated EXTENSION of the borders (outpainting) instead of a flat pad/crop, generate a new image with generate_image at the target size — that DOES use the image-generation quota.

[#9ca805]

archive_designA

Archive a design so it stops showing in the default gallery listing. Reversible with restore_design, and safe: it never touches products that already use the design. This is the right way to retire an unwanted or orphan design. Prefer it over delete_design unless the design must be removed permanently. Find orphan designs first with list_my_designs(on_products=false).

[#16a475]

restore_designA

Restore a previously archived design so it appears in the default gallery listing again. List archived designs with list_my_designs(archived=true).

[#f0d74b]

delete_designA

Permanently delete a design and its stored files. Irreversible. Refused with design_in_use if any live product still uses the design, in which case archive_design is the safe alternative. Use archive_design unless the design genuinely must be erased.

[#02e216]

upload_designA

Upload artwork the merchant ALREADY OWNS and turn it into a design_uuid usable by create_product / ship_product. This is the way to build products from a client's own files — a logo, a brand mark, a cleared cover, a photograph — instead of generating something new. If a client says their mark must not be redrawn, use this; never regenerate or approximate a mark to work around a missing file.

Three ways to supply the file, pick the cheapest one available:

  1. source_url — an https URL the server can fetch. One call, no context cost. Best when the asset is already hosted or reachable by link (the link must not require sign-in).

  2. no source at all — returns a presigned upload_url you PUT the bytes to yourself, then call this tool again with the returned image_uuid to finish. No context cost, full resolution, and the right choice whenever you can make an HTTP request (curl, fetch, requests).

  3. image_base64 — inline bytes. Works anywhere, but costs roughly 350k tokens per megabyte of file, so reserve it for small files when neither of the above is possible.

Accepts PNG, JPEG, WEBP and SVG. SVG is the BEST input for a logo or mark: it is rendered server-side at print resolution, so it stays crisp at any size. Two things must be true of the SVG first — text converted to outlines, and any linked image embedded — otherwise the upload is refused with instructions rather than silently losing that part of the artwork. For pixel art, or any hard-edge raster mark that must stay crisp, pass upscale="pixel" so a small file is enlarged without being smoothed.

[#85542c]

ship_productA

End-to-end pipeline in ONE call: take a design, generate + verify a mockup (one per imported color, so every color variant has a matching mockup), create the product with the correct field names, add all variants, associate with a store, sync to fulfillment, then (optionally) sync to sales channels as DRAFT. Handles EMBROIDERY garments automatically WHEN the garment is actually embroidered: routes the design to the real embroidery placement and attaches thread colors (derived from the design, or pass thread_colors). Headwear is NOT inherently embroidered -- some providers carry printed (DTF) caps that take photoreal art as-is, so check accepts_photoreal on the garment rather than assuming, and call find_garments before concluding a design cannot go on a hat. Face goods (canvas, posters, backpacks, bags, socks, towels, blankets, pillows, cases...) default to print_style "fill": the design is recomposed onto an aesthetically matching background and printed edge-to-edge, so no green-screen background or contrasting borders reach the product. Enforces pricing floors and guards the AQUA-vs-Navy variant trap. Streams progress. PREFER this over chaining create_product + add_variants + sync_to_fulfillment + sync_to_channel yourself — especially for AUTOMATED or SCHEDULED runs — because it guarantees the correct order (store association + fulfillment sync BEFORE any channel sync). Use the split primitives only when you deliberately need a partial/interactive flow.

[#232f74]

create_productA

Create a STANDALONE product from a design (split primitive) — it is NOT placed on any store yet. Applies the correct field names + pricing floor, routes EMBROIDERY garments (caps/beanies) to their real embroidery placement with Printful thread colors (derived or explicit), and defaults face goods (canvas/backpacks/bags/socks/towels/blankets/pillows/cases...) to print_style "fill" (design recomposed onto a matching background, printed edge-to-edge). Set generate_mockup: true to render a garment mockup as the display image (it auto-derives representative variants from the catalog, so you do NOT need mockup_variant_ids) — otherwise the raw design is used as the display image. To get it onto a store and listed, the required sequence is: add_variants -> sync_to_fulfillment(product_uuid, store_uuid) [associates it with the store + syncs to Printful/Printify] -> sync_to_channel [sales channel]. To run that whole pipeline in one call instead, use ship_product.

[#e8704a]

add_variantsB

Add variants to an existing product (split primitive). Resolves provider_variant_ids by color+size from the product's provider options (or pass them explicitly). Warns on the AQUA-vs-Navy trap. Variants must exist before syncing.

[#c9cff4]

sync_to_fulfillmentA

Associate a product with a store AND sync it to that store's fulfillment provider (Printful/Printify). This is the REQUIRED step before sync_to_channel: it both puts the product on the store (a product from create_product is standalone) and creates the manufacturing path the sales-channel listing binds to. Run it after the product has variants.

[#58f859]

sync_to_channelA

Sync one product to a sales channel (WooCommerce/Shopify/Wix) as a listing. PREREQUISITE: the product must first be associated with the store AND synced to its fulfillment provider — call sync_to_fulfillment(product_uuid, store_uuid) FIRST (it does the store association too). If that prerequisite is missing, this tool now AUTO-HEALS it (associate + fulfillment-sync, then retries once) instead of failing with "product not associated with store" — but the clean, explicit order is sync_to_fulfillment then sync_to_channel, and ship_product does the whole pipeline in one call. Defaults to DRAFT — only push live when the user explicitly asks.

[#32962d]

update_productA

Update a product (name, description, price). For a price change that must propagate to synced channels, prefer cascade_price_change. Optionally set tiktok_listing to enrich the TikTok Shop listing (SEO search terms, product highlights, brand, packaging, TikTok-only title/description, and category_id) — applied when the product is synced to a TikTok channel; ignored by other channels. For channel-defined ATTRIBUTES (Material, Style, Washing Instructions...) use set_listing_attributes instead: it validates against the listing category's real schema and tells you which values the channel refused, which this tool cannot.

[#c20857]

set_product_imagesA

Set an existing product's listing images: attach an uploaded photo or a generated lifestyle shot, reorder them, and choose the cover. Use this AFTER the product exists — create_product / ship_product pick the initial mockup themselves.

⚠️ THE LIST REPLACES, IT DOES NOT MERGE. What you send becomes the whole gallery, in the order given. To add one image, READ the current list first and send it back with the new entry in it — sending the new entry alone deletes every other image. Pass images: null to reset the gallery back to the product's provider mockups.

⚠️ ORDER IS FUNCTIONAL, NOT COSMETIC. Channels cap how many images a listing may carry and TRUNCATE IN GALLERY ORDER, so position decides what actually ships: TikTok Shop takes 9, Wix 15, Shopify and WooCommerce are unlimited. On a capped channel an image in position 10 is not a lower-priority image, it is an absent one. Put the images that must survive first. The platform stores at most 20.

Each entry carries provenance. source says where the file came from (mockup / upload / ai_mockup / print_file / unknown). ai_generated is SEPARATE and tri-state on purpose: an uploaded photo may itself have been AI-generated and the platform cannot detect that, so only you can say. Set it truthfully — true, false, or leave it unset when you genuinely do not know. Do not guess it from source.

cover sets the display image independently of order, so the cover need not be first. A cover that is not in the gallery is added to it. Replace the gallery without naming a cover and the cover follows to the new first image.

CONCURRENCY: this reads the product first and passes its version back with the write, so a change someone else made in between is REFUSED rather than silently overwritten. On a conflict the tool re-reads and returns conflict: true with the current images — it does NOT retry, because the list you built was based on a gallery that no longer exists. Rebuild from current_images and call again.

[#781240]

generate_listing_imageA

Generate listing photography for an existing product — an on-model shot, a detail crop, a flat lay, or the product in a real setting.

HOW IT WORKS: this EDITS the product's own rendered mockup. It is not text-to-image, and that is the point — the photo shows the actual colourway and the actual printed design, so it depicts the product a shopper will receive.

⚠️ A PRODUCT WITH NO MOCKUP IS REFUSED, not silently generated from scratch. A from-scratch product photo invents a product that does not exist and publishes it as photography of one that does — a listing-takedown and chargeback risk, not merely a quality problem. On product_has_no_mockup, render a mockup preview first (ship_product / create_product do this) and call again. Raw print artwork does not count as a mockup.

guidance is EXTRA wording folded in on top of the chosen preset — it does NOT replace it, and it cannot override the constraint that keeps the garment, colour and artwork unchanged. Use it for setting or mood ("outdoors at golden hour"), not to restate the product.

COST: this spends an image generation from the account's quota, like any other. Four styles across thirty products is 120 generations — more than some plans allow in total. Check the plan before looping over a catalogue.

By default the image is generated and RETURNED, not attached: putting a machine-made photo on a live storefront is a separate decision from making one. Pass attach: true to append it to the gallery — appended, so existing images are kept, unlike set_product_images which replaces the whole gallery.

[#b24313]

unsync_from_channelA

Remove a product from ONE sales channel, leaving every other channel and the fulfillment provider untouched. The product stays in ApparelHub; only that channel listing goes away. Use this to delist from a single channel — do NOT hand-roll it against the raw unsync endpoint: that endpoint is product-level and defaults to detaching fulfillment AND cascading to every channel, so getting the parameters slightly wrong unsyncs far more than you asked for. To remove a product from EVERYTHING, use archive_product instead.

[#bd6407]

delete_productA

Delete (default) or archive a product. Hard delete cascades to variants; if the product is synced to channels, unsync it first to avoid orphan listings — unsync_from_channel for one channel, archive_product for all of them. (sync_to_channel cannot unsync; it only syncs.)

[#020483]

diagnose_tiktok_listingsA

Diagnose TikTok Shop listing quality and optionally apply TikTok's own recommendations. TikTok grades each listing POOR/FAIR/GOOD and a low grade suppresses reach. Returns, per listing: the current tier, the machine-readable issues behind it (code + how_to_solve + the tier that ONE fix unlocks), and TikTok's recommended search terms / titles / descriptions. READ-ONLY unless you pass apply. apply:['search_terms'] is the safe default action — search terms are hidden listing metadata. Passing 'title' or 'description' replaces merchant-visible copy with machine-generated text, so ask the user first; those land on a TikTok-ONLY override and never rewrite the shared product record (which would also change the Shopify/WooCommerce/Wix listings). Use dry_run to preview. IMPORTANT — TikTok often flags a title WITHOUT offering a replacement, so apply:["title"] returns no_recommendation. That is not a dead end: each listing also carries requirements (the computed target, e.g. 40-150 chars — TikTok's own length rules contradict each other and this is the intersection), building_blocks (the product's real garment/colors/sizes, so you write from facts rather than inventing them), and candidates.title (ready-to-use options, shortest first, each already validated against the requirements). Offer the candidates to the user, or write your own title to the requirements and set it via update_product tiktok_listing.title. Check issues[].fixable_by before acting: photography means the listing needs new imagery, not better writing — report it rather than trying to write around it. ⚠️ diagnosable means "TikTok returned a diagnosis", NOT "this listing is live". TikTok also answers for deactivated and deleted listings, so a catalog can come back entirely diagnosable:true while a third of it is no longer for sale. Read listing_health for liveness: "Removed" is gone, "Needs Attention" is present but not visible to buyers, and null means we have never checked — which is NOT the same as healthy. Do not advise a user to delist something on the strength of diagnosable alone. Tier is a US-market signal. After applying, re-run this tool LATER to see the new tier: TikTok re-grades asynchronously, so the tier does not move the instant an edit lands.

[#a912af]

analyze_what_worksC

Surface insights from the merchant's own products + orders: best sellers, top channel, average order value. Read-only. Own-account signal (cross-merchant intelligence is a future feature).

[#f6f4f3]

auto_optimize_listingsA

Propose (and, with dry_run=false, apply) optimizations across listings. Uses the sales channel's own demand data, so a listing that people SEE but do not buy is flagged for a listing fix rather than archived — that listing is proven demand with broken conversion, and archiving it destroys the best opportunity in the catalogue. Only a listing the channel reports as genuinely inert is ever archived. Where no demand data is available the proposal is "review" and NOTHING is applied. DEFAULTS TO DRY-RUN; applying only ever archives (never deletes, never goes live).

[#170c11]

cascade_price_changeA

Change a product price once and propagate it: the platform cascades to all variants, and (when store_uuid is given) this re-syncs each connected channel so the price is consistent everywhere. Avoids the "changed on one channel, forgot the others" footgun.

[#b8aca8]

set_prices_by_marginA

Set each variant's price to hit a target profit margin off its OWN cost: price = cost / (1 - margin). Reads per-variant production cost (populated after the fulfillment sync), applies a per-variant price, then re-syncs connected channels. Use this instead of one flat price when costs tier by size (larger sizes cost more, so a single price gives a different margin per size — and can go negative on the biggest). Requires store_uuid (cost lives on the store-products list, not product detail).

[#54cd6b]

recover_from_outageA

Find products in a failed sync state (fulfillment or channel) and, with dry_run=false + a store_uuid, retry the syncs. DEFAULTS TO DRY-RUN (diagnose only).

[#57cf54]

verify_design_qualityA

Local QC gate for a design: transparency correctness (alpha, clean corners, white premultiply), resolution, and detected text. Returns a 0-100 score + issues. Needs local Python + Pillow.

[#8e74ec]

check_design_complianceA

Advisory pre-flight for IP / trademark / prohibited-content risk. Scans the prompt/name and any detected text against common protected marks. NOT legal advice, and NOT an image-content trademark check.

[#fba5cb]

verify_mockup_qualityA

QC gate for a rendered product MOCKUP (verify_design_quality checks the design; this checks the render on the garment). Deterministically catches three defects that have actually shipped: an un-keyed chroma-green background printed onto the product, an empty render, and a render too small to judge. It does NOT decide whether the design is upright, clipped, seam-split, or whether every face is printed: those need looking at the image, and a pixel statistic that guessed would be confidently wrong on exactly those cases. It returns a fixed visual_checklist for you to answer by VIEWING the render, so grading is consistent across callers. Treat a clean result as "no hard defect found", not "the mockup is good" until you have answered the checklist.

[#feb72a]

approve_orderA

Approve an order that is awaiting approval, releasing it for fulfillment. For sales-channel (webhook) orders this also auto-submits the order to the fulfillment provider (Printful/Printify). Use when an order is held for review and the user wants to let it proceed.

[#9b6ea5]

unapprove_orderA

Revert an approved order back to pending so it can be reviewed / re-approved. Only works if the order has NOT yet been submitted to the fulfillment provider. Use to undo an approve_order that was done too early.

[#1d050e]

hold_orderA

Put an order on hold with an optional reason, pausing it before it is submitted to fulfillment. Use when the user wants to stop an order from proceeding (e.g. to double-check the design or address). Release it later with approve_order.

[#9a2fd5]

cancel_orderA

Cancel an order. Cancels it locally and, where possible, cancels the draft/order at the fulfillment provider (Printful/Printify). This does NOT refund the customer on the sales channel — the channel is the source of payment. Destructive: only cancel when the user explicitly asks.

[#9e800b]

confirm_orderA

Confirm a DRAFT order to send it into production at the fulfillment provider. Only works for orders in "draft" status that have already been submitted to a provider (have a provider order id). Use after submit_order_to_fulfillment on a "prepare, then I confirm" store.

[#ebe558]

submit_order_to_fulfillmentA

Manually submit an order to its fulfillment provider (Printful/Printify) as a DRAFT. For sales-channel orders this auto-fetches the recipient from the channel. Use to un-stick a paid order that never got submitted; confirm it afterward with confirm_order if the store requires confirmation.

[#437d68]

add_order_itemA

Add an item (e.g. another variant of the same product) to a DRAFT order, before it is confirmed to production. Optionally set custom_price (the new item's per-unit retail price) and/or shipping_cost (the order-level retail shipping the customer pays — NOT the provider's cost); omit them and the variant price / existing shipping are kept. Only works while the order is in "draft" status. Printful and Gelato edit the existing provider draft IN PLACE; Printify has no edit API, so it CANCELS + RE-CREATES the order — the result then carries edit_method="recreated" and a new fulfillment_external_id. Nothing is charged on a draft, so re-creation is safe. Returns 409 "order_not_editable" if the order was already confirmed/submitted to production.

[#f416d1]

remove_order_itemA

Remove a line item from a DRAFT order (the order must keep at least one item). Same provider semantics as add_order_item: Printful/Gelato edit in place, Printify cancels + re-creates. Only works while the order is a draft. Get the order_item_id from get_order_details (each item carries an id).

[#b20b6e]

check_order_statusA

Poll the fulfillment provider for the latest status of an order and update it locally (including any design-approval holds). Read-mostly refresh — safe to call repeatedly. Use to see whether an order has shipped or is on hold at the provider.

[#81b1a2]

reconcile_orderA

Reconcile a sales-channel order with the channel it came from: pull payment / cancellation FROM the channel and push fulfillment status + tracking TO it. Only sales-channel orders can be reconciled (native orders return reconcilable=false). Use to re-sync an order that drifted (e.g. tracking not relayed to the storefront).

[#ac6b88]

list_order_holdsA

List the design-approval holds on an order (active and released). Set refresh=true to also poll the fulfillment provider for newly-discovered holds. Read-only. Use to see why an order is stuck at the provider and get the hold_uuid for approve_order_hold / request_hold_changes.

[#2c7422]

approve_order_holdA

Approve a design-approval hold on an order so the provider can proceed. If the provider can't flip the hold via its API (Printful today), the result is deferred with a dashboard_url to finish the approval manually — the hold stays active until the provider's release fires. Get the hold_uuid from list_order_holds.

[#7b5295]

request_hold_changesA

Request design changes on a held shipment instead of approving it. change_kind is 'minor' (notes REQUIRED — describe the edit) or 'full_replacement' (re-do the design). If the provider can't action it via API (Printful today), the result is deferred with a dashboard_url. Get the hold_uuid from list_order_holds.

[#acd99f]

report_fulfillment_issueA

Report a post-sale fulfillment issue (defect) on an order: the item does not match the approved mockup, poor print quality, damaged in transit, wrong/missing item, late or lost. Creates a tracked issue and computes the provider report window (30 days from delivery). Follow up with check_fulfillment_issue for the provider-ready problem report and resolve_fulfillment_issue to file/close it or create a replacement order.

[#dc88bc]

list_fulfillment_issuesA

List fulfillment issues. With order_uuid: that order's issues plus its report-window eligibility. Without: the workspace-wide issues inbox, filterable by status ('open_any' = open + filed upstream) and store, with limit/offset paging. Read-only.

[#533758]

check_fulfillment_issueA

Fetch one fulfillment issue in full (affected items, evidence attachments, provider claim tracking, resolution) and, by default, the provider-ready problem report: a copy-paste summary_text plus the provider dashboard deep-link where the report must be filed (Printful/Printify accept problem reports only in their own dashboards). Read-only.

[#2f6bdb]

resolve_fulfillment_issueA

Progress a fulfillment issue. action='submit_upstream' records that the problem report was filed with the provider (optionally with their claim reference) and returns the dashboard link + summary. action='resolve' closes it with a resolution_type (reprint, refund_wallet, refund_customer, replacement_order, other, none). action='create_replacement' builds a one-click zero-charge replacement (reship) draft order from the affected items; if it cannot be built automatically (no recipient on the provider record, an unlinked variant, or a replacement already exists) the error says what to do instead.

[#a819f9]

analytics_summaryA

Headline order/merch KPIs for a date range (gross revenue, orders, units, AOV, COGS, gross profit, margin, cancel/refund/hold rates, fulfillment velocity) plus prior-period deltas. Defaults to the last 30 days. Requires an Advanced Analytics plan (Professional or Enterprise). Read-only.

[#6b72a2]

analytics_timeseriesA

KPI trend series over a date range, bucketed by day, week, or month (zero-filled). Each bucket carries gross revenue, gross profit, COGS, order count, units, AOV, average margin, and margin coverage. Requires an Advanced Analytics plan. Read-only.

[#48246d]

analytics_breakdownA

Aggregate KPIs broken down by one dimension: product_type, sales_channel, fulfillment_provider, product, variant, or hold_reason. Rows are sorted for display; overflow past the limit folds into an "(everything else)" row so totals still reconcile. Requires an Advanced Analytics plan. Read-only.

[#127113]

analytics_opsA

Operational health for a date range: fulfillment velocity (payment→submit→ship→deliver averages), order counts, and cancellation / refund / hold rates, plus a hold-reason breakdown. Requires an Advanced Analytics plan. Read-only.

[#ed8ddd]

analytics_portfolioA

Cross-client portfolio: per-workspace (per-client) KPIs plus rolled-up totals — the agency view. Groups store rollups by each store's current workspace over every workspace you can view analytics in. Requires an agency (Enterprise) account with Advanced Analytics; other accounts get a feature_unavailable error. Read-only.

[#65a008]

describe_listing_attributesA

Discover the channel-defined listing fields you can set — TikTok product attributes, eBay item specifics, WooCommerce product attributes — and what is currently set. READ-ONLY. Call this BEFORE set_listing_attributes or set_channel_settings: the field names and their allowed values are defined by the channel, so guessing them gets the value dropped.

Pass product_uuid for one listing, or integration_uuid alone for the shop-wide settings (compliance answers, the shipping template, and a fallback size chart).

BRAND and the per-listing SIZE CHART are per-PRODUCT, not shop-wide — both describe the blank, so a shop selling two blanks needs two values, and a shop-wide size chart would replace the accurate per-garment one on every other listing at once. Ask for them with product_uuid.

Each field carries value_type, cardinality (single vs multi), free_text (whether a value outside the list is accepted) and requirement. Those are separate on purpose: most fields are enumerated AND accept free text, so neither flag alone tells you what is legal. requirement: "conditional" means the field only becomes required once required_when holds — typically after you answer a related question one particular way.

values is what is LIVE ON THE CHANNEL, which is not the same as what was last written from here: platform auto-fills and merchant edits made directly in the channel's own admin show up here too. That drift is usually the most useful thing in the response.

unset_required lists fields that are required and empty. Those are NOT filled in for you, deliberately — several are legal attestations. Left unset, the channel picks its own default or grades the listing down, so they are worth resolving with the merchant.

⚠️ CHECK resolved_for.resolution when it is present. explicit_override means the merchant chose the category. keyword_match means it was GUESSED from the product name, and a wrong guess means these fields belong to a different kind of product entirely — setting attributes against it is worse than setting none. Treat keyword_match as unverified and say so.

Big value lists are omitted by default and reported as allowed_values_count; pass include_values to expand them (one real field carries 647 values).

A field whose value_type is object takes a STRUCTURE, not a string, and publishes its shape in channel_ref.object_schema. Build the value from that schema — size_chart_measurements is one, and import_size_measurements will fill it for you from the fulfillment provider.

A channel with no listing attributes answers supported: false with an empty fields — a real answer, not an error.

[#b71f15]

set_listing_attributesA

Set channel-defined listing attributes on ONE product (Material, Style, Washing Instructions and similar). Call describe_listing_attributes first to learn the field keys and their allowed values.

A PARTIAL WRITE SUCCEEDS. Send four values with one bad and the three good ones are stored while the bad one is reported — you do not have to get them all right at once. A value the channel refuses comes back in rejected with a machine-readable reason and the allowed values echoed, so you can correct it in one more turn rather than guessing. Rejections are never dropped silently.

⛔ NEVER INVENT A VALUE. Relay what the merchant told you. If you cannot get a value from them, leave it UNSET and say so — an unset field is honest, an invented one is not. Do not infer it from the product type, do not copy it from another shop, and do not pick the nearest allowed value because it looks close.

📏 SIZE CHART. US apparel is graded down without one. A chart is normally rendered automatically from the fulfillment provider's real measurements, so most listings need nothing. When one IS flagged, prefer size_chart_measurements (an object — call import_size_measurements to fill it from the provider) over size_chart_template_id: the template id can only come from a human in the channel's own admin, because the channel publishes no way to list, verify or correct one.

⛔ NEVER INVENT MEASUREMENTS. They are what a buyer reads before choosing a size. Do not derive a table from the garment type, do not copy one from a similar product, and do not fill a gap with a plausible number. A malformed table is refused whole, with a reason — nothing is half-applied. A missing cell is fine and renders blank; an invented one means somebody receives a garment that does not fit.

Setting a value does NOT change the live listing on its own — the channel is updated on the next sync. Pass sync: true to push it immediately, or run sync_to_channel afterwards.

[#ef218b]

set_channel_settingsA

Set SHOP-WIDE listing settings for one connected sales channel: product compliance attestations, the shipping template, and a fallback size chart. These apply to every listing on that channel, so they are set once rather than per product. Call describe_listing_attributes with integration_uuid (and no product_uuid) first to see which settings this channel defines and what each one accepts.

⚠️ BRAND and the per-listing SIZE CHART are NOT here — they are per-product (use set_listing_attributes), because both describe the blank rather than the shop. default_size_measurements is the one size-chart setting that is shop-wide, and only as a FALLBACK for listings with no provider measurements of their own. Set it only when the whole catalogue is ONE blank: with a mixed catalogue it would be applied to garments it does not describe.

⛔ SOME OF THESE ARE LEGAL ATTESTATIONS. Product-compliance answers (for example California Proposition 65 questions) are statements the MERCHANT makes about their goods, and they carry legal weight. ⛔ NEVER INVENT A VALUE. Relay what the merchant told you. If you cannot get a value from them, leave it UNSET and say so — an unset field is honest, an invented one is not. Do not infer it from the product type, do not copy it from another shop, and do not pick the nearest allowed value because it looks close. In particular: do not answer "No" because it is usually "No", and do not reason from the product being printed apparel — Proposition 65 covers clothing, and some inks and finishes do contain listed chemicals. Ask the merchant, relay their answer, and if they do not have one, leave it unset and tell them it is outstanding.

Answering one of these questions "Yes" can make a follow-up field required — naming the specific chemicals, from a list of hundreds. That follow-up appears in unset_required and is never filled in for the merchant.

A value the channel refuses comes back in rejected with a machine-readable reason and the allowed values echoed, so you can correct it in one more turn rather than guessing. Rejections are never dropped silently.

Existing listings pick these up on their next sync.

[#40e61c]

import_size_measurementsA

Get the blank's real per-size measurements from its fulfillment provider, in the exact shape size_chart_measurements takes. READ-ONLY. Use this instead of asking a merchant to type a size chart, and never instead of asking them when it comes back unavailable.

It imports nothing by itself — adopting a set of measurements is the merchant's decision. Show them the table, let them correct it, then write it back with set_listing_attributes as size_chart_measurements.

available: false is an ANSWER, not a failure. Branch on reason: • provider_publishes_no_size_guide — this provider has no size-guide API at all (Printify and Gelato), so no product of theirs will ever import. Permanent: ask the merchant for the blank manufacturer's own numbers. • no_size_guide_for_this_blank — the provider does publish guides, just not for this item. Normal for non-apparel. • provider_lookup_unavailable — transient. Retry. • product_has_no_fulfillment_provider — nothing to import from.

⚠️ TELL THE MERCHANT WHERE THE NUMBERS CAME FROM. source names the provider and the catalog item. These are measurements a buyer makes a purchase decision on, published in the merchant's name — present them as the provider's figures for a specific blank, not as something you know.

notes, when present, lists what was adjusted on the way through (a provider sometimes files a measurement under a size outside its own size list). Pass those on rather than dropping them.

[#19618b]

channel_performanceA

What the sales channel reports about each of your listings: impressions, clicks, click-through rate and units sold, plus a state telling you what to do about it. Use this to find listings people SEE but do not BUY — the order-based analytics tools cannot show you those, because to them a listing with 5,000 views and no sales looks identical to one nobody has ever seen. States: winner (scale it), conversion_blocked (lots of views, few clicks — the listing card is losing them), pdp_blocked (they click but do not buy — the product page is losing them), starved (too few views to judge; needs discovery, NOT a rewrite), dead (no activity at all; the only state safe to archive), no_channel_data (synced to the channel, but the channel has never reported it — usually means it is not actually live; check the listing before anything else), insufficient_data (not enough signal, or this channel does not report it). READ summary.shop FIRST. If it says no_channel_traffic, the whole shop is barely being served and no per-listing state means anything yet — the problem is distribution, and editing titles or images cannot fix a listing nobody is shown. Each row says which channel and store it came from — always check that before comparing two rows, since a channel product id is only unique within its own channel. ALWAYS check the coverage block before treating a missing metric as zero. Read-only.

[#73dd2d]

channel_opportunitiesA

The listings wasting the most demand: proven traffic, broken conversion, ranked by how many people saw them and did not buy. This is the natural starting point for an optimisation pass — fix these before touching anything else, because the demand is already there and only the listing is in the way. Also returns per-state counts and, separately, the listings that are genuinely inert (state "dead") and therefore safe to archive. Nothing else is safe to archive. READ shop BEFORE acting on anything else here. If the shop as a whole is getting almost no views, safe_to_archive will be empty and top_opportunities will be thin — not because the listings are fine, but because nothing has been seen enough to judge. That is a distribution problem and no listing edit will move it. Read-only.

[#7c8c30]

channel_coverageA

Which of your connected sales channels report performance data, and which metrics each one supplies. Check this before concluding a listing has no traffic: a channel that reports nothing looks identical to a channel reporting zeros unless you look here. Also flags shops that must be RECONNECTED before performance data can flow. Read-only.

[#df2820]

listing_changesA

What has been changed on your listings, and whether it worked. The other half of channel_performance: that says what to fix, this says whether the last fix landed.

Every shopper-visible change — title, description, images, price, search terms, variants, availability — is recorded automatically when it is made, along with the signal state that prompted it. Once the channel has finalised enough days either side, a verdict is computed on the ONE metric that change should have moved (a title is judged on click-through, not revenue).

⛔ unmeasurable IS THE DEFAULT VERDICT, NOT AN ERROR, and it does not mean the change had no effect. It means the data cannot support a conclusion — most often because the shop is not getting enough views for any single edit to register, in which case the answer is distribution and not more editing. Read verdict_reason before saying anything about a change: no_shop_traffic, window_not_final, metric_not_reported, no_baseline.

confounded means two changes landed close enough together that neither owns the result. Do not attribute it to whichever was most recent.

Read-only. Verdicts settle when read, so a window that closed since you last looked is already answered.

[#a02f68]

list_collectionsC

List a store's product collections (categories/groups), each with its product count and per-channel sync status. Read-only.

[#1d7020]

get_collectionB

Get a single collection by uuid, including its member products and per-channel sync status. Read-only.

[#71cbae]

create_collectionA

Create a new (empty) collection in a store. Provide a name (sent to the platform as the collection title) and an optional description. Add products with add_products_to_collection, then sync_collection to push it to a sales channel.

[#ff2c5e]

update_collectionC

Update a collection's name and/or description. A name change is sent to the platform as the collection title. Editing a synced collection marks it for re-sync.

[#1d73cf]

delete_collectionA

Delete a collection. If it is synced to any sales channel, the platform unsyncs it there first. The member products are NOT deleted, only the grouping.

[#afdbfe]

add_products_to_collectionA

Add one or more products (by uuid) to a collection. The products must already be associated with the store. If the collection is synced to a channel, the products are added there too.

[#e8080a]

remove_product_from_collectionB

Remove a single product from a collection (the product itself is not deleted). If the collection is synced to a channel, the product is removed there too.

[#c2fc5a]

sync_collectionA

Sync a collection to a sales channel (creates/updates the channel-side category and places all products in it that are already synced there). integration_uuid selects which channel; not all channels support collections (e.g. TikTok Shop), which returns a clear "collections_unsupported" error.

[#7f246a]

copy_product_to_workspaceA

Copy a product into another workspace (agency accounts). Non-destructive: the original is untouched and the copy lands as an unsynced DRAFT (no store mapping, fresh variants). Use list_my_workspaces to get the destination workspace uuid. If the product lives in a non-Default workspace, pass source_workspace too.

[#d046a8]

move_product_to_workspaceA

Move a product to another workspace (agency accounts) by re-stamping its workspace. Fails with a 409 (blocking list) if the product is mapped to a store or has orders — copy it instead in that case (check first with check_product_move). Use list_my_workspaces for the destination uuid; pass source_workspace if the product is not in your Default workspace.

[#f36e77]

check_product_moveA

Dry run: report whether a product can be MOVED to another workspace, without changing anything. Returns {eligible, blockers} — a non-empty blockers list (e.g. asset_in_use, asset_has_orders, forbidden_source/destination) means move would fail, so copy instead. Read-only.

[#81f916]

copy_design_to_workspaceA

Copy a generated design image into another workspace (agency accounts). Non-destructive: the original stays put and the copy gets its own duplicated image file. Use list_my_workspaces for the destination uuid; pass source_workspace if the design is not in your Default workspace.

[#3090dc]

move_design_to_workspaceA

Move a generated design image to another workspace (agency accounts). Fails with a 409 (blocking list) if a product that uses the design is mapped to a store or has orders — copy it instead in that case (check first with check_design_move). Use list_my_workspaces for the destination uuid; pass source_workspace if the design is not in your Default workspace.

[#8b8b8a]

check_design_moveA

Dry run: report whether a generated design can be MOVED to another workspace, without changing anything. Returns {eligible, blockers} — a non-empty blockers list (a product using the design is in use, or forbidden_source/destination) means move would fail, so copy instead. Read-only.

[#1e988c]

create_workspaceA

Create a new workspace in the account (agency / Enterprise). Name must be unique within the account. Needs an account-wide key; a tier without the agency feature gets feature_unavailable. Returns the new workspace uuid.

[#51f6a7]

update_workspaceA

Rename a workspace or archive/unarchive it (agency / Enterprise). The Default workspace cannot be archived. Needs an account-wide key.

[#e8ebf4]

check_workspace_deletionA

Dry run: preview deleting a workspace (agency / Enterprise) — the stores that would move to the Default workspace and the members whose assignment would be revoked. Changes nothing. Read-only.

[#bcfd4e]

delete_workspaceA

Delete a workspace (agency / Enterprise). Its stores are reassigned to the Default workspace and member assignments revoked first. The Default workspace cannot be deleted. Preview with check_workspace_deletion. Needs an account-wide key.

[#c566a1]

assign_workspace_memberA

Assign an account member to a workspace with a role, or update their existing role (agency / Enterprise). The target must already be a member of the account (invite_member first). Needs an account-wide key.

[#5ec6df]

unassign_workspace_memberA

Revoke a member's assignment to a workspace (agency / Enterprise). The account owner cannot be unassigned from the Default workspace. Needs an account-wide key.

[#7d3ad6]

move_store_to_workspaceA

Move a store into one of the account's workspaces (agency / Enterprise). This changes who can access the store, so it needs account owner/admin + an account-wide key.

[#9dde84]

get_account_overviewA

Account name, your role, whether the agency feature is enabled, and seat accounting (used / included / billable). Agency / Enterprise; needs an account-wide key. Read-only.

[#bf5472]

get_role_matrixA

The workspace roles and the role → capability matrix, so you can pick a role before assigning a member. Agency / Enterprise; needs an account-wide key. Read-only.

[#894f5c]

list_account_membersA

List account members and their per-workspace assignments (agency / Enterprise). Filterable + paginated. Needs an account-wide key. Read-only.

[#b3bd65]

remove_memberA

Remove a member from the account entirely (agency / Enterprise): all their workspace assignments are revoked and seat billing synced. The account owner cannot be removed. Needs an account-wide key.

[#e5169b]

invite_memberA

Invite someone to the account by email, optionally pre-assigning a workspace + role (agency / Enterprise). An existing ApparelHub user is auto-added immediately; a new email gets a pending invite. Needs an account-wide key.

[#d3c424]

list_invitesA

List the account’s pending invites, each with the target workspace name and a copyable accept URL (agency / Enterprise). Needs an account-wide key. Read-only.

[#0cf62c]

revoke_inviteA

Revoke a pending invite so its token can no longer be used (agency / Enterprise). Needs an account-wide key.

[#8a3ee8]

resend_inviteA

Re-send a pending invite’s email with the SAME token and extend its TTL 14 days (agency / Enterprise). Needs an account-wide key.

[#4dd71c]

accept_inviteA

Accept a pending invite by token. The authenticated key-holder’s email must match the invite. Works on any tier and with a workspace-scoped key (the invitee side). Returns the account + workspace you were added to.

[#e7e5ee]

get_store_settingsA

Read a store's fulfillment workflow + notification settings: fulfillment_mode (auto/confirm/review), approval_authority (human/agent/rules), the margin / high-value / first-time-customer hold guardrails, auto-reconcile, and payment settings. Read-only.

[#3b3cd0]

update_store_settingsA

Update a store's fulfillment workflow / notification settings. Only the fields you pass are changed. fulfillment_mode: "auto" (auto-pilot: paid -> draft -> auto-confirm -> production), "confirm" (auto-draft, you confirm each order), "review" (held before submission for approval). The hold_* guardrails escalate an otherwise-auto/confirm order to a pre-submission review. Set hold_orders_above_amount / hold_below_margin_pct to null to disable that guardrail. hold_channel_risk_review is ON by default and OVERRIDES fulfillment_mode (including "auto"): an order the sales channel is reviewing is never sent to fulfillment while it may still be voided.

[#fe3014]

create_storeA

Create a new ApparelHub store. Only a name is required. The store starts CLOSED — connect a fulfillment provider (Printful/Printify), then call activate_store to make it ACTIVE. In an agency account pass workspace= to create it in a specific client workspace.

[#9d5cbc]

archive_storeA

Archive a store (use instead of delete for stores with order history — order records are kept for accounting, but the store is hidden from the default listing and stops ingesting new orders). Restore it later with unarchive_store. Set disconnect_provider=true to also disconnect every connected fulfillment provider and remove its stored credentials.

[#b85c96]

unarchive_storeA

Restore an archived store. It comes back as CLOSED (or ACTIVE if a fulfillment provider is still connected); if it landed CLOSED, connect a provider and call activate_store to reopen it.

[#468f04]

activate_storeA

Activate a store so it can list products and ingest orders. Requires at least one fulfillment provider (e.g. Printful) to be connected first — otherwise this fails. Use after create_store or unarchive_store once a provider is connected.

[#87c31f]

record_order_paymentA

Record a manual payment on an order that is awaiting payment (payment_status="pending"). Use payment_method="sales_channel" for an order already paid on its storefront (Shopify/WooCommerce/Wix — the channel is the source of payment), or "stripe" for an order taken through ApparelHub's own card flow. This marks the order paid; it does not charge a card.

[#81d42b]

mark_order_no_paymentA

Mark an order as having no payment expected (e.g. a free / comp / sample order). Sets its payment status to "no payment". Use when an order should proceed without a recorded payment.

[#23c7f4]

set_order_payment_methodA

Change the recorded payment method on an order that already has a payment recorded (e.g. correct "stripe" to "sales_channel"). This is a bookkeeping label change; it does not move any money.

[#588a7f]

sync_ordersA

Pull the latest orders from connected fulfillment providers. Pass store_uuid to sync one store; omit it to sync all of your stores. Use to refresh orders that have not come through yet.

[#64e731]

estimate_order_costsA

Estimate production + shipping + tax + total for an order WITHOUT creating it (read-only against the fulfillment provider, no order placed). Give the store, the recipient, and the variants + quantities. Use to preview landed cost before placing an order. AVAILABLE FOR PRINTFUL AND GELATO ONLY: Printify offers no pre-order estimate, so a Printify-fulfilled store returns a refusal rather than a number — do not retry it, and do not present a cross-provider landed-cost comparison that silently omits Printify. Both country_code AND address1 are required; the platform rejects the request without a street address. The variants must already be synced to the fulfillment provider.

[#a2bd48]

get_orders_summaryA

Aggregated stats for the orders dashboard: counts of orders pending approval / awaiting payment / in fulfillment / shipped today, plus today's revenue and profit, and a per-store breakdown. Read-only.

[#88d8a4]

list_pending_fulfillmentsB

List orders in a store that have pending fulfillment data needing attention (used by the reconciliation view). Read-only. Use to find orders that stalled before reaching the provider.

[#80ba1e]

archive_productA

Archive a product: unsync it from every connected sales channel and its fulfillment provider, then hide it. Fails (returns blocking_orders) if any pending order still references its variants — cancel or fulfill those first. Restore it later with restore_product. Use archive rather than delete_product when a product has order history.

[#4b1462]

restore_productA

Restore a previously archived product (sets it back to active). It is not re-synced to any sales channel automatically — sync it again afterward if you want it live. Use to undo archive_product.

[#8d20f7]

get_api_referenceA

Discover the full ApparelHub agent API: returns a compact index of every endpoint (path, methods, summary) from the live OpenAPI spec. Use this when no dedicated tool covers what you need, then call it with api_request. Read-only.

Also returns connector, which reports what THIS server actually serves: its version, and the name of every tool. If a capability seems missing, check that first. A tool listed in connector.tool_names that you cannot call means your own tool list is stale, not that the tool is unbuilt — say so and tell the user to reconnect, rather than reporting the feature as missing.

[#5dc40c]

api_requestA

Escape hatch: make an authenticated request to any ApparelHub agent API endpoint under /agents/v1, as the connected account. PREFER a dedicated tool when one exists (they return clean, guarded results) — use this only for capabilities no tool covers. Call get_api_reference first to find the right path. path is relative (e.g. "orders", "store//settings"); no full URLs. Scoped to the account's own permissions.

[#48e53d]

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.5/5.0

Scored across 123 tools

Disambiguation4/5

Most tools have clearly distinct resource/action targets, and descriptions actively steer between close neighbors (ship_product vs the split primitives, find_garments vs browse_catalog, cascade_price_change vs update_product). Still, with 123 tools there are overlapping clusters—design generation/processing, analytics, and workspace copy/move/check—where misselection remains possible despite the detailed guidance.

Naming Consistency4/5

The dominant convention is snake_case verb_noun (list_my_products, create_product, sync_to_channel, approve_order_hold), used consistently across most resources. A few names deviate into noun phrases or less predictable forms (analytics_summary, channel_performance, listing_changes, api_request), but they remain readable rather than chaotic.

Tool Count1/5

123 tools is an extreme mismatch for a single MCP server, far beyond the 50+ threshold for a 1. Even given ApparelHub's broad domain, this volume imposes severe discoverability and context-selection costs, and many adjacent tools likely could be consolidated or grouped.

Completeness5/5

The surface covers the full lifecycle: design upload/generation/QC/archive, product creation, variants, store/fulfillment/channel sync, ordering, holds, issues, collections, workspaces, members, settings, analytics, and an API escape hatch. No obvious CRUD or lifecycle dead ends are apparent.

Maintenance

ActivityNo data
ResponsivenessUnresponsive