53 tools across 14 workflow domains. Generated from the @mcp_tool registry — every signature, credit cost, and scope here matches what the server accepts.
Utility
ping
Return the provided string back to the caller.
Parameters
Any string the caller wants echoed.
Returns
The string you passed in.
Catalog
catalog.list_blanks
List catalog blank products.
Parameters
Optional substring matched case-insensitively against title, name, brand, or vaybel_sku. Common shopper terms are normalized (for example "tee" to "t-shirt" and "women's" to "womens"). Preference words such as "premium" and "best-seller" help interpret the search phrase but do not imply true sales or quality data.
Optional technique filter. Accepts: * A specific provider technique string — "dtg", "cut-sew", "sublimation", "direct-to-fabric", "embroidery", "screen-print". * "aop" as a meta-value meaning "any all-over-print technique". Uses is_aop_technique so the set stays in sync with the rest of the platform. Omit to return products of any technique.
Optional substring matched against the product's human category title (e.g. "hoodie", "tee", "bag") and its provider type classification (e.g. "T-SHIRT", "CUT-SEW"). Case-insensitive — a match on either column includes the product.
Max products returned. Clamped to [1, 100].
Returns
{"products": [...], "count": <int>} — each product carries uuid, vaybel_sku, handle, name, title, type, brand, default_technique, category, product_tier, and genders. Variants are intentionally omitted (fetched per-product later).
Brand DNA
brand_dna.get_brand_dna
Return the persisted Brand DNA for the caller's organization.
Returns
false when the org hasn't generated a Brand DNA yet. Remaining fields will be empty strings / empty lists (not null) so agents can inspect this flag once.
AI-generated summary of the brand identity.
Raw brand description the user originally provided.
Hex color codes.
Typography guidance.
Voice-and-tone descriptor.
Product category names associated with the brand.
Fully-qualified CDN URL for the uploaded logo, or null if none.
AI description of the logo, or null if no logo.
Target audiences. Each: key, label, gender_options, ethnicity_options, age_range ({min, max}). The key + gender_options are what you pass to virtual_model.generate / virtual_model.list and what drive VTO mockups. Virtual models are auto-generated when an audience is created.
brand_dna.set_brand_dna
Fully replace the caller organization's Brand DNA. This write is deterministic for agents: omitted non-logo Brand DNA fields are replaced with empty values. Existing logo fields are preserved unless the optional logo object is supplied.
Parameters
Reviewed brand identity description.
Brand colors as strings or hex codes. Omitted means replace with [].
Typography guidance. Omitted means replace with "".
Voice-and-tone guidance. Omitted means replace with "".
Product type names, slugs, or display terms. Omitted means replace with [].
Business niches. Omitted means replace with [].
Target audiences. Generated Brand DNA audience suggestions are accepted.
Raw source description. Omitted means replace with "".
Legacy category names, also used to resolve product types when product_types is absent.
Optional object with logo_url, logo_s3_key, and/or logo_description to update logo fields.
Returns
Persisted brand description.
Persisted colors.
Persisted typography guidance.
Persisted tone guidance.
Persisted product type names.
Persisted niche rows.
Persisted audience rows.
Whether a trend rerun was queued after the description changed.
Credits
credits.check_credits
Inspect the caller's credit wallet.
Parameters
Optional credit amount to test against the balance. When provided, sufficient reflects whether the org can afford it. 0 just returns the current balance.
Returns
Current credit balance for your organization.
Echo of the required argument.
Whether balance >= required. true when required is 0.
Designs
design.generate_design
Dispatch a design-generation Celery task.
Parameters
catalog.Product uuid (e.g. an AOP blank).
Free-text design brief passed to the AI Design Generator.
Optional catalog.VariantGroup uuid — pin the colorway. Omit to let the pipeline pick a default.
Returns
Opaque async handle. Pass to design.get.
Describes the design.get(..., wait_sec=...) contract.
design.get
Return design-generation status and result fields.
Parameters
The task id returned from design.generate_design.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the task is complete/failed or the timeout expires.
Returns
Same as design_id once known.
Design UUID. null until the pipeline has produced a design.
Fractional progress 0.0-1.0 when known.
design.list_designs
Paginated list of designs for the caller's org, newest first.
Parameters
1-indexed.
Clamped to [1, 100].
Optional case-insensitive substring match against title.
Returns
Each: uuid, title, type, generation_status, generation_stage, generation_progress, generation_error, prompt, catalog_product, catalog_variant_group_uuid, master_design_uuid, referenced_product_design_uuid, trend_match_uuid, created_at.
design.get_design
Return a single design.
Parameters
ProductDesign.uuid.
Returns
See _serialize_design for the shape.
design.get_design_history
Return prior revisions / siblings of a design. Walks both the regen chain (via referenced_product_design / next_product_designs) and the colorway family (via master_design / colorways).
Parameters
ProductDesign.uuid.
Returns
Same shape as list_designs.results, ordered by created_at ascending.
Mockups
mockup.generate_mockup
Dispatch mockup generation for a completed ProductDesign.
Parameters
UUID of the ProductDesign. Must belong to the session org for session-token callers.
Which mockups to make — any of "flat" (product-on-white), "detail_closeup", "vto" (virtual try-on). Defaults to ["flat"].
Required when kinds includes "vto" — the audience whose virtual model wears the design (see brand_dna.get_brand_dna for keys). Call virtual_model.generate first if no model exists.
Optional VTO gender ("men" or "women") — useful for unisex products that support both. Must be a gender the audience and product share and that has a CREATED model. Omit to use the first such gender. One gender per call, matching the studio.
"standard" (raw Printful) or "pro" (AI-enhanced). Defaults to pro. Applies to flats.
Returns
Pass to mockup.get. null when every requested mockup already existed (status complete) — read those with mockup.list_mockups(design_id).
Mockups dispatched (= credits charged); 0 on a no-op.
Describes the mockup.get(..., wait_sec=...) contract.
mockup.get
Return mockup generation status and the generated assets.
Parameters
The task id returned by generate_mockup.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the mockups complete/fail or the timeout expires.
Returns
Fractional progress 0.0-1.0 when known.
Each: id, status, external_key, image_url, video_url, error, stage, progress.
mockup.list_mockups
Paginated mockup list, scoped to the caller's org.
Parameters
Optional ProductDesign.uuid to filter to one design.
Optional MockupStatus value (PREPARING / QUEUED / GENERATING / CREATED / FAILED).
Optional MockupGroup value (e.g. flat_images, vto, lifestyle, shoppable_videos).
1-indexed.
Clamped to [1, 100].
Returns
mockup.get_mockup
Return a single mockup's full detail.
Parameters
mockup.update_mockup_selection
Toggle the selected flag — drives which mockups make it onto a listing's image list when listing.create_listing is run.
Parameters
Mockup.uuid.
True to mark for inclusion, False to deselect.
Returns
Updated mockup payload (same shape as get_mockup).
mockup.submit_mockup_feedback
Record like/dislike feedback on a mockup. Feedback is consumed by the retry flow — calling retry_mockup with feedback set on the row instructs the generator to course- correct on the next pass.
Parameters
Mockup.uuid.
"like" / "dislike" / null to clear.
mockup.retry_mockup
Re-dispatch generation for a CREATED or FAILED mockup. Matches the dashboard's per-mockup retry. The original generation was already billed; retries are free (the worker reuses the same pipeline without a second credit deduction).
Parameters
Mockup.uuid.
Optional free-text feedback merged into the regen conversation history. Omit to reuse any value previously set via submit_mockup_feedback.
Returns
Always "PREPARING" immediately after dispatch.
Product Video
The short marketplace showcase clip attached to a listing — its own domain, not a mockup. Rendered from the design's virtual try-on (VTO) front/back mockups, so generate those first. The agent picks a channel; the aspect ratio is chosen for it (TikTok Shop → 1:1, Etsy → 1:2). Distinct from social content.* videos.
product_video.generate
Dispatch product-video generation for a design. Requires the design's VTO mockups to be ready (mockup.generate_mockup(design_id, kinds=["vto"], audience_key=...) first). Costs 20 credits per video, billed by the worker on successful render (failed renders aren't charged); a balance preflight rejects underfunded batches up front. Idempotent — channels already rendered are skipped (not re-dispatched or re-charged).
Parameters
UUID of the ProductDesign. Must belong to the session org for session-token callers.
Which channels to make a listing video for — any of "tiktok_shop" (1:1 square) or "etsy" (1:2 vertical). Defaults to both. One video per channel; the aspect ratio is chosen for you.
Returns
The product-video ids for the requested channels.
Channels dispatched, aligned with the request.
complete (with no dispatch) when every requested channel already exists.
Describes the product_video.get(design_id, wait_sec=...) contract.
product_video.get
Return a design's product videos and their generation status. Keyed by design_id (videos are design-scoped, one per channel).
Parameters
UUID of the ProductDesign whose videos to read.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when every video completes/fails or the timeout expires.
Returns
Each: id, channel, video_type, status, video_url, aspect_ratio, error.
Virtual Models
virtual_model.list
List the org's virtual models (the on-model identities behind VTO).
Parameters
Optional — restrict to one audience (see brand_dna.get_brand_dna for keys).
Optional — DRAFT, CREATED (usable for VTO), or FAILED.
1-based page number.
Clamped to [1, 100].
Returns
Each: uuid, audience_key, audience_label, gender, ethnicity, age, status, image_url.
Number of models before pagination.
Current page.
Effective page size.
virtual_model.generate
Generate (or top up) virtual models for one audience. Generates one model per gender in the audience that doesn't already have a CREATED one — so this is a safe "fill in what's missing" call. Costs 1 credit per model generated (models auto-created when an audience is first saved are free). When everything already exists it's a no-op (task_id empty, no charge).
Parameters
Audience to generate for (see brand_dna.get_brand_dna).
Returns
The task id; pass to virtual_model.get. null when nothing needed generating.
Models being generated (= credits charged).
Already-existing model ids (when complete).
Describes the virtual_model.get(..., wait_sec=...) contract.
virtual_model.get
Return virtual-model generation status and the resulting models.
Parameters
The task id returned by virtual_model.generate.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when generation completes/fails or the timeout expires.
Returns
Fractional progress 0.0-1.0 when known.
The audience's models and their statuses (same shape as virtual_model.list rows).
Listings
listing.create_listing
Dispatch a draft-listing generation task for a ProductDesign.
Parameters
UUID of the completed ProductDesign to list.
Sales channel. One of "tiktok_shop", "etsy", "shopify".
Optional. Required only when the underlying blank is unisex and you want to override the gender inferred from selected mockups. "mens" or "womens".
Returns
Opaque async handle. Pass to listing.get.
Describes the listing.get(..., wait_sec=...) contract.
listing.get_listing
Return a unified listing payload, resolving the channel automatically.
Parameters
UUID of the parent Listing (the same handle the dashboard uses across TikTok/Etsy/Shopify).
Returns
Listing dict with at minimum uuid, channel, status, content (title/description/images), and channel-native fields (e.g. warehouse, tags).
listing.list_listings
Paginated cross-channel listing index, scoped to the caller's org.
Parameters
Optional. Filter to listings for one ProductDesign.
Optional. One of "tiktok" / "tiktok_shop" / "etsy" / "shopify". Omit to span all channels.
Optional. Comma-separated list of statuses ("DRAFT", "ACTIVE", "FAILED", ...). Case-insensitive.
1-indexed.
Clamped to [1, 100].
Returns
listing.update_listing
Partial update + push the diff to the listing's channel. Only text fields (title / description / tags) are supported today — those are what the provider push actually mirrors to the marketplace. Image and video updates have to go through the channel patch service in a follow-up tool; until that lands, do not accept them here (otherwise local content drifts away from the live listing without anyone knowing).
Parameters
Parent Listing UUID.
New title.
New description.
New tag list. Etsy/Shopify only — passing tags on a TikTok listing is a no-op.
Returns
listing.regenerate_listing_field
AI-regenerate one of title, description, or tags. Mirrors the dashboard's per-field regen button. Does not push to the channel — call update_listing after if you want the channel updated.
Parameters
Parent Listing UUID.
One of "title", "description", "tags".
Returns
listing.publish_listing
Dispatch the channel-specific publish task for a draft listing. For TikTok Shop, warehouse must be assigned on the listing first (set via update_listing with warehouse_id once that field is plumbed, or in the dashboard). For Etsy/Shopify, the listing must be in DRAFT status.
Parameters
Parent Listing UUID.
Returns
Opaque async handle. Pass to listing.get.
Describes the listing.get(..., wait_sec=...) contract.
listing.delete_listing
Delete a draft listing. Only DRAFT listings (or FAILED listings with no channel-side external id) can be deleted.
Parameters
Parent Listing UUID.
Returns
listing.get
Return listing task status and result fields.
Parameters
Task UUID returned from create_listing or publish_listing.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the task is complete/failed or the timeout expires.
Returns
Same as listing_id once known.
Fractional progress 0.0-1.0.
Populated once the worker writes the created or published listing.
Content
content.generate
Dispatch a multi-format social-content generation pipeline. The same Short row covers every output format — the difference is what the worker produces (AI video, slideshow MP4, multi-image post, or single still). Each format bills against a different credit action on success (social_video 40 / social_slideshow 12 / social_carousel 4 / social_single 1).
Parameters
UUID of the parent Listing for a TikTok listing. Non-TikTok listings (Etsy/Shopify) are rejected — the underlying Short.listing FK is to TikTokListing. The resolved buy destination can still be a non-TikTok marketplace.
Video archetype. Must be one of the values defined in short.types.VideoArchetype (e.g. "graphic_led", "try_on", "lifestyle", "unboxing", ...). Used by the video / slideshow pipelines; carousel / single ignore it but still validate it.
One of "lifestyle" or "studio". Drives scene staging for video / slideshow; carousel / single ignore it.
One of "video" (default, AI shoppable video), "slideshow" (Ken Burns over stills + music), "carousel" (multi-image post), or "single" (one image).
Source image CDN URLs. Required (≥1) for carousel/single; single accepts at most one. Allowed (and used as slideshow inputs) for slideshow; allowed but unused for video.
Optional override for the primary CTA sales channel ("tiktok_shop" / "etsy" / "shopify" / "storefront"). Blank/None defers to runtime resolution at publish time.
Returns
The content id — pass to content.get and the social_post.* tools.
Content format the worker will produce.
Describes the content.get(..., wait_sec=...) contract.
content.get
Return content status and generated output fields.
Parameters
UUID returned from content.generate.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the content is complete/failed or the timeout expires.
Returns
Same as content_id.
Raw current_phase: planning, generation, assembly, export, complete, failed.
Fractional progress 0.0-1.0.
0-100 integer.
Content format produced by the worker.
True for video/slideshow (produces an MP4); False for carousel/single (no MP4).
Primary sales channel for CTA copy (e.g. "tiktok_shop", "etsy", "shopify"). Defaults to "tiktok_shop" until resolved at publish time.
Final MP4 URL (video/slideshow only).
Source images (carousel/single — also returned as publishable_image_refs).
Image refs that will be pushed to the per-channel publisher for carousel/single posts.
content.list
List content for the caller's org, newest first.
Parameters
Optional parent Listing.uuid filter.
1-indexed.
Clamped to [1, 50].
Returns
Each: content_id, listing_id, listing_title, status, phase, progress, format, requires_video_assembly, resolved_sales_channel, video_url, image_urls, archetype, short_type, scenes_count, created_at.
content.delete
Delete a content item. Mirrors the dashboard's delete — there's no constraint on phase, so in-progress content items can be deleted (the Celery task is best-effort — deleting the row mid-pipeline leaves the worker writing into a stale parent that no longer exists; the row's gone either way).
Parameters
UUID from generate_content.
Returns
Trends
trend.list_trends
List ranked trends for the caller's org, newest opportunity first.
Parameters
One of "all" / "brand" / "seasonal". Filters by seed_group.
Optional ProductType.search_term filter (e.g. "tshirt", "hoodie").
1-indexed.
Clamped to [1, 100].
Returns
Each: id (uuid), trend_name, seed_group, product_type, search_volume, demand, competition, opportunity, why_it_fits, has_concept, is_dismissed, created_at.
{ all, brand, seasonal } counts for view-switcher UIs.
trend.get_trend_match
Return a single trend with detail fields + any generated concept.
Parameters
TrendMatch.uuid.
Returns
Trend detail dict with component_scores, why_it_fits, and a launch_concept list (one entry per audience+gender pairing, each containing the product blueprint). launch_concept is null if generation hasn't been kicked off yet.
trend.generate_launch_concept
Dispatch launch-concept generation for a trend. The concept is an LLM-generated matrix of audience x gender x product type with prompts, written back to TrendMatch.launch_concept. Generation typically completes in 10-60s; call trend.get with wait_sec=0 for a snapshot or wait_sec>0 to long-poll. Bills CONCEPT_CREATED (2 credits) only when a new job is dispatched. Calling on a trend whose concept is already cached returns the cached concept immediately and is free.
Parameters
TrendMatch.uuid.
Returns
Opaque async handle. Same as match_id.
Populated when status == "complete"; null when newly dispatched.
true only when a new generation was kicked off (and a credit charged).
Describes the trend.get(..., wait_sec=...) contract.
trend.get
Return trend detail plus launch-concept generation status.
Parameters
TrendMatch.uuid returned from trend.generate_launch_concept.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the launch concept is complete/failed or the timeout expires.
Returns
Same as match_id.
Fractional progress 0.0-1.0.
Trend detail fields, including launch_concept once generated.
trend.submit_trend_feedback
Record feedback on a trend (drives the calibration loop).
Parameters
TrendMatch.uuid.
One of "viewed" / "saved" / "dismissed" / "created_concept" / "created_product" / "listed_product".
Optional. The product/listing id associated with the action (used by "created_product" / "listed_product").
Optional 30-day revenue attribution (USD).
Optional 30-day units-sold attribution.
Optional CR attribution (0.0-1.0).
Returns
{"status": "ok"} on success.
trend.list_seasonal_events
Return seasonal events currently in their resolved date window. The seasonal calendar is global (not org-scoped); same data the dashboard's /dashboard/trends seasonal sidebar reads.
Returns
Each: name, event_date, year, resolved_start, resolved_end, country, pod_relevance, prep_lead_weeks, design_themes, audience_affinity, product_affinity, mood_tags, gift_driven, historical_volume_multiplier, counter_themes.
Insights
insight.get_overview
Return chart-free performance KPIs, deltas, channels, and narrative insights.
Parameters
Time range: 7d or 28d. Defaults to 28d.
all, tiktok, etsy, shopify, or instagram. Defaults to all.
Returns
false when no meaningful insight snapshots exist for the period.
Orders, GMV, views, and CVR for the selected channel or all channels.
Period-over-period percent changes for orders, GMV, views, and CVR.
Channel breakdown rows with orders, GMV, views, CTR, and CVR.
Narrative insight rows with type, severity, and message.
insight.list_design_performance
Rank every active design by performance, top to bottom, with paging. Aggregates per-design metrics from the daily analytics snapshots across the range. Covers every design with channel activity (views or orders) in the window — so the bottom of the list is your underperformer/cull signal. Designs with no recorded activity at all are not included.
Parameters
Time range: 7d or 28d. Defaults to 28d.
Sort metric: gmv, orders, or views. Per-design CVR is not available consistently.
1-based page number.
Clamped to [1, 100].
Returns
Per-design rows including product_design_id, title, views, orders, and GMV.
Notes the "designs with activity" coverage limit.
Number of designs before pagination.
Current page.
Effective page size.
insight.get_guidance
Return next-best-action guidance plus stage, revenue, and streak state.
Returns
{key, title, reason, confidence, requires_credits} or null.
Current journey and dashboard stage.
Total revenue in cents and dollars.
Weekly publish streak counters.
Optimize Product
optimize.list_providers
Return the POD providers connected to this org that support import.
Returns
Each: key ("printify" / "printful"), name, optional shop_id.
optimize.list_provider_products
Paginated catalog of importable products from the chosen provider.
Parameters
"printify" or "printful".
Optional. Required for Printify when multiple shops are connected — pick which shop to read from.
1-indexed.
Provider-dependent; the underlying service caps it.
Returns
Each: external_id, title, thumbnail_url, variant_count, is_imported, existing_design_uuid, is_supported, is_vaybel_origin.
optimize.check_duplicate
Has this external product already been imported into this org? Cheaper than list_provider_products when the agent only needs the yes/no for one product.
Parameters
"printify" or "printful".
The provider-side product id.
Returns
optimize.optimize_product
Dispatch the import + listing-discovery pipeline for one product. The Celery task reads the product from the provider, creates a ProductDesign (plus any colorway variants), discovers the linked sales-channel listing if there is one, and renders the design thumbnail. The MCP wrapper itself doesn't bill — downstream design generation and listing operations handle their own credit accounting.
Parameters
"printify" or "printful".
External product id from the provider.
Optional. Printify-only — picks the shop when multiple are connected.
Returns
Opaque async handle. Pass to optimize.get.
Describes the optimize.get(..., wait_sec=...) contract.
optimize.refresh_listing
Re-check the POD provider for a sales-channel listing linked to a design. Useful when the merchant publishes the product on Etsy/TikTok after starting the Vaybel import — the initial import found no channel listing, but refreshing later discovers it and imports it.
Parameters
ProductDesign.uuid from a previous optimize_product dispatch.
Returns
optimize.get
Return optimize-import status and result fields.
Parameters
Task UUID returned from optimize_product.
0 returns an instant snapshot. Positive values long-poll up to that many seconds and return when the task is complete/failed or the timeout expires.
Returns
Same as product_design_uuid once known.
0.0-1.0.
Populates around 40% progress.
Set only if a sales-channel listing was discovered.
Social Post
social_post.generate
Generate per-channel captions + hashtags and persist one social post per channel. Resolves the buy destination per social channel (TikTok Shop when live for TikTok, best non-TikTok marketplace otherwise), runs the AI caption generator with the right CTA guardrails, and upserts one social post per channel (status pending).
Parameters
UUID returned from generate_content.
Subset of ["tiktok", "instagram", "youtube", "x"].
Returns
Each: id, content_id, channel, text, hashtags, link_url, status (pending after generation), post_url, external_id, error, created_at, updated_at, published_at, created (bool, true on first creation).
social_post.list
List the social posts persisted for a content item. Org-scoped (pinned tokens must match the content item's organization).
Parameters
UUID returned from generate_content.
Returns
One row per persisted channel.
social_post.update
Edit caption / hashtags / link on a social post before publish. Allowed only when the row is in pending or failed (publishing or published rows are immutable).
Parameters
UUID of the social post.
New caption text (omit to leave unchanged).
New hashtags list (omit to leave unchanged; each entry may include a leading # which is stripped).
New buy URL. Pass an empty string to clear; omit to leave unchanged.
Returns
same shape as list_social_posts rows.
social_post.publish
Publish persisted social posts to the per-channel publishers. For each channel, runs the format-aware guardrail (e.g. YouTube has no carousel surface) and the atomic pending/failed → publishing transition (so concurrent publish calls cannot double-dispatch the same post), then hands the assembled payload to the per-channel publisher.
Parameters
UUID returned from generate_content.
Subset of ["tiktok", "instagram", "youtube", "x"]. Each channel must have a persisted social post (created via social_post.generate).
Optional TikTok post settings (privacy_level, disable_comment, disable_duet, ...). Required fields when present: privacy_level.
Returns
One entry per requested channel: channel, status, publish_url, external_id, error.