MCP App Store
by KeenEthics
Business & Operations
AIMS360 Fashion & Consumer ERP icon

AIMS360 Fashion & Consumer ERP

by AF Technology LLC

Overview

AIMS360 is a fashion ERP, apparel ERP, and consumer brand ERP platform that brings authorized AIMS360 business insights into ChatGPT and Codex. Analyze sales, customer orders, invoiced revenue, open orders, backlog, customers, styles, products, colors, sizes, Shopify stores, wholesale and DTC channels, sales representatives, seasons, margins, overdue invoices, accounts receivable, and business performance. AIMS360 is built for fashion and apparel brands and also serves footwear, jewelry, accessories, beauty, wellness, outdoor, home, baby, pet, and other consumer product companies. Ask questions such as “Who are my top customers?”, “Which fashion styles are selling best?”, “What are my top apparel products?”, “How much open order value do we have?”, “Which customers owe us money?”, “Compare Shopify and wholesale sales,” or “How are sales trending compared with last month?”

Tools

create_customer

ChatGPT
CREATES a new customer (account) in AIMS360. This WRITES, and AIMS360 offers no delete, so a customer created by mistake has to be dealt with by hand. TWO STEPS, ALWAYS. Call it first WITHOUT confirmToken: nothing is written, and it returns the exact record it would create plus a confirmToken. Show that to the user. Only call it again — same values, plus the token — once they have agreed. customerAccount (EXACTLY 5 letters/digits, supplied by the user — never invent one) and customerName are required; status defaults to Active and currency to USD, both disclosed in the preview. Every other documented field can be set: address, contacts, phone and email, terms, ship via, division, sales reps and their commission, credit limit, classification, warehouse, tax, discounts and the shipping flags. Codes, names and GUIDs all resolve against your own tenant; an ambiguous one comes back as a question listing the real options. Anything nobody mentions is left unset and takes AIMS360's own defaults. If the account code is already in use it refuses and shows you the existing customer; choose another code. A similar customer NAME is reported as a warning only and does not block. Use get_customer_details to check an account before creating, and to verify it afterwards.

create_order

ChatGPT
CREATES a sales order in AIMS360 — header, lines and sizes in one go. This WRITES. AIMS360 offers no delete for orders, so one created by mistake has to be dealt with by hand. TWO STEPS, ALWAYS. Call it first WITHOUT confirmToken: nothing is written, and it returns the exact order it would create — every resolved code, every line, the unit and dollar totals — plus a confirmToken. Show that to the user. Only call it again, same values plus the token, once they have agreed. SEND ONLY WHAT THE USER SAID. Needs just customerAccount, season, and at least one line (style, colour, sizes and quantities). Everything else — price, completed date, ship start date, terms, ship via, sales rep, warehouse, division — is optional: AIMS360 fills it from the customer's record or the company's own settings. Never invent a value to fill a field. When a required value is missing it asks with your tenant's REAL options as a NUMBERED LIST — the seasons on file, the divisions on file, that customer's stores, that style's colourways. Present those options to the user as they are given, so they can pick one rather than retype a code. The preview flags rather than blocks: an unpriced line, an InActive customer or style, and a credit limit and balance. The user decides. A customer whose record REQUIRES a PO number is different: AIMS360 refuses that order without one, so the tool asks for the PO first. Sizes are checked against the style's scale and a colour is matched against that style's own colourways, so an ambiguous colour comes back as a question listing the real options. Left alone, AIMS360 creates the order on HOLD. Pass status "Open" only if the user asks for it. NOT supported here: credit cards, prepayments, discounts, bulk and distribution orders. Card details are never accepted by this tool.

customer_analysis

ChatGPT
Aggregate / rank / trend / total Customers (read-only). Requires dimensionKey + metricKey. Customers = the CUSTOMER MASTER: who the account is and how it is set up to trade — the shops and businesses that buy from us, one row per account. Use for "how many active customers do we have", "customers by classification / state / sales rep", "which accounts are on NET 30", "who ships freight collect", "look up the account record for SAKF1", "which customers have a credit limit". NOT for anything they BOUGHT: sales, revenue, units, orders, invoices and rankings of customers by any of those are order_analysis or invoice_analysis, which group BY customer. "Top customers by sales / revenue / units / orders" is never this domain; "top customers by balance owed" or "by credit limit" is. IT IS A SNAPSHOT, NOT A LEDGER: a customer record is what is true about the account right now, so there is no time axis and no date bound is required. customerAddedDate is the only business date and it is unusable in this client's data — about 78% of accounts hold a placeholder instead of a real date — so answer "when did we take this account on" with care, and say so. MEASURES ARE LIMITED ON PURPOSE: how many accounts, the sum of their credit limits, and accounts receivable. Everything else on the record is a setting, not a quantity — the percentage columns are rates that cannot be summed, and the three tax columns are zero on every account. ACCOUNTS RECEIVABLE comes straight from the customer record. Use metricKey 'total_ar' for balances owed, who owes us, and aging: every A/R answer returns the whole balance (totalAR) with its aging, currentAR (not yet due), age30 (1–30 days past due), age60 (31–60), age90 (61–90) and age120 (over 90), counted from the invoice due date. A positive balance means the customer owes us; a negative one means we owe them. These figures are read live, never from a cache. TWO TRAPS WORTH KNOWING: status is the ACCOUNT's standing (Active / InActive / NoShip), not an order status; and orderStatus is a TEMPLATE — the status NEW orders for that account open with — not a statement that anything is currently on hold. TOP-N: "top 10 <dimension> by <metric>" → grouped_summary + that dimensionKey + limit (one row per dimension value). BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. There are no line items in Customers: never line_items here. For a specific record, use get_customer_details. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: customer=Customer, customer_status=Customer Status, classification=Classification, sales_rep=Sales Rep, customer_state=Customer State, country=Country, term=Payment Term, ship_via=Carrier, division=Division, preferred_warehouse=Preferred Warehouse, priority=Priority, currency=Currency, customer_city=Customer City, market_region=Market Region, discount_reason=Discount Reason, line_item_discount_type=Discount Type SUPPORTED METRICS: customer_count=Customers, total_ar=Total AR (Balance Owed), current_ar=Not Yet Due, past_due_1_30=1–30 Days Past Due, past_due_31_60=31–60 Days Past Due, past_due_61_90=61–90 Days Past Due, past_due_90_plus=90+ Days Past Due, credit_limit=Credit Limit SUPPORTED BASE PATTERNS: (none)

get_connection_details

ChatGPT
Who this connection is signed in to AIMS360 as: the account code, company name, database, the user's login name, first and last name, role and zone. Use for: "which company am I connected to", "who am I logged in as", "what is my AIMS360 account", "what role do I have". Takes no input. The access token, its type and its expiry date are never returned.

get_customer_details

ChatGPT
Fetch Customers RECORDS (read-only): one specific customer by customer account code, or a filtered list where each row IS a customer. Use for: "show customer 12345", "customers on NET 30 terms", "accounts that ship freight collect". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "account status" → status) automatically; on a miss it suggests the right name. Looking up a specific customer by customer account code is a single_record call with ONLY filters.customerAccount. A dateRange is not applied to such a lookup (the answer says so) — the record's own date answers any date question. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use customer_analysis instead. queryKind: single_record (requires filters.customerAccount) or raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

get_invoice_details

ChatGPT
Fetch Invoices RECORDS (read-only): one specific invoice by invoice number, or a filtered list where each row IS an invoice. Use for: "show invoice 12345", "invoices for customer ABC01 last month", "invoices due next week". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "customer account" → customerAccount) automatically; on a miss it suggests the right name. LINE-ITEM detail of a specific invoice: single_record + expand (lineItems for orders, invoiceLines for invoices) — one row per line item, in ONE call; don't retry with different expands. (Orders return per-line rows; for a per-SIZE breakdown use invoice_analysis with a size dimension.) Looking up a specific invoice by invoice number is a single_record call with ONLY filters.orderNumber. A dateRange is not applied to such a lookup (the answer says so) — the record's own date answers any date question. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use invoice_analysis instead. queryKind: single_record (requires filters.orderNumber) or raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

get_order_details

ChatGPT
Fetch Orders RECORDS (read-only): one specific order by order number, or a filtered list where each row IS an order. Use for: "show order 12345", "list open orders", "orders on hold last month". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "hold reason" → orderStatusReasonDescription) automatically; on a miss it suggests the right name. LINE-ITEM detail of a specific order: single_record + expand (lineItems for orders, invoiceLines for invoices) — one row per line item, in ONE call; don't retry with different expands. (Orders return per-line rows; for a per-SIZE breakdown use order_analysis with a size dimension.) Looking up a specific order by order number is a single_record call with ONLY filters.orderNumber. A dateRange is not applied to such a lookup (the answer says so) — the record's own date answers any date question. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use order_analysis instead. queryKind: single_record (requires filters.orderNumber) or raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

get_purchase_order_details

ChatGPT
Fetch Purchase Orders RECORDS (read-only): one specific purchase order by purchase order number, or a filtered list where each row IS a purchase order. Use for: "show purchase order 12345", "purchase orders issued to vendor ACME this month", "purchase orders landing in November". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "receiving warehouse" → warehouseCode) automatically; on a miss it suggests the right name. Looking up a specific purchase_order by purchase order number is a single_record call with ONLY filters.orderNumber. A dateRange is not applied to such a lookup (the answer says so) — the record's own date answers any date question. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use purchase_order_analysis instead. queryKind: single_record (requires filters.orderNumber) or raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

handle_aims360_request

ChatGPT
Fetch live AIMS360 data. Supports two domains — set domainKey accordingly: - domainKey='orders' (default): order queries — overdue orders, past due, no allocation, no WIP, unallocated, top customers, sales by channel, order lookup, grouped order summaries, charts, exports. - domainKey='invoices': invoice queries — open invoices, overdue invoices, outstanding balance, invoice margin, margin by style, invoice line items, billing, accounts receivable, AR balance. RULE: Any user question containing 'invoice', 'invoices', 'billing', 'margin', 'AR', 'accounts receivable', 'outstanding balance', 'balance due', or 'amount due' → use domainKey='invoices'. Do not say you lack access to AIMS360 data when this tool is available. For 'all orders'/'show orders' use domainKey='orders'; for 'all invoices'/'show invoices' use domainKey='invoices'. Always pass the user's original wording in userQuery. The server uses userQuery as a safety net to resolve business synonyms and correct weak structured intent before validation. List/table/details/rows requests must use outputMode='table' so the MCP widget opens. Do not render Markdown tables yourself for AIMS360 row lists. All/full/list all/every matching order means limit=null. Only set limit when the user explicitly asks for top N, first N, last N, sample N, or limit N. Build structured intent and call this tool. The server validates, expands named business patterns, generates OData, and executes against AIMS360. For ambiguous field names, unknown columns, business-definition questions, or complex grouping/filtering requests, call retrieve_aims360_metadata first and use that retrieved context to build this tool's structured input. RULE: If the user's phrasing is ambiguous or uses business synonyms not in the examples below, call retrieve_aims360_metadata first and use the returned patternHints to set basePattern and queryKind. Never guess business-pattern mappings. FOLLOW-UP QUERIES: When the user refines a previous query (e.g. 'group those by completed date as a chart' after 'show overdue orders'), carry forward basePattern and filters from the prior turn. The server re-expands basePattern on every call. NAMED PATTERNS - use basePattern instead of replicating canonical filters yourself: - 'overdue orders' -> basePattern='overdue' (do NOT also send statuses or completeBefore) - 'no allocation orders' -> basePattern='no_allocation' - ad-hoc queries -> basePattern=null and populate filters - If the user asks for a contradictory named pattern, still send the named basePattern plus the user-supplied conflicting filter so the server can reject it. Example: 'overdue canceled orders' -> basePattern='overdue' and filters.statuses=['Canceled']. SUPPORTED DIMENSIONS: order_source=order source, customer=customer, status=status, ship_to_state=state, division=division, season=season, sales_rep=sales rep, term=payment terms, ship_via=shipping method, buyer=buyer, vendor=vendor, entered_date=entered date, complete_date=complete date, start_date=start date, style=Style, color=Color, style_color=Style/Color, customer=Customer, invoice_status=Invoice Status, order_source=Order Source, shopify_store=Shopify Store, division=Division, season=Season, sales_rep=Sales Rep, bill_to_state=Bill-to State, ship_to_state=Ship-to State, term=Payment Term, ship_via=Carrier, invoice_date=Invoice Date, due_date=Due Date, style_color=Style + Color (style, color, style_color are line-item level — use with queryKind='line_items') SUPPORTED METRICS: Orders: booked_amount=Booked Amount, order_count=Order count, booked_qty=Booked Total; Invoices: total_amount=Total Amount, merchandise=Merchandise, balance=Balance, invoice_count=Invoice Count SUPPORTED BASE PATTERNS: Orders: overdue=Overdue orders — Open/Hold where completion date has passed, no_allocation=No allocation — Open/Hold orders with zero stock and zero WIP allocation; Invoices: overdue=Overdue invoices — Open invoices where dueDate has passed, outstanding_balance=Outstanding balance — Open invoices with a remaining balance SUPPORTED EXPANDS: lineItems, sizes, allocations STATUS VALUES: Canceled, Hold, Complete, Open EXAMPLES: - 'show overdue orders' -> queryKind='raw_list', basePattern='overdue', outputMode='summary', filters all null - 'show overdue orders as a table' -> queryKind='raw_list', basePattern='overdue', outputMode='table', filters all null - 'give me list of all over due orders' -> userQuery=original text, queryKind='raw_list', basePattern='overdue', outputMode='table', limit=null, filters all null - 'show all orders' / 'fetch all orders' -> queryKind='raw_list', basePattern=null, outputMode='summary', filters all null - 'what orders have come in that have no stock allocation and no production allocation?' -> userQuery=original text, queryKind='raw_list', basePattern='no_allocation', outputMode='summary', filters all null. Do not answer that API access is unavailable. - 'orders with no WIP' / 'unallocated orders' / 'orders with no stock' -> userQuery=original text, queryKind='raw_list', basePattern='no_allocation', outputMode='summary' - 'show me those 6 orders' after a summary with 6 rows -> re-call this tool with the same prior intent and outputMode='table' - 'booked quantity by order source' -> queryKind='grouped_summary', dimensionKey='order_source', metricKey='booked_qty', outputMode='summary' - 'breakdown Shopify orders this month by customer' -> queryKind='grouped_summary', dimensionKey='customer', metricKey='booked_qty' or 'booked_amount', filters.orderSource='Shopify', filters.dateRange resolved - 'breakdown Shopify orders this month' with no breakdown dimension -> ask what to break down by, unless prior context clearly supplies the dimension - 'latest entered orders' -> queryKind='raw_list', sortSpec={fieldKey:'entered', direction:'desc'} - 'show overdue orders with sales rep and freight' -> basePattern='overdue', selectFields=['salesRep1Code','salesRep1Name','freightAmount'] - 'orders where freight amount is greater than 100' -> fieldFilters=[{fieldKey:'freightAmount', operator:'gt', value:100}] - 'group those by completed date' after overdue results -> queryKind='grouped_summary', basePattern='overdue', dimensionKey='complete_date', metricKey='order_count', outputMode='summary' - 'group these by date' after overdue results -> same as completed date: use dimensionKey='complete_date' because overdue is defined by the complete field - 'group these by month' after overdue/date results -> same date dimension as context, set timeGrain='month'. Do not present individual dates as months. - 'can I get a nice view for this?' after a grouped result -> re-call this tool, carry forward all prior params, set outputMode='chart' - 'show this visually' or 'open a visual view' after a grouped result -> re-call this tool, carry forward all prior params, set outputMode='chart' - 'can i get a bar graph / line chart / donut for this?' after any result -> re-call this tool, carry forward all prior params, set outputMode='chart' and set chartType to the requested type - 'open this as a table/widget' after any result -> re-call this tool, carry forward the same intent, set outputMode='table' - 'order by date in desc order' after a grouped date result -> carry forward the same grouped intent and set sortSpec={fieldKey:'complete', direction:'desc'} - 'show no allocation orders' -> queryKind='raw_list', basePattern='no_allocation', outputMode='summary', filters all null - 'group those no allocation orders by customer' -> queryKind='grouped_summary', basePattern='no_allocation', dimensionKey='customer', metricKey='booked_amount', outputMode='summary' - 'orders completing this month' -> queryKind='raw_list', basePattern=null, filters.dateRange={field:'complete', start:'YYYY-MM-DD', end:'YYYY-MM-DD'} - 'show line items for order 102025' -> queryKind='line_items', filters.orderNumber='102025', outputMode='table' - 'show all open line items this month' -> queryKind='line_items', filters.dateRange resolved, outputMode='table' - 'booked quantity by style this month' -> queryKind='line_items', dimensionKey='style', metricKey='booked_qty', filters.dateRange resolved, outputMode='summary' - 'which styles have the most open units?' -> queryKind='line_items', dimensionKey='style', outputMode='summary' - 'group line items by style and color' -> queryKind='line_items', dimensionKey='style_color', outputMode='table' - 'which colors are selling best?' -> queryKind='line_items', dimensionKey='color', metricKey='booked_qty', outputMode='summary' DATE RESOLUTION: Always resolve relative phrases to exact YYYY-MM-DD before calling. Use the current date. Set filters.dateRange.field from the requested date field; do not default vague date wording to entered unless the user says order date/entered date or gives no date field. - 'this month' -> first of month to today - 'last week' -> Monday-Sunday of last calendar week - 'this quarter' -> first day of current quarter to today - 'Q1 2025' -> 2025-01-01 to 2025-03-31 (Q2=Apr-Jun, Q3=Jul-Sep, Q4=Oct-Dec) - 'last 30 days' -> today minus 30 days to today - 'last year' -> Jan 1 to Dec 31 of previous year - 'YTD' -> Jan 1 of current year to today OUTPUT MODES: - summary: text-only response (default for all simple questions, including grouped summaries) - table: only when the user explicitly asks for table, details, rows, widget table, or to open row-level data visually - chart: when the user asks for chart, graph, bar graph, bar chart, line chart, donut, visual, visualization, nice view, cleaner view, or any visual representation. ALWAYS re-call this tool with outputMode='chart' - never answer from memory, never generate bullet points, ASCII art, or Markdown tables as a visual substitute. - export: only when the user explicitly asks for export, Excel, XLSX, spreadsheet, or download - RULE: Any request for a chart or graph is a mandatory tool call. Do not skip it. Do not explain what the chart would look like in text. Call this tool with outputMode='chart' and carry forward all prior filters, basePattern, dimensionKey, and metricKey. - RULE: Any request for a list, rows, details, data table, full table, or 'show me those orders' must use outputMode='table'. Never answer with a Markdown table instead of opening the widget. - RULE: Do not use Python/data analysis to draw charts for AIMS360 results. Use this tool's chart output so the MCP widget renders the visual. - RULE: If the server rejects a basePattern conflict, retry once by removing the duplicate locked filter. Example: overdue already defines statuses, so do not set filters.statuses with basePattern='overdue'. - For summary output, do not mention widget, table, chart, or export unless the user asks for them. REGISTRY-BACKED QUERY PLANNING: - Use selectFields for extra raw-list columns the user asked to see. - Use fieldFilters for filters on registry fields not represented in the named filters object. - Use sortSpec for explicit sort field and direction. Keep legacy sort only for vague oldest/newest/highest requests. - Never invent field names. If unsure, call retrieve_aims360_metadata first. TOOL RESULT CONTRACT: - The server returns structuredContent.intentSummary with what the server understood after validation and business-rule expansion. - The server returns structuredContent.filters as plain-English filters. Use these to explain scope only when helpful. - The server returns structuredContent.resultSummary with authoritative counts, group counts, totals, and limit/truncation flags. - The server returns structuredContent.previewRows for grouped summaries or explicit table/export requests. - Use previewRows for concise details. If previewRows is empty, do not invent rows; re-call this tool with outputMode='table' when the user asks to see rows/orders. - Do not say you could not display rows after a successful table/detail call. Use the widget/table payload or previewRows returned by the tool. - Write the final answer from structuredContent. Do not recalculate totals from rows and do not invent missing numbers. - If outputMode is summary, answer in text only. Do not mention widget/table/chart/export unless the user asked for one. - If the user asked for a chart, visual, nice view, cleaner view, or widget, do not leave outputMode as summary. If the server returns a clarification message, relay it to the user and ask for the missing detail. If the user's intent is genuinely unclear, ask before calling.

inventory_analysis

ChatGPT
Aggregate / rank / trend / total Inventory (read-only). Requires dimensionKey + metricKey. Inventory = STOCK AS IT STANDS RIGHT NOW, by warehouse / bin / style / color / size — a point-in-time snapshot, never a period of activity. Use for "what do we have", "available to sell", "stock by warehouse", "which bins hold style X", "how much is allocated / picked / packed". NOT for anything that HAPPENED over a period: booked / ordered / open-order units and allocation against orders → order_analysis; sold / shipped / revenue / margin / units shipped → invoice_analysis. NO TIME FRAME APPLIES: the only date column, lastCountedOn, is a cycle-count audit stamp that is null on ~99.9% of rows, so it does not bound a stock question. METRICS: available_units (openStockQuantity) = what can actually be promised = on-hand less picked, in-transfer and allocated; on_hand_units (stockQuantity) = the physical figure before those reservations; packed_units is a SUBSET of picked_units, so never add the two together; transfer_out_units is stock reserved to move OUT to another warehouse and is still inside on-hand — it is not inbound in-transit stock. EVERYTHING IS INCLUDED, NOTHING FILTERED: every warehouse, bin and size counts whatever its status, and uncounted bins count too. When part of a figure sits in an inactive warehouse, bin or size, that split is part of the figure ("1,204 units; 87 in 2 inactive bins"), in each warehouse breakdown as well. STOCK VS DEMAND is not available here: there is no join between inventory and orders/invoices. For ONE order or ONE style it is legitimate to answer in two calls — read the order or the style's demand first, then this tool filtered to those styles — stating that the two figures come from different queries. A BULK question ("which of our open orders can we fill") cannot be answered with this tool: previewRows is a sample, never a basis for a coverage answer. TOP-N: "top 10 <dimension> by <metric>" → grouped_summary + that dimensionKey + limit (one row per dimension value). BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. There are no line items in Inventory: never line_items here. To list individual records, use search_inventory. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: warehouse=Warehouse, bin=Bin Location, bin_category=Bin Category, style=Style, color=Color, style_color=Style + Color, size=Size, sku=SKU (Style + Color + Size), warehouse_status=Warehouse Status, size_status=Size Status SUPPORTED METRICS: available_units=Available Units, on_hand_units=On-Hand Units, allocated_units=Allocated Units, picked_units=Picked Units, packed_units=Packed Units, transfer_out_units=Outbound Transfer Units, bin_records=Bin Records SUPPORTED BASE PATTERNS: (none)

invoice_analysis

ChatGPT
Aggregate / rank / trend / total Invoices (read-only). Requires dimensionKey + metricKey. Invoices = SALES / SOLD / REVENUE (shipped & invoiced), units shipped, margin. Use for "total sales", "top sold styles", "revenue by month", "margin by customer". TOP-N: "top customers by $" → grouped_summary + dimensionKey=customer (one row per customer); "top styles/sizes by units" → line_items + dimensionKey=style/size. Pick queryKind by what the user wants ONE ROW PER, not the word "top". BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. "by month / quarter / year" → grouped_summary + a date dimension + timeGrain. For a specific record, use get_invoice_details. Line-item-only metrics (ship_quantity, back_order_quantity) MUST use line_items. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: customer=Customer, invoice_status=Invoice Status, order_source=Order Source, retail_invoice=Retail / DTC, shopify_store=Shopify Store, division=Division, season=Season, sales_rep=Sales Rep, bill_to_state=Bill-to State, ship_to_state=Ship-to State, term=Payment Term, ship_via=Carrier, invoice_date=Invoice Date, due_date=Due Date, style=Style, color=Color, style_color=Style + Color, size=Size, style_size=Style + Size, style_color_size=Style + Color + Size SUPPORTED METRICS: total_amount=Total Amount, merchandise=Merchandise, balance=Balance, invoice_count=Invoice Count, ship_quantity=Units Shipped, back_order_quantity=Units Back-Ordered, margin_pct=Margin %, aur=Avg Unit Retail, net_sales=Net Sales, gross_margin=Gross Margin SUPPORTED BASE PATTERNS: overdue=Overdue invoices — Open invoices where dueDate has passed, outstanding_balance=Outstanding balance — Open invoices with a remaining balance

order_analysis

ChatGPT
Aggregate / rank / trend / total Orders (read-only). Requires dimensionKey + metricKey. Orders = BOOKED / ORDERED (backlog, open units, allocation) — NOT yet shipped. For SALES / SOLD / REVENUE / units-shipped / margin use invoice_analysis. TOP-N: "top customers by $" → grouped_summary + dimensionKey=customer (one row per customer); "top styles/sizes by units" → line_items + dimensionKey=style/size. Pick queryKind by what the user wants ONE ROW PER, not the word "top". BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. "by month / quarter / year" → grouped_summary + a date dimension + timeGrain. For a specific record, use get_order_details. Line-item-only metrics (ship_quantity, back_order_quantity) MUST use line_items. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: order_source=order source, customer=customer, status=status, ship_to_state=state, division=division, season=season, sales_rep=sales rep, term=payment terms, ship_via=shipping method, buyer=buyer, vendor=vendor, retail_order=retail order, bulk_order=bulk order, created_date=created date, entered_date=entered date, complete_date=complete date, start_date=start date, style=Style, color=Color, cancel_reason=Cancellation Reason, style_color=Style/Color, size=Size, style_size=Style/Size, style_color_size=Style/Color/Size SUPPORTED METRICS: ordered_amount=Ordered amount, open_amount=Open amount, ship_amount=Shipped amount, original_booked_amount=Original booked amount, cancelled_amount=Cancelled amount, order_count=Order count, booked_qty=Booked Total, original_booked_qty=Original booked quantity, open_qty=Open units, ship_qty=Units shipped, cancel_qty=Cancelled quantity, fill_rate=Fill Rate, cancellation_rate=Cancellation Rate SUPPORTED BASE PATTERNS: overdue=Overdue orders — Open/Hold where completion date has passed, no_allocation=No allocation — Open/Hold orders with zero stock and zero WIP allocation

purchase_order_analysis

ChatGPT
Aggregate / rank / trend / total Purchase Orders (read-only). Requires dimensionKey + metricKey. Purchase orders = what WE BUY FROM VENDORS so we can fulfil what customers order — finished goods (type Style) or raw goods (type Material), one row per purchase order header. Use for "what have we got on order", "purchase orders by vendor", "units still to be received", "what is landing in November", "how much did we commit to buy this quarter", "which vendor has the most open units", "goods received from a vendor". NOT for what customers ordered from us — that is order_analysis. The word "orders" alone always means CUSTOMER orders; only "purchase orders" means this. A customer's own PO reference on a sales order is an ORDERS field, not this domain. TWO DATES: issuedDate is when the purchase order was raised (the default), inWarehouseDate is when the goods are expected to arrive. "POs in August" means issued in August; "arriving in November" means inWarehouseDate. They are different questions. UNITS AND VALUE ARE SEPARATE MEASURES throughout — budget/open/received/cancelled/damaged are piece counts, and each has its own *Amount measure in money; a unit figure is never a money figure. THE FIGURES ARE TAKEN AT FACE VALUE. The only stated composition is open = openForAllocation + allocated. In particular RECEIVED CAN EXCEED BUDGET and that is normal — a vendor sometimes cuts more pieces than were asked for — so it is not an error and does not imply a shortfall. TOP-N: "top 10 <dimension> by <metric>" → grouped_summary + that dimensionKey + limit (one row per dimension value). BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. There are no line items in Purchase Orders: never line_items here. "by month / quarter / year" → grouped_summary + a date dimension + timeGrain. For a specific record, use get_purchase_order_details. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: vendor=Vendor, po_status=PO Status, po_type=PO Type, division=Division, warehouse=Warehouse, country_of_origin=Country of Origin, issued_date=Issued Date, in_warehouse_date=In-Warehouse Date, purchase_order=Purchase Order, created_by=Created By SUPPORTED METRICS: po_count=Purchase Orders, budget_units=Units Ordered, budget_amount=Value Ordered, open_units=Units Open, open_amount=Value Open, received_units=Units Received, received_amount=Value Received, cancelled_units=Units Cancelled, cancelled_amount=Value Cancelled, damaged_units=Units Damaged, damaged_amount=Value Damaged, allocated_units=Units Allocated, open_for_allocation_units=Units Open for Allocation, wip_units=Units in WIP SUPPORTED BASE PATTERNS: (none)

retrieve_aims360_metadata

ChatGPT
Resolve AIMS360 field names, business synonyms, dimensions, metrics, and business patterns before building a query intent. Use this first when the user asks about fields, columns, meanings, business definitions, grouping choices, metrics, filters, or ambiguous phrases. Use this first when the user's phrasing contains business domain vocabulary such as unallocated, past due, no WIP, outstanding balance, or overdue invoices. The returned patternHints field tells you the correct basePattern and recommended queryKind to use in handle_aims360_request. This is a RAG-style retrieval layer over the field registry, curated overlay, supported dimensions/metrics, expands, and business patterns for the requested domain. Use the returned fields, dimensions, metrics, businessDefinitions, and intentHints to choose the structured input for handle_aims360_request. The retrieved context is guidance only; handle_aims360_request still validates the final intent against the full registry.

search_inventory

ChatGPT
Fetch Inventory RECORDS (read-only): a filtered list where each row IS an inventory. Use for: "which bins hold style 6212KN", "stock of style 6212KN in warehouse 00002". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "shelf" → binLocation) automatically; on a miss it suggests the right name. There is NO single-record lookup here — an inventory is found by filtering, not fetched by number. Use raw_list with the filters that identify what you want. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use inventory_analysis instead. queryKind: raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

search_style_inventory_adjustments

ChatGPT
Fetch Style Inventory Adjustments RECORDS (read-only): a filtered list where each row IS a style inventory adjustment. Use for: "adjustments to style 6212KN last week", "transfers into warehouse 00002 in September". Add selectFields/filters/sortSpec as needed — the server resolves field synonyms (e.g. "movement date" → transactionDate) automatically; on a miss it suggests the right name. There is NO single-record lookup here — a style inventory adjustment is found by filtering, not fetched by number. Use raw_list with the filters that identify what you want. For totals, rankings, breakdowns, trends, or per-style/size aggregation, use style_inventory_adjustment_analysis instead. queryKind: raw_list. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD.

style_inventory_adjustment_analysis

ChatGPT
Aggregate / rank / trend / total Style Inventory Adjustments (read-only). Requires dimensionKey + metricKey. Style inventory adjustments = the LEDGER OF STOCK MOVEMENTS — every change to stock, one row per movement, with when it happened, which style/color/size, which warehouse and bin, WHY (the transaction code) and by how much. Use for "what adjustments were made to style X", "which styles had the biggest negative adjustments", "physical inventory corrections by warehouse", "who made manual adjustments last week", "how much stock moved in and out of warehouse Y". NOT for what is on the shelf NOW — current/available/on-hand stock is search_inventory or inventory_analysis. NOT for orders or invoices. THE METRIC IS A SIGNED NET CHANGE: quantityTotal is taken at face value — positive adds stock, negative removes it, and summing gives the NET movement for the period. It is NOT re-interpreted by transaction code, so there is no "units received" or "units sold" measure here. If a reader wants that split, GROUP BY transaction_code and let them read it. Note Transfer-In and Transfer-Out mirror each other exactly and net to zero across the company, which is correct for a net-change figure. TRANSACTION CODE IS THE MOST IMPORTANT DIMENSION on this domain — most questions about adjustments are really questions about WHY stock moved. The 15 codes are a closed set; use the code (PI, AM, PR…) or say the description ("physical inventory") and it resolves. ALWAYS BOUND BY A DATE: this table holds 9.6M rows going back to 2006, and an unbounded rollup is slow or fails. transactionDate is the only date here. COST IS NOT AVAILABLE as a measure yet, pending confirmation from the dev team of what the cost represents. Stock BALANCE after a movement is not available either. TOP-N: "top 10 <dimension> by <metric>" → grouped_summary + that dimensionKey + limit (one row per dimension value). BOTTOM-N ("slowest", "lowest", "fewest", "bottom 5") is the same call with sort='lowest'. There are no line items in Style Inventory Adjustments: never line_items here. To list individual records, use search_style_inventory_adjustments. Always pass the user's wording in userQuery and clientDate as YYYY-MM-DD. The server resolves dimension/metric synonyms automatically. SUPPORTED DIMENSIONS: transaction_code=Transaction Type, style=Style, color=Color, style_color=Style + Color, size=Size, sku=SKU (Style + Color + Size), warehouse=Warehouse, bin=Bin Location, bin_category=Bin Category, created_by=Created By SUPPORTED METRICS: net_change=Net Change (Units), adjustment_count=Adjustment Records SUPPORTED BASE PATTERNS: (none)

update_customer

ChatGPT
UPDATES an existing customer in AIMS360. This WRITES and OVERWRITES — the previous value is not kept anywhere, so a wrong change has to be put back by hand. Say WHICH customer with customerAccount (the 5-character code) or customerID. This tool does not search by name — use get_customer_details to find the account first. TWO STEPS, ALWAYS. Call it first WITHOUT confirmToken: nothing is written, and it returns every requested field as CURRENT → NEW, plus a confirmToken. Show that to the user. Only call it again — same values, plus the token — once they have agreed. SEND ONLY WHAT THE USER ASKED TO CHANGE. Every field is optional; a field left null is not sent and keeps its current value. Never fill in a field just because you know its current value. To REMOVE a value (blank the fax, take the factor off) list it in clearFields. A null or empty field is never treated as a request to clear. The account code itself cannot be changed; the name can. One customer per call. Custom fields are not supported. Codes, names and GUIDs for terms, ship via, division, sales reps, classification, warehouse and the rest resolve against your own tenant; an ambiguous one comes back as a question listing the real options. Afterwards it reads the customer back and names any value AIMS360 did not store as sent, and any field that changed without being asked for. If AIMS360 rejects the change, its own error is returned.

update_order

ChatGPT
UPDATES an existing sales order in AIMS360 — header fields, existing lines and new lines. This WRITES and OVERWRITES; previous values are kept nowhere. Only Open and Hold orders can be changed. Say WHICH order with order (the order number) or orderID. It does not search — use get_order_details to find the order first. TWO STEPS, ALWAYS. Call it first WITHOUT confirmToken: nothing is written, and it returns every requested change as CURRENT → NEW, each line marked UPDATE or ADD, plus a confirmToken. Show that to the user, including its notes. Only call again — same values, plus the token — once they agree. SEND ONLY WHAT THE USER ASKED TO CHANGE. Every field is optional; anything left out is not sent. AIMS360 may still adjust related values itself (e.g. every line's commission after a rep change) — the preview notes say so where known. Remove a value with clearFields. LINES are named by style + colour and matched to THIS order's own lines; a style-colour already on the order is updated, never duplicated. A size can be SET (quantity) or changed by an amount (add / remove) — the server does the arithmetic. If a size already has shipped or cancelled units, a SET quantity is ambiguous (total, or still to ship?) and the tool ASKS: pass the user's answer as quantityMeaning. Never guess it. When the tool comes back with a QUESTION or a numbered list (which line, which colour, which card, which option), put it to the user as given and re-call with their answer. Cannot be changed here (AIMS360's own rules): the customer, the order number, third-party order ID, drop-ship and bulk/distribution settings, prepayments, and cancelling the order. A whole line cannot be removed yet, but quantities can be lowered. Card numbers are never accepted — choose one of the customer's SAVED cards by its last 4 digits. Afterwards it reads the order back and reports anything not stored as sent, anything the read cannot confirm, and anything AIMS360 changed on its own. If AIMS360 refuses, its own error is returned. If the outcome is UNKNOWN (a dropped connection), say so and check the order before any retry.

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

19

Tools

3

Prompts

ChatGPT

Platforms

Works with

ChatGPT

Data refreshed daily