agentee
Shop all-over print cotton tees with your AI agent: search, cart, promos, checkout. Human pays.
Should I use this
Quality & Safety
Findings (3)
- HIGH
- LOWin remove_promo
- LOWin prepare_order
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"agentee": {
"url": "https://allover.art/mcp"
}
}
}Remote endpoints
https://allover.art/mcpstreamable-httpWhat it can do
Tool inventory
Tools (22)
š¢search_products(query, theme, section, color, style, ...)
Search the allover.art catalog; returns one card per design (good_id, code, price, url) plus the total match count. Use it for any 'find me a ā¦' request ā list_collections is for curated themed pages, get_product for one card's sizes and fabrics. Filters combine: query is free text ('cat', 'neon koi'); theme is a canonical theme (Cats, Anime, Skulls; comma-separate several); style should follow the shopper's saved fit from get_user_prefs (basic ā tee, oversized ā oversized); max_price is USD. Ranked by relevance with a query, by best-sellers without. No paging: you get the top `limit` (default 24, max 48), so narrow the filters to reach the rest. Adult-only designs are excluded; an unknown color or style returns an error listing the valid values.
Input Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Free-text search, e.g. 'cat' or 'neon koi'."
},
"theme": {
"type": "string",
"description": "Canonical theme filter (Cats, Anime, Skulls, ...); comma-separate several."
},
"section": {
"type": "string",
"enum": [
"mens",
"womens",
"kids"
],
"description": "Catalog section."
},
"color": {
"type": "string",
"enum": [
"Black",
"Grey",
"White",
"Navy",
"Beige",
"Turquoise",
"Pink",
"Brown",
"Red",
"Purple",
"Olive",
"Blue",
"Green",
"Yellow",
"Orange",
"Burgundy",
"Multicolor"
],
"description": "Main color of the print."
},
"style": {
"type": "string",
"enum": [
"tee",
"oversized",
"sleeveless",
"long_sleeve",
"oversized_long_sleeve"
],
"description": "Garment cut: tee, oversized, sleeveless (men's oversized tee without sleeves), long_sleeve or oversized_long_sleeve."
},
"limit": {
"type": "integer",
"description": "Max cards to return (default 24, max 48)."
},
"max_price": {
"type": "number",
"description": "Only items priced at or below this amount, USD."
}
}
}Output Schema
{
"type": "object",
"properties": {
"total": {
"type": "integer",
"description": "Total catalog matches for the filters."
},
"showing": {
"type": "integer",
"description": "Number of cards returned."
},
"items": {
"type": "array",
"description": "Product cards.",
"items": {
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"theme": {
"type": "string"
},
"image": {
"type": "string"
},
"url": {
"type": "string",
"description": "Canonical product page."
}
}
}
},
"error": {
"type": "string",
"description": "Unknown color or style, with the valid values."
}
}
}š¢get_product(code)
Get one product by its code: available sizes, fabrics, the price of each size+fabric variant, and the design's 'about' text. Call it before add_to_cart when the human hasn't picked a size yet or may want another fabric ā a search card doesn't list them. code is the `code` field of a search_products card (the end of its /p/<code> url); add_to_cart then takes the numeric good_id, which this result also returns. Read-only; an unknown code returns error 'product not found'.
Input Schema
{
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Product code from search_products results."
}
},
"required": [
"code"
]
}Output Schema
{
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"theme": {
"type": "string"
},
"image": {
"type": "string"
},
"url": {
"type": "string"
},
"sizes": {
"type": "array",
"items": {
"type": "string"
}
},
"fabrics": {
"type": "array",
"items": {
"type": "string"
}
},
"variants": {
"type": "array",
"description": "Price per size+fabric combination.",
"items": {
"type": "object",
"properties": {
"size": {
"type": "string"
},
"fabric": {
"type": "string"
},
"price": {
"type": "number"
}
}
}
},
"about": {
"type": "string",
"description": "Design description text (may be null)."
},
"error": {
"type": "string",
"description": "Present when the product was not found."
}
}
}š¢list_collections(limit)
List active curated collections ā themed landing pages on allover.art, trending first ā with title, slug and url. Use it when the human wants ideas or a themed page to browse; send them the url. Collections are not a search filter: to find products in a theme, call search_products with theme or query. limit caps the list (default 50, max 100). Read-only.
Input Schema
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Max collections to return (default 50, max 100)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"collections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"slug": {
"type": "string"
},
"title": {
"type": "string"
},
"url": {
"type": "string",
"description": "Collection landing page."
}
}
}
}
}
}š¢view_cart
Show the lines in the user's cart with qty, size, fabric and subtotal. It is the same server-side cart the human sees at allover.art/cart when signed in, so items they added in the browser appear here too. Use it to get the zero-based line index that update_cart_item takes ā re-read after removing a line, since later indexes shift. Prices are as added; for the payable total with fresh prices, promo and shipping use get_order_preview. Read-only.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Cart lines in index order ā this index is what update_cart_item takes.",
"items": {
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"size": {
"type": "string"
},
"fabric": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"qty": {
"type": "integer"
},
"custom": {
"type": "boolean",
"description": "True when the line is a user-generated custom print."
}
}
}
},
"subtotal": {
"type": "number",
"description": "Sum of price x qty over all lines, USD."
},
"currency": {
"type": "string"
},
"checkout_url": {
"type": "string",
"description": "Cart page URL for the human."
},
"error": {
"type": "string",
"description": "Present instead of a cart when the call failed (bad index, unavailable size, ...)."
}
}
}š”add_to_cart(good_id, size, fabric, qty)
Add a catalog product to the user's cart and return the updated cart. good_id comes from a search_products or get_product result; size must be one of get_product's sizes ā omit it to use the shopper's saved default from get_user_prefs. Omit fabric to take the first one offered in that size. qty (default 1) is added: if the same product, size and fabric is already in the cart, that line grows (capped at 99) instead of a new line appearing. An unknown good_id or unavailable size returns an error listing the available sizes, and the cart stays unchanged. For an AI-generated print use add_custom_to_cart; to change a line already in the cart, update_cart_item.
Input Schema
{
"type": "object",
"properties": {
"good_id": {
"type": "integer",
"description": "Numeric product id from search_products/get_product."
},
"size": {
"type": "string",
"description": "Size label; must be one of the product's available sizes. Optional when a default size is saved."
},
"fabric": {
"type": "string",
"description": "Fabric label from get_product, if the product offers a choice."
},
"qty": {
"type": "integer",
"description": "Quantity to add (default 1, max 99)."
}
},
"required": [
"good_id"
]
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Cart lines in index order ā this index is what update_cart_item takes.",
"items": {
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"size": {
"type": "string"
},
"fabric": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"qty": {
"type": "integer"
},
"custom": {
"type": "boolean",
"description": "True when the line is a user-generated custom print."
}
}
}
},
"subtotal": {
"type": "number",
"description": "Sum of price x qty over all lines, USD."
},
"currency": {
"type": "string"
},
"checkout_url": {
"type": "string",
"description": "Cart page URL for the human."
},
"error": {
"type": "string",
"description": "Present instead of a cart when the call failed (bad index, unavailable size, ...)."
}
}
}š¢get_order_status(number, limit)
Look up orders placed with the signed-in account's email ā the latest ones, or one by its number ā with status, total and a tracking page url. Use it for 'where is my order'; for an order not placed yet use get_order_preview. status is e.g. draft (unpaid, from prepare_order), pending_payment, paid, in_production, shipped, delivered or cancelled. number is the full order number such as AO-261023-1234; without it you get the newest orders first (limit default 5, max 20). Read-only: it can't cancel or change an order. An account with no email returns an empty list and a note.
Input Schema
{
"type": "object",
"properties": {
"number": {
"type": "string",
"description": "Exact order number to look up, e.g. AO-261023-1234; omit for the most recent orders."
},
"limit": {
"type": "integer",
"description": "Max orders to return (default 5, max 20)."
}
}
}Output Schema
{
"type": "object",
"properties": {
"orders": {
"type": "array",
"items": {
"type": "object",
"properties": {
"number": {
"type": "string"
},
"status": {
"type": "string"
},
"total": {
"type": "number"
},
"currency": {
"type": "string"
},
"created_at": {
"type": "string",
"description": "ISO 8601 timestamp."
},
"url": {
"type": "string",
"description": "Order tracking page."
}
}
}
},
"note": {
"type": "string",
"description": "Present when the account has no email on file."
}
}
}š“update_cart_item(index, qty, size, fabric)
Change one line already in the cart, addressed by its zero-based index from view_cart: set qty (0 removes the line; max 99) and/or switch size or fabric, which re-prices the line. Pass only what changes. After a removal the lines below move up one index, so re-read view_cart before the next edit. A bad index or an unavailable size/fabric returns an error (with the sizes on offer) and changes nothing. Returns the updated cart. To add a different product use add_to_cart.
Input Schema
{
"type": "object",
"properties": {
"index": {
"type": "integer",
"description": "Zero-based cart line index from view_cart."
},
"qty": {
"type": "integer",
"description": "New quantity; 0 removes the line."
},
"size": {
"type": "string",
"description": "New size for this line (must be available for the product)."
},
"fabric": {
"type": "string",
"description": "New fabric for this line (must be available for the product)."
}
},
"required": [
"index"
]
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Cart lines in index order ā this index is what update_cart_item takes.",
"items": {
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"size": {
"type": "string"
},
"fabric": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"qty": {
"type": "integer"
},
"custom": {
"type": "boolean",
"description": "True when the line is a user-generated custom print."
}
}
}
},
"subtotal": {
"type": "number",
"description": "Sum of price x qty over all lines, USD."
},
"currency": {
"type": "string"
},
"checkout_url": {
"type": "string",
"description": "Cart page URL for the human."
},
"error": {
"type": "string",
"description": "Present instead of a cart when the call failed (bad index, unavailable size, ...)."
}
}
}š“apply_promo(code)
Validate a promo code the human gave you and attach it to the cart. Returns applied=true with the new subtotal, discount, shipping and total, or applied=false with a reason ā an invalid or expired code, or a bundle price in the cart that beats it (codes don't stack with bundle pricing). Codes are case-insensitive and a cart holds one: a valid new code replaces the current one, a rejected one leaves it in place; remove_promo just drops it. Needs at least one item in the cart. Never guess or try codes the human didn't give. The code is re-checked in get_order_preview and prepare_order.
Input Schema
{
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "Promo code exactly as the human gave it (case-insensitive)."
}
},
"required": [
"code"
]
}Output Schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"code": {
"type": "string",
"description": "Normalized promo code (when applied)."
},
"bundle": {
"type": "string",
"description": "Bundle price that beats the code (when applied=false for that reason)."
},
"subtotal": {
"type": "number"
},
"discount": {
"type": "number"
},
"shipping": {
"type": "number"
},
"total": {
"type": "number"
},
"currency": {
"type": "string"
},
"reason": {
"type": "string",
"description": "Why the code was rejected (when applied=false)."
},
"error": {
"type": "string",
"description": "Present when the cart is empty or code is missing."
}
}
}š“remove_promo
Drop the promo code from the cart, so totals go back to full price (a bundle price, if any, still applies). Use it when the human no longer wants the code; it isn't needed before apply_promo, which replaces the code anyway. Safe to repeat: with no code applied or an empty cart it does nothing and still returns applied=false.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean",
"description": "Always false after removal."
}
}
}š¢get_user_prefs
Return the shopper's saved default size and fit. Call this BEFORE asking the user for a size ā if a default is set, apply it automatically (add_to_cart uses it when size is omitted), and search in their fit: search_products style='oversized' for oversized, style='tee' for basic.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"size": {
"type": "string",
"description": "Saved default size, or null."
},
"fit": {
"type": "string",
"description": "Saved fit preference: basic | oversized, or null."
}
}
}š”set_user_prefs(size, fit)
Save the shopper's default size and/or fit on their allover.art account, so later chats can skip asking. Call it only when the human states a size or fit or asks you to remember one; read it back with get_user_prefs. Pass only what they stated: an omitted field keeps its saved value, an empty string clears it. size is XS, S, M, L, XL or 2XLā5XL (case-insensitive); fit is basic or oversized. The saved size fills in add_to_cart when size is omitted, and the fit maps to search_products style (basic ā tee, oversized ā oversized). Any other value returns an error and saves nothing.
Input Schema
{
"type": "object",
"properties": {
"size": {
"type": "string",
"description": "Default size: XS, S, M, L, XL, 2XLā¦5XL; empty string clears it."
},
"fit": {
"type": "string",
"description": "Fit preference: basic or oversized; empty string clears it."
}
}
}Output Schema
{
"type": "object",
"properties": {
"size": {
"type": "string"
},
"fit": {
"type": "string"
},
"error": {
"type": "string"
}
}
}š¢get_saved_addresses
Return up to 5 distinct shipping addresses from the user's past orders (matched by the account email), newest first. For a returning buyer, call it before asking for an address, show the options, and pass the one they pick to set_shipping_address ā this tool only reads and selects nothing. An empty list means no past orders: ask the human for the address.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"addresses": {
"type": "array",
"description": "Up to 5 distinct addresses from past orders, newest first.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"country": {
"type": "string"
},
"city": {
"type": "string"
},
"address": {
"type": "string"
},
"zip": {
"type": "string"
},
"phone": {
"type": "string"
},
"summary": {
"type": "string",
"description": "One-line address summary."
}
}
}
}
}
}š”set_shipping_address(name, country, city, address, zip, ...)
Set the delivery address for the current cart's checkout; get_order_preview and prepare_order use it. Needs at least one item in the cart and replaces any address set before. For a returning buyer, offer get_saved_addresses first and pass the chosen one here. The phone is normalized to international form; if that fails the result carries a warning ā ask the human for the number with its country code, since the courier calls it. Only the required fields and the phone are checked; the street itself is not verified. Missing fields or an empty cart return an error and save nothing. The country can switch the order to local currency (UZS for Uzbekistan).
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Recipient full name."
},
"country": {
"type": "string",
"description": "Destination country: name or 2-letter code, e.g. 'Australia' or 'AU'."
},
"city": {
"type": "string",
"description": "Destination city."
},
"address": {
"type": "string",
"description": "Street, house and apartment in one line."
},
"zip": {
"type": "string",
"description": "Postal / ZIP code; omit where the country has none."
},
"phone": {
"type": "string",
"description": "Recipient phone, ideally with country code, e.g. +61 412 462 423."
}
},
"required": [
"name",
"country",
"city",
"address",
"phone"
]
}Output Schema
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"shipping": {
"type": "object",
"description": "Saved address snapshot.",
"properties": {
"name": {
"type": "string"
},
"country": {
"type": "string"
},
"city": {
"type": "string"
},
"address_line": {
"type": "string"
},
"zip": {
"type": "string"
},
"phone": {
"type": "string"
},
"full_address": {
"type": "string"
}
}
},
"warning": {
"type": "string",
"description": "Phone could not be put in international form ā ask the human for it with the country code."
},
"error": {
"type": "string",
"description": "Missing fields or empty cart."
}
}
}š¢get_shipping_options
List the shipping methods for the current cart with price, ETA and the free-shipping threshold. Today there is one: worldwide tracked shipping, 7ā14 business days, free once the cart subtotal reaches free_shipping_from. Use it to answer 'how much / how long is shipping' or to tell the human how much more gets free shipping. Read-only and works on an empty cart too. Prices here are USD for the cart as it is; the final shipping amount, in the destination's currency, is in get_order_preview.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Pass this to set_shipping_method."
},
"label": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"eta": {
"type": "string"
},
"note": {
"type": "string"
}
}
}
},
"free_shipping_from": {
"type": "number",
"description": "Subtotal (USD) at which shipping becomes free."
}
}
}š”set_shipping_method(option_id)
Select the shipping method for the current cart's checkout by an id from get_shipping_options. Only 'worldwide' exists today and it is already the default, so this call is optional ā use it when the human explicitly picks a method, or once more methods appear. Needs at least one item in the cart; an unknown option_id returns an error and changes nothing. Repeating it is harmless.
Input Schema
{
"type": "object",
"properties": {
"option_id": {
"type": "string",
"description": "Shipping option id from get_shipping_options (currently 'worldwide')."
}
}
}Output Schema
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"shipping_method": {
"type": "string"
},
"error": {
"type": "string",
"description": "Unknown option_id or empty cart."
}
}
}š¢get_order_preview
Show the full order before checkout: re-priced lines, promo or bundle discount (they don't stack ā the better one applies), shipping, the address from set_shipping_address, and the grand total in the order currency (local for some destinations, e.g. UZS for Uzbekistan). Call it once the address is set and show the result to the human for confirmation before prepare_order. Read-only and safe to repeat; prices come from the live catalog, not from the cart. ready_to_prepare stays false while the address is missing or a line is unavailable ā fix what issues lists (update_cart_item, set_shipping_address) first. An empty cart returns an error.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Re-priced order lines.",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"size": {
"type": "string"
},
"qty": {
"type": "integer"
},
"price": {
"type": "number"
},
"custom": {
"type": "boolean"
}
}
}
},
"subtotal": {
"type": "number"
},
"promo_code": {
"type": "string"
},
"bundle": {
"type": "string",
"description": "Bundle price applied instead of the promo code, if any."
},
"discount": {
"type": "number"
},
"shipping": {
"type": "object",
"properties": {
"method": {
"type": "string"
},
"price": {
"type": "number"
}
}
},
"shipping_address": {
"type": "object",
"description": "Address set via set_shipping_address (null if not set)."
},
"total": {
"type": "number"
},
"currency": {
"type": "string"
},
"ready_to_prepare": {
"type": "boolean",
"description": "True when an address is set and all lines are orderable."
},
"issues": {
"type": "array",
"items": {
"type": "string"
},
"description": "Lines that became unavailable, if any."
},
"note": {
"type": "string"
},
"error": {
"type": "string",
"description": "Present when the cart is empty."
}
}
}š”prepare_order
Turn the cart, address and promo into a draft order and return {checkout_url, draft_id, expires_at}. Send checkout_url to the human: checkout opens pre-filled and they review and pay themselves ā the agent never pays. Call it only after showing get_order_preview and getting the human's OK. Each call creates a NEW draft with its own number, so call it once per purchase; the cart itself is not emptied. The draft expires after 48 hours. Prices are re-checked; an empty cart, a missing address or no orderable items return an error (with issues) and create nothing.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"draft_id": {
"type": "string",
"description": "Draft order number."
},
"checkout_url": {
"type": "string",
"description": "Pre-filled checkout link ā send it to the human to review and pay."
},
"expires_at": {
"type": "string",
"description": "ISO 8601 time when the draft expires (48 h)."
},
"total": {
"type": "number"
},
"currency": {
"type": "string"
},
"note": {
"type": "string"
},
"error": {
"type": "string",
"description": "Empty cart, missing address or no orderable items."
},
"issues": {
"type": "array",
"items": {
"type": "string"
}
}
}
}š¢get_studio_options
START HERE for any custom-print request: the menu of generation choices (print placements with plain-language descriptions, products, backgrounds, engines+costs). Present these to the human ā at minimum ask which PLACEMENT and which PRODUCT they want ā before calling generate_custom_print.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"placements": {
"type": "array",
"description": "Print size/position choices.",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"label": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
},
"products": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"label": {
"type": "string"
}
}
}
},
"backgrounds": {
"type": "array",
"items": {
"type": "string"
}
},
"models": {
"type": "array",
"description": "Generation engines with cost notes.",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"label": {
"type": "string"
},
"default": {
"type": "boolean"
}
}
}
},
"note": {
"type": "string"
}
}
}š¢generate_custom_print(prompt, product, background, placement, model, ...)
Generate a CUSTOM t-shirt print from a text prompt (AI, takes 2-10 min). SPENDS THE ACCOUNT OWNER'S STUDIO CREDITS: tell them the cost and their balance and get a yes BEFORE calling this ā never spend silently, and never spend to 'try something' on your own initiative. Credits are earned (20 free on signup, 20 with every tee bought), so a wasted one is a real loss to them. Free exception: preserve=true prints their own image as-is and costs nothing. IMPORTANT: first call get_studio_options and ask the human to pick placement + product (and optionally background); do NOT silently use defaults. Args: prompt (design description), product? (one of ['kids_basic_tshirt_boy', 'kids_basic_tshirt_girl', 'kids_oversize_tshirt_boy', 'kids_oversize_tshirt_girl', 'mens_basic_tshirt', 'mens_oversize_tshirt', 'womens_basic_tshirt', 'womens_oversize_tshirt']), background? (t-shirt background, one of ['washed-beige', 'washed-black', 'washed-blue', 'washed-brown', 'washed-gray', 'washed-green', 'washed-orange', 'washed-pink', 'washed-red', 'washed-yellow', 'watercolor-beige', 'watercolor-blue', 'watercolor-sky']), placement? (print size/position, one of ['portrait_extended', 'square_center', 'chest_small']), model? (nb2 default | gpt-image-2 ā both 1 credit, different styles), image_url? (https link to the user's OWN image ā used as style/subject reference), preserve? (true = print the user's image exactly as-is, no AI redraw ā kids' drawings, own art; FREE, no credits; requires image_url). Returns print_id ā poll get_studio_status until done.
Input Schema
{
"type": "object",
"properties": {
"prompt": {
"type": "string",
"description": "Text description of the design to generate."
},
"product": {
"type": "string",
"description": "Studio product base from get_studio_options (default mens_oversize_tshirt)."
},
"background": {
"type": "string",
"description": "T-shirt background choice (see get_studio_options backgrounds)."
},
"placement": {
"type": "string",
"description": "Print size/position: portrait_extended (default), square_center or chest_small."
},
"model": {
"type": "string",
"description": "Generation engine: nb2 (default) or gpt-image-2 ā both 1 credit."
},
"image_url": {
"type": "string",
"description": "https link to the user's OWN image, used as style/subject reference."
},
"preserve": {
"type": "boolean",
"description": "true = print the image exactly as-is, no AI redraw (free); requires image_url."
}
},
"required": [
"prompt"
]
}Output Schema
{
"type": "object",
"properties": {
"print_id": {
"type": "string",
"description": "Generation id ā poll get_studio_status with it."
},
"status": {
"type": "string"
},
"cost_credits": {
"type": "number",
"description": "Credits spent on this generation."
},
"balance_before": {
"type": "number"
},
"balance_after": {
"type": "number",
"description": "Credits left after this generation."
},
"tell_user": {
"type": "string",
"description": "Say this to the account owner ā what was spent from their balance and what is left."
},
"studio_account_created": {
"type": "boolean",
"description": "Present when a Studio account was auto-created for the user."
},
"signup_bonus": {
"type": "number"
},
"note": {
"type": "string"
},
"error": {
"type": "string",
"description": "e.g. not enough Studio credits, daily limit reached, invalid product."
},
"detail": {
"type": "string"
},
"topup_url": {
"type": "string",
"description": "Where the user can buy credits (present on 'not enough credits')."
}
}
}š¢get_studio_status(print_id)
Poll a custom print started by generate_custom_print. status 'done' and 'failed' are final; anything else means still working ā poll about every 30 seconds (generation takes 2ā10 min) and don't start another generation meanwhile, since an account runs one at a time. When done it returns preview_url (the raw image: embed or attach it so the human sees the print) and design_url (the page to share); then offer add_custom_to_cart with the same print_id. 'failed' carries the reason, and its credits are refunded automatically. Read-only ā polling costs nothing.
Input Schema
{
"type": "object",
"properties": {
"print_id": {
"type": "string",
"description": "Generation id returned by generate_custom_print; the same id goes to add_custom_to_cart."
}
},
"required": [
"print_id"
]
}Output Schema
{
"type": "object",
"properties": {
"print_id": {
"type": "string"
},
"status": {
"type": "string",
"description": "Generation state; 'done' and 'failed' are terminal."
},
"preview_url": {
"type": "string",
"description": "Raw print image (when done) ā embed/attach it so the human sees the print in chat."
},
"design_url": {
"type": "string",
"description": "Shareable Studio design page (when done) ā the link to SHARE with the human."
},
"note": {
"type": "string"
},
"error": {
"type": "string",
"description": "Generation failure reason (credits are refunded)."
},
"detail": {
"type": "string"
}
}
}š¢get_studio_credits
Return the account owner's Studio credit balance; reading it spends nothing. Check it before generate_custom_print so you can tell the human the cost (1 credit per generation with either engine; preserve=true is free) and what will be left. No Studio account yet ā balance 0 and studio_account=false; the first generation creates the account with 20 welcome credits. Every bought tee adds 20 credits, and more can be bought at allover.art/studio.
Input Schema
{
"type": "object",
"properties": {}
}Output Schema
{
"type": "object",
"properties": {
"balance": {
"type": "number",
"description": "Current Studio credit balance."
},
"studio_account": {
"type": "boolean",
"description": "False if the user has no Studio account yet (first generate auto-creates one)."
},
"note": {
"type": "string"
},
"error": {
"type": "string"
},
"detail": {
"type": "string"
}
}
}š”add_custom_to_cart(print_id, product, size, qty)
Put a finished custom print (from generate_custom_print) into the cart as a garment and return the updated cart. Call it once get_studio_status reports done and the human has chosen product and size; for catalog designs use add_to_cart instead. product is the garment the human picked in get_studio_options (default mens_oversize_tshirt); size must exist for it ā an error lists the sizes. Adding the same print on the same product and size again grows that line (max 99). An unfinished print returns 'print is not ready' and nothing is added. Then checkout goes as usual: set_shipping_address ā get_order_preview ā prepare_order.
Input Schema
{
"type": "object",
"properties": {
"print_id": {
"type": "string",
"description": "Finished print id ā get_studio_status must report status=done."
},
"product": {
"type": "string",
"enum": [
"kids_basic_tshirt_boy",
"kids_basic_tshirt_girl",
"kids_oversize_tshirt_boy",
"kids_oversize_tshirt_girl",
"mens_basic_tshirt",
"mens_oversize_tshirt",
"womens_basic_tshirt",
"womens_oversize_tshirt"
],
"description": "Studio garment base, as chosen in get_studio_options (default mens_oversize_tshirt)."
},
"size": {
"type": "string",
"description": "Size label; must be available for the chosen product."
},
"qty": {
"type": "integer",
"description": "Quantity (default 1, max 99)."
}
},
"required": [
"print_id",
"size"
]
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Cart lines in index order ā this index is what update_cart_item takes.",
"items": {
"type": "object",
"properties": {
"good_id": {
"type": "integer"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
},
"product": {
"type": "string"
},
"size": {
"type": "string"
},
"fabric": {
"type": "string"
},
"price": {
"type": "number"
},
"currency": {
"type": "string"
},
"qty": {
"type": "integer"
},
"custom": {
"type": "boolean",
"description": "True when the line is a user-generated custom print."
}
}
}
},
"subtotal": {
"type": "number",
"description": "Sum of price x qty over all lines, USD."
},
"currency": {
"type": "string"
},
"checkout_url": {
"type": "string",
"description": "Cart page URL for the human."
},
"error": {
"type": "string",
"description": "Present instead of a cart when the call failed (bad index, unavailable size, ...)."
}
}
}Recommended Prompts
search_productssearch_productslist_collectionsget_productget_productCommunity
Evidence