apparelhub-mcp
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| APPARELHUB_API_KEY | Yes | Your ApparelHub API key. Required. Not needed on the hosted connector. | |
| APPARELHUB_MCP_PYTHON | No | Path to the Python 3 interpreter for the local image tools. | python3 |
| APPARELHUB_MCP_TELEMETRY | No | Set 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
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| 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 [#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. [#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 [#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 [#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:
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 [#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 ⚠️ 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.
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 [#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
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 [#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 [#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 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 Each field carries
⚠️ CHECK Big value lists are omitted by default and reported as A field whose A channel with no listing attributes answers [#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 ⛔ 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 ⛔ 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 [#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 ⚠️ 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. ⛔ 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 A value the channel refuses comes back in 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 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
⚠️ TELL THE MERCHANT WHERE THE NUMBERS CAME FROM.
[#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 [#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 [#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). ⛔
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 [#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. [#48e53d] |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 123 tools
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.
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.
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.
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.